Repository: endojs/endo
Pull request #2386 (2024-07-27 01:28:14)

feat(ses): Compartment options migration
Refs: #400

## Description

To converge with XS in the patterns accepted by SES for Compartment construction, this change introduces a `__options__` property to the first argument of the Compartment constructor that indicates that the constructor accepts a single options bag argument and does not receive separate endowments and module map arguments.

### Security Considerations

None.

### Scaling Considerations

None.

### Documentation Considerations

This change includes updates for NEWS (with migration instructions and a notice of intent to break deprecated usage patterns) and README (to encourage recommended usage). We intend to follow up with an update to hardenedjs.org upon release.

### Testing Considerations

All tests have been updated to use the new constructor pattern except those already marked as legacy, which remain to exercise support for the deprecated usage patterns.

### Compatibility Considerations

There is a remote possibility that existing code uses `__options__` as the name of an endowment and will now be misinterpreted. We do not imagine any guest programs are in a position to influence their host compartment’s construction.

### Upgrade Considerations

None.


Patch:
diff --git a/packages/compartment-mapper/src/import-archive-lite.js b/packages/compartment-mapper/src/import-archive-lite.js
index 774e8e077..6d48630f7 100644
--- a/packages/compartment-mapper/src/import-archive-lite.js
+++ b/packages/compartment-mapper/src/import-archive-lite.js
@@ -230,32 +230,6 @@ const makeArchiveImportHookMaker = (
   return makeImportHook;
 };
 
-/**
- * Creates a fake module namespace object that passes a brand check.
- *
- * @param {typeof Compartment} Compartment
- * @returns {ModuleExportsNamespace}
- */
-const makeFauxModuleExportsNamespace = Compartment => {
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      resolveHook() {
-        return '.';
-      },
-      async importHook() {
-        return {
-          imports: [],
-          execute() {},
-          exports: [],
-        };
-      },
-    },
-  );
-  return compartment.module('.');
-};
-
 // Have to give it a name to capture the external meaning of Compartment
 // Otherwise @param {typeof Compartment} takes the Compartment to mean
 // the const variable defined within the function.
