@substrat-run/contract-tests 0.1.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/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # @substrat-run/contract-tests
2
+
3
+ The conformance suite for [Substrat](https://github.com/substrat-run/substrat)
4
+ scope-host adapters. Every adapter — pure SQLite, Cloudflare Durable Objects, and any
5
+ future one — must pass this suite **unchanged**, forever. If an adapter needs the suite
6
+ modified, the contract changed, and that is a decision, not a patch.
7
+
8
+ This package exports test *suites* (built on [Vitest](https://vitest.dev)); it runs
9
+ nothing itself. Each adapter runs the suite from its own `test/` folder.
10
+
11
+ ## Usage
12
+
13
+ ```ts
14
+ // packages/adapter-yours/test/contract.test.ts
15
+ import { scopeHostContractSuite } from '@substrat-run/contract-tests';
16
+ import { YourScopeHost } from '../src/index.js';
17
+
18
+ scopeHostContractSuite('adapter-yours', async () => {
19
+ const host = new YourScopeHost({ ... });
20
+ return {
21
+ host,
22
+ cleanup: async () => host.close(),
23
+ };
24
+ });
25
+ ```
26
+
27
+ ## What the suite verifies
28
+
29
+ - **Strict serialization per scope** — 10 concurrent read-await-write increments must
30
+ land on exactly 10.
31
+ - **Structured-clone boundary** — mutating an input after `invoke()`, or a returned
32
+ result, must never affect scope state.
33
+ - **Kernel-stamped envelopes** — tenant, scope, ULID id, and timestamp are stamped
34
+ below the API surface.
35
+ - **PII classification enforced** — a PII-classed event without a `subjectId` is
36
+ rejected at emit.
37
+ - **Isolation and fail-closed addressing** — writes in one scope are invisible in
38
+ another; a mismatched `(tenantId, scopeId)` pair throws.
39
+
40
+ The suite grows with the kernel (migration journal, crash-mid-migration,
41
+ duplicate-delivery harnesses); adapters inherit new checks by upgrading.
42
+
43
+ ## Status
44
+
45
+ Pre-release (0.x): the suite expands as kernel contracts land.
@@ -0,0 +1,4 @@
1
+ export { scopeHostContractSuite } from './scope-host-suite.js';
2
+ export type { ScopeHostFixture } from './scope-host-suite.js';
3
+ export { permissionContractSuite } from './permission-suite.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { scopeHostContractSuite } from './scope-host-suite.js';
2
+ export { permissionContractSuite } from './permission-suite.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"}
@@ -0,0 +1,8 @@
1
+ import type { ScopeHostFixture } from './scope-host-suite.js';
2
+ /**
3
+ * Contract suite for the default (tuple) permission checker (design doc §4.2,
4
+ * D-23). The fixture host must use the adapter's DEFAULT checker — no
5
+ * UNSAFE_allowAllChecker.
6
+ */
7
+ export declare function permissionContractSuite(adapterName: string, makeFixture: () => Promise<ScopeHostFixture>): void;
8
+ //# sourceMappingURL=permission-suite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-suite.d.ts","sourceRoot":"","sources":["../src/permission-suite.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AA6B9D;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAC3C,IAAI,CAsHN"}
@@ -0,0 +1,129 @@
1
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
2
+ import { moduleManifest, permissionKey, principalId, scopeId, tenantId, } from '@substrat-run/contracts';
3
+ import { ulid } from '@substrat-run/kernel';
4
+ const permModManifest = moduleManifest.parse({
5
+ id: '@perm/mod',
6
+ version: '1.0.0',
7
+ kernelContract: '^0.0.1',
8
+ permissions: [
9
+ { key: 'perm:use', description: 'use the thing' },
10
+ { key: 'perm:read', description: 'read the thing' },
11
+ ],
12
+ events: { emits: [], consumes: [] },
13
+ migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
14
+ attachmentTargets: [],
15
+ entityRelations: [{ entityType: 'item', parentType: 'box' }],
16
+ entitlementKey: 'perm',
17
+ });
18
+ const linkOp = (ctx, input) => {
19
+ ctx.link(input.child, input.parent);
20
+ };
21
+ const probeOp = (ctx, input) => ctx.check(input.permission, input.entity);
22
+ const PERM_USE = permissionKey.parse('perm:use');
23
+ const PERM_READ = permissionKey.parse('perm:read');
24
+ /**
25
+ * Contract suite for the default (tuple) permission checker (design doc §4.2,
26
+ * D-23). The fixture host must use the adapter's DEFAULT checker — no
27
+ * UNSAFE_allowAllChecker.
28
+ */
29
+ export function permissionContractSuite(adapterName, makeFixture) {
30
+ describe(`permission contract (tuple checker): ${adapterName}`, () => {
31
+ let fixture;
32
+ let host;
33
+ const t1 = tenantId.parse(ulid());
34
+ const s1 = scopeId.parse(ulid());
35
+ const s2 = scopeId.parse(ulid()); // same tenant, second scope
36
+ const alice = principalId.parse(ulid()); // tenant-level admin
37
+ const bob = principalId.parse(ulid()); // scope role at s1 only
38
+ const carol = principalId.parse(ulid()); // entity-narrowed grant
39
+ const dave = principalId.parse(ulid()); // expired grant
40
+ const erin = principalId.parse(ulid()); // via org membership
41
+ const probe = async (who, scope, permission, entity) => {
42
+ const stub = await host.getScope(who, t1, scope);
43
+ return stub.invoke('perm/probe', {
44
+ permission,
45
+ entity,
46
+ });
47
+ };
48
+ beforeAll(async () => {
49
+ fixture = await makeFixture();
50
+ host = fixture.host;
51
+ host.registerModule({
52
+ manifest: permModManifest,
53
+ operations: { 'perm/link': linkOp, 'perm/probe': probeOp },
54
+ });
55
+ await host.provisionScope({ tenantId: t1, scopeId: s1 });
56
+ await host.provisionScope({ tenantId: t1, scopeId: s2 });
57
+ host.admin.defineRole(t1, {
58
+ key: 'admin',
59
+ permissions: [PERM_USE, PERM_READ],
60
+ source: 'vertical',
61
+ });
62
+ host.admin.defineRole(t1, { key: 'tech', permissions: [PERM_READ], source: 'vertical' });
63
+ host.admin.assignRole({ principalId: alice, roleKey: 'admin', node: { tenantId: t1, scopeId: null } });
64
+ host.admin.assignRole({ principalId: bob, roleKey: 'tech', node: { tenantId: t1, scopeId: s1 } });
65
+ // Entity graph in s1: item i1 → box b1, item i2 → box b2.
66
+ const stub = await host.getScope(alice, t1, s1);
67
+ await stub.invoke('perm/link', {
68
+ child: { entityType: 'item', entityId: 'i1' },
69
+ parent: { entityType: 'box', entityId: 'b1' },
70
+ });
71
+ await stub.invoke('perm/link', {
72
+ child: { entityType: 'item', entityId: 'i2' },
73
+ parent: { entityType: 'box', entityId: 'b2' },
74
+ });
75
+ host.admin.grant({
76
+ principalId: carol,
77
+ permission: PERM_READ,
78
+ node: { tenantId: t1, scopeId: s1 },
79
+ entity: { entityType: 'box', entityId: 'b1' },
80
+ grantedBy: alice,
81
+ });
82
+ host.admin.grant({
83
+ principalId: dave,
84
+ permission: PERM_READ,
85
+ node: { tenantId: t1, scopeId: s1 },
86
+ expiresAt: (await import('@substrat-run/contracts')).instant.parse('2000-01-01T00:00:00Z'),
87
+ grantedBy: alice,
88
+ });
89
+ host.admin.grantToOrg('acme', PERM_READ, { tenantId: t1, scopeId: s1 });
90
+ host.admin.addMember(t1, erin, 'acme');
91
+ });
92
+ afterAll(async () => {
93
+ await fixture.cleanup();
94
+ });
95
+ it('denies by default with the checked permission and node', async () => {
96
+ const d = await probe(principalId.parse(ulid()), s1, PERM_READ);
97
+ expect(d.allowed).toBe(false);
98
+ });
99
+ it('tenant-level roles inherit downward into scopes (rule 2), with proof', async () => {
100
+ const d = await probe(alice, s1, PERM_USE);
101
+ expect(d.allowed).toBe(true);
102
+ expect(d.proof.length).toBeGreaterThanOrEqual(2);
103
+ });
104
+ it('scope roles are confined to their scope — no sideways leakage', async () => {
105
+ await expect(probe(bob, s1, PERM_READ)).resolves.toMatchObject({ allowed: true });
106
+ await expect(probe(bob, s2, PERM_READ)).resolves.toMatchObject({ allowed: false });
107
+ });
108
+ it('entity-narrowed grants resolve through declared parent edges (rule 3)', async () => {
109
+ const own = await probe(carol, s1, PERM_READ, { entityType: 'item', entityId: 'i1' });
110
+ expect(own.allowed).toBe(true);
111
+ // proof contains the parent tuple AND the grant — the walk shown
112
+ expect(JSON.stringify(own.proof)).toContain('"item:i1"');
113
+ expect(JSON.stringify(own.proof)).toContain('"box:b1"');
114
+ const other = await probe(carol, s1, PERM_READ, { entityType: 'item', entityId: 'i2' });
115
+ expect(other.allowed).toBe(false);
116
+ // No node-level access: the narrow grant does not widen.
117
+ await expect(probe(carol, s1, PERM_READ)).resolves.toMatchObject({ allowed: false });
118
+ });
119
+ it('expired grants are dead', async () => {
120
+ await expect(probe(dave, s1, PERM_READ)).resolves.toMatchObject({ allowed: false });
121
+ });
122
+ it('org membership reaches org grants (rule 4), membership tuple in the proof', async () => {
123
+ const d = await probe(erin, s1, PERM_READ);
124
+ expect(d.allowed).toBe(true);
125
+ expect(JSON.stringify(d.proof)).toContain('org:acme');
126
+ });
127
+ });
128
+ }
129
+ //# sourceMappingURL=permission-suite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-suite.js","sourceRoot":"","sources":["../src/permission-suite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type ScopeHost } from '@substrat-run/kernel';
2
+ export interface ScopeHostFixture {
3
+ host: ScopeHost;
4
+ cleanup(): Promise<void>;
5
+ }
6
+ /**
7
+ * The scope-host contract suite (design doc §11). Every adapter — pure SQLite,
8
+ * Cloudflare, and any future one — must pass this unchanged (D-14). If an
9
+ * adapter needs the suite modified, the contract changed and that is a
10
+ * decision, not a patch.
11
+ */
12
+ export declare function scopeHostContractSuite(adapterName: string, makeFixture: () => Promise<ScopeHostFixture>): void;
13
+ //# sourceMappingURL=scope-host-suite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-host-suite.d.ts","sourceRoot":"","sources":["../src/scope-host-suite.ts"],"names":[],"mappings":"AAWA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAiEnF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAYD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAC3C,IAAI,CAwVN"}
@@ -0,0 +1,338 @@
1
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
2
+ import { dataSubjectId, moduleManifest, principalId, scopeId, tenantId, } from '@substrat-run/contracts';
3
+ import { ulid } from '@substrat-run/kernel';
4
+ const testModManifest = moduleManifest.parse({
5
+ id: '@test/mod',
6
+ version: '1.0.0',
7
+ kernelContract: '^0.0.1',
8
+ permissions: [{ key: 'testmod:use', description: 'test permission' }],
9
+ events: { emits: [], consumes: [] },
10
+ migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
11
+ attachmentTargets: [],
12
+ entityRelations: [{ entityType: 'item', parentType: 'box' }],
13
+ entitlementKey: 'testmod',
14
+ });
15
+ const flowModManifest = moduleManifest.parse({
16
+ id: '@test/flow',
17
+ version: '1.0.0',
18
+ kernelContract: '^0.0.1',
19
+ permissions: [{ key: 'flow:use', description: 'flow permission' }],
20
+ events: {
21
+ emits: [
22
+ { type: 'flow.step1', schemaVersion: 1 },
23
+ { type: 'flow.step2', schemaVersion: 1 },
24
+ ],
25
+ consumes: [
26
+ { type: 'flow.step1', schemaVersion: 1 },
27
+ { type: 'flow.step2', schemaVersion: 1 },
28
+ ],
29
+ },
30
+ migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
31
+ attachmentTargets: [],
32
+ entitlementKey: 'flow',
33
+ });
34
+ const lateModManifest = moduleManifest.parse({
35
+ id: '@test/late',
36
+ version: '1.0.0',
37
+ kernelContract: '^0.0.1',
38
+ permissions: [{ key: 'late:use', description: 'late module permission' }],
39
+ events: { emits: [], consumes: [] },
40
+ migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
41
+ attachmentTargets: [],
42
+ entitlementKey: 'late',
43
+ });
44
+ const addItem = (ctx, input) => {
45
+ ctx.sql.exec('INSERT INTO testmod_items (id, box) VALUES (?, ?)', [input.id, input.box]);
46
+ ctx.link({ entityType: 'item', entityId: input.id }, { entityType: 'box', entityId: input.box });
47
+ };
48
+ const relinkItem = (ctx, input) => {
49
+ ctx.link({ entityType: 'item', entityId: input.id }, { entityType: 'box', entityId: input.box });
50
+ };
51
+ const linkUndeclared = (ctx) => {
52
+ ctx.link({ entityType: 'box', entityId: 'b1' }, { entityType: 'item', entityId: 'i1' });
53
+ };
54
+ const readJournal = (ctx) => ctx.sql.query('SELECT module_id, version FROM _substrat_migrations ORDER BY module_id');
55
+ const readTuples = (ctx) => ctx.sql.query('SELECT subject, relation, object FROM _substrat_tuples ORDER BY subject');
56
+ /**
57
+ * The scope-host contract suite (design doc §11). Every adapter — pure SQLite,
58
+ * Cloudflare, and any future one — must pass this unchanged (D-14). If an
59
+ * adapter needs the suite modified, the contract changed and that is a
60
+ * decision, not a patch.
61
+ */
62
+ export function scopeHostContractSuite(adapterName, makeFixture) {
63
+ describe(`scope-host contract: ${adapterName}`, () => {
64
+ let fixture;
65
+ let host;
66
+ const t1 = tenantId.parse(ulid());
67
+ const t2 = tenantId.parse(ulid());
68
+ const s1 = scopeId.parse(ulid());
69
+ const s2 = scopeId.parse(ulid());
70
+ const alice = principalId.parse(ulid());
71
+ beforeAll(async () => {
72
+ fixture = await makeFixture();
73
+ host = fixture.host;
74
+ host.defineOperation('test/init-counter', (ctx) => {
75
+ ctx.sql.exec('CREATE TABLE IF NOT EXISTS counter (n INTEGER NOT NULL)');
76
+ ctx.sql.exec('DELETE FROM counter');
77
+ ctx.sql.exec('INSERT INTO counter (n) VALUES (0)');
78
+ });
79
+ // Read → await → write. Under interleaving this loses updates; under
80
+ // strict serialization it cannot.
81
+ host.defineOperation('test/slow-increment', async (ctx) => {
82
+ const [row] = ctx.sql.query('SELECT n FROM counter');
83
+ await new Promise((r) => setTimeout(r, 5));
84
+ ctx.sql.exec('UPDATE counter SET n = ?', [row.n + 1]);
85
+ });
86
+ host.defineOperation('test/read-counter', (ctx) => {
87
+ const [row] = ctx.sql.query('SELECT n FROM counter');
88
+ return row.n;
89
+ });
90
+ const stash = {};
91
+ host.defineOperation('test/stash', (_ctx, input) => {
92
+ stash.value = input;
93
+ });
94
+ host.defineOperation('test/read-stash', () => {
95
+ return stash.value;
96
+ });
97
+ host.defineOperation('test/emit-event', (ctx, input) => {
98
+ ctx.emit({
99
+ type: 'test.happened',
100
+ schemaVersion: 1,
101
+ entity: { entityType: 'test-thing', entityId: 'x1' },
102
+ piiClass: input?.subject ? 'pseudonymous' : 'none',
103
+ ...(input?.subject ? { subjectId: dataSubjectId.parse(input.subject) } : {}),
104
+ payload: { hello: 'world' },
105
+ });
106
+ });
107
+ host.defineOperation('test/emit-unclassified-pii', (ctx) => {
108
+ // piiClass 'direct' without subjectId — must be rejected at emit (§6.1)
109
+ ctx.emit({
110
+ type: 'test.bad',
111
+ schemaVersion: 1,
112
+ entity: { entityType: 'test-thing', entityId: 'x2' },
113
+ piiClass: 'direct',
114
+ payload: {},
115
+ });
116
+ });
117
+ host.defineOperation('test/read-outbox', (ctx) => ctx.sql.query('SELECT * FROM _substrat_outbox ORDER BY id'));
118
+ host.defineOperation('test/write-marker', (ctx, input) => {
119
+ ctx.sql.exec('CREATE TABLE IF NOT EXISTS marker (v TEXT NOT NULL)');
120
+ ctx.sql.exec('INSERT INTO marker (v) VALUES (?)', [input.v]);
121
+ });
122
+ host.defineOperation('test/read-markers', (ctx) => {
123
+ ctx.sql.exec('CREATE TABLE IF NOT EXISTS marker (v TEXT NOT NULL)');
124
+ return ctx.sql.query('SELECT v FROM marker').map((r) => r.v);
125
+ });
126
+ host.defineOperation('test/atomic-init', (ctx) => {
127
+ ctx.sql.exec('CREATE TABLE IF NOT EXISTS atomic_t (n INTEGER NOT NULL)');
128
+ });
129
+ host.defineOperation('test/atomic-fail', (ctx) => {
130
+ ctx.sql.exec('INSERT INTO atomic_t (n) VALUES (1)');
131
+ ctx.emit({
132
+ type: 'test.atomic',
133
+ schemaVersion: 1,
134
+ entity: { entityType: 'test-thing', entityId: 'x9' },
135
+ piiClass: 'none',
136
+ payload: {},
137
+ });
138
+ throw new Error('boom');
139
+ });
140
+ host.defineOperation('test/atomic-read', (ctx) => ({
141
+ rows: ctx.sql.query('SELECT n FROM atomic_t').length,
142
+ events: ctx.sql.query('SELECT id FROM _substrat_outbox WHERE type = ?', ['test.atomic'])
143
+ .length,
144
+ }));
145
+ host.registerModule({
146
+ manifest: testModManifest,
147
+ migrations: [
148
+ {
149
+ version: '0001-init',
150
+ sql: 'CREATE TABLE testmod_items (id TEXT PRIMARY KEY, box TEXT NOT NULL)',
151
+ },
152
+ ],
153
+ operations: {
154
+ 'testmod/add': addItem,
155
+ 'testmod/relink': relinkItem,
156
+ 'testmod/link-undeclared': linkUndeclared,
157
+ 'testmod/read-journal': readJournal,
158
+ 'testmod/read-tuples': readTuples,
159
+ },
160
+ });
161
+ host.registerModule({
162
+ manifest: flowModManifest,
163
+ migrations: [
164
+ {
165
+ version: '0001-init',
166
+ sql: 'CREATE TABLE flow_log (event_id TEXT PRIMARY KEY, type TEXT NOT NULL)',
167
+ },
168
+ ],
169
+ operations: {
170
+ 'flow/produce': ((ctx) => {
171
+ ctx.emit({
172
+ type: 'flow.step1',
173
+ schemaVersion: 1,
174
+ entity: { entityType: 'flow-thing', entityId: 'f1' },
175
+ piiClass: 'none',
176
+ payload: {},
177
+ });
178
+ }),
179
+ 'flow/log': ((ctx) => ctx.sql.query('SELECT event_id, type FROM flow_log ORDER BY event_id')),
180
+ 'flow/deliveries': ((ctx) => ctx.sql.query(`SELECT event_id, consumer_module, error FROM _substrat_deliveries
181
+ WHERE consumer_module = '@test/flow' ORDER BY event_id`)),
182
+ 'flow/step2-actors': ((ctx) => ctx.sql.query(`SELECT actor FROM _substrat_outbox WHERE type = 'flow.step2'`)),
183
+ },
184
+ consumers: {
185
+ 'flow.step1': (ctx, event) => {
186
+ ctx.sql.exec('INSERT INTO flow_log (event_id, type) VALUES (?, ?)', [
187
+ event.id,
188
+ event.type,
189
+ ]);
190
+ ctx.emit({
191
+ type: 'flow.step2',
192
+ schemaVersion: 1,
193
+ entity: event.entity,
194
+ piiClass: 'none',
195
+ payload: {},
196
+ });
197
+ },
198
+ 'flow.step2': (ctx, event) => {
199
+ ctx.sql.exec('INSERT INTO flow_log (event_id, type) VALUES (?, ?)', [
200
+ event.id,
201
+ event.type,
202
+ ]);
203
+ },
204
+ },
205
+ });
206
+ await host.provisionScope({ tenantId: t1, scopeId: s1, jurisdiction: 'eu' });
207
+ await host.provisionScope({ tenantId: t2, scopeId: s2, jurisdiction: 'eu' });
208
+ });
209
+ afterAll(async () => {
210
+ await fixture.cleanup();
211
+ });
212
+ it('provisioning is idempotent', async () => {
213
+ await expect(host.provisionScope({ tenantId: t1, scopeId: s1, jurisdiction: 'eu' })).resolves.toBeUndefined();
214
+ });
215
+ it('fails closed on a mismatched (tenantId, scopeId) pair (K-3)', async () => {
216
+ await expect(host.getScope(alice, t2, s1)).rejects.toThrow();
217
+ await expect(host.getScope(alice, t1, scopeId.parse(ulid()))).rejects.toThrow();
218
+ });
219
+ it('serializes operations strictly per scope (K-6)', async () => {
220
+ const stub = await host.getScope(alice, t1, s1);
221
+ await stub.invoke('test/init-counter');
222
+ await Promise.all(Array.from({ length: 10 }, () => stub.invoke('test/slow-increment')));
223
+ await expect(stub.invoke('test/read-counter')).resolves.toBe(10);
224
+ });
225
+ it('clones inputs and results across the stub boundary (K-6)', async () => {
226
+ const stub = await host.getScope(alice, t1, s1);
227
+ const input = { items: ['a'] };
228
+ await stub.invoke('test/stash', input);
229
+ input.items.push('MUTATED-AFTER-CALL');
230
+ const first = await stub.invoke('test/read-stash');
231
+ expect(first.items).toEqual(['a']);
232
+ first.items.push('MUTATED-RESULT');
233
+ const second = await stub.invoke('test/read-stash');
234
+ expect(second.items).toEqual(['a']);
235
+ });
236
+ it('stamps the event envelope kernel-side (§6.1)', async () => {
237
+ const stub = await host.getScope(alice, t1, s1);
238
+ await stub.invoke('test/emit-event');
239
+ const rows = await stub.invoke('test/read-outbox');
240
+ expect(rows.length).toBeGreaterThan(0);
241
+ const row = rows[rows.length - 1];
242
+ expect(row.tenant_id).toBe(t1);
243
+ expect(row.scope_id).toBe(s1);
244
+ expect(row.id).toMatch(/^[0-9A-HJKMNP-TV-Z]{26}$/);
245
+ expect(new Date(row.occurred_at).getTime()).not.toBeNaN();
246
+ expect(row.pii_class).toBe('none');
247
+ });
248
+ it('rejects PII-classed events without a subjectId (§6.1)', async () => {
249
+ const stub = await host.getScope(alice, t1, s1);
250
+ await expect(stub.invoke('test/emit-unclassified-pii')).rejects.toThrow(/subjectId/);
251
+ });
252
+ it('accepts PII-classed events with a subjectId', async () => {
253
+ const stub = await host.getScope(alice, t1, s1);
254
+ await expect(stub.invoke('test/emit-event', { subject: ulid() })).resolves.toBeUndefined();
255
+ });
256
+ it('isolates scope storage: a write in one scope is invisible in another', async () => {
257
+ const stub1 = await host.getScope(alice, t1, s1);
258
+ const stub2 = await host.getScope(alice, t2, s2);
259
+ await stub1.invoke('test/write-marker', { v: 'only-in-s1' });
260
+ await expect(stub2.invoke('test/read-markers')).resolves.toEqual([]);
261
+ await expect(stub1.invoke('test/read-markers')).resolves.toEqual(['only-in-s1']);
262
+ });
263
+ it('rejects unknown operations', async () => {
264
+ const stub = await host.getScope(alice, t1, s1);
265
+ await expect(stub.invoke('test/does-not-exist')).rejects.toThrow(/unknown operation/);
266
+ });
267
+ it('rolls back the entire operation when the handler throws (K-4)', async () => {
268
+ const stub = await host.getScope(alice, t1, s1);
269
+ await stub.invoke('test/atomic-init');
270
+ await expect(stub.invoke('test/atomic-fail')).rejects.toThrow('boom');
271
+ // Neither the write NOR its emitted event survive — one transaction.
272
+ await expect(stub.invoke('test/atomic-read')).resolves.toEqual({ rows: 0, events: 0 });
273
+ });
274
+ it('applies module migrations lazily and journals them per (module, version)', async () => {
275
+ const stub = await host.getScope(alice, t1, s1);
276
+ const journal = await stub.invoke('testmod/read-journal');
277
+ expect(journal).toContainEqual({ module_id: '@test/mod', version: '0001-init' });
278
+ // Idempotent: another wake applies nothing twice.
279
+ const again = await host.getScope(alice, t1, s1);
280
+ const journal2 = await again.invoke('testmod/read-journal');
281
+ expect(journal2.filter((r) => r.module_id === '@test/mod')).toHaveLength(1);
282
+ });
283
+ it('applies migrations of modules registered after a scope was first accessed', async () => {
284
+ host.registerModule({
285
+ manifest: lateModManifest,
286
+ migrations: [
287
+ { version: '0001-init', sql: 'CREATE TABLE late_t (id TEXT PRIMARY KEY)' },
288
+ ],
289
+ operations: {
290
+ 'late/check': ((ctx) => ctx.sql.query(`SELECT name FROM sqlite_master WHERE name = 'late_t'`)
291
+ .length),
292
+ },
293
+ });
294
+ const stub = await host.getScope(alice, t1, s1);
295
+ await expect(stub.invoke('late/check')).resolves.toBe(1);
296
+ const journal = await stub.invoke('testmod/read-journal');
297
+ expect(journal).toContainEqual({ module_id: '@test/late', version: '0001-init' });
298
+ });
299
+ it('rejects duplicate module registration', () => {
300
+ expect(() => host.registerModule({ manifest: testModManifest })).toThrow(/already registered/);
301
+ });
302
+ it('links declared entity relations, idempotently (K-16)', async () => {
303
+ const stub = await host.getScope(alice, t1, s1);
304
+ await stub.invoke('testmod/add', { id: 'i1', box: 'b1' });
305
+ await stub.invoke('testmod/relink', { id: 'i1', box: 'b1' }); // no duplicate
306
+ const tuples = await stub.invoke('testmod/read-tuples');
307
+ expect(tuples.filter((t) => t.subject === 'item:i1')).toEqual([
308
+ { subject: 'item:i1', relation: 'parent', object: 'box:b1' },
309
+ ]);
310
+ });
311
+ it('rejects links for undeclared entity relations', async () => {
312
+ const stub = await host.getScope(alice, t1, s1);
313
+ await expect(stub.invoke('testmod/link-undeclared')).rejects.toThrow(/undeclared entity relation/);
314
+ });
315
+ it('dispatches events to consumers, cascading, exactly once per (event, consumer)', async () => {
316
+ const stub = await host.getScope(alice, t1, s1);
317
+ await stub.invoke('flow/produce');
318
+ const log = await stub.invoke('flow/log');
319
+ expect(log.map((r) => r.type).sort()).toEqual(['flow.step1', 'flow.step2']);
320
+ const deliveries = await stub.invoke('flow/deliveries');
321
+ expect(deliveries).toHaveLength(2);
322
+ expect(deliveries.every((d) => d.error === null)).toBe(true);
323
+ await stub.invoke('flow/produce');
324
+ const log2 = await stub.invoke('flow/log');
325
+ expect(log2).toHaveLength(4); // two new, none duplicated
326
+ await expect(stub.invoke('flow/deliveries')).resolves.toHaveLength(4);
327
+ });
328
+ it('runs consumers under a system actor — consumer-emitted events carry it', async () => {
329
+ const stub = await host.getScope(alice, t1, s1);
330
+ const actors = await stub.invoke('flow/step2-actors');
331
+ expect(actors.length).toBeGreaterThan(0);
332
+ for (const row of actors) {
333
+ expect(JSON.parse(row.actor)).toEqual({ system: '@test/flow' });
334
+ }
335
+ });
336
+ });
337
+ }
338
+ //# sourceMappingURL=scope-host-suite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-host-suite.js","sourceRoot":"","sources":["../src/scope-host-suite.ts"],"names":[],"mappings":"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"}