@substrat-run/contract-tests 0.105.0 → 0.107.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -20,6 +20,6 @@ export { nodeOnlySuite, declaredNodeOnlySuite } from './node-only-suite.js';
20
20
  export type { NodeOnlyOptions } from './node-only-suite.js';
21
21
  export { declareEntityChecks, declareNodeOnly, assertNodeOnly } from './conformance.js';
22
22
  export type { ConformanceDeclaration, DrivenConformance, DeclaredNodeOnlyConformance, AssertedNodeOnlyConformance, } from './conformance.js';
23
- export { atomicMod, billedMod, brokenMod, connectorMod, contractTestBareOps, contractTestInitialModules, contractTestModules, permMod, scheduleMod, freshnessMod, searchMod, searchModManifest, listMod, listModManifest, parseMod, parseModManifest, } from './modules.js';
23
+ export { atomicMod, billedMod, brokenMod, connectorMod, contractTestBareOps, contractTestInitialModules, contractTestModules, permMod, scheduleMod, testMod, freshnessMod, searchMod, searchModManifest, listMod, listModManifest, parseMod, parseModManifest, } from './modules.js';
24
24
  export { connectorCalls, connectorTestFetch, resetConnectorCalls, type ConnectorCall, } from './connector-fixture.js';
25
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAC/F,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACzG,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxF,YAAY,EACV,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,WAAW,EACX,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAC/F,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACzG,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxF,YAAY,EACV,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,WAAW,EACX,OAAO,EACP,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -15,6 +15,6 @@ export { grantExpiryContractSuite } from './grant-expiry-suite.js';
15
15
  export { entityCheckConformanceSuite, planEntityCheckCoverage } from './entity-check-suite.js';
16
16
  export { nodeOnlySuite, declaredNodeOnlySuite } from './node-only-suite.js';
17
17
  export { declareEntityChecks, declareNodeOnly, assertNodeOnly } from './conformance.js';
18
- export { atomicMod, billedMod, brokenMod, connectorMod, contractTestBareOps, contractTestInitialModules, contractTestModules, permMod, scheduleMod, freshnessMod, searchMod, searchModManifest, listMod, listModManifest, parseMod, parseModManifest, } from './modules.js';
18
+ export { atomicMod, billedMod, brokenMod, connectorMod, contractTestBareOps, contractTestInitialModules, contractTestModules, permMod, scheduleMod, testMod, freshnessMod, searchMod, searchModManifest, listMod, listModManifest, parseMod, parseModManifest, } from './modules.js';
19
19
  export { connectorCalls, connectorTestFetch, resetConnectorCalls, } from './connector-fixture.js';
20
20
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAE/F,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAOxF,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,WAAW,EACX,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GAEpB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAE/F,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAOxF,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,WAAW,EACX,OAAO,EACP,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GAEpB,MAAM,wBAAwB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"scope-host-suite.d.ts","sourceRoot":"","sources":["../src/scope-host-suite.ts"],"names":[],"mappings":"AAuBA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAW9B,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AA2BD,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,EAC5C,IAAI,GAAE,qBAA0B,GAC/B,IAAI,CA63JN"}
1
+ {"version":3,"file":"scope-host-suite.d.ts","sourceRoot":"","sources":["../src/scope-host-suite.ts"],"names":[],"mappings":"AAuBA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAW9B,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AA2BD,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,EAC5C,IAAI,GAAE,qBAA0B,GAC/B,IAAI,CA83JN"}
@@ -2940,30 +2940,30 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
2940
2940
  };