@@ -377,7 +351,7 @@ export const parseArchive = async (
       languageForExtension,
       modules: Object.fromEntries(
         Object.keys(modules || {}).map(specifier => {
-          return [specifier, makeFauxModuleExportsNamespace(Compartment)];
+          return [specifier, { namespace: {} }];
         }),
       ),
       Compartment,
diff --git a/packages/compartment-mapper/src/link.js b/packages/compartment-mapper/src/link.js
index c417c8597..f08068756 100644
--- a/packages/compartment-mapper/src/link.js
+++ b/packages/compartment-mapper/src/link.js
@@ -449,13 +449,14 @@ export const link = (
       scopes,
     );
 
-    const compartment = new Compartment(create(null), undefined, {
+    const compartment = new Compartment({
+      name: location,
       resolveHook,
       importHook,
       moduleMapHook,
       transforms,
       __shimTransforms__,
-      name: location,
+      __options__: true,
     });
 
     if (!archiveOnly) {
diff --git a/packages/ses/NEWS.md b/packages/ses/NEWS.md
index 10a93aa9a..dca15dc6c 100644
--- a/packages/ses/NEWS.md
+++ b/packages/ses/NEWS.md
@@ -2,7 +2,43 @@ User-visible changes in SES:
 
 # Next version
 
+- *NOTICE*: This version introduces multiple features to converge upon a
+  more common standard for [Hardened JavaScript](https://hardenedjs.org).
+  All code should begin migrating to these usage patterns as the older
+  patterns are now deprecated and will not be supported in a future major
+  version of SES.
+
+- To converge on a portable pattern for using `Compartment`, introduces an
+  `__options__` property for the first argument of the `Compartment`
+  constructor that must be `true` if present and indicates the object is the
+  options bag and not the global endowments. All code going forward should
+  include this flag until the next major version of SES, when we plan for it to
+  become vesgitial and drop support for three-argument `Compartment`
+  construction.
+
+  In the unlikely event that existing code names an endowment `__options__`,
+  that code will break and need to be adjusted to adopt this version.
+  Because we rate this unlikely, we have elected not to mark this with
+  a major version bump.
+
+- Adds a `__noNamespaceBox__` option that aligns the behavior of the `import`
+  method on SES `Compartment` with the behavior of XS and the behavior we will
+  champion for compartment standards.
+  All use of `Compartment` should migrate to use this option as the standard
+  behavior will be enabled by default with the next major version of SES.
+
 - Adds support for module descriptors better aligned with XS.
+  Compartments use module desriptors to load and link modules.
+  The importHook, importNowHook, and moduleMapHook all return module descriptors
+  (sometimes promises for module descriptors).
+  The modules option or argument to the Compatment constructor has module
+  descriptors for all its values.
+  - `{record, specifier, compartment}` should become `{source: record,
+    specifier, compartment}`.
+  - `{specifier, compartment}` should become `{source: specifier,
+    compartment}`.
+  - `{record: compartment.module(specifier)}` should become `{namespace:
+    specifier, compartment}`.
 
 - When running transpiled code on Node, the SES error taming
   gives line-numbers into the generated JavaScript, which often don't match the
@@ -25,12 +61,6 @@ User-visible changes in SES:
   the stacktrace line-numbers point back into the original
   source, as they do on Node without SES.
   
-- Adds a `__noNamespaceBox__` option that aligns the behavior of the `import`
-  method on SES `Compartment` with the behavior of XS and the behavior we will
-  champion for compartment standards.
-  All use of `Compartment` should migrate to use this option as the standard
-  behavior will be enabled by default with the next major version of SES.
-
 # v1.5.0 (2024-05-06)
 
 - Adds `importNowHook` to the `Compartment` options. The compartment will invoke the hook whenever it encounters a missing dependency while running `compartmentInstance.importNow(specifier)`, which cannot use an asynchronous `importHook`.
diff --git a/packages/ses/README.md b/packages/ses/README.md
index 10a2cdc8d..c2cba8449 100644
--- a/packages/ses/README.md
+++ b/packages/ses/README.md
@@ -169,7 +169,10 @@ function on `globalThis`.
 import 'ses';
 
 const c = new Compartment({
-  print: harden(console.log),
+  globals: {
+    print: harden(console.log),
+  },
+  __options__: true, // temporary migration affordance
 });
 
 c.evaluate(`
@@ -213,7 +216,10 @@ through:
 * by assigning them to the compartment's `globalThis` after construction.
 
 ```js
-const powerfulCompartment = new Compartment({ Math });
+const powerfulCompartment = new Compartment({
+  globals: { Math },
+  __options__: true, // temporary migration affordance
+});
 powerfulCompartment.globalThis.Date = Date;
 ```
 
@@ -286,7 +292,7 @@ specifier for another module from a referrer module and the import specifier.
 import 'ses';
 import { ModuleSource } from '@endo/module-source';
 
-const c1 = new Compartment({}, {}, {
+const c1 = new Compartment({
   name: "first compartment",
   resolveHook: (moduleSpecifier, moduleReferrer) => {
     return resolve(moduleSpecifier, moduleReferrer);
@@ -298,6 +304,7 @@ const c1 = new Compartment({}, {}, {
         source: new ModuleSource(moduleText, moduleLocation);
     };
   },
+  __options__: true, // temporary migration affordance
 });
 ```
 
@@ -310,15 +317,17 @@ const c1 = new Compartment({}, {}, {
 A compartment can also link a module in another compartment.
 
 ```js
-const c2 = new Compartment({}, {
-  'c1': {
-    source: './main.js',
-    compartment: c1,
-  },
-}, {
+const c2 = new Compartment({
   name: "second compartment",
+  modules: {
+    'c1': {
+      source: './main.js',
+      compartment: c1,
+    },
+  },
   resolveHook,
   importHook,
+  __options__: true, // temporary migration affordance
 });
 ```
 
@@ -406,9 +415,10 @@ const importHook = async specifier => {
   throw new Error(`Cannot find module ${specifier}`);
 };
 
-const compartment = new Compartment({}, {}, {
+const compartment = new Compartment({
   resolveHook,
   importHook,
+  __options__: true, // temporary migration affordance
 });
 ```
 
@@ -443,16 +453,18 @@ const moduleMapHook = moduleSpecifier => {
   }
 };
 
-const even = new Compartment({}, {}, {
+const even = new Compartment({
   resolveHook: nodeResolveHook,
   importHook: makeImportHook('https://example.com/even'),
   moduleMapHook,
+  __options__: true, // temporary migration affordance
 });
 
-const odd = new Compartment({}, {}, {
+const odd = new Compartment({
   resolveHook: nodeResolveHook,
   importHook: makeImportHook('https://example.com/odd'),
   moduleMapHook,
+  __options__: true, // temporary migration affordance
 });
 ```
 
@@ -471,12 +483,13 @@ receive the same record type as from `importHook` or throw if it cannot.
 import 'ses';
 import { ModuleSource } from '@endo/module-source';
 
-const compartment = new Compartment({}, {
-  c: {
-    source: new ModuleSource(''),
-  },
-}, {
+const compartment = new Compartment({
   name: "first compartment",
+  modules: {
+    c: {
+      source: new ModuleSource(''),
+    },
+  },
   resolveHook: (moduleSpecifier, moduleReferrer) => {
     return resolve(moduleSpecifier, moduleReferrer);
   },
@@ -495,6 +508,7 @@ const compartment = new Compartment({}, {
       source: new ModuleSource(moduleText, moduleLocation),
     };
   },
+  __options__: true, // temporary migration affordance
 });
 //...                   | importHook | importNowHook
 await compartment.import('a'); //| called     | not called
@@ -595,7 +609,11 @@ not a module.
 
 ```js
 const transforms = [addCodeCoverageInstrumentation];
-const c = new Compartment({ console, coverage }, null, { transforms });
+const c = new Compartment({
+  globals: { console, coverage },
+  transforms,
+  __options__: true, // temporary migration affordance
+});
 c.evaluate('console.log("Hello");');
 ```
 
@@ -633,8 +651,10 @@ instead of `transforms`.
 
 ```js
 const __shimTransforms__ = [addCoverage];
-const c = new Compartment({ console, coverage }, null, {
+const c = new Compartment({
+  globals: { console, coverage },
   __shimTransforms__,
+  __options__: true, // temporary migration affordance
 });
 c.evaluate('console.log("Hello");');
 ```
@@ -741,11 +761,17 @@ abilities.
 lockdown();
 
 const promise = new Promise(resolve => {
-  const compartmentA = new Compartment(harden({ resolve }));
+  const compartmentA = new Compartment({
+    globals: harden({ resolve }),
+  __options__: true, // temporary migration affordance
+  });
   compartmentA.evaluate(programA);
 });
 
-const compartmentB = new Compartment(harden({ promise }));
+const compartmentB = new Compartment({
+  globals: harden({ promise }),
+  __options__: true, // temporary migration affordance
+});
 compartmentB.evaluate(programB);
 ```
 
diff --git a/packages/ses/src/compartment.js b/packages/ses/src/compartment.js
index 270c8203c..7e7c9d9a0 100644
--- a/packages/ses/src/compartment.js
+++ b/packages/ses/src/compartment.js
@@ -19,6 +19,7 @@ import {
   setGlobalObjectMutableProperties,
   setGlobalObjectEvaluators,
 } from './global-object.js';
+import { assertEqual } from './error/assert.js';
 import { sharedGlobalPropertyNames } from './permits.js';
 import { load, loadNow } from './module-load.js';
 import { link } from './module-link.js';
@@ -26,6 +27,8 @@ import { getDeferredExports } from './module-proxy.js';
 import { compartmentEvaluate } from './compartment-evaluate.js';
 import { makeSafeEvaluator } from './make-safe-evaluator.js';
 
+/** @import {ModuleDescriptor} from '../types.js' */
+
 // moduleAliases associates every public module exports namespace with its
 // corresponding compartment and specifier so they can be used to link modules
 // across compartments.
@@ -172,6 +175,55 @@ defineProperties(InertCompartment, {
  * @returns {Compartment['constructor']}
  */
 
+// In order to facilitate migration from the deprecated signature
+// of the compartment constructor,
+//   new Compartent(globals?, modules?, options?)
+// to the new signature:
+//   new Compartment(options?)
+// where globals and modules are expressed in the options bag instead of
+// positional arguments, this function detects the temporary sigil __options__
+// on the first argument and coerces compartments arguments into a single
+// compartments object.
+const compartmentOptions = (...args) => {
+  if (args.length === 0) {
+    return {};
+  }
+  if (
+    args.length === 1 &&
+    typeof args[0] === 'object' &&
+    args[0] !== null &&
+    '__options__' in args[0]
+  ) {
+    const { __options__, ...options } = args[0];
+    assert(
+      __options__ === true,
+      `Compartment constructor only supports true __options__ sigil, got ${__options__}`,
+    );
+    return options;
+  } else {
+    const [
+      globals = /** @type {Map<string, any>} */ ({}),
+      modules = /** @type {Map<string, ModuleDescriptor>} */ ({}),
+      options = {},
+    ] = args;
+    assertEqual(
+      options.modules,
+      undefined,
+      `Compartment constructor must receive either a module map argument or modules option, not both`,
+    );
+    assertEqual(
+      options.globals,
+      undefined,
+      `Compartment constructor must receive either globals argument or option, not both`,
+    );
+    return {
+      ...options,
+      globals,
+      modules,
+    };
+  }
+};
+
 /** @type {MakeCompartmentConstructor} */
 export const makeCompartmentConstructor = (
   targetMakeCompartmentConstructor,
@@ -179,11 +231,7 @@ export const makeCompartmentConstructor = (
   markVirtualizedNativeFunction,
   parentCompartment = undefined,
 ) => {
-  function Compartment(
-    endowmentsOption = {},
-    moduleMapOption = {},
-    options = {},
-  ) {
+  function Compartment(...args) {
     if (new.target === undefined) {
       throw TypeError(
         "Class constructor Compartment cannot be invoked without 'new'",
@@ -195,13 +243,15 @@ export const makeCompartmentConstructor = (
       name = '<unknown>',
       transforms = [],
       __shimTransforms__ = [],
+      globals: endowmentsOption = {},
+      modules: moduleMapOption = {},
       resolveHook,
       importHook,
       importNowHook,
       moduleMapHook,
       importMetaHook,
       __noNamespaceBox__: noNamespaceBox = false,
-    } = options;
+    } = compartmentOptions(...args);
     const globalTransforms = [...transforms, ...__shimTransforms__];
     const endowments = { __proto__: null, ...endowmentsOption };
     const moduleMap = { __proto__: null, ...moduleMapOption };
diff --git a/packages/ses/src/error/assert.js b/packages/ses/src/error/assert.js
index 9106b7ee8..29f6f8d76 100644
--- a/packages/ses/src/error/assert.js
+++ b/packages/ses/src/error/assert.js
@@ -568,5 +568,15 @@ const assert = makeAssert();
 export { assert };
 
 // Internal, to obviate polymorphic dispatch, but may become rigorously
-// consistent with @endo/error.
-export { makeError, note as annotateError, redactedDetails as X, quote as q };
+// consistent with @endo/error:
+
+/** @type {AssertionFunctions['equal']} */
+const assertEqual = assert.equal;
+
+export {
+  assertEqual,
+  makeError,
+  note as annotateError,
+  redactedDetails as X,
+  quote as q,
+};
diff --git a/packages/ses/types.d.ts b/packages/ses/types.d.ts
index 4d40fc801..ae342bcca 100644
--- a/packages/ses/types.d.ts
+++ b/packages/ses/types.d.ts
@@ -102,7 +102,8 @@ export type ModuleDescriptor =
   | RecordModuleDescriptor
   | ModuleExportsNamespace
   | VirtualModuleSource
-  | PrecompiledModuleSource;
+  | PrecompiledModuleSource
+  | string;
 
 // Deprecated type aliases:
 export type PrecompiledStaticModuleInterface = PrecompiledModuleSource;
@@ -122,6 +123,10 @@ export type ModuleMapHook = (
 ) => ModuleDescriptor | undefined;
 export type ImportHook = (moduleSpecifier: string) => Promise<ModuleDescriptor>;
 export type ImportNowHook = (moduleSpecifier: string) => ModuleDescriptor;
+export type ImportMetaHook = (
+  moduleSpecifier: string,
+  importMeta: Object,
+) => void;
 
 export interface CompartmentOptions {
   name?: string;
@@ -129,8 +134,12 @@ export interface CompartmentOptions {
   moduleMapHook?: ModuleMapHook;
   importHook?: ImportHook;
   importNowHook?: ImportNowHook;
+  importMetaHook?: ImportMetaHook;
   resolveHook?: ResolveHook;
+  globals?: Map<string, any>;
+  modules?: Map<string, ModuleDescriptor>;
   __shimTransforms__?: Array<Transform>;
+  __noNamespaceBox__?: boolean;
 }
 
 export interface EvaluateOptions {
@@ -532,9 +541,12 @@ declare global {
    * code in a context bound to a new global creates a new compartment.
    */
   export class Compartment {
+    constructor(options?: CompartmentOptions & { __options__: true });
+
+    // Deprecated:
     constructor(
-      globals?: Object,
-      moduleMap?: ModuleMap,
+      globals?: Record<string, any> | undefined,
+      modules?: Record<string, ModuleDescriptor>,
       options?: CompartmentOptions,
     );
 


Test patch:
diff --git a/packages/compartment-mapper/test/bundle.test.js b/packages/compartment-mapper/test/bundle.test.js
index 2fcf01e69..abc5fc007 100644
--- a/packages/compartment-mapper/test/bundle.test.js
+++ b/packages/compartment-mapper/test/bundle.test.js
@@ -61,7 +61,10 @@ test('bundles work', async t => {
   const print = entry => {
     log.push(entry);
   };
-  const compartment = new Compartment({ print });
+  const compartment = new Compartment({
+    globals: { print },
+    __options__: true,
+  });
   compartment.evaluate(bundle);
   t.deepEqual(log, expectedLog);
 });
@@ -93,7 +96,10 @@ test.failing('bundle cjs-compat', async t => {
   const print = entry => {
     log.push(entry);
   };
-  const compartment = new Compartment({ print });
+  const compartment = new Compartment({
+    globals: { print },
+    __options__: true,
+  });
   compartment.evaluate(bundle);
   t.deepEqual(log, expectedLog);
 });
diff --git a/packages/compartment-mapper/test/main.test.js b/packages/compartment-mapper/test/main.test.js
index 47e24585e..8200845e4 100644
--- a/packages/compartment-mapper/test/main.test.js
+++ b/packages/compartment-mapper/test/main.test.js
@@ -95,11 +95,14 @@ test('makeBundle / importArchive', async t => {
 
   const archiverBundle = await makeBundle(readPowers.read, archiverLocation);
   const archiverCompartment = new Compartment({
-    TextEncoder,
-    TextDecoder,
-    URL,
-    // See https://github.com/Agoric/agoric-sdk/issues/9515
-    assert: globalThis.assert,
+    globals: {
+      TextEncoder,
+      TextDecoder,
+      URL,
+      // See https://github.com/Agoric/agoric-sdk/issues/9515
+      assert: globalThis.assert,
+    },
+    __options__: true,
   });
   const evasiveArchiverBundle = archiverBundle
     .replace(/(?<!\.)\bimport\b(?![:"'])/g, 'IMPORT')
diff --git a/packages/ses/test/compartment-constructor.test.js b/packages/ses/test/compartment-constructor.test.js
index bea5f6021..e2e670a6a 100644
--- a/packages/ses/test/compartment-constructor.test.js
+++ b/packages/ses/test/compartment-constructor.test.js
@@ -35,21 +35,18 @@ test('Compartment class', t => {
 });
 
 test('Compartment name', t => {
-  const c = new Compartment({}, {}, { name: 'x' });
+  const c = new Compartment({ name: 'x', __options__: true });
   t.is(c.name, 'x');
 });
 
 test('Compartment name object toString', t => {
-  const c = new Compartment(
-    {},
-    {},
-    {
-      name: {
-        toString() {
-          return 'x';
-        },
+  const c = new Compartment({
+    name: {
+      toString() {
+        return 'x';
       },
     },
-  );
+    __options__: true,
+  });
   t.is(c.name, 'x');
 });
diff --git a/packages/ses/test/compartment-transforms.test.js b/packages/ses/test/compartment-transforms.test.js
index 2e18ff708..bdc0b01e2 100644
--- a/packages/ses/test/compartment-transforms.test.js
+++ b/packages/ses/test/compartment-transforms.test.js
@@ -9,7 +9,7 @@ test('transforms apply to evaluated expressions', t => {
 
   const transform = source => source.replace(/Farewell/g, 'Hello');
   const transforms = [transform];
-  const c = new Compartment({}, {}, { transforms });
+  const c = new Compartment({ transforms, __options__: true });
   const greeting = c.evaluate('"Farewell, World!"');
 
   t.is(greeting, 'Hello, World!');
@@ -20,13 +20,13 @@ test('transforms apply to dynamic eval in compartments', t => {
 
   const transform = source => source.replace(/Farewell/g, 'Hello');
   const transforms = [transform];
-  const c = new Compartment(
-    {
+  const c = new Compartment({
+    transforms,
+    globals: {
       greeting: '"Farewell, World!"',
     },
-    {},
-    { transforms },
-  );
+    __options__: true,
+  });
   const greeting = c.evaluate('(0, eval)(greeting)');
 
   t.is(greeting, 'Hello, World!');
@@ -37,7 +37,7 @@ test('transforms do not apply to dynamic eval in compartments within compartment
 
   const transform = source => source.replace(/Farewell/g, 'Hello');
   const transforms = [transform];
-  const c = new Compartment({}, {}, { transforms });
+  const c = new Compartment({ transforms, __options__: true });
   const d = c.evaluate('new Compartment()');
   const greeting = d.evaluate('"Farewell, World!"');
 
@@ -52,11 +52,13 @@ test('transforms do not apply to imported modules', async t => {
   const resolveHook = () => '';
   const importHook = () =>
     new ModuleSource('export default "Farewell, World!";');
-  const c = new Compartment(
-    {},
-    {},
-    { transforms, resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const c = new Compartment({
+    transforms,
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await c.import('any-string-here');
   const { default: greeting } = namespace;
@@ -69,7 +71,10 @@ test('__shimTransforms__ apply to evaluated expressions', t => {
 
   const transform = source => source.replace(/Farewell/g, 'Hello');
   const transforms = [transform];
-  const c = new Compartment({}, {}, { __shimTransforms__: transforms });
+  const c = new Compartment({
+    __shimTransforms__: transforms,
+    __options__: true,
+  });
   const greeting = c.evaluate('"Farewell, World!"');
 
   t.is(greeting, 'Hello, World!');
@@ -83,16 +88,13 @@ test('__shimTransforms__ do apply to imported modules', async t => {
   const resolveHook = () => '';
   const importHook = () =>
     new ModuleSource('export default "Farewell, World!";');
-  const c = new Compartment(
-    {},
-    {},
-    {
-      __shimTransforms__: transforms,
-      __noNamespaceBox__: true,
-      resolveHook,
-      importHook,
-    },
-  );
+  const c = new Compartment({
+    __shimTransforms__: transforms,
+    __noNamespaceBox__: true,
+    __options__: true,
+    resolveHook,
+    importHook,
+  });
 
   const namespace = await c.import('any-string-here');
   const { default: greeting } = namespace;
diff --git a/packages/ses/test/compartment.test.js b/packages/ses/test/compartment.test.js
index d5517f301..5e20dc0ed 100644
--- a/packages/ses/test/compartment.test.js
+++ b/packages/ses/test/compartment.test.js
@@ -44,7 +44,7 @@ test('SES compartment also has compartments', t => {
 //   // });
 
 test('SES compartment has harden', t => {
-  const c = new Compartment({ a: 123 });
+  const c = new Compartment({ globals: { a: 123 }, __options__: true });
   const obj = c.evaluate('harden({a})');
   t.is(obj.a, 123, 'expected object');
   if (!harden.isFake) {
@@ -96,11 +96,17 @@ test('main use case', t => {
     }
     return power(arg);
   }
-  const attenuatedPower = new Compartment({ power }).evaluate(`(${attenuate})`);
+  const attenuatedPower = new Compartment({
+    globals: { power },
+    __options__: true,
+  }).evaluate(`(${attenuate})`);
   function use(arg) {
     return power(arg);
   }
-  const c = new Compartment({ power: attenuatedPower });
+  const c = new Compartment({
+    globals: { power: attenuatedPower },
+    __options__: true,
+  });
   const user = c.evaluate(`(${use})`);
   t.is(user(1), 2);
   t.throws(() => user(-1), { instanceOf: TypeError });
diff --git a/packages/ses/test/confinement.test.js b/packages/ses/test/confinement.test.js
index 6dfa91339..7573bd5a3 100644
--- a/packages/ses/test/confinement.test.js
+++ b/packages/ses/test/confinement.test.js
@@ -71,7 +71,7 @@ test('confinement evaluation Symbol.unscopables with-statement escape', t => {
   // by leaving its shadow on the actual global scope.
   globalThis.flag = 'unsafe';
 
-  const c = new Compartment({ flag: 'safe' });
+  const c = new Compartment({ globals: { flag: 'safe' }, __options__: true });
 
   // Known loss of fidility of emulating a proper host:
   t.throws(() => c.evaluate('Symbol.unscopables = { flag: true };'));
diff --git a/packages/ses/test/error/tame-console-unfilteredError.test.js b/packages/ses/test/error/tame-console-unfilteredError.test.js
index 0136d7252..c65e85359 100644
--- a/packages/ses/test/error/tame-console-unfilteredError.test.js
+++ b/packages/ses/test/error/tame-console-unfilteredError.test.js
@@ -21,12 +21,18 @@ test('console', t => {
 
   harden(getPrototypeOf(console));
   harden(console);
-  const c1 = new Compartment({ console });
+  const c1 = new Compartment({
+    globals: { console },
+    __options__: true,
+  });
   t.is(console, c1.evaluate('(console)'));
 
   const fakeConsole = { log: console.log };
   harden(fakeConsole);
-  const c2 = new Compartment({ console: fakeConsole });
+  const c2 = new Compartment({
+    globals: { console: fakeConsole },
+    __options__: true,
+  });
   t.is(console.log, c2.evaluate('(console.log)'));
 });
 
diff --git a/packages/ses/test/error/tame-console-unsafe-unfilteredError.test.js b/packages/ses/test/error/tame-console-unsafe-unfilteredError.test.js
index af8b3a001..6bfadbf6d 100644
--- a/packages/ses/test/error/tame-console-unsafe-unfilteredError.test.js
+++ b/packages/ses/test/error/tame-console-unsafe-unfilteredError.test.js
@@ -25,12 +25,18 @@ test('console', t => {
 
   harden(getPrototypeOf(console));
   harden(console);
-  const c1 = new Compartment({ console });
+  const c1 = new Compartment({
+    globals: { console },
+    __options__: true,
+  });
   t.is(console, c1.evaluate('(console)'));
 
   const fakeConsole = { log: console.log };
   harden(fakeConsole);
-  const c2 = new Compartment({ console: fakeConsole });
+  const c2 = new Compartment({
+    globals: { console: fakeConsole },
+    __options__: true,
+  });
   t.is(console.log, c2.evaluate('(console.log)'));
 });
 
diff --git a/packages/ses/test/error/tame-console-unsafe-unsafeError-unfilteredError.test.js b/packages/ses/test/error/tame-console-unsafe-unsafeError-unfilteredError.test.js
index b02588b3b..337c040e7 100644
--- a/packages/ses/test/error/tame-console-unsafe-unsafeError-unfilteredError.test.js
+++ b/packages/ses/test/error/tame-console-unsafe-unsafeError-unfilteredError.test.js
@@ -27,12 +27,18 @@ test('console', t => {
 
   harden(getPrototypeOf(console));
   harden(console);
-  const c1 = new Compartment({ console });
+  const c1 = new Compartment({
+    globals: { console },
+    __options__: true,
+  });
   t.is(console, c1.evaluate('(console)'));
 
   const fakeConsole = { log: console.log };
   harden(fakeConsole);
-  const c2 = new Compartment({ console: fakeConsole });
+  const c2 = new Compartment({
+    globals: { console: fakeConsole },
+    __options__: true,
+  });
   t.is(console.log, c2.evaluate('(console.log)'));
 });
 
diff --git a/packages/ses/test/error/tame-console-unsafe-unsafeError.test.js b/packages/ses/test/error/tame-console-unsafe-unsafeError.test.js
index f32cfdf28..de7a0e75e 100644
--- a/packages/ses/test/error/tame-console-unsafe-unsafeError.test.js
+++ b/packages/ses/test/error/tame-console-unsafe-unsafeError.test.js
@@ -26,12 +26,18 @@ test('console', t => {
 
   harden(getPrototypeOf(console));
   harden(console);
-  const c1 = new Compartment({ console });
+  const c1 = new Compartment({
+    globals: { console },
+    __options__: true,
+  });
   t.is(console, c1.evaluate('(console)'));
 
   const fakeConsole = { log: console.log };
   harden(fakeConsole);
-  const c2 = new Compartment({ console: fakeConsole });
+  const c2 = new Compartment({
+    globals: { console: fakeConsole },
+    __options__: true,
+  });
   t.is(console.log, c2.evaluate('(console.log)'));
 });
 
diff --git a/packages/ses/test/error/tame-console-unsafe.test.js b/packages/ses/test/error/tame-console-unsafe.test.js
index 0565669f1..4bc1f2bc1 100644
--- a/packages/ses/test/error/tame-console-unsafe.test.js
+++ b/packages/ses/test/error/tame-console-unsafe.test.js
@@ -21,12 +21,18 @@ test('console', t => {
 
   harden(getPrototypeOf(console));
   harden(console);
-  const c1 = new Compartment({ console });
+  const c1 = new Compartment({
+    globals: { console },
+    __options__: true,
+  });
   t.is(console, c1.evaluate('(console)'));
 
   const fakeConsole = { log: console.log };
   harden(fakeConsole);
-  const c2 = new Compartment({ console: fakeConsole });
+  const c2 = new Compartment({
+    globals: { console: fakeConsole },
+    __options__: true,
+  });
   t.is(console.log, c2.evaluate('(console.log)'));
 });
 
diff --git a/packages/ses/test/error/tame-console-unsafeError.test.js b/packages/ses/test/error/tame-console-unsafeError.test.js
index e0314362e..c6ba5b7d9 100644
--- a/packages/ses/test/error/tame-console-unsafeError.test.js
+++ b/packages/ses/test/error/tame-console-unsafeError.test.js
@@ -22,12 +22,18 @@ test('console', t => {
 
   harden(getPrototypeOf(console));
   harden(console);
-  const c1 = new Compartment({ console });
+  const c1 = new Compartment({
+    globals: { console },
+    __options__: true,
+  });
   t.is(console, c1.evaluate('(console)'));
 
   const fakeConsole = { log: console.log };
   harden(fakeConsole);
-  const c2 = new Compartment({ console: fakeConsole });
+  const c2 = new Compartment({
+    globals: { console: fakeConsole },
+    __options__: true,
+  });
   t.is(console.log, c2.evaluate('(console.log)'));
 });
 
diff --git a/packages/ses/test/error/tame-console.test.js b/packages/ses/test/error/tame-console.test.js
index 7f4bc6fcd..4b9d78889 100644
--- a/packages/ses/test/error/tame-console.test.js
+++ b/packages/ses/test/error/tame-console.test.js
@@ -21,12 +21,18 @@ test('console', t => {
 
   harden(getPrototypeOf(console));
   harden(console);
-  const c1 = new Compartment({ console });
+  const c1 = new Compartment({
+    globals: { console },
+    __options__: true,
+  });
   t.is(console, c1.evaluate('(console)'));
 
   const fakeConsole = { log: console.log };
   harden(fakeConsole);
-  const c2 = new Compartment({ console: fakeConsole });
+  const c2 = new Compartment({
+    globals: { console: fakeConsole },
+    __options__: true,
+  });
   t.is(console.log, c2.evaluate('(console.log)'));
 });
 
diff --git a/packages/ses/test/error/tame-v8-error-unsafe.test.js b/packages/ses/test/error/tame-v8-error-unsafe.test.js
index d4ba40333..6cf7495c9 100644
--- a/packages/ses/test/error/tame-v8-error-unsafe.test.js
+++ b/packages/ses/test/error/tame-v8-error-unsafe.test.js
@@ -52,7 +52,10 @@ function simulateDepd() {
 }
 
 test('SES compartment error compatibility - minimal case', t => {
-  const c1 = new Compartment({ t });
+  const c1 = new Compartment({
+    globals: { t },
+    __options__: true,
+  });
   const result = c1.evaluate(`
     const obj = {};
     Error.stackTraceLimit = 10;
@@ -64,7 +67,10 @@ test('SES compartment error compatibility - minimal case', t => {
 });
 
 test('SES compartment error compatibility - basic: prepareStackTrace accepts assignment', t => {
-  const c1 = new Compartment({ t });
+  const c1 = new Compartment({
+    globals: { t },
+    __options__: true,
+  });
   const result = c1.evaluate(`
     const obj = {};
     const newPST = (stack) => stack;
@@ -77,7 +83,10 @@ test('SES compartment error compatibility - basic: prepareStackTrace accepts ass
 });
 
 test('SES compartment error compatibility - functional prepareStackTrace', t => {
-  const c1 = new Compartment({ t });
+  const c1 = new Compartment({
+    globals: { t },
+    __options__: true,
+  });
   const result = c1.evaluate(`
     const prepareObjectStackTrace = (_, stack) => {
       t.fail('must not be called');
@@ -91,7 +100,10 @@ test('SES compartment error compatibility - functional prepareStackTrace', t =>
 });
 
 test('SES compartment error compatibility - endow w Error power', t => {
-  const c1 = new Compartment({ t, Error });
+  const c1 = new Compartment({
+    globals: { t, Error },
+    __options__: true,
+  });
   const result = c1.evaluate(`
     const obj = {
       toString: () => 'Pseudo Error',
@@ -155,7 +167,10 @@ test('SES compartment error compatibility - endow w Error with locally configura
     return LocalError;
   }
 
-  const c1 = new Compartment({ t, Error: createLocalError(Error) });
+  const c1 = new Compartment({
+    globals: { t, Error: createLocalError(Error) },
+    __options__: true,
+  });
   const result1 = c1.evaluate(`
   ${simulateDepd.toString()};
   simulateDepd();
@@ -163,7 +178,10 @@ test('SES compartment error compatibility - endow w Error with locally configura
   t.is(result1, 'getStack');
 
   // assert LocalError is not leaking to Error prototype
-  const evilC = new Compartment({ t, Error: createLocalError(Error) });
+  const evilC = new Compartment({
+    globals: { t, Error: createLocalError(Error) },
+    __options__: true,
+  });
   evilC.evaluate(`
     Error.prepareStackTrace = () => {
       t.fail('prepareStackTrace from evil compartment should not have been called');
diff --git a/packages/ses/test/global-lexicals-evaluate.test.js b/packages/ses/test/global-lexicals-evaluate.test.js
index e81e988c6..422fbe2d0 100644
--- a/packages/ses/test/global-lexicals-evaluate.test.js
+++ b/packages/ses/test/global-lexicals-evaluate.test.js
@@ -4,9 +4,11 @@ import '../index.js';
 test('endowments own properties are mentionable', t => {
   t.plan(1);
 
-  const endowments = { hello: 'World!' };
-  const modules = {};
-  const compartment = new Compartment(endowments, modules);
+  const globals = { hello: 'World!' };
+  const compartment = new Compartment({
+    globals,
+    __options__: true,
+  });
 
   const whom = compartment.evaluate('hello');
   t.is(whom, 'World!');
@@ -15,9 +17,11 @@ test('endowments own properties are mentionable', t => {
 test('endowments own properties are enumerable', t => {
   t.plan(1);
 
-  const endowments = { hello: 'World!' };
-  const modules = {};
-  const compartment = new Compartment(endowments, modules);
+  const globals = { hello: 'World!' };
+  const compartment = new Compartment({
+    globals,
+    __options__: true,
+  });
 
   const keys = compartment.evaluate('Object.keys(globalThis)');
   t.deepEqual(keys, ['hello']);
@@ -26,9 +30,11 @@ test('endowments own properties are enumerable', t => {
 test('endowments prototypically inherited properties are not mentionable', t => {
   t.plan(1);
 
-  const endowments = { __proto__: { hello: 'World!' } };
-  const modules = {};
-  const compartment = new Compartment(endowments, modules);
+  const globals = { __proto__: { hello: 'World!' } };
+  const compartment = new Compartment({
+    globals,
+    __options__: true,
+  });
 
   t.throws(() => compartment.evaluate('hello'), {
     message: /hello is not defined/,
@@ -38,9 +44,11 @@ test('endowments prototypically inherited properties are not mentionable', t =>
 test('endowments prototypically inherited properties are not enumerable', t => {
   t.plan(1);
 
-  const endowments = { __proto__: { hello: 'World!' } };
-  const modules = {};
-  const compartment = new Compartment(endowments, modules);
+  const globals = { __proto__: { hello: 'World!' } };
+  const compartment = new Compartment({
+    globals,
+    __options__: true,
+  });
 
   const keys = compartment.evaluate('Object.keys(globalThis)');
   t.deepEqual(keys, []);
diff --git a/packages/ses/test/global-object-mutability.test.js b/packages/ses/test/global-object-mutability.test.js
index 86ff9a177..2443deac1 100644
--- a/packages/ses/test/global-object-mutability.test.js
+++ b/packages/ses/test/global-object-mutability.test.js
@@ -11,7 +11,7 @@ test('globalObject properties mutable', t => {
   t.is(c.evaluate('Date()'), 'bogus');
 
   c.evaluate('Compartment = function(opts) { this.extra = "extra" }');
-  t.is(c.evaluate('(new Compartment({})).extra'), 'extra');
+  t.is(c.evaluate('(new Compartment()).extra'), 'extra');
 
   c.evaluate('Function = function() { this.extra = "extra" }');
   t.is(c.evaluate('new Function().extra'), 'extra');
diff --git a/packages/ses/test/import-cjs.test.js b/packages/ses/test/import-cjs.test.js
index b80b47e92..8821331c1 100644
--- a/packages/ses/test/import-cjs.test.js
+++ b/packages/ses/test/import-cjs.test.js
@@ -86,11 +86,12 @@ test('import a CommonJS module with exports assignment', async t => {
     );
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const module = compartment.module('.');
   const { meaning } = await compartment.import('.');
 
@@ -111,11 +112,12 @@ test('import a CommonJS module with exports replacement', async t => {
     );
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const module = compartment.module('.');
   const { default: meaning } = await compartment.import('.');
 
@@ -148,11 +150,12 @@ test('CommonJS module imports CommonJS module by name', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -184,11 +187,12 @@ test('CommonJS module imports CommonJS module as default', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const namespace = await compartment.import('./odd');
   const { default: odd } = namespace;
 
@@ -221,11 +225,12 @@ test('ESM imports CommonJS module as default', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { default: odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -257,11 +262,12 @@ test('ESM imports CommonJS module as star', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { default: odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -295,11 +301,12 @@ test('ESM imports CommonJS module with replaced exports as star', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { default: odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -331,11 +338,12 @@ test('ESM imports CommonJS module by name', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { default: odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -367,11 +375,12 @@ test('CommonJS module imports ESM as default', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { default: odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -405,11 +414,12 @@ test('CommonJS module imports ESM by name', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -462,11 +472,13 @@ test('cross import ESM and CommonJS modules', async t => {
     throw Error(`Cannot load module for specifier ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   await compartment.import('./src/main.js');
 });
 
@@ -507,7 +519,12 @@ test('live bindings through through an ESM between CommonJS modules', async t =>
     throw Error(`Cannot load module for specifier ${specifier}`);
   };
 
-  const compartment = new Compartment({ t }, {}, { resolveHook, importHook });
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook,
+    importHook,
+    __options__: true,
+  });
   await compartment.import('./src/main.js');
 });
 
@@ -540,14 +557,12 @@ test('export name as default from CommonJS module', async t => {
     throw Error(`Cannot load module for specifier ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook,
-    },
-  );
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook,
+    __options__: true,
+  });
 
   await compartment.import('./main.js');
 });
@@ -581,15 +596,13 @@ test('synchronous loading via importNowHook', async t => {
     throw Error(`Cannot load module for specifier ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: async () => {},
-      importNowHook,
-    },
-  );
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook: async () => {},
+    importNowHook,
+    __options__: true,
+  });
 
   compartment.importNow('./main.js');
 });
@@ -629,15 +642,13 @@ test('importNowHook only called if specifier was not imported before', async t =
     throw Error(`Cannot load module for specifier ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook,
-      importNowHook,
-    },
-  );
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook,
+    importNowHook,
+    __options__: true,
+  });
 
   // compartment.import would be the more natural here, but all prerequisites
   // to synchronously finding the module before calling importNowHook should
diff --git a/packages/ses/test/import-gauntlet.test.js b/packages/ses/test/import-gauntlet.test.js
index 14bdc61da..1ed87f111 100644
--- a/packages/ses/test/import-gauntlet.test.js
+++ b/packages/ses/test/import-gauntlet.test.js
@@ -17,14 +17,11 @@ test('import for side effect', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-    },
-  );
+  const compartment = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    __options__: true,
+  });
 
   await compartment.import('./main.js');
 });
@@ -43,15 +40,12 @@ test('import all from module', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-      __noNamespaceBox__: true,
-    },
-  );
+  const compartment = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await compartment.import('./main.js');
 
@@ -73,15 +67,12 @@ test('import named exports from me', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-      __noNamespaceBox__: true,
-    },
-  );
+  const compartment = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await compartment.import('./main.js');
 
@@ -102,15 +93,12 @@ test('import color from module', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-      __noNamespaceBox__: true,
-    },
-  );
+  const compartment = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await compartment.import('./main.js');
 
@@ -129,15 +117,12 @@ test('import and reexport', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-      __noNamespaceBox__: true,
-    },
-  );
+  const compartment = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await compartment.import('./main.js');
 
@@ -157,15 +142,12 @@ test('import and export all', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-      __noNamespaceBox__: true,
-    },
-  );
+  const compartment = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await compartment.import('./main.js');
 
@@ -188,15 +170,12 @@ test('live binding', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-      __noNamespaceBox__: true,
-    },
-  );
+  const compartment = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await compartment.import('./main.js');
 
@@ -225,14 +204,12 @@ test('live binding through reexporting intermediary', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-    },
-  );
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    __options__: true,
+  });
 
   await compartment.import('./main.js');
 });
@@ -251,14 +228,12 @@ test('export name as default', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-    },
-  );
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    __options__: true,
+  });
 
   await compartment.import('./main.js');
 });
@@ -292,14 +267,12 @@ test('export-as with duplicated export name', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-    },
-  );
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    __options__: true,
+  });
 
   await compartment.import('./main.js');
 });
@@ -321,14 +294,12 @@ test.failing('reexport with implicit default syntax', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-    },
-  );
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    __options__: true,
+  });
 
   await compartment.import('./main.js');
 });
@@ -351,24 +322,22 @@ test('importHook returning a RedirectStaticModuleInterface with a specified comp
     './meaning.js': './alias-target.js',
   };
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: async moduleSpecifier => {
-        const aliasTarget = aliasRegistry[moduleSpecifier];
-        if (aliasTarget !== undefined) {
-          const record = {
-            specifier: aliasTarget,
-            compartment,
-          };
-          return record;
-        }
-        return importHook(moduleSpecifier);
-      },
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook: async moduleSpecifier => {
+      const aliasTarget = aliasRegistry[moduleSpecifier];
+      if (aliasTarget !== undefined) {
+        const record = {
+          specifier: aliasTarget,
+          compartment,
+        };
+        return record;
+      }
+      return importHook(moduleSpecifier);
     },
-  );
+    __options__: true,
+  });
 
   await compartment.import('./main.js');
 });
@@ -394,27 +363,25 @@ test('importHook returning a ModuleInstance with a precompiled functor', async t
   });
   const importHook = makeImportHook('https://example.com');
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: async moduleSpecifier => {
-        await null;
-        if (moduleSpecifier === './precompiled.js') {
-          const baseRecord = await importHook(moduleSpecifier);
-          return {
-            ...baseRecord,
-            __syncModuleFunctor__: ({ onceVar, liveVar }) => {
-              onceVar.a(123);
-              liveVar.b(456);
-            },
-          };
-        }
-        return importHook(moduleSpecifier);
-      },
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook: async moduleSpecifier => {
+      await null;
+      if (moduleSpecifier === './precompiled.js') {
+        const baseRecord = await importHook(moduleSpecifier);
+        return {
+          ...baseRecord,
+          __syncModuleFunctor__: ({ onceVar, liveVar }) => {
+            onceVar.a(123);
+            liveVar.b(456);
+          },
+        };
+      }
+      return importHook(moduleSpecifier);
     },
-  );
+    __options__: true,
+  });
 
   await compartment.import('./main.js');
 });
@@ -429,14 +396,12 @@ test('this in module scope must be undefined', async t => {
   });
   const importHook = makeImportHook('https://example.com');
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook,
-    },
-  );
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook,
+    __options__: true,
+  });
 
   await compartment.import('./index.js');
 });
diff --git a/packages/ses/test/import-hook.test.js b/packages/ses/test/import-hook.test.js
index 12b587000..d66cd1e30 100644
--- a/packages/ses/test/import-hook.test.js
+++ b/packages/ses/test/import-hook.test.js
@@ -7,84 +7,66 @@ import { ModuleSource } from '@endo/module-source';
 import '../index.js';
 
 test('import hook returns module source descriptor with precompiled module source', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      resolveHook: specifier => specifier,
-      importHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: new ModuleSource('export default 42'),
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const compartment = new Compartment({
+    resolveHook: specifier => specifier,
+    importHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: new ModuleSource('export default 42'),
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const index = await compartment.import('./index.js');
   t.is(index.default, 42);
 });
 
 test('import hook returns module source descriptor with virtual module source', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      resolveHook: specifier => specifier,
-      importHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: {
-              imports: [],
-              exports: ['default'],
-              execute(env) {
-                env.default = 42;
-              },
+  const compartment = new Compartment({
+    resolveHook: specifier => specifier,
+    importHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: {
+            imports: [],
+            exports: ['default'],
+            execute(env) {
+              env.default = 42;
             },
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+          },
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const index = await compartment.import('./index.js');
   t.is(index.default, 42);
 });
 
 test('import hook returns parent compartment module source descriptor with string reference to parent compartment', async t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      resolveHook: specifier => specifier,
-      importHook(specifier) {
-        if (specifier === './meaning.js') {
-          return {
-            source: {
-              imports: [],
-              exports: ['default'],
-              execute(env) {
-                env.default = 42;
-              },
+  const parent = new Compartment({
+    resolveHook: specifier => specifier,
+    importHook(specifier) {
+      if (specifier === './meaning.js') {
+        return {
+          source: {
+            imports: [],
+            exports: ['default'],
+            execute(env) {
+              env.default = 42;
             },
-          };
-        }
-        return undefined;
-      },
+          },
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const compartment = new parent.globalThis.Compartment(
     // endowments:
@@ -110,108 +92,90 @@ test('import hook returns parent compartment module source descriptor with strin
 });
 
 test('import hook returns parent compartment module source reference with different specifier', async t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'parent',
-      resolveHook(relative, specifier) {
-        t.is(relative, './meaningful.js');
-        t.is(specifier, './meaning.js');
-        return relative;
-      },
-      importHook(specifier) {
-        if (specifier === './meaningful.js') {
-          return {
-            source: {
-              imports: [],
-              exports: ['meaning'],
-              execute() {
-                throw new Error('should not execute');
-              },
+  const parent = new Compartment({
+    name: 'parent',
+    resolveHook(relative, specifier) {
+      t.is(relative, './meaningful.js');
+      t.is(specifier, './meaning.js');
+      return relative;
+    },
+    importHook(specifier) {
+      if (specifier === './meaningful.js') {
+        return {
+          source: {
+            imports: [],
+            exports: ['meaning'],
+            execute() {
+              throw new Error('should not execute');
             },
-          };
-        } else if (specifier === './meaning.js') {
-          return {
-            source: {
-              imports: ['./meaningful.js'],
-              exports: ['default'],
-              execute(env, c, resolutions) {
-                // eslint-disable-next-line no-use-before-define
-                t.is(c, compartment);
-                const { meaning } = c.importNow(resolutions['./meaningful.js']);
-                env.default = meaning;
-              },
+          },
+        };
+      } else if (specifier === './meaning.js') {
+        return {
+          source: {
+            imports: ['./meaningful.js'],
+            exports: ['default'],
+            execute(env, c, resolutions) {
+              // eslint-disable-next-line no-use-before-define
+              t.is(c, compartment);
+              const { meaning } = c.importNow(resolutions['./meaningful.js']);
+              env.default = meaning;
             },
-          };
-        }
-        return undefined;
-      },
+          },
+        };
+      }
+      return undefined;
     },
-  );
-
-  const compartment = new parent.globalThis.Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'child',
-      resolveHook(relative, specifier) {
-        t.is(relative, './meaningful.js');
-        t.is(specifier, './lib/meaning.js');
-        return './lib/meaningful.js';
-      },
-      importHook(specifier) {
-        if (specifier === './lib/meaningful.js') {
-          return {
-            source: {
-              imports: [],
-              exports: ['meaning'],
-              execute(env) {
-                env.meaning = 42;
-              },
+    __options__: true,
+  });
+
+  const compartment = new parent.globalThis.Compartment({
+    name: 'child',
+    resolveHook(relative, specifier) {
+      t.is(relative, './meaningful.js');
+      t.is(specifier, './lib/meaning.js');
+      return './lib/meaningful.js';
+    },
+    importHook(specifier) {
+      if (specifier === './lib/meaningful.js') {
+        return {
+          source: {
+            imports: [],
+            exports: ['meaning'],
+            execute(env) {
+              env.meaning = 42;
             },
-          };
-        } else if (specifier === './index.js') {
-          return {
-            source: './meaning.js',
-            specifier: './lib/meaning.js',
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+          },
+        };
+      } else if (specifier === './index.js') {
+        return {
+          source: './meaning.js',
+          specifier: './lib/meaning.js',
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const index = await compartment.import('./index.js');
   t.is(index.default, 42);
 });
 
 test('import hook returns module source descriptor for parent compartment with string reference', async t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'parent',
-      importHook(specifier) {
-        if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const parent = new Compartment({
+    name: 'parent',
+    importHook(specifier) {
+      if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: parentObject } = await parent.import('./object.js');
   t.is(parentObject.meaning, 42);
@@ -244,25 +208,19 @@ test('import hook returns module source descriptor for parent compartment with s
 });
 
 test('import hook returns parent compartment module namespace descriptor', async t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'parent',
-      importHook(specifier) {
-        if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const parent = new Compartment({
+    name: 'parent',
+    importHook(specifier) {
+      if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: parentObject } = await parent.import('./object.js');
   t.is(parentObject.meaning, 42);
@@ -295,49 +253,37 @@ test('import hook returns parent compartment module namespace descriptor', async
 });
 
 test('import hook returns module source descriptor with string reference to parent compartment', async t => {
-  const compartment1 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'compartment1',
-      importHook(specifier) {
-        if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const compartment1 = new Compartment({
+    name: 'compartment1',
+    importHook(specifier) {
+      if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: object1 } = await compartment1.import('./object.js');
   t.is(object1.meaning, 42);
 
-  const compartment2 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'child',
-      importHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: './object.js',
-            compartment: compartment1,
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const compartment2 = new Compartment({
+    name: 'child',
+    importHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: './object.js',
+          compartment: compartment1,
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: object2 } = await compartment2.import('./index.js');
   t.is(object2.meaning, 42);
@@ -346,49 +292,37 @@ test('import hook returns module source descriptor with string reference to pare
 });
 
 test('import hook returns other compartment module namespace descriptor', async t => {
-  const compartment1 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'compartment1',
-      importHook(specifier) {
-        if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const compartment1 = new Compartment({
+    name: 'compartment1',
+    importHook(specifier) {
+      if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: object1 } = await compartment1.import('./object.js');
   t.is(object1.meaning, 42);
 
-  const compartment2 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'child',
-      importHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            namespace: './object.js',
-            compartment: compartment1,
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const compartment2 = new Compartment({
+    name: 'child',
+    importHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          namespace: './object.js',
+          compartment: compartment1,
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: object2 } = await compartment2.import('./index.js');
   t.is(object2.meaning, 42);
@@ -397,82 +331,68 @@ test('import hook returns other compartment module namespace descriptor', async
 });
 
 test('import hook returns module namespace descriptor and namespace object', async t => {
-  const compartment1 = new Compartment(
-    {},
-    {},
-    {
-      importHook(specifier) {
-        if (specifier === 'a') {
-          return {
-            source: new ModuleSource(`export default 42`),
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const compartment1 = new Compartment({
+    importHook(specifier) {
+      if (specifier === 'a') {
+        return {
+          source: new ModuleSource(`export default 42`),
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const namespace1 = await compartment1.import('a');
-  const compartment2 = new Compartment(
-    {},
-    {},
-    {
-      importHook(specifier) {
-        if (specifier === 'z') {
-          return { namespace: namespace1 };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const compartment2 = new Compartment({
+    importHook(specifier) {
+      if (specifier === 'z') {
+        return { namespace: namespace1 };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const namespace2 = await compartment2.import('z');
   t.is(namespace2.default, 42);
   t.is(namespace1, namespace2);
 });
 
 test('import hook returns module namespace descriptor and non-namespace object', async t => {
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      importHook(specifier) {
-        if (specifier === '1') {
-          return { namespace: { meaning: 42 } };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const compartment = new Compartment({
+    importHook(specifier) {
+      if (specifier === '1') {
+        return { namespace: { meaning: 42 } };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const namespace = await compartment.import('1');
   t.is(namespace.meaning, 42);
 });
 
 test('import hook returns module source descriptor for specifier in own compartment', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new Compartment({
+    modules: {
       './object.js': {
         source: new ModuleSource('export default { meaning: 42 }'),
       },
     },
-    // options:
-    {
-      importHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: './object.js',
-            compartment,
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+    importHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: './object.js',
+          compartment,
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: object1 } = await compartment.import('./object.js');
   t.is(object1.meaning, 42);
@@ -483,30 +403,25 @@ test('import hook returns module source descriptor for specifier in own compartm
 });
 
 test('import hook returns module source descriptor for specifier in own compartment and overridden base specifier that collides', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new Compartment({
+    modules: {
       './object.js': {
         source: new ModuleSource('export default { meaning: 42 }'),
       },
     },
-    // options:
-    {
-      importHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: './object.js',
-            specifier: './object.js',
-            compartment,
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+    importHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: './object.js',
+          specifier: './object.js',
+          compartment,
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: object1 } = await compartment.import('./object.js');
   t.is(object1.meaning, 42);
@@ -517,29 +432,24 @@ test('import hook returns module source descriptor for specifier in own compartm
 });
 
 test('import hook returns module namespace descriptor for specifier in own compartment', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new Compartment({
+    modules: {
       './object.js': {
         source: new ModuleSource('export default { meaning: 42 }'),
       },
     },
-    // options:
-    {
-      importHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            namespace: './object.js',
-            compartment,
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+    importHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          namespace: './object.js',
+          compartment,
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: object1 } = await compartment.import('./object.js');
   t.is(object1.meaning, 42);
@@ -550,29 +460,23 @@ test('import hook returns module namespace descriptor for specifier in own compa
 });
 
 test('module map hook precedes import hook', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      moduleMapHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: new ModuleSource(`
+  const compartment = new Compartment({
+    moduleMapHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: new ModuleSource(`
               export default 42;
             `),
-          };
-        }
-        return undefined;
-      },
-      importHook() {
-        throw new Error('not reached');
-      },
-      __noNamespaceBox__: true,
+        };
+      }
+      return undefined;
     },
-  );
+    importHook() {
+      throw new Error('not reached');
+    },
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: meaning } = await compartment.import('./index.js');
   t.is(meaning, 42);
diff --git a/packages/ses/test/import-non-esm.test.js b/packages/ses/test/import-non-esm.test.js
index bb9e5211f..644258e0a 100644
--- a/packages/ses/test/import-non-esm.test.js
+++ b/packages/ses/test/import-non-esm.test.js
@@ -17,11 +17,12 @@ test('import a non-ESM', async t => {
     };
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const module = compartment.module('.');
   const { meaning } = await compartment.import('.');
 
@@ -56,11 +57,12 @@ test('non-ESM imports non-ESM by name', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -94,11 +96,12 @@ test('non-ESM imports non-ESM as default', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { default: odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -131,11 +134,12 @@ test('ESM imports non-ESM as default', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { default: odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -168,11 +172,12 @@ test('ESM imports non-ESM by name', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -205,11 +210,12 @@ test('non-ESM imports ESM as default', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { default: odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -242,11 +248,12 @@ test('non-ESM imports ESM by name', async t => {
     throw Error(`Cannot load module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const { odd } = await compartment.import('./odd');
 
   t.is(odd(1), true);
@@ -304,10 +311,11 @@ test('cross import ESM and non-ESMs', async t => {
     throw Error(`Cannot load module for specifier ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    {},
-    {},
-    { resolveHook, importHook, __noNamespaceBox__: true },
-  );
+  const compartment = new Compartment({
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   await compartment.import('./src/main.js');
 });
diff --git a/packages/ses/test/import-now-hook.test.js b/packages/ses/test/import-now-hook.test.js
index 4f5755a71..b43cae955 100644
--- a/packages/ses/test/import-now-hook.test.js
+++ b/packages/ses/test/import-now-hook.test.js
@@ -7,80 +7,62 @@ import { ModuleSource } from '@endo/module-source';
 import '../index.js';
 
 test('import now hook returns module source descriptor with precompiled module source', t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      resolveHook: specifier => specifier,
-      importNowHook(specifier) {
-        if (specifier === './index.js') {
-          return { source: new ModuleSource('export default 42') };
-        }
-        return undefined;
-      },
+  const compartment = new Compartment({
+    resolveHook: specifier => specifier,
+    importNowHook(specifier) {
+      if (specifier === './index.js') {
+        return { source: new ModuleSource('export default 42') };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
   const index = compartment.importNow('./index.js');
   t.is(index.default, 42);
 });
 
 test('import now hook returns module source descriptor with virtual module source', t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      resolveHook: specifier => specifier,
-      importNowHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: {
-              imports: [],
-              exports: ['default'],
-              execute(env) {
-                env.default = 42;
-              },
+  const compartment = new Compartment({
+    resolveHook: specifier => specifier,
+    importNowHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: {
+            imports: [],
+            exports: ['default'],
+            execute(env) {
+              env.default = 42;
             },
-          };
-        }
-        return undefined;
-      },
+          },
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
   const index = compartment.importNow('./index.js');
   t.is(index.default, 42);
 });
 
 test('import now hook returns parent compartment module source descriptor with string reference to parent compartment', t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      resolveHook: specifier => specifier,
-      importNowHook(specifier) {
-        if (specifier === './meaning.js') {
-          return {
-            source: {
-              imports: [],
-              exports: ['default'],
-              execute(env) {
-                env.default = 42;
-              },
+  const parent = new Compartment({
+    resolveHook: specifier => specifier,
+    importNowHook(specifier) {
+      if (specifier === './meaning.js') {
+        return {
+          source: {
+            imports: [],
+            exports: ['default'],
+            execute(env) {
+              env.default = 42;
             },
-          };
-        }
-        return undefined;
-      },
+          },
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const compartment = new parent.globalThis.Compartment(
     // endowments:
@@ -105,48 +87,42 @@ test('import now hook returns parent compartment module source descriptor with s
 });
 
 test('import now hook returns parent compartment module source reference with different specifier', t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'parent',
-      resolveHook(relative, specifier) {
-        t.is(relative, './meaningful.js');
-        t.is(specifier, './meaning.js');
-        return relative;
-      },
-      importNowHook(specifier) {
-        if (specifier === './meaningful.js') {
-          return {
-            source: {
-              imports: [],
-              exports: ['meaning'],
-              execute() {
-                throw new Error('should not execute');
-              },
+  const parent = new Compartment({
+    name: 'parent',
+    resolveHook(relative, specifier) {
+      t.is(relative, './meaningful.js');
+      t.is(specifier, './meaning.js');
+      return relative;
+    },
+    importNowHook(specifier) {
+      if (specifier === './meaningful.js') {
+        return {
+          source: {
+            imports: [],
+            exports: ['meaning'],
+            execute() {
+              throw new Error('should not execute');
             },
-          };
-        } else if (specifier === './meaning.js') {
-          return {
-            source: {
-              imports: ['./meaningful.js'],
-              exports: ['default'],
-              execute(env, c, resolutions) {
-                // eslint-disable-next-line no-use-before-define
-                t.is(c, compartment);
-                const { meaning } = c.importNow(resolutions['./meaningful.js']);
-                env.default = meaning;
-              },
+          },
+        };
+      } else if (specifier === './meaning.js') {
+        return {
+          source: {
+            imports: ['./meaningful.js'],
+            exports: ['default'],
+            execute(env, c, resolutions) {
+              // eslint-disable-next-line no-use-before-define
+              t.is(c, compartment);
+              const { meaning } = c.importNow(resolutions['./meaningful.js']);
+              env.default = meaning;
             },
-          };
-        }
-        return undefined;
-      },
+          },
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const compartment = new parent.globalThis.Compartment(
     // endowments:
@@ -187,24 +163,18 @@ test('import now hook returns parent compartment module source reference with di
 });
 
 test('import now hook returns module source descriptor for parent compartment with string reference', t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'parent',
-      importNowHook(specifier) {
-        if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
+  const parent = new Compartment({
+    name: 'parent',
+    importNowHook(specifier) {
+      if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const { default: parentObject } = parent.importNow('./object.js');
   t.is(parentObject.meaning, 42);
@@ -236,24 +206,18 @@ test('import now hook returns module source descriptor for parent compartment wi
 });
 
 test('import now hook returns parent compartment module namespace descriptor', t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'parent',
-      importNowHook(specifier) {
-        if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
+  const parent = new Compartment({
+    name: 'parent',
+    importNowHook(specifier) {
+      if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const { default: parentObject } = parent.importNow('./object.js');
   t.is(parentObject.meaning, 42);
@@ -285,47 +249,35 @@ test('import now hook returns parent compartment module namespace descriptor', t
 });
 
 test('import now hook returns module source descriptor with string reference to parent compartment', t => {
-  const compartment1 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'compartment1',
-      importNowHook(specifier) {
-        if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
+  const compartment1 = new Compartment({
+    name: 'compartment1',
+    importNowHook(specifier) {
+      if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const { default: object1 } = compartment1.importNow('./object.js');
   t.is(object1.meaning, 42);
 
-  const compartment2 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'child',
-      importNowHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: './object.js',
-            compartment: compartment1,
-          };
-        }
-        return undefined;
-      },
+  const compartment2 = new Compartment({
+    name: 'child',
+    importNowHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: './object.js',
+          compartment: compartment1,
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const { default: object2 } = compartment2.importNow('./index.js');
   t.is(object2.meaning, 42);
@@ -334,47 +286,35 @@ test('import now hook returns module source descriptor with string reference to
 });
 
 test('import now hook returns other compartment module namespace descriptor', t => {
-  const compartment1 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'compartment1',
-      importNowHook(specifier) {
-        if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
+  const compartment1 = new Compartment({
+    name: 'compartment1',
+    importNowHook(specifier) {
+      if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const { default: object1 } = compartment1.importNow('./object.js');
   t.is(object1.meaning, 42);
 
-  const compartment2 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'child',
-      importNowHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            namespace: './object.js',
-            compartment: compartment1,
-          };
-        }
-        return undefined;
-      },
+  const compartment2 = new Compartment({
+    name: 'child',
+    importNowHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          namespace: './object.js',
+          compartment: compartment1,
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const { default: object2 } = compartment2.importNow('./index.js');
   t.is(object2.meaning, 42);
@@ -383,78 +323,64 @@ test('import now hook returns other compartment module namespace descriptor', t
 });
 
 test('import now hook returns module namespace descriptor and namespace object', t => {
-  const compartment1 = new Compartment(
-    {},
-    {},
-    {
-      importNowHook(specifier) {
-        if (specifier === 'a') {
-          return {
-            source: new ModuleSource(`export default 42`),
-          };
-        }
-        return undefined;
-      },
+  const compartment1 = new Compartment({
+    importNowHook(specifier) {
+      if (specifier === 'a') {
+        return {
+          source: new ModuleSource(`export default 42`),
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
   const namespace1 = compartment1.importNow('a');
-  const compartment2 = new Compartment(
-    {},
-    {},
-    {
-      importNowHook(specifier) {
-        if (specifier === 'z') {
-          return { namespace: namespace1 };
-        }
-        return undefined;
-      },
+  const compartment2 = new Compartment({
+    importNowHook(specifier) {
+      if (specifier === 'z') {
+        return { namespace: namespace1 };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
   const namespace2 = compartment2.importNow('z');
   t.is(namespace2.default, 42);
   t.is(namespace1, namespace2);
 });
 
 test('import now hook returns module namespace descriptor and non-namespace object', t => {
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      importNowHook(specifier) {
-        if (specifier === '1') {
-          return { namespace: { meaning: 42 } };
-        }
-        return undefined;
-      },
+  const compartment = new Compartment({
+    importNowHook(specifier) {
+      if (specifier === '1') {
+        return { namespace: { meaning: 42 } };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
   const namespace = compartment.importNow('1');
   t.is(namespace.meaning, 42);
 });
 
 test('import now hook returns module source descriptor for specifier in own compartment', t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new Compartment({
+    modules: {
       './object.js': {
         source: new ModuleSource('export default { meaning: 42 }'),
       },
     },
-    // options:
-    {
-      importNowHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: './object.js',
-            compartment,
-          };
-        }
-        return undefined;
-      },
+    importNowHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: './object.js',
+          compartment,
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const { default: object1 } = compartment.importNow('./object.js');
   t.is(object1.meaning, 42);
@@ -465,29 +391,24 @@ test('import now hook returns module source descriptor for specifier in own comp
 });
 
 test('import now hook returns module source descriptor for specifier in own compartment and overridden base specifier that collides', t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new Compartment({
+    modules: {
       './object.js': {
         source: new ModuleSource('export default { meaning: 42 }'),
       },
     },
-    // options:
-    {
-      importNowHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: './object.js',
-            specifier: './object.js',
-            compartment,
-          };
-        }
-        return undefined;
-      },
+    importNowHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: './object.js',
+          specifier: './object.js',
+          compartment,
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const { default: object1 } = compartment.importNow('./object.js');
   t.is(object1.meaning, 42);
@@ -498,28 +419,22 @@ test('import now hook returns module source descriptor for specifier in own comp
 });
 
 test('import now hook returns module namespace descriptor for specifier in own compartment', t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      importNowHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            namespace: './object.js',
-            compartment,
-          };
-        } else if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
+  const compartment = new Compartment({
+    importNowHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          namespace: './object.js',
+          compartment,
+        };
+      } else if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const { default: object1 } = compartment.importNow('./object.js');
   t.is(object1.meaning, 42);
@@ -530,28 +445,22 @@ test('import now hook returns module namespace descriptor for specifier in own c
 });
 
 test('module map hook precedes import now hook', t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      moduleMapHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: new ModuleSource(`
+  const compartment = new Compartment({
+    moduleMapHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: new ModuleSource(`
               export default 42;
             `),
-          };
-        }
-        return undefined;
-      },
-      importNowHook() {
-        throw new Error('not reached');
-      },
+        };
+      }
+      return undefined;
     },
-  );
+    importNowHook() {
+      throw new Error('not reached');
+    },
+    __options__: true,
+  });
 
   const { default: meaning } = compartment.importNow('./index.js');
   t.is(meaning, 42);
diff --git a/packages/ses/test/import-stack-traces.test.js b/packages/ses/test/import-stack-traces.test.js
index 54efaaca8..fe71f5b77 100644
--- a/packages/ses/test/import-stack-traces.test.js
+++ b/packages/ses/test/import-stack-traces.test.js
@@ -16,14 +16,11 @@ test('preserve file names in stack traces', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    {}, // endowments
-    {}, // module map
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com/packages/erroneous'),
-    },
-  );
+  const compartment = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com/packages/erroneous'),
+    __options__: true,
+  });
 
   let error;
   try {
diff --git a/packages/ses/test/import.test.js b/packages/ses/test/import.test.js
index d2bc5365a..85d21c3e4 100644
--- a/packages/ses/test/import.test.js
+++ b/packages/ses/test/import.test.js
@@ -27,17 +27,15 @@ test('import within one compartment, web resolution', async t => {
   const resolveHook = (spec, referrer) => new URL(spec, referrer).toString();
   const importHook = makeImporter(locate, retrieve);
 
-  const compartment = new Compartment(
-    {
+  const compartment = new Compartment({
+    globals: {
       double: n => n * 2,
     },
-    {},
-    {
-      resolveHook,
-      importHook,
-      __noNamespaceBox__: true,
-    },
-  );
+    resolveHook,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await compartment.import(
     'https://example.com/packages/example/',
@@ -61,17 +59,15 @@ test('import within one compartment, node resolution', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    {
+  const compartment = new Compartment({
+    globals: {
       double: n => n * 2,
     },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com/packages/example'),
-      __noNamespaceBox__: true,
-    },
-  );
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com/packages/example'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await compartment.import('./main.js');
 
@@ -99,20 +95,17 @@ test('two compartments, three modules, one endowment', async t => {
     `,
   });
 
-  const doubleCompartment = new Compartment(
-    {
+  const doubleCompartment = new Compartment({
+    globals: {
       double: n => n * 2,
     },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com/packages/double'),
-    },
-  );
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com/packages/double'),
+    __options__: true,
+  });
 
-  const compartment = new Compartment(
-    {},
-    {
+  const compartment = new Compartment({
+    modules: {
       // Notably, this is the first case where we thread a depencency between
       // two compartments, using the sigil of one's namespace to indicate
       // linkage before the module has been loaded.
@@ -121,12 +114,11 @@ test('two compartments, three modules, one endowment', async t => {
         compartment: doubleCompartment,
       },
     },
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com/packages/example'),
-      __noNamespaceBox__: true,
-    },
-  );
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com/packages/example'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await compartment.import('./main.js');
 
@@ -142,15 +134,12 @@ test('module exports namespace as an object', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com/packages/meaning'),
-      __noNamespaceBox__: true,
-    },
-  );
+  const compartment = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com/packages/meaning'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await compartment.import('./main.js');
 
@@ -215,15 +204,12 @@ test('modules are memoized', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com/packages/example'),
-      __noNamespaceBox__: true,
-    },
-  );
+  const compartment = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com/packages/example'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await compartment.import('./main.js');
   const { clive, clerk } = namespace;
@@ -240,25 +226,19 @@ test('compartments with same sources do not share instances', async t => {
     `,
   });
 
-  const leftCompartment = new Compartment(
-    {},
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com/packages/arm'),
-      __noNamespaceBox__: true,
-    },
-  );
+  const leftCompartment = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com/packages/arm'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
-  const rightCompartment = new Compartment(
-    {},
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com/packages/arm'),
-      __noNamespaceBox__: true,
-    },
-  );
+  const rightCompartment = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com/packages/arm'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const [{ default: leftArm }, { default: rightArm }] = await Promise.all([
     leftCompartment.import('./main.js'),
@@ -300,38 +280,33 @@ test('module map hook', async t => {
     `,
   });
 
-  const dependency = new Compartment(
-    {},
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com/dependency'),
-      __noNamespaceBox__: true,
-    },
-  );
+  const dependency = new Compartment({
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com/dependency'),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-      moduleMapHook: moduleSpecifier => {
-        const remainder = trimModuleSpecifierPrefix(
-          moduleSpecifier,
-          'dependency',
-        );
-        if (remainder) {
-          return {
-            namespace: remainder,
-            compartment: dependency,
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    moduleMapHook: moduleSpecifier => {
+      const remainder = trimModuleSpecifierPrefix(
+        moduleSpecifier,
+        'dependency',
+      );
+      if (remainder) {
+        return {
+          namespace: remainder,
+          compartment: dependency,
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   await compartment.import('./main.js');
 });
@@ -378,42 +353,33 @@ test('mutual dependency between compartments', async t => {
     return undefined;
   };
 
-  const even = new Compartment(
-    {},
-    {},
-    {
-      name: 'https://example.com/even',
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com/even'),
-      moduleMapHook,
-      __noNamespaceBox__: true,
-    },
-  );
+  const even = new Compartment({
+    name: 'https://example.com/even',
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com/even'),
+    moduleMapHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
-  const odd = new Compartment(
-    {},
-    {},
-    {
-      name: 'https://example.com/odd',
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com/odd'),
-      moduleMapHook,
-      [Symbol.for('options')]: true,
-      __noNamespaceBox__: true,
-    },
-  );
+  const odd = new Compartment({
+    name: 'https://example.com/odd',
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com/odd'),
+    moduleMapHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      name: 'https://example.com',
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-      moduleMapHook,
-      __noNamespaceBox__: true,
-    },
-  );
+  const compartment = new Compartment({
+    globals: { t },
+    name: 'https://example.com',
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    moduleMapHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   await compartment.import('./main.js');
 });
@@ -449,15 +415,13 @@ test('import redirect shorthand', async t => {
     throw Error(`Cannot find module ${specifier}`);
   };
 
-  const compartment = new Compartment(
-    { Math },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook,
-      __noNamespaceBox__: true,
-    },
-  );
+  const compartment = new Compartment({
+    globals: { Math },
+    resolveHook: resolveNode,
+    importHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const namespace = await compartment.import('./main');
   t.is(
@@ -519,16 +483,14 @@ test('import reflexive module alias', async t => {
     return undefined;
   };
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      resolveHook: resolveNode,
-      importHook,
-      moduleMapHook,
-      __noNamespaceBox__: true,
-    },
-  );
+  const compartment = new Compartment({
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook,
+    moduleMapHook,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   await compartment.import('./index.js');
 });
@@ -569,18 +531,16 @@ test('import.meta populated from module record', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      name: 'https://example.com',
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com', {
-        meta: { url: 'https://example.com/index.js' },
-      }),
-      __noNamespaceBox__: true,
-    },
-  );
+  const compartment = new Compartment({
+    name: 'https://example.com',
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com', {
+      meta: { url: 'https://example.com/index.js' },
+    }),
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: metaurl } = await compartment.import('./index.js');
   t.is(metaurl, 'https://example.com/index.js');
@@ -596,19 +556,17 @@ test('importMetaHook', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      name: 'https://example.com',
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com'),
-      importMetaHook: (_moduleSpecifier, meta) => {
-        meta.url = 'https://example.com/index.js';
-      },
-      __noNamespaceBox__: true,
+  const compartment = new Compartment({
+    name: 'https://example.com',
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com'),
+    importMetaHook: (_moduleSpecifier, meta) => {
+      meta.url = 'https://example.com/index.js';
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: metaurl } = await compartment.import('./index.js');
   t.is(metaurl, 'https://example.com/index.js');
@@ -624,22 +582,20 @@ test('importMetaHook and meta from record', async t => {
     `,
   });
 
-  const compartment = new Compartment(
-    { t },
-    {},
-    {
-      name: 'https://example.com',
-      resolveHook: resolveNode,
-      importHook: makeImportHook('https://example.com', {
-        meta: { url: 'https://example.com/index.js' },
-      }),
-      importMetaHook: (_moduleSpecifier, meta) => {
-        meta.url += '?foo';
-        meta.isStillMutableHopefully = 1;
-      },
-      __noNamespaceBox__: true,
+  const compartment = new Compartment({
+    name: 'https://example.com',
+    globals: { t },
+    resolveHook: resolveNode,
+    importHook: makeImportHook('https://example.com', {
+      meta: { url: 'https://example.com/index.js' },
+    }),
+    importMetaHook: (_moduleSpecifier, meta) => {
+      meta.url += '?foo';
+      meta.isStillMutableHopefully = 1;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: metaurl } = await compartment.import('./index.js');
   t.is(metaurl, 'https://example.com/index.js?foo');
diff --git a/packages/ses/test/lockdown-compartment.test.js b/packages/ses/test/lockdown-compartment.test.js
index 15426d3ef..4129b2745 100644
--- a/packages/ses/test/lockdown-compartment.test.js
+++ b/packages/ses/test/lockdown-compartment.test.js
@@ -6,7 +6,7 @@ test('lockdown returns or throws', t => {
 
   // Compartment constructor does not throw before lockdown.
   (() => {
-    const c = new Compartment({}, {}, {});
+    const c = new Compartment();
     const functionConstructor = c.evaluate('Function.prototype.constructor');
     t.is(
       functionConstructor,
@@ -19,7 +19,7 @@ test('lockdown returns or throws', t => {
 
   // Compartment constructor does not throw after lockdown.
   (() => {
-    const c = new Compartment({}, {}, {});
+    const c = new Compartment();
     const cf = c.evaluate('Function.prototype.constructor');
     t.not(
       cf,
@@ -27,7 +27,7 @@ test('lockdown returns or throws', t => {
       'after lockdown, Function.prototype.constructor must be tamed inside compartments',
     );
 
-    const d = new Compartment({}, {}, {});
+    const d = new Compartment();
     const df = d.evaluate('Function.prototype.constructor');
     t.is(
       cf,
diff --git a/packages/ses/test/module-map-hook.test.js b/packages/ses/test/module-map-hook.test.js
index 38c123819..567e5fc49 100644
--- a/packages/ses/test/module-map-hook.test.js
+++ b/packages/ses/test/module-map-hook.test.js
@@ -7,82 +7,64 @@ import { ModuleSource } from '@endo/module-source';
 import '../index.js';
 
 test('module map hook returns module source descriptor with precompiled module source', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      resolveHook: specifier => specifier,
-      moduleMapHook(specifier) {
-        if (specifier === './index.js') {
-          return { source: new ModuleSource('export default 42') };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const compartment = new Compartment({
+    resolveHook: specifier => specifier,
+    moduleMapHook(specifier) {
+      if (specifier === './index.js') {
+        return { source: new ModuleSource('export default 42') };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const index = await compartment.import('./index.js');
   t.is(index.default, 42);
 });
 
 test('module map hook returns  module source descriptor with virtual module source', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      resolveHook: specifier => specifier,
-      moduleMapHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: {
-              imports: [],
-              exports: ['default'],
-              execute(env) {
-                env.default = 42;
-              },
+  const compartment = new Compartment({
+    resolveHook: specifier => specifier,
+    moduleMapHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: {
+            imports: [],
+            exports: ['default'],
+            execute(env) {
+              env.default = 42;
             },
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+          },
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const index = await compartment.import('./index.js');
   t.is(index.default, 42);
 });
 
 test('module map hook returns parent compartment module source descriptor with string reference to parent compartment', async t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      resolveHook: specifier => specifier,
-      moduleMapHook(specifier) {
-        if (specifier === './meaning.js') {
-          return {
-            source: {
-              imports: [],
-              exports: ['default'],
-              execute(env) {
-                env.default = 42;
-              },
+  const parent = new Compartment({
+    resolveHook: specifier => specifier,
+    moduleMapHook(specifier) {
+      if (specifier === './meaning.js') {
+        return {
+          source: {
+            imports: [],
+            exports: ['default'],
+            execute(env) {
+              env.default = 42;
             },
-          };
-        }
-        return undefined;
-      },
+          },
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const compartment = new parent.globalThis.Compartment(
     // endowments:
@@ -108,48 +90,42 @@ test('module map hook returns parent compartment module source descriptor with s
 });
 
 test('module map hook returns parent compartment module source reference with different specifier', async t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'parent',
-      resolveHook(relative, specifier) {
-        t.is(relative, './meaningful.js');
-        t.is(specifier, './meaning.js');
-        return relative;
-      },
-      moduleMapHook(specifier) {
-        if (specifier === './meaningful.js') {
-          return {
-            source: {
-              imports: [],
-              exports: ['meaning'],
-              execute() {
-                throw new Error('should not execute');
-              },
+  const parent = new Compartment({
+    name: 'parent',
+    resolveHook(relative, specifier) {
+      t.is(relative, './meaningful.js');
+      t.is(specifier, './meaning.js');
+      return relative;
+    },
+    moduleMapHook(specifier) {
+      if (specifier === './meaningful.js') {
+        return {
+          source: {
+            imports: [],
+            exports: ['meaning'],
+            execute() {
+              throw new Error('should not execute');
             },
-          };
-        } else if (specifier === './meaning.js') {
-          return {
-            source: {
-              imports: ['./meaningful.js'],
-              exports: ['default'],
-              execute(env, c, resolutions) {
-                // eslint-disable-next-line no-use-before-define
-                t.is(c, compartment);
-                const { meaning } = c.importNow(resolutions['./meaningful.js']);
-                env.default = meaning;
-              },
+          },
+        };
+      } else if (specifier === './meaning.js') {
+        return {
+          source: {
+            imports: ['./meaningful.js'],
+            exports: ['default'],
+            execute(env, c, resolutions) {
+              // eslint-disable-next-line no-use-before-define
+              t.is(c, compartment);
+              const { meaning } = c.importNow(resolutions['./meaningful.js']);
+              env.default = meaning;
             },
-          };
-        }
-        return undefined;
-      },
+          },
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const compartment = new parent.globalThis.Compartment(
     // endowments:
@@ -191,49 +167,37 @@ test('module map hook returns parent compartment module source reference with di
 });
 
 test('module map hook returns module source descriptor for parent compartment with string reference', async t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'parent',
-      moduleMapHook(specifier) {
-        if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const parent = new Compartment({
+    name: 'parent',
+    moduleMapHook(specifier) {
+      if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: parentObject } = await parent.import('./object.js');
   t.is(parentObject.meaning, 42);
 
-  const compartment = new parent.globalThis.Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'child',
-      moduleMapHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: './object.js',
-            // implies parent compartment
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const compartment = new parent.globalThis.Compartment({
+    name: 'child',
+    moduleMapHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: './object.js',
+          // implies parent compartment
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: childObject } = await compartment.import('./index.js');
   t.is(childObject.meaning, 42);
@@ -242,49 +206,37 @@ test('module map hook returns module source descriptor for parent compartment wi
 });
 
 test('module map hook returns parent compartment module namespace descriptor', async t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'parent',
-      moduleMapHook(specifier) {
-        if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const parent = new Compartment({
+    name: 'parent',
+    moduleMapHook(specifier) {
+      if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: parentObject } = await parent.import('./object.js');
   t.is(parentObject.meaning, 42);
 
-  const compartment = new parent.globalThis.Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'child',
-      moduleMapHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            namespace: './object.js',
-            // implies parent compartment
-          };
-        }
-        return undefined;
-      },
-      __noNamespaceBox__: true,
+  const compartment = new parent.globalThis.Compartment({
+    name: 'child',
+    moduleMapHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          namespace: './object.js',
+          // implies parent compartment
+        };
+      }
+      return undefined;
     },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: childObject } = await compartment.import('./index.js');
   t.is(childObject.meaning, 42);
@@ -293,49 +245,37 @@ test('module map hook returns parent compartment module namespace descriptor', a
 });
 
 test('module map hook returns module source descriptor with string reference to parent compartment', async t => {
-  const compartment1 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'compartment1',
-      moduleMapHook(specifier) {
-        if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
+  const compartment1 = new Compartment({
+    name: 'compartment1',
+    moduleMapHook(specifier) {
+      if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const {
     namespace: { default: object1 },
   } = await compartment1.import('./object.js');
   t.is(object1.meaning, 42);
 
-  const compartment2 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'child',
-      moduleMapHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: './object.js',
-            compartment: compartment1,
-          };
-        }
-        return undefined;
-      },
+  const compartment2 = new Compartment({
+    name: 'child',
+    moduleMapHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: './object.js',
+          compartment: compartment1,
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const {
     namespace: { default: object2 },
@@ -346,49 +286,37 @@ test('module map hook returns module source descriptor with string reference to
 });
 
 test('module map hook returns other compartment module namespace descriptor', async t => {
-  const compartment1 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'compartment1',
-      moduleMapHook(specifier) {
-        if (specifier === './object.js') {
-          return {
-            source: new ModuleSource('export default { meaning: 42 }'),
-          };
-        }
-        return undefined;
-      },
+  const compartment1 = new Compartment({
+    name: 'compartment1',
+    moduleMapHook(specifier) {
+      if (specifier === './object.js') {
+        return {
+          source: new ModuleSource('export default { meaning: 42 }'),
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const {
     namespace: { default: object1 },
   } = await compartment1.import('./object.js');
   t.is(object1.meaning, 42);
 
-  const compartment2 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {},
-    // options:
-    {
-      name: 'child',
-      moduleMapHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            namespace: './object.js',
-            compartment: compartment1,
-          };
-        }
-        return undefined;
-      },
+  const compartment2 = new Compartment({
+    name: 'child',
+    moduleMapHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          namespace: './object.js',
+          compartment: compartment1,
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const {
     namespace: { default: object2 },
@@ -399,78 +327,64 @@ test('module map hook returns other compartment module namespace descriptor', as
 });
 
 test('module map hook returns module namespace descriptor and namespace object', async t => {
-  const compartment1 = new Compartment(
-    {},
-    {},
-    {
-      moduleMapHook(specifier) {
-        if (specifier === 'a') {
-          return {
-            source: new ModuleSource(`export default 42`),
-          };
-        }
-        return undefined;
-      },
+  const compartment1 = new Compartment({
+    moduleMapHook(specifier) {
+      if (specifier === 'a') {
+        return {
+          source: new ModuleSource(`export default 42`),
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
   const { namespace: namespace1 } = await compartment1.import('a');
-  const compartment2 = new Compartment(
-    {},
-    {},
-    {
-      moduleMapHook(specifier) {
-        if (specifier === 'z') {
-          return { namespace: namespace1 };
-        }
-        return undefined;
-      },
+  const compartment2 = new Compartment({
+    moduleMapHook(specifier) {
+      if (specifier === 'z') {
+        return { namespace: namespace1 };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
   const { namespace: namespace2 } = await compartment2.import('z');
   t.is(namespace2.default, 42);
   t.is(namespace1, namespace2);
 });
 
 test('module map hook returns module namespace descriptor and non-namespace object', async t => {
-  const compartment = new Compartment(
-    {},
-    {},
-    {
-      moduleMapHook(specifier) {
-        if (specifier === '1') {
-          return { namespace: { meaning: 42 } };
-        }
-        return undefined;
-      },
+  const compartment = new Compartment({
+    moduleMapHook(specifier) {
+      if (specifier === '1') {
+        return { namespace: { meaning: 42 } };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
   const { namespace } = await compartment.import('1');
   t.is(namespace.meaning, 42);
 });
 
 test('module map hook returns module source descriptor for specifier in own compartment', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new Compartment({
+    modules: {
       './object.js': {
         source: new ModuleSource('export default { meaning: 42 }'),
       },
     },
-    // options:
-    {
-      moduleMapHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: './object.js',
-            compartment,
-          };
-        }
-        return undefined;
-      },
+    moduleMapHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: './object.js',
+          compartment,
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const {
     namespace: { default: object1 },
@@ -485,29 +399,24 @@ test('module map hook returns module source descriptor for specifier in own comp
 });
 
 test('module map hook returns module source descriptor for specifier in own compartment and overridden base specifier that collides', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new Compartment({
+    modules: {
       './object.js': {
         source: new ModuleSource('export default { meaning: 42 }'),
       },
     },
-    // options:
-    {
-      moduleMapHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            source: './object.js',
-            specifier: './object.js',
-            compartment,
-          };
-        }
-        return undefined;
-      },
+    moduleMapHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          source: './object.js',
+          specifier: './object.js',
+          compartment,
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const {
     namespace: { default: object1 },
@@ -522,28 +431,23 @@ test('module map hook returns module source descriptor for specifier in own comp
 });
 
 test('module map hook returns module namespace descriptor for specifier in own compartment', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new Compartment({
+    modules: {
       './object.js': {
         source: new ModuleSource('export default { meaning: 42 }'),
       },
     },
-    // options:
-    {
-      moduleMapHook(specifier) {
-        if (specifier === './index.js') {
-          return {
-            namespace: './object.js',
-            compartment,
-          };
-        }
-        return undefined;
-      },
+    moduleMapHook(specifier) {
+      if (specifier === './index.js') {
+        return {
+          namespace: './object.js',
+          compartment,
+        };
+      }
+      return undefined;
     },
-  );
+    __options__: true,
+  });
 
   const {
     namespace: { default: object1 },
@@ -558,24 +462,19 @@ test('module map hook returns module namespace descriptor for specifier in own c
 });
 
 test('module map precedes module map hook', t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new Compartment({
+    modules: {
       './index.js': {
         source: new ModuleSource(`
           export default 42;
         `),
       },
     },
-    // options:
-    {
-      moduleMapHook() {
-        throw new Error('not reached');
-      },
+    moduleMapHook() {
+      throw new Error('not reached');
     },
-  );
+    __options__: true,
+  });
 
   const { default: meaning } = compartment.importNow('./index.js');
   t.is(meaning, 42);
diff --git a/packages/ses/test/module-map.test.js b/packages/ses/test/module-map.test.js
index e69ce3d27..8fd233db7 100644
--- a/packages/ses/test/module-map.test.js
+++ b/packages/ses/test/module-map.test.js
@@ -5,31 +5,23 @@ import { ModuleSource } from '@endo/module-source';
 import '../index.js';
 
 test('module map primed with module source descriptor with precompiled module source', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new Compartment({
+    modules: {
       './index.js': {
         source: new ModuleSource('export default 42'),
       },
     },
-    // options:
-    {
-      resolveHook: specifier => specifier,
-      __noNamespaceBox__: true,
-    },
-  );
+    resolveHook: specifier => specifier,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const index = await compartment.import('./index.js');
   t.is(index.default, 42);
 });
 
 test('module map primed with module source descriptor with virtual module source', async t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new Compartment({
+    modules: {
       './index.js': {
         source: {
           imports: [],
@@ -40,22 +32,17 @@ test('module map primed with module source descriptor with virtual module source
         },
       },
     },
-    // options:
-    {
-      resolveHook: specifier => specifier,
-      __noNamespaceBox__: true,
-    },
-  );
+    resolveHook: specifier => specifier,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const index = await compartment.import('./index.js');
   t.is(index.default, 42);
 });
 
 test('module map primed with parent compartment module source descriptor with string reference to parent compartment', async t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const parent = new Compartment({
+    modules: {
       './meaning.js': {
         source: {
           imports: [],
@@ -66,37 +53,27 @@ test('module map primed with parent compartment module source descriptor with st
         },
       },
     },
-    // options:
-    {
-      resolveHook: specifier => specifier,
-    },
-  );
+    resolveHook: specifier => specifier,
+    __options__: true,
+  });
 
-  const compartment = new parent.globalThis.Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new parent.globalThis.Compartment({
+    modules: {
       './index.js': {
         source: './meaning.js',
       },
     },
-    // options:
-    {
-      resolveHook: specifier => specifier,
-      __noNamespaceBox__: true,
-    },
-  );
+    resolveHook: specifier => specifier,
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const index = await compartment.import('./index.js');
   t.is(index.default, 42);
 });
 
 test('module map primed with parent compartment module source reference with different specifier', async t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const parent = new Compartment({
+    modules: {
       './meaningful.js': {
         source: {
           imports: [],
@@ -119,16 +96,14 @@ test('module map primed with parent compartment module source reference with dif
         },
       },
     },
-    // options:
-    {
-      name: 'parent',
-      resolveHook(relative, specifier) {
-        t.is(relative, './meaningful.js');
-        t.is(specifier, './meaning.js');
-        return relative;
-      },
+    name: 'parent',
+    resolveHook(relative, specifier) {
+      t.is(relative, './meaningful.js');
+      t.is(specifier, './meaning.js');
+      return relative;
     },
-  );
+    __options__: true,
+  });
 
   const compartment = new parent.globalThis.Compartment(
     // endowments:
@@ -165,41 +140,31 @@ test('module map primed with parent compartment module source reference with dif
 });
 
 test('module map primed with module source descriptor for parent compartment with string reference', async t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const parent = new Compartment({
+    name: 'parent',
+    modules: {
       './object.js': {
         source: new ModuleSource('export default { meaning: 42 }'),
       },
     },
-    // options:
-    {
-      name: 'parent',
-      __noNamespaceBox__: true,
-    },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: parentObject } = await parent.import('./object.js');
   t.is(parentObject.meaning, 42);
 
-  const compartment = new parent.globalThis.Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new parent.globalThis.Compartment({
+    name: 'child',
+    modules: {
       './index.js': {
         source: './object.js',
         // implies parent compartment
       },
     },
-    // options:
-    {
-      name: 'child',
-      __noNamespaceBox__: true,
-    },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: childObject } = await compartment.import('./index.js');
   t.is(childObject.meaning, 42);
@@ -208,41 +173,31 @@ test('module map primed with module source descriptor for parent compartment wit
 });
 
 test('module map primed with parent compartment module namespace descriptor', async t => {
-  const parent = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const parent = new Compartment({
+    name: 'parent',
+    modules: {
       './object.js': {
         source: new ModuleSource('export default { meaning: 42 }'),
       },
     },
-    // options:
-    {
-      name: 'parent',
-      __noNamespaceBox__: true,
-    },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: parentObject } = await parent.import('./object.js');
   t.is(parentObject.meaning, 42);
 
-  const compartment = new parent.globalThis.Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new parent.globalThis.Compartment({
+    name: 'child',
+    modules: {
       './index.js': {
         namespace: './object.js',
         // implies parent compartment
       },
     },
-    // options:
-    {
-      name: 'child',
-      __noNamespaceBox__: true,
-    },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: childObject } = await compartment.import('./index.js');
   t.is(childObject.meaning, 42);
@@ -251,41 +206,31 @@ test('module map primed with parent compartment module namespace descriptor', as
 });
 
 test('module map primed with module source descriptor with string reference to parent compartment', async t => {
-  const compartment1 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment1 = new Compartment({
+    name: 'compartment1',
+    modules: {
       './object.js': {
         source: new ModuleSource('export default { meaning: 42 }'),
       },
     },
-    // options:
-    {
-      name: 'compartment1',
-      __noNamespaceBox__: true,
-    },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: object1 } = await compartment1.import('./object.js');
   t.is(object1.meaning, 42);
 
-  const compartment2 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment2 = new Compartment({
+    name: 'child',
+    modules: {
       './index.js': {
         source: './object.js',
         compartment: compartment1,
       },
     },
-    // options:
-    {
-      name: 'child',
-      __noNamespaceBox__: true,
-    },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: object2 } = await compartment2.import('./index.js');
   t.is(object2.meaning, 42);
@@ -294,41 +239,31 @@ test('module map primed with module source descriptor with string reference to p
 });
 
 test('module map primed with other compartment module namespace descriptor', async t => {
-  const compartment1 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment1 = new Compartment({
+    name: 'compartment1',
+    modules: {
       './object.js': {
         source: new ModuleSource('export default { meaning: 42 }'),
       },
     },
-    // options:
-    {
-      name: 'compartment1',
-      __noNamespaceBox__: true,
-    },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: object1 } = await compartment1.import('./object.js');
   t.is(object1.meaning, 42);
 
-  const compartment2 = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment2 = new Compartment({
+    name: 'child',
+    modules: {
       './index.js': {
         namespace: './object.js',
         compartment: compartment1,
       },
     },
-    // options:
-    {
-      name: 'child',
-      __noNamespaceBox__: true,
-    },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
 
   const { default: object2 } = await compartment2.import('./index.js');
   t.is(object2.meaning, 42);
@@ -337,65 +272,54 @@ test('module map primed with other compartment module namespace descriptor', asy
 });
 
 test('module map primed with module namespace descriptor and namespace object', async t => {
-  const compartment1 = new Compartment(
-    {},
-    {
+  const compartment1 = new Compartment({
+    modules: {
       a: {
         source: new ModuleSource(`export default 42`),
       },
     },
-    {
-      __noNamespaceBox__: true,
-    },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const namespace1 = await compartment1.import('a');
-  const compartment2 = new Compartment(
-    {},
-    {
+  const compartment2 = new Compartment({
+    modules: {
       z: { namespace: namespace1 },
     },
-    {
-      __noNamespaceBox__: true,
-    },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const namespace2 = await compartment2.import('z');
   t.is(namespace2.default, 42);
   t.is(namespace1, namespace2);
 });
 
 test('module map primed with module namespace descriptor and non-namespace object', async t => {
-  const compartment = new Compartment(
-    {},
-    {
+  const compartment = new Compartment({
+    modules: {
       1: { namespace: { meaning: 42 } },
     },
-    {
-      __noNamespaceBox__: true,
-    },
-  );
+    __noNamespaceBox__: true,
+    __options__: true,
+  });
   const namespace = await compartment.import('1');
   t.is(namespace.meaning, 42);
 });
 
 test('module map precedes module map hook', t => {
-  const compartment = new Compartment(
-    // endowments:
-    {},
-    // modules:
-    {
+  const compartment = new Compartment({
+    modules: {
       './index.js': {
         source: new ModuleSource(`
           export default 42;
         `),
       },
     },
-    // options:
-    {
-      moduleMapHook() {
-        throw new Error('not reached');
-      },
+    moduleMapHook() {
+      throw new Error('not reached');
     },
-  );
+    __options__: true,
+  });
 
   const { default: meaning } = compartment.importNow('./index.js');
   t.is(meaning, 42);
diff --git a/packages/ses/test/ses.test.js b/packages/ses/test/ses.test.js
index dc654beaf..c6a443fe7 100644
--- a/packages/ses/test/ses.test.js
+++ b/packages/ses/test/ses.test.js
@@ -23,7 +23,10 @@ test('tamed constructors', t => {
   t.throws(() => Error.__proto__.constructor(''), { instanceOf: TypeError });
   t.throws(() => Function.prototype.constructor(''), { instanceOf: TypeError });
 
-  const c = new Compartment({ console });
+  const c = new Compartment({
+    globals: { console },
+    __options__: true,
+  });
 
   t.throws(() => c.evaluate("Error.__proto__.constructor('')"), {
     instanceOf: TypeError,
@@ -99,7 +102,10 @@ test('SES compartment also has compartments', t => {
 //   // });
 
 test('SES compartment has harden', t => {
-  const c = new Compartment({ a: 123 });
+  const c = new Compartment({
+    globals: { a: 123 },
+    __options__: true,
+  });
   const obj = c.evaluate('harden({a})');
   t.is(obj.a, 123, 'expected object');
   if (!harden.isFake) {
@@ -151,11 +157,17 @@ test('main use case', t => {
     }
     return power(arg);
   }
-  const attenuatedPower = new Compartment({ power }).evaluate(`(${attenuate})`);
+  const attenuatedPower = new Compartment({
+    globals: { power },
+    __options__: true,
+  }).evaluate(`(${attenuate})`);
   function use(arg) {
     return power(arg);
   }
-  const c = new Compartment({ power: attenuatedPower });
+  const c = new Compartment({
+    globals: { power: attenuatedPower },
+    __options__: true,
+  });
   const user = c.evaluate(`(${use})`);
   t.is(user(1), 2);
   t.throws(() => user(-1), { instanceOf: c.globalThis.TypeError });