@sensigo/realm-testing 0.26.0 → 0.27.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 +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/store/fenced-trace-buffer-contract.d.ts +87 -0
- package/dist/store/fenced-trace-buffer-contract.d.ts.map +1 -0
- package/dist/store/fenced-trace-buffer-contract.js +970 -0
- package/dist/store/fenced-trace-buffer-contract.js.map +1 -0
- package/dist/store/in-memory-store.d.ts.map +1 -1
- package/dist/store/in-memory-store.js +5 -8
- package/dist/store/in-memory-store.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export { perRunArtifactStoreContract } from './store/per-run-artifact-store-cont
|
|
|
3
3
|
export type { ArtifactStoreLaw, ArtifactStoreContractCase, PerRunArtifactStoreContractAdapter, } from './store/per-run-artifact-store-contract.js';
|
|
4
4
|
export { runStoreFidelityContract } from './store/run-store-fidelity-contract.js';
|
|
5
5
|
export type { RunStoreFidelityLaw, RunStoreFidelityContractCase, RunStoreFidelityContractAdapter, } from './store/run-store-fidelity-contract.js';
|
|
6
|
+
export { fencedTraceBufferContract } from './store/fenced-trace-buffer-contract.js';
|
|
7
|
+
export type { FencedTraceBufferLaw, FencedTraceBufferContractCase, FencedTraceBufferContractAdapter, } from './store/fenced-trace-buffer-contract.js';
|
|
6
8
|
export { loadFixtureFromFile, loadFixtureFromString, loadFixturesFromDir, } from './fixtures/fixture-loader.js';
|
|
7
9
|
export type { TestFixture, MockOperations } from './fixtures/fixture-loader.js';
|
|
8
10
|
export { MockServiceRecorder } from './mocks/mock-service.js';
|
|
@@ -17,5 +19,5 @@ export { runFixtureTests } from './runner/test-runner.js';
|
|
|
17
19
|
export type { TestResult, RunFixtureTestsOptions } from './runner/test-runner.js';
|
|
18
20
|
export { startGitHubMockServer } from './servers/github-mock-server.js';
|
|
19
21
|
export type { GitHubMockServerHandle } from './servers/github-mock-server.js';
|
|
20
|
-
export declare const VERSION = "0.
|
|
22
|
+
export declare const VERSION = "0.27.0";
|
|
21
23
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,2BAA2B,EAAE,MAAM,4CAA4C,CAAC;AACzF,YAAY,EACV,gBAAgB,EAChB,yBAAyB,EACzB,kCAAkC,GACnC,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AAClF,YAAY,EACV,mBAAmB,EACnB,4BAA4B,EAC5B,+BAA+B,GAChC,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,2BAA2B,EAAE,MAAM,4CAA4C,CAAC;AACzF,YAAY,EACV,gBAAgB,EAChB,yBAAyB,EACzB,kCAAkC,GACnC,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AAClF,YAAY,EACV,mBAAmB,EACnB,4BAA4B,EAC5B,+BAA+B,GAChC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AACpF,YAAY,EACV,oBAAoB,EACpB,6BAA6B,EAC7B,gCAAgC,GACjC,MAAM,yCAAyC,CAAC;AAGjD,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGhF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,YAAY,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAGlF,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,YAAY,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAE9E,eAAO,MAAM,OAAO,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
export { InMemoryStore } from './store/in-memory-store.js';
|
|
4
4
|
export { perRunArtifactStoreContract } from './store/per-run-artifact-store-contract.js';
|
|
5
5
|
export { runStoreFidelityContract } from './store/run-store-fidelity-contract.js';
|
|
6
|
+
export { fencedTraceBufferContract } from './store/fenced-trace-buffer-contract.js';
|
|
6
7
|
// Fixtures
|
|
7
8
|
export { loadFixtureFromFile, loadFixtureFromString, loadFixturesFromDir, } from './fixtures/fixture-loader.js';
|
|
8
9
|
// Mocks
|
|
@@ -19,5 +20,5 @@ export { testAdapter } from './helpers/test-adapter.js';
|
|
|
19
20
|
export { runFixtureTests } from './runner/test-runner.js';
|
|
20
21
|
// Servers
|
|
21
22
|
export { startGitHubMockServer } from './servers/github-mock-server.js';
|
|
22
|
-
export const VERSION = '0.
|
|
23
|
+
export const VERSION = '0.27.0';
|
|
23
24
|
//# 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,iEAAiE;AAEjE,QAAQ;AACR,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,2BAA2B,EAAE,MAAM,4CAA4C,CAAC;AAMzF,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAEjE,QAAQ;AACR,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,2BAA2B,EAAE,MAAM,4CAA4C,CAAC;AAMzF,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AAMlF,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AAOpF,WAAW;AACX,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAGtC,QAAQ;AACR,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,aAAa;AACb,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAElC,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,SAAS;AACT,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,UAAU;AACV,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAGxE,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { type TraceBufferStore } from '@sensigo/realm';
|
|
2
|
+
/**
|
|
3
|
+
* One of the laws every fenced-trio-declaring `TraceBufferStore` must satisfy. The original five
|
|
4
|
+
* (issue #207) cover the fenced trio itself; the remaining five (issue #197 PR-1) cover the
|
|
5
|
+
* optional capability-ladder rungs a trio-declaring store MAY additionally declare (`seal` and
|
|
6
|
+
* `writer_nonce_carriage`) — each of those five produces an explicit, VISIBLE documented-skip case
|
|
7
|
+
* (never a silent omission) for a store that does not declare the relevant rung, mirroring the
|
|
8
|
+
* `fenceForm: 'native-predicate'` skip precedent already established for the latch-based trio
|
|
9
|
+
* laws below.
|
|
10
|
+
*/
|
|
11
|
+
export type FencedTraceBufferLaw = 'STRUCTURAL' | 'FENCE_REFUSES' | 'CS_OCCUPANCY' | 'PER_KEY_INDEPENDENCE' | 'NO_SILENT_LOSS' | 'CARRIAGE_ROUND_TRIP' | 'SEAL' | 'SEAL_BUDGET' | 'PER_WRITER_BUDGET' | 'VERBATIM';
|
|
12
|
+
/**
|
|
13
|
+
* A single, framework-agnostic contract case. `run()` throws (rejects) on failure — any test
|
|
14
|
+
* framework's `await run()` (rejecting fails the test) or `expect(run()).resolves...` /
|
|
15
|
+
* `expect(run()).rejects...` maps directly onto this.
|
|
16
|
+
*/
|
|
17
|
+
export interface FencedTraceBufferContractCase {
|
|
18
|
+
law: FencedTraceBufferLaw;
|
|
19
|
+
name: string;
|
|
20
|
+
run: () => Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
/** Adapter a calling test file supplies to parameterize the contract against one concrete store. */
|
|
23
|
+
export interface FencedTraceBufferContractAdapter {
|
|
24
|
+
/** The store under test — already declaring the fenced trio (`appendFenced`/`deleteFenced`/
|
|
25
|
+
* `deleteAllForRunFenced`). For `fenceForm: 'guard-in-cs'` stores, this instance should already
|
|
26
|
+
* be constructed with a sufficiently generous lock-acquisition profile (see `lockProfile`
|
|
27
|
+
* below) so a deliberately-parked guard in the latch-based laws doesn't cause a concurrent
|
|
28
|
+
* caller's own acquisition attempt to give up before the law's observation window completes. */
|
|
29
|
+
store: TraceBufferStore;
|
|
30
|
+
/** Returns a fresh, never-before-used (runId, stepId) pair for one case — callers should treat
|
|
31
|
+
* every returned pair as belonging to a disjoint run from every other pair this returns. */
|
|
32
|
+
makeKey: () => {
|
|
33
|
+
runId: string;
|
|
34
|
+
stepId: string;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* `'guard-in-cs'`: the store enforces the fence via an in-process critical section — the guard
|
|
38
|
+
* literally runs inside the same lock/mutex the destructive effect does. `'native-predicate'`:
|
|
39
|
+
* the store enforces the fence via a transaction-scoped SQL predicate instead (e.g. a future
|
|
40
|
+
* Postgres store) — the latch-based laws (`CS_OCCUPANCY`, `PER_KEY_INDEPENDENCE`,
|
|
41
|
+
* `NO_SILENT_LOSS`) do not apply to this fence form and produce an explicit, VISIBLE
|
|
42
|
+
* documented-skip case rather than a silent omission. **A green TCK run does NOT verify race
|
|
43
|
+
* closure for a native-predicate store** — that store's own in-transaction fencing suite must
|
|
44
|
+
* (the same posture `RunStore.claimStep`'s cross-host obligation already states for
|
|
45
|
+
* `CLAIM_SINGLE_OWNER`, issue #188).
|
|
46
|
+
*/
|
|
47
|
+
fenceForm: 'guard-in-cs' | 'native-predicate';
|
|
48
|
+
/** Descriptive only (present for `'guard-in-cs'` adapters): the lock-acquisition profile the
|
|
49
|
+
* `store` instance above was actually constructed with, for the calling test file's own
|
|
50
|
+
* documentation — the TCK itself does not need to act on this value; it exists so a wiring
|
|
51
|
+
* test can assert (and a reader can see) that a genuinely generous profile is in use. */
|
|
52
|
+
lockProfile?: unknown;
|
|
53
|
+
/**
|
|
54
|
+
* Per-adapter byte oracle for `PER_WRITER_BUDGET` (issue #197 PR-1) — since the in-memory and fs
|
|
55
|
+
* stores compute "bytes" via genuinely different formulas (whole-array restringify vs
|
|
56
|
+
* JSONL-additive), this TCK can only assert exact ENTRY COUNTS store-agnostically; exact BYTE
|
|
57
|
+
* equality needs each adapter to supply its own oracle, computed however that concrete store's
|
|
58
|
+
* own `AppendResult.buffer_bytes`/`file_bytes` are actually derived. Optional — a store without
|
|
59
|
+
* this hook still runs every count-based `PER_WRITER_BUDGET` assertion; only the byte-exactness
|
|
60
|
+
* sub-assertion is skipped (visibly, never silently) for that adapter.
|
|
61
|
+
*/
|
|
62
|
+
bytesOracle?: (runId: string, stepId: string, writerNonce: string | undefined) => Promise<{
|
|
63
|
+
count: number;
|
|
64
|
+
bytes: number;
|
|
65
|
+
}>;
|
|
66
|
+
/**
|
|
67
|
+
* fs-scoped raw on-disk byte access for `VERBATIM` (issue #197 PR-1) — reads the RAW bytes of a
|
|
68
|
+
* live WAL path and of one sealed artifact (`seq`), so the law can assert a seal moves bytes
|
|
69
|
+
* byte-for-byte (no parse/re-copy/truncation/dedup). `undefined` from either function means "no
|
|
70
|
+
* file at that path" (mirrors `readIfExists`'s absence convention). Optional — a store without
|
|
71
|
+
* this hook (e.g. the in-memory store, which has no on-disk representation at all) skips ONLY
|
|
72
|
+
* the raw-byte-exactness case; the shape-tolerant sibling case still runs unconditionally for
|
|
73
|
+
* every `seal`-declaring store.
|
|
74
|
+
*/
|
|
75
|
+
rawWalAccess?: {
|
|
76
|
+
readLiveRaw: (runId: string, stepId: string) => Promise<string | undefined>;
|
|
77
|
+
readSealedRaw: (runId: string, stepId: string, seq: number) => Promise<string | undefined>;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Builds the contract cases for `adapter`. See each law's own doc above (the `build*Case`
|
|
82
|
+
* functions) for what it asserts. For `fenceForm: 'native-predicate'` adapters, `CS_OCCUPANCY`,
|
|
83
|
+
* `PER_KEY_INDEPENDENCE`, and `NO_SILENT_LOSS` are replaced with an explicit, VISIBLE
|
|
84
|
+
* documented-skip case each (never a silent omission) — see the adapter's own `fenceForm` doc.
|
|
85
|
+
*/
|
|
86
|
+
export declare function fencedTraceBufferContract(adapter: FencedTraceBufferContractAdapter): FencedTraceBufferContractCase[];
|
|
87
|
+
//# sourceMappingURL=fenced-trace-buffer-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fenced-trace-buffer-contract.d.ts","sourceRoot":"","sources":["../../src/store/fenced-trace-buffer-contract.ts"],"names":[],"mappings":"AAcA,OAAO,EAGL,KAAK,gBAAgB,EAStB,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAC5B,YAAY,GACZ,eAAe,GACf,cAAc,GACd,sBAAsB,GACtB,gBAAgB,GAChB,qBAAqB,GACrB,MAAM,GACN,aAAa,GACb,mBAAmB,GACnB,UAAU,CAAC;AAEf;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,GAAG,EAAE,oBAAoB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,oGAAoG;AACpG,MAAM,WAAW,gCAAgC;IAC/C;;;;qGAIiG;IACjG,KAAK,EAAE,gBAAgB,CAAC;IACxB;iGAC6F;IAC7F,OAAO,EAAE,MAAM;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD;;;;;;;;;;OAUG;IACH,SAAS,EAAE,aAAa,GAAG,kBAAkB,CAAC;IAC9C;;;8FAG0F;IAC1F,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,CACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,SAAS,KAC5B,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE/C;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE;QACb,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;QAC5E,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;KAC5F,CAAC;CACH;AAk1BD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gCAAgC,GACxC,6BAA6B,EAAE,CAuVjC"}
|
|
@@ -0,0 +1,970 @@
|
|
|
1
|
+
// fenced-trace-buffer-contract.ts — framework-agnostic Test Compatibility Kit (TCK) for the
|
|
2
|
+
// TraceBufferStore fenced trio (issue #207, converged design D3 — plans/issue-207-design-d3.md
|
|
3
|
+
// in the realm repo).
|
|
4
|
+
//
|
|
5
|
+
// Pure case descriptors, NOT describe/it/expect — mirrors per-run-artifact-store-contract.ts's
|
|
6
|
+
// and run-store-fidelity-contract.ts's own precedent (importing vitest here would make it a
|
|
7
|
+
// runtime dependency of this published package). Each calling test file supplies an adapter and
|
|
8
|
+
// wires the returned descriptors into ITS OWN test framework.
|
|
9
|
+
//
|
|
10
|
+
// The choreography for CS_OCCUPANCY and NO_SILENT_LOSS is deadlock-free BY CONSTRUCTION (D3 §7 is
|
|
11
|
+
// normative — implemented here as written, not improvised): every parked promise has a `.catch`
|
|
12
|
+
// attached before the law ever awaits anything else, the "drain" step never depends on the
|
|
13
|
+
// latched call's own settlement, and the latch is always released before the law awaits the
|
|
14
|
+
// latched call's result.
|
|
15
|
+
import { WorkflowError, FsIoError, storeDeclaresSeal, storeDeclaresNonceCarriage, validateTraceCapabilities, BUFFER_LIMIT_COUNT, BUFFER_BACKSTOP_COUNT, SEALED_ARTIFACTS_LIMIT_PER_STEP, } from '@sensigo/realm';
|
|
16
|
+
const REFUSAL_CODE = 'STATE_RUN_BUSY';
|
|
17
|
+
/** A guard that always refuses with a typed, populated-category rejection — used by every
|
|
18
|
+
* FENCE_REFUSES case. Deliberately a real `WorkflowError` (not a bare `Error`) so the law can
|
|
19
|
+
* assert the reason category actually propagates, not just "something" propagates. */
|
|
20
|
+
function refusingGuard() {
|
|
21
|
+
return async () => {
|
|
22
|
+
throw new WorkflowError('fenced-tck: guard refused (simulated)', {
|
|
23
|
+
code: REFUSAL_CODE,
|
|
24
|
+
category: 'STATE',
|
|
25
|
+
agentAction: 'report_to_user',
|
|
26
|
+
retryable: true,
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function passingGuard() {
|
|
31
|
+
return async () => { };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A minimal, otherwise-legal `TraceBufferStore` STUB (issue #197 PR-1) — implements only the four
|
|
35
|
+
* mandatory legacy methods (never actually called by these cases) plus a HAND-SET
|
|
36
|
+
* `traceCapabilities`, deliberately WITHOUT any of the fenced-trio/seal methods regardless of what
|
|
37
|
+
* `caps` declares. Used exclusively to exercise `validateTraceCapabilities` against a
|
|
38
|
+
* declared-but-inconsistent shape — never mixed with the real adapter store, which always
|
|
39
|
+
* satisfies its OWN declaration (see the "internally consistent" STRUCTURAL case instead).
|
|
40
|
+
*/
|
|
41
|
+
function minimalStubStore(caps) {
|
|
42
|
+
return {
|
|
43
|
+
...(caps !== undefined ? { traceCapabilities: caps } : {}),
|
|
44
|
+
append: async () => ({
|
|
45
|
+
buffer_count: 0,
|
|
46
|
+
buffer_bytes: 0,
|
|
47
|
+
limit_count: 0,
|
|
48
|
+
limit_bytes: 0,
|
|
49
|
+
final_limit_entries: 0,
|
|
50
|
+
final_limit_bytes: 0,
|
|
51
|
+
}),
|
|
52
|
+
read: async () => [],
|
|
53
|
+
delete: async () => { },
|
|
54
|
+
deleteAllForRun: async () => { },
|
|
55
|
+
readAllForRun: async () => ({}),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** Runs a SYNCHRONOUS throwing function and returns what it threw, or `undefined` if it didn't —
|
|
59
|
+
* `validateTraceCapabilities` is synchronous, so this avoids an unnecessary async try/catch at
|
|
60
|
+
* every call site above. */
|
|
61
|
+
function catchSync(fn) {
|
|
62
|
+
try {
|
|
63
|
+
fn();
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
return err;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Asserts `err` is exactly the typed `TRACE_CAPABILITY_INCONSISTENT` `WorkflowError`
|
|
71
|
+
* `validateTraceCapabilities` throws for a declared-but-inconsistent rung, naming `capability` in
|
|
72
|
+
* its `details` — never some other error shape. */
|
|
73
|
+
function assertCapabilityInconsistent(err, capability) {
|
|
74
|
+
if (!(err instanceof WorkflowError) ||
|
|
75
|
+
err.code !== 'TRACE_CAPABILITY_INCONSISTENT' ||
|
|
76
|
+
err.details.capability !== capability) {
|
|
77
|
+
throw new Error(`expected a typed WorkflowError(TRACE_CAPABILITY_INCONSISTENT, details.capability=${capability}), got: ${err instanceof Error ? err.message : err}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function eventsOf(entries) {
|
|
81
|
+
return entries.map((e) => e.event);
|
|
82
|
+
}
|
|
83
|
+
function assertDeepEqualEvents(actual, expected, label) {
|
|
84
|
+
const a = eventsOf(actual);
|
|
85
|
+
const e = eventsOf(expected);
|
|
86
|
+
const equal = a.length === e.length && a.every((v, i) => v === e[i]);
|
|
87
|
+
if (!equal) {
|
|
88
|
+
throw new Error(`${label}: expected events ${JSON.stringify(e)}, got ${JSON.stringify(a)}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Forces the event loop / I/O queue to advance without a fixed wall-clock sleep and without
|
|
93
|
+
* depending on the latched call's own settlement: ≥5 awaited round-trips of `store.read` against
|
|
94
|
+
* a DISJOINT sentinel key (never written by any other case), plus one trailing `setImmediate`
|
|
95
|
+
* (D3 §7's normative drain). Used before checking a latch-based law's "Phase 1" (occupancy)
|
|
96
|
+
* assertion.
|
|
97
|
+
*/
|
|
98
|
+
async function drain(store) {
|
|
99
|
+
const sentinelRunId = `fenced-tck-sentinel-run-${Math.random().toString(36).slice(2)}`;
|
|
100
|
+
for (let i = 0; i < 5; i++) {
|
|
101
|
+
await store.read(sentinelRunId, 'fenced-tck-sentinel-step');
|
|
102
|
+
}
|
|
103
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
104
|
+
}
|
|
105
|
+
/** A guard that signals when it has been entered (parked) and blocks on an externally-released
|
|
106
|
+
* latch — the core primitive both CS_OCCUPANCY and PER_KEY_INDEPENDENCE latch a CS open with. */
|
|
107
|
+
function makeLatch() {
|
|
108
|
+
let releaseFn;
|
|
109
|
+
const latchPromise = new Promise((resolve) => {
|
|
110
|
+
releaseFn = resolve;
|
|
111
|
+
});
|
|
112
|
+
let enteredResolve;
|
|
113
|
+
const entered = new Promise((resolve) => {
|
|
114
|
+
enteredResolve = resolve;
|
|
115
|
+
});
|
|
116
|
+
const guard = async () => {
|
|
117
|
+
enteredResolve();
|
|
118
|
+
await latchPromise;
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
guard,
|
|
122
|
+
entered,
|
|
123
|
+
release: () => releaseFn(),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/** Settlement outcome recorder — lets a law check "has this promise ALREADY settled" without
|
|
127
|
+
* awaiting it (which would just wait for eventual settlement, defeating the point of checking a
|
|
128
|
+
* point-in-time occupancy snapshot after `drain`). The recorder promise itself is pre-attached
|
|
129
|
+
* with a no-op catch so an eventual rejection observed only for BOOKKEEPING never produces an
|
|
130
|
+
* unhandled-rejection warning. */
|
|
131
|
+
function recordSettlement(p) {
|
|
132
|
+
let state = 'pending';
|
|
133
|
+
let capturedError;
|
|
134
|
+
p.then(() => {
|
|
135
|
+
state = 'fulfilled';
|
|
136
|
+
}, (err) => {
|
|
137
|
+
state = 'rejected';
|
|
138
|
+
capturedError = err;
|
|
139
|
+
});
|
|
140
|
+
return { outcome: () => state, error: () => capturedError };
|
|
141
|
+
}
|
|
142
|
+
/** Starts `holder` latched open on (runId, stepId), returning the parked promise + latch handle.
|
|
143
|
+
* Every fenced method requires an existing store to hold — for delete/deleteAllForRunFenced, the
|
|
144
|
+
* key is pre-seeded with a throwaway entry (the specific content doesn't matter; only that the
|
|
145
|
+
* operation has something to act on). */
|
|
146
|
+
async function startLatchedHolder(store, holder, runId, stepId, entriesForAppend) {
|
|
147
|
+
const latch = makeLatch();
|
|
148
|
+
let parkedP;
|
|
149
|
+
if (holder === 'appendFenced') {
|
|
150
|
+
parkedP = store.appendFenced(runId, stepId, entriesForAppend, latch.guard);
|
|
151
|
+
}
|
|
152
|
+
else if (holder === 'deleteFenced') {
|
|
153
|
+
parkedP = store.deleteFenced(runId, stepId, latch.guard);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
parkedP = store.deleteAllForRunFenced(runId, latch.guard);
|
|
157
|
+
}
|
|
158
|
+
await latch.entered;
|
|
159
|
+
return { parkedP, latch };
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Builds the CS_OCCUPANCY case for one `holder` kind (issue #207, D3 §7).
|
|
163
|
+
*
|
|
164
|
+
* Honest guarantee this law provides (issue #207 correction): it is deterministic-no-false-red —
|
|
165
|
+
* a conforming store can never fail it by bad luck, only a genuinely non-serializing store fails
|
|
166
|
+
* it. It is NOT deterministic-no-false-green against every possible violator: a store whose
|
|
167
|
+
* read/delete merely SKIP the lock (rather than sharing no critical section at all) can, on a
|
|
168
|
+
* sufficiently loaded machine, false-green here — the lock-skipping concurrent call may simply
|
|
169
|
+
* not have reached its own I/O completion yet when the Phase-1 assertion runs, even though it
|
|
170
|
+
* never actually respected the CS. An in-memory (synchronous-scheduling) violator has no such
|
|
171
|
+
* escape and reddens deterministically. Empirically (mutation probe (b), issue #207 correction),
|
|
172
|
+
* the fs store's own lock-skipping mutation reddened deterministically 5/5 runs on a fast,
|
|
173
|
+
* unloaded machine — this does not contradict the caveat above; it shows the false-green risk is
|
|
174
|
+
* a loaded/slow-environment concern, not a claim that the fs law usually (or ever, on a given
|
|
175
|
+
* machine) false-greens.
|
|
176
|
+
*
|
|
177
|
+
* The single-waiter subcase (`buildCsOccupancySingleWaiterCase`, below) is this law's
|
|
178
|
+
* probabilistic net against a "CS-split" store — one that releases its lock/CS handle before the
|
|
179
|
+
* write it guards has actually completed (write-after-release). Such a store could conceivably
|
|
180
|
+
* survive the multi-op Phase 1 above by chance (three concurrent operations racing the same
|
|
181
|
+
* narrow post-release window), but a single, isolated concurrent read is a comparatively larger
|
|
182
|
+
* fraction of that same window to land inside — raising, not guaranteeing, the odds of catching a
|
|
183
|
+
* CS-split violator. Like the caveat above, this is a probabilistic, not deterministic, net.
|
|
184
|
+
*/
|
|
185
|
+
function buildCsOccupancyCase(adapter, holder) {
|
|
186
|
+
return {
|
|
187
|
+
law: 'CS_OCCUPANCY',
|
|
188
|
+
name: `${holder} holding the CS: concurrent read/delete/deleteAllForRun neither succeed during occupancy nor corrupt state after release`,
|
|
189
|
+
run: async () => {
|
|
190
|
+
const { store } = adapter;
|
|
191
|
+
const { runId, stepId } = adapter.makeKey();
|
|
192
|
+
const B1 = [{ event: 'b1-e0' }, { event: 'b1-e1' }];
|
|
193
|
+
await store.append(runId, stepId, B1);
|
|
194
|
+
const B2 = [{ event: 'b2-e0' }];
|
|
195
|
+
const { parkedP, latch } = await startLatchedHolder(store, holder, runId, stepId, B2);
|
|
196
|
+
const readP = store.read(runId, stepId);
|
|
197
|
+
const deleteP = store.delete(runId, stepId);
|
|
198
|
+
const deleteAllP = store.deleteAllForRun(runId);
|
|
199
|
+
// Attach catches BEFORE draining — deadlock/unhandled-rejection-free by construction.
|
|
200
|
+
const readRec = recordSettlement(readP.catch((e) => Promise.reject(e)));
|
|
201
|
+
const deleteRec = recordSettlement(deleteP.catch((e) => Promise.reject(e)));
|
|
202
|
+
const deleteAllRec = recordSettlement(deleteAllP.catch((e) => Promise.reject(e)));
|
|
203
|
+
await drain(store);
|
|
204
|
+
// Phase 1 (occupancy): NONE of the three may have completed SUCCESSFULLY yet — still
|
|
205
|
+
// pending, or ANY rejection (not just a typed lock-contention error), both conform.
|
|
206
|
+
// Immediate success is the deterministic red. Tolerating any rejection type here (wider
|
|
207
|
+
// than requiring a specific typed lock-contention error) is deliberate (issue #207
|
|
208
|
+
// correction): widening what counts as "conforming" can only ever make this check
|
|
209
|
+
// false-green (a store rejecting for some unrelated reason still passes Phase 1), never
|
|
210
|
+
// false-red — consistent with Phase 1's own guarantee already being one-sided toward
|
|
211
|
+
// false-green, never false-red (see this function's own doc, above).
|
|
212
|
+
for (const [label, rec] of [
|
|
213
|
+
['read', readRec],
|
|
214
|
+
['delete', deleteRec],
|
|
215
|
+
['deleteAllForRun', deleteAllRec],
|
|
216
|
+
]) {
|
|
217
|
+
if (rec.outcome() === 'fulfilled') {
|
|
218
|
+
throw new Error(`CS_OCCUPANCY violated (holder=${holder}): ${label}() completed successfully while ` +
|
|
219
|
+
'the CS was still latched open — it must remain pending or reject with a typed ' +
|
|
220
|
+
'lock-contention error until the latch releases.');
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Phase 2 (visibility): release the latch FIRST, then let everything settle.
|
|
224
|
+
latch.release();
|
|
225
|
+
await parkedP;
|
|
226
|
+
await Promise.allSettled([readP, deleteP, deleteAllP]);
|
|
227
|
+
const finalRead = await store.read(runId, stepId);
|
|
228
|
+
const fullBatch = holder === 'appendFenced' ? [...B1, ...B2] : B1;
|
|
229
|
+
const isFullBatch = eventsOf(finalRead).length === eventsOf(fullBatch).length &&
|
|
230
|
+
eventsOf(finalRead).every((v, i) => v === eventsOf(fullBatch)[i]);
|
|
231
|
+
const isEmpty = finalRead.length === 0;
|
|
232
|
+
if (!isFullBatch && !isEmpty) {
|
|
233
|
+
throw new Error(`CS_OCCUPANCY violated (holder=${holder}): expected exactly the full committed batch ` +
|
|
234
|
+
`or exactly [] after release, got ${JSON.stringify(eventsOf(finalRead))} — a partial/` +
|
|
235
|
+
'garbled result means the CS did not actually serialize these operations.');
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/** The single-waiter subcase (issue #207, D3 §7): park a holder, start exactly ONE concurrent
|
|
241
|
+
* `read()`, release — the read must show deterministic FULL-batch visibility (no "or []" arm,
|
|
242
|
+
* since a read never destroys data — this is the case's whole point: with no concurrent
|
|
243
|
+
* destroyer in the mix, visibility after release is unambiguous). */
|
|
244
|
+
function buildCsOccupancySingleWaiterCase(adapter) {
|
|
245
|
+
return {
|
|
246
|
+
law: 'CS_OCCUPANCY',
|
|
247
|
+
name: 'single-waiter subcase: one concurrent read (no concurrent destroyer) sees deterministic full-batch visibility post-release',
|
|
248
|
+
run: async () => {
|
|
249
|
+
const { store } = adapter;
|
|
250
|
+
const { runId, stepId } = adapter.makeKey();
|
|
251
|
+
const B1 = [{ event: 'b1-e0' }];
|
|
252
|
+
await store.append(runId, stepId, B1);
|
|
253
|
+
const B2 = [{ event: 'b2-e0' }];
|
|
254
|
+
const { parkedP, latch } = await startLatchedHolder(store, 'appendFenced', runId, stepId, B2);
|
|
255
|
+
const readP = store.read(runId, stepId);
|
|
256
|
+
await drain(store);
|
|
257
|
+
latch.release();
|
|
258
|
+
await parkedP;
|
|
259
|
+
const result = await readP;
|
|
260
|
+
assertDeepEqualEvents(result, [...B1, ...B2], 'single-waiter subcase');
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function buildPerKeyIndependenceCase(adapter) {
|
|
265
|
+
return {
|
|
266
|
+
law: 'PER_KEY_INDEPENDENCE',
|
|
267
|
+
name: 'a disjoint-run key completes a full append+read round-trip while another key is latched open (global-lock stores hang into the framework timeout — the intended red)',
|
|
268
|
+
run: async () => {
|
|
269
|
+
const { store } = adapter;
|
|
270
|
+
const { runId, stepId } = adapter.makeKey();
|
|
271
|
+
const other = adapter.makeKey();
|
|
272
|
+
const { parkedP, latch } = await startLatchedHolder(store, 'appendFenced', runId, stepId, [
|
|
273
|
+
{ event: 'latched' },
|
|
274
|
+
]);
|
|
275
|
+
await store.append(other.runId, other.stepId, [{ event: 'independent' }]);
|
|
276
|
+
const result = await store.read(other.runId, other.stepId);
|
|
277
|
+
assertDeepEqualEvents(result, [{ event: 'independent' }], 'PER_KEY_INDEPENDENCE');
|
|
278
|
+
latch.release();
|
|
279
|
+
await parkedP;
|
|
280
|
+
},
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Builds the NO_SILENT_LOSS case (issue #207, D3 §7): a settle (read-then-delete) racing a
|
|
285
|
+
* still-parked `appendFenced` must adopt the full committed batch — never lose it silently.
|
|
286
|
+
*
|
|
287
|
+
* Scope note (issue #207 correction): this case only exercises the "settle wins the race, the
|
|
288
|
+
* guard is never asked to refuse" path. The complementary branch — the guard REFUSING because a
|
|
289
|
+
* settle already started (the `settledFlag` check inside this case's own guard) — is deliberately
|
|
290
|
+
* NOT separately re-asserted as its own top-level assertion here: it is absorbed by
|
|
291
|
+
* FENCE_REFUSES's own `appendFenced` refusal case above, which already asserts identical content
|
|
292
|
+
* (typed rejection, nothing written). Duplicating that assertion under this law's banner too would
|
|
293
|
+
* add no additional coverage.
|
|
294
|
+
*
|
|
295
|
+
* The one-sided fs caveat from `buildCsOccupancyCase`'s doc (above) applies here too: against a
|
|
296
|
+
* lock-skipping (rather than genuinely non-serializing) violator, false-green risk here is a
|
|
297
|
+
* loaded/slow-environment concern only, not a claim this case usually passes such a store.
|
|
298
|
+
*/
|
|
299
|
+
function buildNoSilentLossCase(adapter) {
|
|
300
|
+
return {
|
|
301
|
+
law: 'NO_SILENT_LOSS',
|
|
302
|
+
name: 'a settle (read-then-delete) starting while append is parked adopts the full committed batch — never silent loss',
|
|
303
|
+
run: async () => {
|
|
304
|
+
const { store } = adapter;
|
|
305
|
+
const { runId, stepId } = adapter.makeKey();
|
|
306
|
+
const B = [{ event: 'b0' }, { event: 'b1' }];
|
|
307
|
+
let settledFlag = false;
|
|
308
|
+
let releaseLatchFn;
|
|
309
|
+
const latch = new Promise((resolve) => {
|
|
310
|
+
releaseLatchFn = resolve;
|
|
311
|
+
});
|
|
312
|
+
let enteredResolveFn;
|
|
313
|
+
const entered = new Promise((resolve) => {
|
|
314
|
+
enteredResolveFn = resolve;
|
|
315
|
+
});
|
|
316
|
+
const guard = async () => {
|
|
317
|
+
enteredResolveFn();
|
|
318
|
+
if (settledFlag) {
|
|
319
|
+
throw new WorkflowError('fenced-tck: refused (settled already)', {
|
|
320
|
+
code: REFUSAL_CODE,
|
|
321
|
+
category: 'STATE',
|
|
322
|
+
agentAction: 'report_to_user',
|
|
323
|
+
retryable: true,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
await latch;
|
|
327
|
+
};
|
|
328
|
+
const appendP = store.appendFenced(runId, stepId, B, guard);
|
|
329
|
+
// Detect (and safely ignore afterwards) a premature settlement — the conforming store must
|
|
330
|
+
// not settle appendP before its guard has been entered.
|
|
331
|
+
const prematureSettle = appendP.then(() => {
|
|
332
|
+
throw new Error('appendFenced settled (fulfilled) before entering its guard — NO_SILENT_LOSS setup invariant violated');
|
|
333
|
+
}, () => {
|
|
334
|
+
throw new Error('appendFenced settled (rejected) before entering its guard — NO_SILENT_LOSS setup invariant violated');
|
|
335
|
+
});
|
|
336
|
+
prematureSettle.catch(() => { }); // only used for the race below; its later settlement is expected
|
|
337
|
+
await Promise.race([entered, prematureSettle]);
|
|
338
|
+
settledFlag = true;
|
|
339
|
+
// Start (never await) the settle sequence.
|
|
340
|
+
const settleP = store
|
|
341
|
+
.read(runId, stepId)
|
|
342
|
+
.then((adopted) => store.delete(runId, stepId).then(() => adopted));
|
|
343
|
+
await drain(store);
|
|
344
|
+
releaseLatchFn();
|
|
345
|
+
const committed = await appendP;
|
|
346
|
+
if (committed.buffer_count !== B.length) {
|
|
347
|
+
throw new Error(`NO_SILENT_LOSS: expected appendFenced to commit all ${B.length} entries, got ` +
|
|
348
|
+
`buffer_count=${committed.buffer_count}`);
|
|
349
|
+
}
|
|
350
|
+
const adopted = await settleP;
|
|
351
|
+
assertDeepEqualEvents(adopted, B, 'NO_SILENT_LOSS (an unlocked or CS-split settle yields [] with the append still committed)');
|
|
352
|
+
const finalRead = await store.read(runId, stepId);
|
|
353
|
+
if (finalRead.length !== 0) {
|
|
354
|
+
throw new Error(`NO_SILENT_LOSS: expected the buffer empty after the settle's delete, got ${finalRead.length} entries`);
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
/** A visible, non-silent documented-skip case for a law that a store's declared capabilities
|
|
360
|
+
* don't reach — mirrors the `fenceForm: 'native-predicate'` skip precedent for the latch-based
|
|
361
|
+
* trio laws. `reason` names exactly why (e.g. "store does not declare 'seal'"). */
|
|
362
|
+
function skipCase(law, name, reason) {
|
|
363
|
+
return {
|
|
364
|
+
law,
|
|
365
|
+
name: `SKIPPED — ${reason}: ${name}`,
|
|
366
|
+
run: async () => {
|
|
367
|
+
// Intentional no-op — see the case name for why.
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
// ── CARRIAGE_ROUND_TRIP (issue #197 PR-1, the writer_nonce_carriage rung) ────────────────────────
|
|
372
|
+
function buildCarriageRoundTripCases(adapter) {
|
|
373
|
+
const { store } = adapter;
|
|
374
|
+
if (!storeDeclaresNonceCarriage(store)) {
|
|
375
|
+
return [
|
|
376
|
+
skipCase('CARRIAGE_ROUND_TRIP', "nonce round-trip via options.writerNonce and read()'s _nonce", "store does not declare 'writer_nonce_carriage'"),
|
|
377
|
+
];
|
|
378
|
+
}
|
|
379
|
+
return [
|
|
380
|
+
{
|
|
381
|
+
law: 'CARRIAGE_ROUND_TRIP',
|
|
382
|
+
name: 'a nonced append round-trips _nonce on read(); a bare append NEVER has _nonce fabricated',
|
|
383
|
+
run: async () => {
|
|
384
|
+
const { runId, stepId } = adapter.makeKey();
|
|
385
|
+
const NONCE = 'carriage-tck-nonce-1';
|
|
386
|
+
await store.append(runId, stepId, [{ event: 'nonced' }], { writerNonce: NONCE });
|
|
387
|
+
await store.append(runId, stepId, [{ event: 'bare' }]);
|
|
388
|
+
const entries = await store.read(runId, stepId);
|
|
389
|
+
const nonced = entries.find((e) => e.event === 'nonced');
|
|
390
|
+
const bare = entries.find((e) => e.event === 'bare');
|
|
391
|
+
if (nonced?._nonce !== NONCE) {
|
|
392
|
+
throw new Error(`expected the nonced entry's _nonce to round-trip as '${NONCE}', got: ${nonced?._nonce}`);
|
|
393
|
+
}
|
|
394
|
+
if (bare !== undefined && Object.prototype.hasOwnProperty.call(bare, '_nonce')) {
|
|
395
|
+
throw new Error(`expected the bare entry to have NO _nonce property at all (never fabricated), got: ${JSON.stringify(bare)}`);
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
];
|
|
400
|
+
}
|
|
401
|
+
// ── SEAL + SEAL_BUDGET (issue #197 PR-1, the seal rung) ──────────────────────────────────────────
|
|
402
|
+
function buildSealCases(adapter) {
|
|
403
|
+
const { store } = adapter;
|
|
404
|
+
if (!storeDeclaresSeal(store)) {
|
|
405
|
+
return [
|
|
406
|
+
skipCase('SEAL', 'sealFenced retires a live WAL to a sealed artifact', "store does not declare 'seal'"),
|
|
407
|
+
skipCase('SEAL_BUDGET', 'repeated seals up to SEALED_ARTIFACTS_LIMIT_PER_STEP, then capped', "store does not declare 'seal'"),
|
|
408
|
+
];
|
|
409
|
+
}
|
|
410
|
+
const cases = [];
|
|
411
|
+
cases.push({
|
|
412
|
+
law: 'SEAL',
|
|
413
|
+
name: 'sealFenced on an absent key returns {sealed:false, reason:"absent"}; the guard still runs',
|
|
414
|
+
run: async () => {
|
|
415
|
+
const { runId, stepId } = adapter.makeKey();
|
|
416
|
+
let guardCalls = 0;
|
|
417
|
+
const result = await store.sealFenced(runId, stepId, async () => {
|
|
418
|
+
guardCalls++;
|
|
419
|
+
});
|
|
420
|
+
if (!(result.sealed === false && result.reason === 'absent')) {
|
|
421
|
+
throw new Error(`expected {sealed:false, reason:'absent'}, got: ${JSON.stringify(result)}`);
|
|
422
|
+
}
|
|
423
|
+
if (guardCalls < 1) {
|
|
424
|
+
throw new Error('expected the guard to run at least once even for an absent key');
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
cases.push({
|
|
429
|
+
law: 'SEAL',
|
|
430
|
+
name: 'sealFenced retires the live WAL: read() goes empty, listSealedForRun reports the same lines',
|
|
431
|
+
run: async () => {
|
|
432
|
+
const { runId, stepId } = adapter.makeKey();
|
|
433
|
+
await store.append(runId, stepId, [{ event: 'a1' }]);
|
|
434
|
+
await store.append(runId, stepId, [{ event: 'a2' }]);
|
|
435
|
+
const result = await store.sealFenced(runId, stepId, passingGuard());
|
|
436
|
+
if (result.sealed !== true) {
|
|
437
|
+
throw new Error(`expected {sealed:true}, got: ${JSON.stringify(result)}`);
|
|
438
|
+
}
|
|
439
|
+
const afterLive = await store.read(runId, stepId);
|
|
440
|
+
if (afterLive.length !== 0) {
|
|
441
|
+
throw new Error(`expected the live WAL empty after sealing, got ${afterLive.length} entries`);
|
|
442
|
+
}
|
|
443
|
+
const sealedArtifacts = await store.listSealedForRun(runId);
|
|
444
|
+
const thisKeyArtifacts = sealedArtifacts.filter((a) => a.step_id === stepId);
|
|
445
|
+
if (thisKeyArtifacts.length !== 1) {
|
|
446
|
+
throw new Error(`expected exactly 1 sealed artifact for this key, got ${thisKeyArtifacts.length}`);
|
|
447
|
+
}
|
|
448
|
+
const sealedEvents = thisKeyArtifacts[0].lines.flatMap((l) => l.entries.map((e) => e.event));
|
|
449
|
+
if (JSON.stringify(sealedEvents) !== JSON.stringify(['a1', 'a2'])) {
|
|
450
|
+
throw new Error(`expected sealed lines to preserve ['a1','a2'] in order, got ${JSON.stringify(sealedEvents)}`);
|
|
451
|
+
}
|
|
452
|
+
},
|
|
453
|
+
});
|
|
454
|
+
cases.push({
|
|
455
|
+
law: 'SEAL',
|
|
456
|
+
name: 'a refusing guard rejects sealFenced — nothing is moved (live content survives, no new sealed artifact)',
|
|
457
|
+
run: async () => {
|
|
458
|
+
const { runId, stepId } = adapter.makeKey();
|
|
459
|
+
await store.append(runId, stepId, [{ event: 'a' }]);
|
|
460
|
+
const before = await store.listSealedForRun(runId);
|
|
461
|
+
let caught;
|
|
462
|
+
try {
|
|
463
|
+
await store.sealFenced(runId, stepId, refusingGuard());
|
|
464
|
+
}
|
|
465
|
+
catch (err) {
|
|
466
|
+
caught = err;
|
|
467
|
+
}
|
|
468
|
+
if (!(caught instanceof WorkflowError) || caught.code !== REFUSAL_CODE) {
|
|
469
|
+
throw new Error(`expected a typed WorkflowError(${REFUSAL_CODE}), got: ${caught}`);
|
|
470
|
+
}
|
|
471
|
+
const afterLive = await store.read(runId, stepId);
|
|
472
|
+
if (afterLive.length !== 1) {
|
|
473
|
+
throw new Error(`expected the live WAL untouched after a refused seal, got ${afterLive.length} entries`);
|
|
474
|
+
}
|
|
475
|
+
const after = await store.listSealedForRun(runId);
|
|
476
|
+
if (after.length !== before.length) {
|
|
477
|
+
throw new Error('expected no new sealed artifact after a refused seal');
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
});
|
|
481
|
+
cases.push({
|
|
482
|
+
law: 'SEAL',
|
|
483
|
+
name: 'deleteAllForRun retires sealed artifacts for the run too, not just the live WAL',
|
|
484
|
+
run: async () => {
|
|
485
|
+
const { runId, stepId } = adapter.makeKey();
|
|
486
|
+
await store.append(runId, stepId, [{ event: 'a' }]);
|
|
487
|
+
await store.sealFenced(runId, stepId, passingGuard());
|
|
488
|
+
const beforeCount = (await store.listSealedForRun(runId)).length;
|
|
489
|
+
if (beforeCount < 1) {
|
|
490
|
+
throw new Error('setup invariant violated: expected at least one sealed artifact before deleteAllForRun');
|
|
491
|
+
}
|
|
492
|
+
await store.deleteAllForRun(runId);
|
|
493
|
+
const after = await store.listSealedForRun(runId);
|
|
494
|
+
if (after.length !== 0) {
|
|
495
|
+
throw new Error(`expected deleteAllForRun to also remove sealed artifacts, got ${after.length} remaining`);
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
});
|
|
499
|
+
cases.push({
|
|
500
|
+
law: 'SEAL_BUDGET',
|
|
501
|
+
name: 'repeated seals of the same key succeed up to SEALED_ARTIFACTS_LIMIT_PER_STEP, then return {sealed:false, reason:"capped"} without evicting or losing data',
|
|
502
|
+
run: async () => {
|
|
503
|
+
const { runId, stepId } = adapter.makeKey();
|
|
504
|
+
for (let i = 0; i < SEALED_ARTIFACTS_LIMIT_PER_STEP; i++) {
|
|
505
|
+
await store.append(runId, stepId, [{ event: `e${i}` }]);
|
|
506
|
+
const result = await store.sealFenced(runId, stepId, passingGuard());
|
|
507
|
+
if (result.sealed !== true) {
|
|
508
|
+
throw new Error(`expected seal #${i} to succeed, got: ${JSON.stringify(result)}`);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
const atCap = (await store.listSealedForRun(runId)).filter((a) => a.step_id === stepId);
|
|
512
|
+
if (atCap.length !== SEALED_ARTIFACTS_LIMIT_PER_STEP) {
|
|
513
|
+
throw new Error(`expected exactly SEALED_ARTIFACTS_LIMIT_PER_STEP (${SEALED_ARTIFACTS_LIMIT_PER_STEP}) sealed artifacts, got ${atCap.length}`);
|
|
514
|
+
}
|
|
515
|
+
await store.append(runId, stepId, [{ event: 'one-too-many' }]);
|
|
516
|
+
const capped = await store.sealFenced(runId, stepId, passingGuard());
|
|
517
|
+
if (!(capped.sealed === false && capped.reason === 'capped')) {
|
|
518
|
+
throw new Error(`expected {sealed:false, reason:'capped'}, got: ${JSON.stringify(capped)}`);
|
|
519
|
+
}
|
|
520
|
+
// No silent eviction: still exactly the same N sealed artifacts, and the live content that
|
|
521
|
+
// failed to seal is still readable (the caller's fallback path — destructive drain — remains
|
|
522
|
+
// available; this law only asserts nothing was silently lost yet).
|
|
523
|
+
const stillAtCap = (await store.listSealedForRun(runId)).filter((a) => a.step_id === stepId);
|
|
524
|
+
if (stillAtCap.length !== SEALED_ARTIFACTS_LIMIT_PER_STEP) {
|
|
525
|
+
throw new Error(`expected the cap to hold at exactly ${SEALED_ARTIFACTS_LIMIT_PER_STEP} (no eviction), got ${stillAtCap.length}`);
|
|
526
|
+
}
|
|
527
|
+
const liveAfterCapped = await store.read(runId, stepId);
|
|
528
|
+
if (liveAfterCapped.length !== 1 || liveAfterCapped[0]?.event !== 'one-too-many') {
|
|
529
|
+
throw new Error('expected the un-sealable live content to remain readable (fallback-eligible), got: ' +
|
|
530
|
+
JSON.stringify(liveAfterCapped));
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
});
|
|
534
|
+
return cases;
|
|
535
|
+
}
|
|
536
|
+
// ── PER_WRITER_BUDGET (issue #197 PR-1, design §5) ────────────────────────────────────────────────
|
|
537
|
+
function buildPerWriterBudgetCases(adapter) {
|
|
538
|
+
const { store } = adapter;
|
|
539
|
+
const batch = (n, label) => Array.from({ length: n }, (_, i) => ({ event: `${label}-${i}` }));
|
|
540
|
+
const cases = [];
|
|
541
|
+
cases.push({
|
|
542
|
+
law: 'PER_WRITER_BUDGET',
|
|
543
|
+
name: "theft-fixed: one writer's near-full own partition does not steal another writer's independent budget on the SAME key",
|
|
544
|
+
run: async () => {
|
|
545
|
+
const { runId, stepId } = adapter.makeKey();
|
|
546
|
+
const NEAR_LIMIT = BUFFER_LIMIT_COUNT - 1;
|
|
547
|
+
await store.append(runId, stepId, batch(NEAR_LIMIT, 'w1'), { writerNonce: 'w1' });
|
|
548
|
+
const r2 = await store.append(runId, stepId, batch(NEAR_LIMIT, 'w2'), { writerNonce: 'w2' });
|
|
549
|
+
// A "theft" bug (partitioning by whole-file instead of by writer) would see w1's NEAR_LIMIT
|
|
550
|
+
// already committed and refuse w2's own NEAR_LIMIT-sized append (combined > BUFFER_LIMIT_COUNT
|
|
551
|
+
// if mistakenly compared against the PER-WRITER ceiling) — a conforming store must not.
|
|
552
|
+
if (r2.buffer_count !== NEAR_LIMIT) {
|
|
553
|
+
throw new Error(`expected writer 'w2' to independently commit its own ${NEAR_LIMIT} entries regardless ` +
|
|
554
|
+
`of writer 'w1's own near-full partition on the same key, got buffer_count=${r2.buffer_count}`);
|
|
555
|
+
}
|
|
556
|
+
},
|
|
557
|
+
});
|
|
558
|
+
cases.push({
|
|
559
|
+
law: 'PER_WRITER_BUDGET',
|
|
560
|
+
name: 'the whole-file backstop binds across combined writers even when no single writer exceeds its own per-writer ceiling',
|
|
561
|
+
run: async () => {
|
|
562
|
+
const { runId, stepId } = adapter.makeKey();
|
|
563
|
+
const THIRD = Math.floor(BUFFER_BACKSTOP_COUNT / 3) + 10; // 3× exceeds the backstop; each alone is well under BUFFER_LIMIT_COUNT
|
|
564
|
+
await store.append(runId, stepId, batch(THIRD, 'a'), { writerNonce: 'a' });
|
|
565
|
+
await store.append(runId, stepId, batch(THIRD, 'b'), { writerNonce: 'b' });
|
|
566
|
+
let caught;
|
|
567
|
+
try {
|
|
568
|
+
await store.append(runId, stepId, batch(THIRD, 'c'), { writerNonce: 'c' });
|
|
569
|
+
}
|
|
570
|
+
catch (err) {
|
|
571
|
+
caught = err;
|
|
572
|
+
}
|
|
573
|
+
if (!(caught instanceof WorkflowError) || caught.code !== 'BUFFER_FULL') {
|
|
574
|
+
throw new Error(`expected a BUFFER_FULL WorkflowError once the combined file exceeds the backstop, got: ${caught}`);
|
|
575
|
+
}
|
|
576
|
+
const details = caught.details;
|
|
577
|
+
if (details.scope !== 'file') {
|
|
578
|
+
throw new Error(`expected details.scope === 'file' for a whole-file-backstop refusal, got: ${JSON.stringify(details)}`);
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
});
|
|
582
|
+
if (adapter.bytesOracle !== undefined) {
|
|
583
|
+
cases.push({
|
|
584
|
+
law: 'PER_WRITER_BUDGET',
|
|
585
|
+
name: "byte-exactness (adapter-supplied oracle): AppendResult's writer/file byte numbers match the oracle's own independent computation",
|
|
586
|
+
run: async () => {
|
|
587
|
+
const { runId, stepId } = adapter.makeKey();
|
|
588
|
+
const NONCE = 'byte-oracle-writer';
|
|
589
|
+
const result = await store.append(runId, stepId, [{ event: 'e1' }, { event: 'e2' }], {
|
|
590
|
+
writerNonce: NONCE,
|
|
591
|
+
});
|
|
592
|
+
const oracle = await adapter.bytesOracle(runId, stepId, NONCE);
|
|
593
|
+
if (result.buffer_bytes !== oracle.bytes || result.buffer_count !== oracle.count) {
|
|
594
|
+
throw new Error(`expected AppendResult writer-scope {count:${oracle.count}, bytes:${oracle.bytes}} per the ` +
|
|
595
|
+
`oracle, got {count:${result.buffer_count}, bytes:${result.buffer_bytes}}`);
|
|
596
|
+
}
|
|
597
|
+
},
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
cases.push(skipCase('PER_WRITER_BUDGET', 'byte-exactness against an adapter-supplied oracle', 'adapter did not supply bytesOracle (count-based assertions above still ran)'));
|
|
602
|
+
}
|
|
603
|
+
return cases;
|
|
604
|
+
}
|
|
605
|
+
// ── VERBATIM (issue #197 PR-1, the seal rung's byte-fidelity guarantee) ──────────────────────────
|
|
606
|
+
function buildVerbatimCases(adapter) {
|
|
607
|
+
const { store } = adapter;
|
|
608
|
+
if (!storeDeclaresSeal(store)) {
|
|
609
|
+
return [
|
|
610
|
+
skipCase('VERBATIM', 'a seal moves bytes/shape without loss', "store does not declare 'seal'"),
|
|
611
|
+
];
|
|
612
|
+
}
|
|
613
|
+
const cases = [];
|
|
614
|
+
// Shape-tolerant sibling — runs UNCONDITIONALLY for every seal-declaring store (in-memory has no
|
|
615
|
+
// on-disk representation at all, so only logical content/order can be asserted for it).
|
|
616
|
+
cases.push({
|
|
617
|
+
law: 'VERBATIM',
|
|
618
|
+
name: 'shape-tolerant: sealed content preserves every entry, in order, with no duplication or loss',
|
|
619
|
+
run: async () => {
|
|
620
|
+
const { runId, stepId } = adapter.makeKey();
|
|
621
|
+
const B = [{ event: 'v0' }, { event: 'v1' }, { event: 'v2' }];
|
|
622
|
+
await store.append(runId, stepId, B);
|
|
623
|
+
await store.sealFenced(runId, stepId, passingGuard());
|
|
624
|
+
const sealedArtifacts = (await store.listSealedForRun(runId)).filter((a) => a.step_id === stepId);
|
|
625
|
+
const events = sealedArtifacts.flatMap((a) => a.lines.flatMap((l) => l.entries.map((e) => e.event)));
|
|
626
|
+
if (JSON.stringify(events) !== JSON.stringify(['v0', 'v1', 'v2'])) {
|
|
627
|
+
throw new Error(`expected sealed content ['v0','v1','v2'] in order, got ${JSON.stringify(events)}`);
|
|
628
|
+
}
|
|
629
|
+
},
|
|
630
|
+
});
|
|
631
|
+
if (adapter.rawWalAccess !== undefined) {
|
|
632
|
+
cases.push({
|
|
633
|
+
law: 'VERBATIM',
|
|
634
|
+
name: 'fs-scoped: a seal moves the live WAL bytes to the sealed artifact byte-for-byte (no parse/re-copy)',
|
|
635
|
+
run: async () => {
|
|
636
|
+
const { runId, stepId } = adapter.makeKey();
|
|
637
|
+
await store.append(runId, stepId, [{ event: 'raw1' }, { event: 'raw2' }]);
|
|
638
|
+
const rawBefore = await adapter.rawWalAccess.readLiveRaw(runId, stepId);
|
|
639
|
+
if (rawBefore === undefined) {
|
|
640
|
+
throw new Error('expected the live WAL to exist (raw bytes) before sealing');
|
|
641
|
+
}
|
|
642
|
+
const result = await store.sealFenced(runId, stepId, passingGuard());
|
|
643
|
+
if (result.sealed !== true) {
|
|
644
|
+
throw new Error(`expected {sealed:true}, got: ${JSON.stringify(result)}`);
|
|
645
|
+
}
|
|
646
|
+
const rawAfter = await adapter.rawWalAccess.readSealedRaw(runId, stepId, 0);
|
|
647
|
+
if (rawAfter === undefined) {
|
|
648
|
+
throw new Error('expected the sealed artifact to exist (raw bytes) at seq 0 after sealing');
|
|
649
|
+
}
|
|
650
|
+
if (rawAfter !== rawBefore) {
|
|
651
|
+
throw new Error('expected the sealed artifact bytes to be byte-for-byte identical to the pre-seal live ' +
|
|
652
|
+
`WAL bytes, got a difference (before=${JSON.stringify(rawBefore)}, after=${JSON.stringify(rawAfter)})`);
|
|
653
|
+
}
|
|
654
|
+
},
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
else {
|
|
658
|
+
cases.push(skipCase('VERBATIM', 'byte-for-byte raw comparison against an adapter-supplied rawWalAccess hook', 'adapter did not supply rawWalAccess (the shape-tolerant sibling case above still ran)'));
|
|
659
|
+
}
|
|
660
|
+
return cases;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Builds the contract cases for `adapter`. See each law's own doc above (the `build*Case`
|
|
664
|
+
* functions) for what it asserts. For `fenceForm: 'native-predicate'` adapters, `CS_OCCUPANCY`,
|
|
665
|
+
* `PER_KEY_INDEPENDENCE`, and `NO_SILENT_LOSS` are replaced with an explicit, VISIBLE
|
|
666
|
+
* documented-skip case each (never a silent omission) — see the adapter's own `fenceForm` doc.
|
|
667
|
+
*/
|
|
668
|
+
export function fencedTraceBufferContract(adapter) {
|
|
669
|
+
const cases = [];
|
|
670
|
+
const { store } = adapter;
|
|
671
|
+
// ── STRUCTURAL ──────────────────────────────────────────────────────────────────────────────
|
|
672
|
+
cases.push({
|
|
673
|
+
law: 'STRUCTURAL',
|
|
674
|
+
name: 'declaring any fenced method requires declaring all three',
|
|
675
|
+
run: async () => {
|
|
676
|
+
const s = store;
|
|
677
|
+
const has = {
|
|
678
|
+
appendFenced: typeof s.appendFenced === 'function',
|
|
679
|
+
deleteFenced: typeof s.deleteFenced === 'function',
|
|
680
|
+
deleteAllForRunFenced: typeof s.deleteAllForRunFenced === 'function',
|
|
681
|
+
};
|
|
682
|
+
const anyDeclared = has.appendFenced || has.deleteFenced || has.deleteAllForRunFenced;
|
|
683
|
+
const allDeclared = has.appendFenced && has.deleteFenced && has.deleteAllForRunFenced;
|
|
684
|
+
if (anyDeclared && !allDeclared) {
|
|
685
|
+
throw new Error(`store declares a SUBSET of the fenced trio (must be all-or-nothing): ${JSON.stringify(has)}`);
|
|
686
|
+
}
|
|
687
|
+
},
|
|
688
|
+
});
|
|
689
|
+
// issue #197 PR-1: the capability-ladder STRUCTURAL cases below. The first three exercise
|
|
690
|
+
// `validateTraceCapabilities` against hand-built STUB stores (never the real adapter store) —
|
|
691
|
+
// this is deliberately a MECHANISM test: PR-1 ships `validateTraceCapabilities` itself, but
|
|
692
|
+
// invoking it at real injection seams is PR-2's job, so there is no real call site yet whose
|
|
693
|
+
// behavior this could observe indirectly.
|
|
694
|
+
cases.push({
|
|
695
|
+
law: 'STRUCTURAL',
|
|
696
|
+
name: 'validateTraceCapabilities: declaring writer_nonce_carriage without seal methods throws TRACE_CAPABILITY_INCONSISTENT',
|
|
697
|
+
run: async () => {
|
|
698
|
+
const stub = minimalStubStore(new Set(['writer_nonce_carriage']));
|
|
699
|
+
const err = catchSync(() => validateTraceCapabilities(stub));
|
|
700
|
+
assertCapabilityInconsistent(err, 'writer_nonce_carriage');
|
|
701
|
+
},
|
|
702
|
+
});
|
|
703
|
+
cases.push({
|
|
704
|
+
law: 'STRUCTURAL',
|
|
705
|
+
name: 'validateTraceCapabilities: declaring seal without the fenced trio + sealFenced/listSealedForRun throws TRACE_CAPABILITY_INCONSISTENT',
|
|
706
|
+
run: async () => {
|
|
707
|
+
const stub = minimalStubStore(new Set(['seal'])); // no fenced trio, no sealFenced
|
|
708
|
+
const err = catchSync(() => validateTraceCapabilities(stub));
|
|
709
|
+
assertCapabilityInconsistent(err, 'seal');
|
|
710
|
+
},
|
|
711
|
+
});
|
|
712
|
+
cases.push({
|
|
713
|
+
law: 'STRUCTURAL',
|
|
714
|
+
name: 'validateTraceCapabilities: an undeclared store (no traceCapabilities at all) is a silent no-op — trio-alone stays legal',
|
|
715
|
+
run: async () => {
|
|
716
|
+
const stub = minimalStubStore(undefined);
|
|
717
|
+
const err = catchSync(() => validateTraceCapabilities(stub));
|
|
718
|
+
if (err !== undefined) {
|
|
719
|
+
throw new Error(`expected no throw for an undeclared store, got: ${err}`);
|
|
720
|
+
}
|
|
721
|
+
},
|
|
722
|
+
});
|
|
723
|
+
cases.push({
|
|
724
|
+
law: 'STRUCTURAL',
|
|
725
|
+
name: "traceCapabilities is immutable: two reads of the REAL adapter store's declaration are content-identical",
|
|
726
|
+
run: async () => {
|
|
727
|
+
const first = store.traceCapabilities;
|
|
728
|
+
const second = store.traceCapabilities;
|
|
729
|
+
const firstArr = [...(first ?? [])].sort();
|
|
730
|
+
const secondArr = [...(second ?? [])].sort();
|
|
731
|
+
if (JSON.stringify(firstArr) !== JSON.stringify(secondArr)) {
|
|
732
|
+
throw new Error(`expected two reads of traceCapabilities to be content-identical, got ${JSON.stringify(firstArr)} then ${JSON.stringify(secondArr)}`);
|
|
733
|
+
}
|
|
734
|
+
},
|
|
735
|
+
});
|
|
736
|
+
cases.push({
|
|
737
|
+
law: 'STRUCTURAL',
|
|
738
|
+
name: "the REAL adapter store's own declaration is internally consistent (ladder holds for what it actually declares)",
|
|
739
|
+
run: async () => {
|
|
740
|
+
const caps = store.traceCapabilities;
|
|
741
|
+
if (caps?.has('seal') === true && !storeDeclaresSeal(store)) {
|
|
742
|
+
throw new Error("adapter store declares 'seal' but storeDeclaresSeal(store) is false — declared but inconsistent");
|
|
743
|
+
}
|
|
744
|
+
if (caps?.has('writer_nonce_carriage') === true && !storeDeclaresNonceCarriage(store)) {
|
|
745
|
+
throw new Error("adapter store declares 'writer_nonce_carriage' but storeDeclaresNonceCarriage(store) is false — declared but inconsistent");
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
});
|
|
749
|
+
// ── FENCE_REFUSES ───────────────────────────────────────────────────────────────────────────
|
|
750
|
+
// Accepted limits of this law (issue #207 correction): FENCE_REFUSES asserts that a guard
|
|
751
|
+
// rejection propagates typed/unwrapped with nothing written/deleted — it does NOT, and cannot,
|
|
752
|
+
// distinguish that outcome from a store that (a) performs the write/delete, THEN discovers the
|
|
753
|
+
// guard should have refused, and rolls the effect back via a compensating action
|
|
754
|
+
// (write-then-rollback); or (b) a genuine crash between the effect and its own bookkeeping
|
|
755
|
+
// happens to leave residue that looks, from this law's own read-after observation, like
|
|
756
|
+
// "nothing written". Both are indistinguishable from a true refusal by this law's assertions —
|
|
757
|
+
// a store relying on either is simply out of this TCK's detection range, not certified free of
|
|
758
|
+
// that residue by a green run here.
|
|
759
|
+
cases.push({
|
|
760
|
+
law: 'FENCE_REFUSES',
|
|
761
|
+
name: 'appendFenced: guard rejection propagates typed with a populated reason category, nothing written',
|
|
762
|
+
run: async () => {
|
|
763
|
+
const { runId, stepId } = adapter.makeKey();
|
|
764
|
+
let caught;
|
|
765
|
+
try {
|
|
766
|
+
await store.appendFenced(runId, stepId, [{ event: 'e' }], refusingGuard());
|
|
767
|
+
}
|
|
768
|
+
catch (err) {
|
|
769
|
+
caught = err;
|
|
770
|
+
}
|
|
771
|
+
if (!(caught instanceof WorkflowError) || caught.code !== REFUSAL_CODE || !caught.category) {
|
|
772
|
+
throw new Error(`expected a typed WorkflowError(${REFUSAL_CODE}) with a populated category, got: ${caught}`);
|
|
773
|
+
}
|
|
774
|
+
const after = await store.read(runId, stepId);
|
|
775
|
+
if (after.length !== 0) {
|
|
776
|
+
throw new Error(`expected nothing written after a refused appendFenced, got ${after.length} entries`);
|
|
777
|
+
}
|
|
778
|
+
},
|
|
779
|
+
});
|
|
780
|
+
cases.push({
|
|
781
|
+
law: 'FENCE_REFUSES',
|
|
782
|
+
name: 'deleteFenced: guard rejection propagates typed with a populated reason category, nothing deleted',
|
|
783
|
+
run: async () => {
|
|
784
|
+
const { runId, stepId } = adapter.makeKey();
|
|
785
|
+
await store.append(runId, stepId, [{ event: 'seed' }]);
|
|
786
|
+
let caught;
|
|
787
|
+
try {
|
|
788
|
+
await store.deleteFenced(runId, stepId, refusingGuard());
|
|
789
|
+
}
|
|
790
|
+
catch (err) {
|
|
791
|
+
caught = err;
|
|
792
|
+
}
|
|
793
|
+
if (!(caught instanceof WorkflowError) || caught.code !== REFUSAL_CODE || !caught.category) {
|
|
794
|
+
throw new Error(`expected a typed WorkflowError(${REFUSAL_CODE}) with a populated category, got: ${caught}`);
|
|
795
|
+
}
|
|
796
|
+
const after = await store.read(runId, stepId);
|
|
797
|
+
if (after.length !== 1) {
|
|
798
|
+
throw new Error(`expected the seeded entry to survive a refused deleteFenced, got ${after.length}`);
|
|
799
|
+
}
|
|
800
|
+
},
|
|
801
|
+
});
|
|
802
|
+
cases.push({
|
|
803
|
+
law: 'FENCE_REFUSES',
|
|
804
|
+
name: 'sequential two-call guard-caching kill: pass-guard append then refuse-guard append — second refuses, first entries intact',
|
|
805
|
+
run: async () => {
|
|
806
|
+
const { runId, stepId } = adapter.makeKey();
|
|
807
|
+
const r1 = await store.appendFenced(runId, stepId, [{ event: 'first' }], passingGuard());
|
|
808
|
+
if (r1.buffer_count !== 1) {
|
|
809
|
+
throw new Error(`expected the first append to commit 1 entry, got buffer_count=${r1.buffer_count}`);
|
|
810
|
+
}
|
|
811
|
+
let threw = false;
|
|
812
|
+
try {
|
|
813
|
+
await store.appendFenced(runId, stepId, [{ event: 'second' }], refusingGuard());
|
|
814
|
+
}
|
|
815
|
+
catch {
|
|
816
|
+
threw = true;
|
|
817
|
+
}
|
|
818
|
+
if (!threw) {
|
|
819
|
+
throw new Error('expected the second (refuse-guard) append to reject — guard-caching would make this incorrectly pass');
|
|
820
|
+
}
|
|
821
|
+
const after = await store.read(runId, stepId);
|
|
822
|
+
assertDeepEqualEvents(after, [{ event: 'first' }], 'sequential two-call guard-caching kill');
|
|
823
|
+
},
|
|
824
|
+
});
|
|
825
|
+
cases.push({
|
|
826
|
+
law: 'FENCE_REFUSES',
|
|
827
|
+
name: 'deleteAllForRunFenced: refusal with >=2 seeded files — ALL files intact, error propagates exactly as the guard threw it',
|
|
828
|
+
run: async () => {
|
|
829
|
+
const { runId } = adapter.makeKey();
|
|
830
|
+
const stepA = 'fenced-tck-step-a';
|
|
831
|
+
const stepB = 'fenced-tck-step-b';
|
|
832
|
+
await store.append(runId, stepA, [{ event: 'a' }]);
|
|
833
|
+
await store.append(runId, stepB, [{ event: 'b' }]);
|
|
834
|
+
let caught;
|
|
835
|
+
try {
|
|
836
|
+
await store.deleteAllForRunFenced(runId, refusingGuard());
|
|
837
|
+
}
|
|
838
|
+
catch (err) {
|
|
839
|
+
caught = err;
|
|
840
|
+
}
|
|
841
|
+
// issue #207 correction: assert the propagated error IS the guard's own typed error —
|
|
842
|
+
// never something a wrapping layer (e.g. toArtifactDeleteFailedError) substituted in its
|
|
843
|
+
// place (that would surface as ENGINE_ARTIFACT_DELETE_FAILED instead of REFUSAL_CODE).
|
|
844
|
+
if (!(caught instanceof WorkflowError) || caught.code !== REFUSAL_CODE) {
|
|
845
|
+
throw new Error(`expected deleteAllForRunFenced to reject with the guard's own typed error ` +
|
|
846
|
+
`(WorkflowError, code=${REFUSAL_CODE}) — never wrapped — got: ${caught}`);
|
|
847
|
+
}
|
|
848
|
+
const a = await store.read(runId, stepA);
|
|
849
|
+
const b = await store.read(runId, stepB);
|
|
850
|
+
if (a.length !== 1 || b.length !== 1) {
|
|
851
|
+
throw new Error(`expected both seeded files intact after a refused sweep, got a=${a.length} b=${b.length}`);
|
|
852
|
+
}
|
|
853
|
+
},
|
|
854
|
+
});
|
|
855
|
+
cases.push({
|
|
856
|
+
law: 'FENCE_REFUSES',
|
|
857
|
+
name: 'deleteAllForRunFenced: zero-match sweep still invokes the guard at least once, and its rejection propagates unwrapped',
|
|
858
|
+
run: async () => {
|
|
859
|
+
const { runId } = adapter.makeKey(); // never written — zero files match
|
|
860
|
+
let guardCalls = 0;
|
|
861
|
+
const countingRefusingGuard = async () => {
|
|
862
|
+
guardCalls++;
|
|
863
|
+
throw new WorkflowError('fenced-tck: guard refused (simulated)', {
|
|
864
|
+
code: REFUSAL_CODE,
|
|
865
|
+
category: 'STATE',
|
|
866
|
+
agentAction: 'report_to_user',
|
|
867
|
+
retryable: true,
|
|
868
|
+
});
|
|
869
|
+
};
|
|
870
|
+
let caught;
|
|
871
|
+
try {
|
|
872
|
+
await store.deleteAllForRunFenced(runId, countingRefusingGuard);
|
|
873
|
+
}
|
|
874
|
+
catch (err) {
|
|
875
|
+
caught = err;
|
|
876
|
+
}
|
|
877
|
+
// issue #207 correction: same exact-identity assertion as the >=2-file case above — a
|
|
878
|
+
// zero-match sweep is not a laxer case, it must reject with the guard's own typed error too.
|
|
879
|
+
if (!(caught instanceof WorkflowError) || caught.code !== REFUSAL_CODE) {
|
|
880
|
+
throw new Error(`expected a zero-match sweep with a refusing guard to reject with the guard's own typed ` +
|
|
881
|
+
`error (WorkflowError, code=${REFUSAL_CODE}) — never wrapped — got: ${caught}`);
|
|
882
|
+
}
|
|
883
|
+
if (guardCalls < 1) {
|
|
884
|
+
throw new Error('expected the guard to be invoked at least once even for a zero-match sweep');
|
|
885
|
+
}
|
|
886
|
+
},
|
|
887
|
+
});
|
|
888
|
+
cases.push({
|
|
889
|
+
law: 'FENCE_REFUSES',
|
|
890
|
+
name: "deleteAllForRunFenced: a guard throwing FsIoError propagates it exactly — never mistaken for deleteIfExists's own failure and wrapped",
|
|
891
|
+
run: async () => {
|
|
892
|
+
// issue #207 correction, dedicated case (D3 §1's own demanded test): a realistic scenario
|
|
893
|
+
// is the guard's lock-free `runStore.get` itself hitting a filesystem error (e.g. EACCES on
|
|
894
|
+
// the run-record file) — since that surfaces as an FsIoError too, a sweep implementation
|
|
895
|
+
// that wraps "any FsIoError seen inside the per-file try" (rather than scoping the wrap to
|
|
896
|
+
// ONLY deleteIfExists's own failure) would incorrectly re-wrap the guard's own error as
|
|
897
|
+
// ENGINE_ARTIFACT_DELETE_FAILED, discarding its original identity.
|
|
898
|
+
const { runId } = adapter.makeKey();
|
|
899
|
+
const stepA = 'fenced-tck-step-fsio';
|
|
900
|
+
await store.append(runId, stepA, [{ event: 'seed' }]);
|
|
901
|
+
const cause = Object.assign(new Error('EACCES (simulated)'), { code: 'EACCES' });
|
|
902
|
+
const fsIoGuard = async () => {
|
|
903
|
+
throw new FsIoError('read', '/fenced-tck/simulated-guard-path', cause);
|
|
904
|
+
};
|
|
905
|
+
let caught;
|
|
906
|
+
try {
|
|
907
|
+
await store.deleteAllForRunFenced(runId, fsIoGuard);
|
|
908
|
+
}
|
|
909
|
+
catch (err) {
|
|
910
|
+
caught = err;
|
|
911
|
+
}
|
|
912
|
+
if (!(caught instanceof FsIoError)) {
|
|
913
|
+
throw new Error(`expected the guard's own FsIoError to propagate exactly (not wrapped as ` +
|
|
914
|
+
`ENGINE_ARTIFACT_DELETE_FAILED via toArtifactDeleteFailedError), got: ${caught}`);
|
|
915
|
+
}
|
|
916
|
+
const after = await store.read(runId, stepA);
|
|
917
|
+
if (after.length !== 1) {
|
|
918
|
+
throw new Error(`expected the seeded file intact after a sweep refused by an FsIoError guard, got ${after.length}`);
|
|
919
|
+
}
|
|
920
|
+
},
|
|
921
|
+
});
|
|
922
|
+
cases.push({
|
|
923
|
+
law: 'FENCE_REFUSES',
|
|
924
|
+
name: 'COUNT_FIDELITY: deleteFenced with a pass-guard returns exactly the seeded entry count',
|
|
925
|
+
run: async () => {
|
|
926
|
+
const { runId, stepId } = adapter.makeKey();
|
|
927
|
+
const N = 5;
|
|
928
|
+
for (let i = 0; i < N; i++) {
|
|
929
|
+
await store.append(runId, stepId, [{ event: `e${i}` }]);
|
|
930
|
+
}
|
|
931
|
+
const count = await store.deleteFenced(runId, stepId, passingGuard());
|
|
932
|
+
if (count !== N) {
|
|
933
|
+
throw new Error(`expected deleteFenced to return exactly ${N}, got ${count}`);
|
|
934
|
+
}
|
|
935
|
+
},
|
|
936
|
+
});
|
|
937
|
+
// ── Latch-based laws: CS_OCCUPANCY, PER_KEY_INDEPENDENCE, NO_SILENT_LOSS ───────────────────
|
|
938
|
+
if (adapter.fenceForm === 'native-predicate') {
|
|
939
|
+
for (const law of ['CS_OCCUPANCY', 'PER_KEY_INDEPENDENCE', 'NO_SILENT_LOSS']) {
|
|
940
|
+
cases.push({
|
|
941
|
+
law,
|
|
942
|
+
name: `SKIPPED for native-predicate stores — TCK-green does NOT verify race closure; ` +
|
|
943
|
+
"the store's own in-transaction fencing suite must (issue #207; the same posture " +
|
|
944
|
+
"CLAIM_SINGLE_OWNER's own cross-host caveat states, issue #188). This case is an " +
|
|
945
|
+
'explicit, visible documented-skip, not a silent omission.',
|
|
946
|
+
run: async () => {
|
|
947
|
+
// Intentional no-op — see the case name for why.
|
|
948
|
+
},
|
|
949
|
+
});
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
else {
|
|
953
|
+
cases.push(buildCsOccupancyCase(adapter, 'appendFenced'));
|
|
954
|
+
cases.push(buildCsOccupancyCase(adapter, 'deleteFenced'));
|
|
955
|
+
cases.push(buildCsOccupancyCase(adapter, 'deleteAllForRunFenced'));
|
|
956
|
+
cases.push(buildCsOccupancySingleWaiterCase(adapter));
|
|
957
|
+
cases.push(buildPerKeyIndependenceCase(adapter));
|
|
958
|
+
cases.push(buildNoSilentLossCase(adapter));
|
|
959
|
+
}
|
|
960
|
+
// ── Capability-ladder laws (issue #197 PR-1): CARRIAGE_ROUND_TRIP, SEAL, SEAL_BUDGET,
|
|
961
|
+
// PER_WRITER_BUDGET, VERBATIM. Each produces a visible documented-skip (never a silent
|
|
962
|
+
// omission) for a store that doesn't declare the relevant rung — see each build*Cases
|
|
963
|
+
// function's own doc.
|
|
964
|
+
cases.push(...buildCarriageRoundTripCases(adapter));
|
|
965
|
+
cases.push(...buildSealCases(adapter));
|
|
966
|
+
cases.push(...buildPerWriterBudgetCases(adapter));
|
|
967
|
+
cases.push(...buildVerbatimCases(adapter));
|
|
968
|
+
return cases;
|
|
969
|
+
}
|
|
970
|
+
//# sourceMappingURL=fenced-trace-buffer-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fenced-trace-buffer-contract.js","sourceRoot":"","sources":["../../src/store/fenced-trace-buffer-contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in-memory-store.d.ts","sourceRoot":"","sources":["../../src/store/in-memory-store.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"in-memory-store.d.ts","sourceRoot":"","sources":["../../src/store/in-memory-store.ts"],"names":[],"mappings":"AACA,OAAO,EAOL,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC/B,MAAM,gBAAgB,CAAC;AAExB,4FAA4F;AAC5F,qBAAa,aAAc,YAAW,QAAQ;IAC5C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgC;IACrD,sGAAsG;IACtG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IAEtD,iGAAiG;IACjG,QAAQ,CAAC,cAAc,QAAQ;IAE/B;wGACoG;IACpG,QAAQ,CAAC,wBAAwB,EAAE,WAAW,CAAC,yBAAyB,CAAC,CAItE;IAEG,MAAM,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,SAAS,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IA4ChF,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAatC,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IA6B7C,SAAS,CACb,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,kBAAkB,GAC7B,OAAO,CAAC,SAAS,CAAC;IAsDf,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;CAOtD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// InMemoryStore — in-memory implementation of RunStore for use in tests.
|
|
2
|
-
import { WorkflowError, findEligibleSteps, deriveRunPhase, decideIdempotencyPolicy, computeClaimDeadline, } from '@sensigo/realm';
|
|
2
|
+
import { WorkflowError, findEligibleSteps, deriveRunPhase, decideIdempotencyPolicy, computeClaimDeadline, isStepSettledOrInFlight, } from '@sensigo/realm';
|
|
3
3
|
/** In-memory implementation of RunStore. Uses a Map keyed by run ID. No I/O, no locking. */
|
|
4
4
|
export class InMemoryStore {
|
|
5
5
|
runs = new Map();
|
|
@@ -106,6 +106,9 @@ export class InMemoryStore {
|
|
|
106
106
|
// tick, during which a second `Promise.all`'d claimStep call's own (equally synchronous) read
|
|
107
107
|
// can run BEFORE either call has written — verified empirically: two concurrent claimStep
|
|
108
108
|
// calls for the same (runId, step) both resolved successfully before this fix.
|
|
109
|
+
// issue #207: `isStepSettledOrInFlight` (below) is pure/synchronous by design — it performs no
|
|
110
|
+
// I/O and awaits nothing, so calling it here does not reintroduce the microtask-yield point
|
|
111
|
+
// this fix removes; the no-await constraint above still holds.
|
|
109
112
|
const run = this.runs.get(runId);
|
|
110
113
|
if (run === undefined) {
|
|
111
114
|
throw new WorkflowError(`Run '${runId}' not found`, {
|
|
@@ -115,13 +118,7 @@ export class InMemoryStore {
|
|
|
115
118
|
retryable: false,
|
|
116
119
|
});
|
|
117
120
|
}
|
|
118
|
-
|
|
119
|
-
...run.completed_steps,
|
|
120
|
-
...run.in_progress_steps,
|
|
121
|
-
...run.failed_steps,
|
|
122
|
-
...run.skipped_steps,
|
|
123
|
-
];
|
|
124
|
-
if (alreadyDone.includes(stepName)) {
|
|
121
|
+
if (isStepSettledOrInFlight(run, stepName)) {
|
|
125
122
|
throw new WorkflowError(`Step '${stepName}' is already claimed or done`, {
|
|
126
123
|
code: 'STATE_STEP_ALREADY_CLAIMED',
|
|
127
124
|
category: 'STATE',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in-memory-store.js","sourceRoot":"","sources":["../../src/store/in-memory-store.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,uBAAuB,EACvB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"in-memory-store.js","sourceRoot":"","sources":["../../src/store/in-memory-store.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sensigo/realm-testing",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"lint": "eslint src"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@sensigo/realm": "^0.
|
|
41
|
+
"@sensigo/realm": "^0.27.0",
|
|
42
42
|
"js-yaml": "^4.2.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|