2941
2941
  it('a private vertical version lands ADMITTED on push, noted as auto-admission', async () => {
2942
2942
  await host.admin.registerVertical(staff, {
2943
- slug: 'egeryds/crm',
2944
- name: 'Egeryds CRM',
2943
+ slug: 'tenant-a/crm',
2944
+ name: 'Tenant A CRM',
2945
2945
  source: 'cli',
2946
2946
  ownerTenant: t2,
2947
2947
  });
2948
- const vid = await publishPrivate('egeryds/crm', '0.1.0');
2949
- const [v] = await host.admin.listVersions(staff, 'egeryds/crm');
2948
+ const vid = await publishPrivate('tenant-a/crm', '0.1.0');
2949
+ const [v] = await host.admin.listVersions(staff, 'tenant-a/crm');
2950
2950
  expect(v?.admission).toBe('admitted');
2951
2951
  expect(v?.admissionNote).toBe(AUTO_ADMISSION_NOTE);
2952
2952
  // Promotable immediately — for a private vertical, push + promote IS the deploy.
2953
- await host.admin.promoteVersion(staff, 'egeryds/crm', 'prod', vid);
2954
- expect((await host.admin.listChannels(staff, 'egeryds/crm')).find((c) => c.channel === 'prod')?.versionId).toBe(vid);
2953
+ await host.admin.promoteVersion(staff, 'tenant-a/crm', 'prod', vid);
2954
+ expect((await host.admin.listChannels(staff, 'tenant-a/crm')).find((c) => c.channel === 'prod')?.versionId).toBe(vid);
2955
2955
  });
2956
2956
  it('getVersion reads ONE version by id, and fails closed across a lineage', async () => {
2957
2957
  // The read that replaced "list every version this vertical ever pushed, then
2958
2958
  // .find() one". Correctness first: same row, same shape as the list gives.
2959
- const vid = await publishPrivate('egeryds/crm', '0.9.0');
2959
+ const vid = await publishPrivate('tenant-a/crm', '0.9.0');
2960
2960
  const one = await host.admin.getVersion(staff, vid);
2961
2961
  expect(one?.id).toBe(vid);
2962
- expect(one).toEqual((await host.admin.listVersions(staff, 'egeryds/crm')).find((v) => v.id === vid));
2962
+ expect(one).toEqual((await host.admin.listVersions(staff, 'tenant-a/crm')).find((v) => v.id === vid));
2963
2963
  // Narrowed, it keeps what the old `.find()`-inside-one-slug's-list gave for free:
2964
2964
  // a version of ANOTHER vertical is absent, not returned across the boundary. Without
2965
2965
  // this, the slug in the URL stops constraining which version a route can hand back.
2966
- expect((await host.admin.getVersion(staff, vid, 'egeryds/crm'))?.id).toBe(vid);
2966
+ expect((await host.admin.getVersion(staff, vid, 'tenant-a/crm'))?.id).toBe(vid);
2967
2967
  expect(await host.admin.getVersion(staff, vid, 'callout')).toBeUndefined();
2968
2968
  // An id nobody published is absent, not a throw — callers branch on undefined.
2969
2969
  expect(await host.admin.getVersion(staff, ulid())).toBeUndefined();
@@ -2976,15 +2976,15 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
2976
2976
  expect(versions.find((v) => v.version === '9.9.9')?.admission).toBe('pending');
2977
2977
  });
2978
2978
  it('promotion appends to the channel history — the go-live timeline rollback picks from', async () => {
2979
- const first = (await host.admin.listChannelHistory(staff, 'egeryds/crm', 'prod'));
2979
+ const first = (await host.admin.listChannelHistory(staff, 'tenant-a/crm', 'prod'));
2980
2980
  expect(first).toHaveLength(1);
2981
2981
  expect(first[0].fromVersionId).toBeNull(); // nothing before the first go-live
2982
- const v2 = await publishPrivate('egeryds/crm', '0.2.0');
2983
- await host.admin.promoteVersion(staff, 'egeryds/crm', 'prod', v2);
2982
+ const v2 = await publishPrivate('tenant-a/crm', '0.2.0');
2983
+ await host.admin.promoteVersion(staff, 'tenant-a/crm', 'prod', v2);
2984
2984
  // Rollback is a NEW promotion of the older version — the timeline only grows.
2985
2985
  const v1 = first[0].versionId;
2986
- await host.admin.promoteVersion(staff, 'egeryds/crm', 'prod', v1);
2987
- const timeline = await host.admin.listChannelHistory(staff, 'egeryds/crm', 'prod');
2986
+ await host.admin.promoteVersion(staff, 'tenant-a/crm', 'prod', v1);
2987
+ const timeline = await host.admin.listChannelHistory(staff, 'tenant-a/crm', 'prod');
2988
2988
  expect(timeline.map((h) => h.versionId)).toEqual([v1, v2, v1]); // newest first
2989
2989
  expect(timeline[0].fromVersionId).toBe(v2);
2990
2990
  expect(timeline[1].fromVersionId).toBe(v1);
@@ -3001,33 +3001,33 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
3001
3001
  const appScope = scopeId.parse(ulid());
3002
3002
  await host.provisionScope(staff, { tenantId: t2, scopeId: appScope });
3003
3003
  await host.admin.activateScope(staff, t2, appScope);
3004
- const prodNow = (await host.admin.listChannels(staff, 'egeryds/crm')).find((c) => c.channel === 'prod')
3004
+ const prodNow = (await host.admin.listChannels(staff, 'tenant-a/crm')).find((c) => c.channel === 'prod')
3005
3005
  .versionId;
3006
3006
  await host.admin.bindScopeVersion(staff, t2, appScope, prodNow);
3007
- const v3 = await publishPrivate('egeryds/crm', '0.3.0');
3008
- await host.admin.promoteVersion(staff, 'egeryds/crm', 'prod', v3);
3007
+ const v3 = await publishPrivate('tenant-a/crm', '0.3.0');
3008
+ await host.admin.promoteVersion(staff, 'tenant-a/crm', 'prod', v3);
3009
3009
  expect((await host.admin.getScopeRecord(staff, t2, appScope))?.verticalVersionId).toBe(v3);
3010
3010
  });
3011
3011
  it('publish refuses an auto-admitted prod version until a staff admit vouches for it', async () => {
3012
3012
  // Listing is the moment OTHER tenants start trusting this code, so the version
3013
3013
  // they would install needs a recorded human decision — the auto-admission note
3014
3014
  // is exactly what marks its absence.
3015
- await expect(host.admin.setVerticalListed(staff, 'egeryds/crm', true)).rejects.toThrow(/auto-admitted.*staff admit/);
3015
+ await expect(host.admin.setVerticalListed(staff, 'tenant-a/crm', true)).rejects.toThrow(/auto-admitted.*staff admit/);
3016
3016
  // A staff admit of the already-admitted version upgrades it to a manual vouch
3017
3017
  // (clears the note, audited) — then listing passes.
3018
- const prodNow = (await host.admin.listChannels(staff, 'egeryds/crm')).find((c) => c.channel === 'prod')
3018
+ const prodNow = (await host.admin.listChannels(staff, 'tenant-a/crm')).find((c) => c.channel === 'prod')
3019
3019
  .versionId;
3020
3020
  await host.admin.admitVersion(staff, prodNow);
3021
- const upgraded = (await host.admin.listVersions(staff, 'egeryds/crm')).find((v) => v.id === prodNow);
3021
+ const upgraded = (await host.admin.listVersions(staff, 'tenant-a/crm')).find((v) => v.id === prodNow);
3022
3022
  expect(upgraded?.admission).toBe('admitted');
3023
3023
  expect(upgraded?.admissionNote).toBeNull();
3024
- await host.admin.setVerticalListed(staff, 'egeryds/crm', true);
3024
+ await host.admin.setVerticalListed(staff, 'tenant-a/crm', true);
3025
3025
  // Listed now: the next push lands PENDING — staff admission is back in the
3026
3026
  // path exactly when the audience widened.
3027
- const v4 = await publishPrivate('egeryds/crm', '0.4.0');
3028
- expect((await host.admin.listVersions(staff, 'egeryds/crm')).find((v) => v.id === v4)?.admission).toBe('pending');
3027
+ const v4 = await publishPrivate('tenant-a/crm', '0.4.0');
3028
+ expect((await host.admin.listVersions(staff, 'tenant-a/crm')).find((v) => v.id === v4)?.admission).toBe('pending');
3029
3029
  // Unlist again so later suites see the vertical private (and pushes self-admit).
3030
- await host.admin.setVerticalListed(staff, 'egeryds/crm', false);
3030
+ await host.admin.setVerticalListed(staff, 'tenant-a/crm', false);
3031
3031
  });
3032
3032
  // -- the provisioning state (K-31) ---------------------------------------
3033
3033
  it('provisions a scope as `provisioning`, not `active`', async () => {
@@ -3703,9 +3703,10 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
3703
3703
  const stub = await host.getScope(alice, t4, s4);
3704
3704
  // Holding nothing: the denial says so, rather than leaving "held" to the imagination.
3705
3705
  await expect(stub.invoke('billed/act')).rejects.toThrow(/holds: none/);
3706
- // The Egeryds shape (#691): the tenant DOES hold keys — just not under the name the
3707
- // manifest declares. Required-alone reads as "buy the SKU" and sends you shopping;
3708
- // required-vs-held shows a near-miss at a glance, which is the actual diagnosis.
3706
+ // The slug-prefixed-key shape (#691): the tenant DOES hold keys — just not
3707
+ // under the name the manifest declares. Required-alone reads as "buy the
3708
+ // SKU" and sends you shopping; required-vs-held shows a near-miss at a
3709
+ // glance, which is the actual diagnosis.
3709
3710
  await host.admin.grantEntitlement(staff, t4, 't-0wv2mwk4j5/billed');
3710
3711
  await host.admin.grantEntitlement(staff, t4, 'workorder');
3711
3712
  const err = await stub.invoke('billed/act').then(() => null, (e) => e.message);
@@ -4102,12 +4103,12 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
4102
4103
  expect(seen).toEqual(all.map((v) => v.slug));
4103
4104
  });
4104
4105
  it('flips listVersions to newest-first on order desc, cursor still exclusive', async () => {
4105
- const asc = await host.admin.listVersions(staff, 'egeryds/crm');
4106
+ const asc = await host.admin.listVersions(staff, 'tenant-a/crm');
4106
4107
  expect(asc.length).toBeGreaterThanOrEqual(4);
4107
- const desc = await host.admin.listVersions(staff, 'egeryds/crm', { order: 'desc' });
4108
+ const desc = await host.admin.listVersions(staff, 'tenant-a/crm', { order: 'desc' });
4108
4109
  expect(desc.map((v) => v.id)).toEqual([...asc.map((v) => v.id)].reverse());
4109
4110
  // Descending pages backward from the cursor, strictly before it.
4110
- const page = await host.admin.listVersions(staff, 'egeryds/crm', {
4111
+ const page = await host.admin.listVersions(staff, 'tenant-a/crm', {
4111
4112
  order: 'desc',
4112
4113
  limit: 2,
4113
4114
  cursor: desc[0].id,
@@ -4115,19 +4116,19 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
4115
4116
  expect(page.map((v) => v.id)).toEqual(desc.slice(1, 3).map((v) => v.id));
4116
4117
  });
4117
4118
  it('keeps listChannelHistory newest-first by default and pages it; asc flips the walk', async () => {
4118
- const newest = await host.admin.listChannelHistory(staff, 'egeryds/crm', 'prod');
4119
+ const newest = await host.admin.listChannelHistory(staff, 'tenant-a/crm', 'prod');
4119
4120
  expect(newest.length).toBeGreaterThanOrEqual(4);
4120
4121
  // Entry ids are ULIDs, so newest-first means descending ids — the shipped order.
4121
4122
  expect(newest.map((h) => h.id)).toEqual([...newest.map((h) => h.id)].sort().reverse());
4122
- const first = await host.admin.listChannelHistory(staff, 'egeryds/crm', 'prod', { limit: 2 });
4123
+ const first = await host.admin.listChannelHistory(staff, 'tenant-a/crm', 'prod', { limit: 2 });
4123
4124
  expect(first.map((h) => h.id)).toEqual(newest.slice(0, 2).map((h) => h.id));
4124
- const next = await host.admin.listChannelHistory(staff, 'egeryds/crm', 'prod', {
4125
+ const next = await host.admin.listChannelHistory(staff, 'tenant-a/crm', 'prod', {
4125
4126
  limit: 2,
4126
4127
  cursor: first[1].id,
4127
4128
  });
4128
4129
  expect(next.map((h) => h.id)).toEqual(newest.slice(2, 4).map((h) => h.id));
4129
4130
  // 'asc' flips to oldest-first — the whole timeline, reversed.
4130
- const oldest = await host.admin.listChannelHistory(staff, 'egeryds/crm', 'prod', {
4131
+ const oldest = await host.admin.listChannelHistory(staff, 'tenant-a/crm', 'prod', {
4131
4132
  order: 'asc',
4132
4133
  });
4133
4134
  expect(oldest.map((h) => h.id)).toEqual([...newest.map((h) => h.id)].reverse());