@junghanacs/entwurf 0.13.1 → 0.14.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/AGENTS.md +48 -15
- package/BASELINE.md +3 -3
- package/CHANGELOG.md +45 -0
- package/CONTRIBUTING.md +13 -9
- package/DELIVERY.md +7 -6
- package/README.md +27 -27
- package/VERIFY.md +22 -14
- package/demo/README.md +1 -1
- package/demo/demo-baseline.sh +1 -3
- package/demo/demo.sh +2 -5
- package/docs/acp-backend-rail.md +9 -4
- package/docs/external-mcp-host.md +4 -5
- package/docs/setup-clean-host.md +8 -7
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +148 -28
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +8 -6
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-control-rpc.js +7 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-core.js +13 -14
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-resume-args.js +45 -40
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +117 -95
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-decider.js +23 -57
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-lock.js +16 -7
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-production.js +5 -53
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-release.js +21 -36
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-runner.js +3 -15
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-send-fallback.js +12 -11
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-send.js +2 -7
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +30 -67
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-visible-resume.js +256 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +91 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +258 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-launch.js +202 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-placement.js +289 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-resume-call.js +170 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/resume-launch-identity.js +136 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/session-id.js +8 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/socket-discovery.js +3 -3
- package/mcp/entwurf-bridge/dist/scripts/meta-facts.js +51 -0
- package/mcp/entwurf-bridge/dist/scripts/new-session-id.js +9 -4
- package/mcp/entwurf-bridge/src/index.ts +164 -28
- package/mcp/entwurf-bridge/start.sh +2 -2
- package/mcp/entwurf-bridge/test.sh +23 -9
- package/mcp/entwurf-bridge/tsconfig.build.json +11 -2
- package/package.json +22 -11
- package/pi-extensions/entwurf-control.ts +218 -40
- package/pi-extensions/lib/acp/backend.ts +71 -12
- package/pi-extensions/lib/acp/overlay.ts +8 -6
- package/pi-extensions/lib/entwurf-control-rpc.ts +7 -5
- package/pi-extensions/lib/entwurf-core.ts +15 -15
- package/pi-extensions/lib/entwurf-resume-args.ts +41 -52
- package/pi-extensions/lib/entwurf-v2-contract-schema.ts +1 -1
- package/pi-extensions/lib/entwurf-v2-contract.ts +120 -99
- package/pi-extensions/lib/entwurf-v2-decider.ts +30 -91
- package/pi-extensions/lib/entwurf-v2-lock.ts +16 -7
- package/pi-extensions/lib/entwurf-v2-production.ts +4 -78
- package/pi-extensions/lib/entwurf-v2-release.ts +25 -49
- package/pi-extensions/lib/entwurf-v2-runner.ts +6 -21
- package/pi-extensions/lib/entwurf-v2-send-fallback.ts +12 -11
- package/pi-extensions/lib/entwurf-v2-send.ts +2 -7
- package/pi-extensions/lib/entwurf-v2-surface.ts +36 -76
- package/pi-extensions/lib/entwurf-v2-visible-resume.ts +370 -0
- package/pi-extensions/lib/meta-session.ts +93 -5
- package/pi-extensions/lib/mux-fresh-call.ts +328 -0
- package/pi-extensions/lib/mux-launch.ts +267 -0
- package/pi-extensions/lib/mux-placement.ts +387 -0
- package/pi-extensions/lib/mux-resume-call.ts +221 -0
- package/pi-extensions/lib/resume-launch-identity.ts +162 -0
- package/pi-extensions/lib/session-id.js +8 -5
- package/pi-extensions/lib/socket-discovery.ts +3 -3
- package/run.sh +471 -201
- package/scripts/agy-bridge-config.py +5 -1
- package/scripts/check-acp-backend-preflight.ts +1 -1
- package/scripts/check-acp-overlay.ts +13 -3
- package/scripts/check-acp-stream-hooks.ts +504 -0
- package/scripts/check-elapsed.sh +25 -0
- package/scripts/check-entwurf-bridge-boot.ts +51 -4
- package/scripts/check-entwurf-bridge-pi-free.ts +6 -5
- package/scripts/check-entwurf-control-rpc.ts +4 -3
- package/scripts/check-entwurf-resume-args.ts +72 -70
- package/scripts/check-entwurf-session-identity.ts +14 -10
- package/scripts/check-entwurf-v2-contract.ts +34 -59
- package/scripts/check-entwurf-v2-decider.ts +17 -177
- package/scripts/check-entwurf-v2-lock.ts +5 -2
- package/scripts/check-entwurf-v2-matrix.ts +3 -53
- package/scripts/check-entwurf-v2-production.ts +2 -91
- package/scripts/check-entwurf-v2-release.ts +10 -105
- package/scripts/check-entwurf-v2-runner.ts +4 -85
- package/scripts/check-entwurf-v2-send-fallback.ts +5 -6
- package/scripts/check-entwurf-v2-send.ts +0 -28
- package/scripts/check-entwurf-v2-surface.ts +157 -128
- package/scripts/check-entwurf-v2-visible-resume.ts +445 -0
- package/scripts/check-fresh-cut-gate.sh +1 -1
- package/scripts/check-gate-qualification.ts +98 -7
- package/scripts/check-install-container.sh +10 -2
- package/scripts/check-install-surface.ts +1 -1
- package/scripts/check-keyset-overlap.py +1 -1
- package/scripts/check-meta-facts.ts +249 -0
- package/scripts/check-meta-identity-consumers.ts +1 -1
- package/scripts/check-meta-session.ts +169 -0
- package/scripts/check-mux-launch-tmux.ts +316 -0
- package/scripts/check-mux-launch.ts +288 -0
- package/scripts/check-mux-launcher-fence.ts +264 -0
- package/scripts/check-mux-parent-artifact.ts +195 -0
- package/scripts/check-mux-placement-tmux.ts +322 -0
- package/scripts/check-mux-placement.ts +323 -0
- package/scripts/check-mux-resume-call.ts +282 -0
- package/scripts/check-probe-cli-shim.ts +25 -22
- package/scripts/check-probe-ordering.ts +84 -76
- package/scripts/check-release-gate-outcomes.ts +127 -7
- package/scripts/check-resume-launch-identity.ts +244 -0
- package/scripts/check-socket-discovery.ts +1 -1
- package/scripts/fixtures/mux-parent-transcript.scrubbed.jsonl +3 -0
- package/scripts/inventory-verification-surface.ts +349 -0
- package/scripts/lib/claude-launcher-fence.ts +322 -0
- package/scripts/lib/mutation-qualify.ts +109 -3
- package/scripts/meta-bridge-doctor.sh +6 -8
- package/scripts/meta-facts.ts +60 -0
- package/scripts/mutants/acp-overlay.json +17 -0
- package/scripts/mutants/acp-stream-hooks.json +158 -0
- package/scripts/mutants/bridge-boot-resume.json +45 -0
- package/scripts/mutants/meta-facts.json +50 -0
- package/scripts/mutants/meta-identity.json +36 -0
- package/scripts/mutants/mux-boundary.json +196 -0
- package/scripts/mutants/mux-fresh-call.json +185 -0
- package/scripts/mutants/mux-launcher-fence.json +123 -0
- package/scripts/mutants/mux-parent-artifact.json +39 -0
- package/scripts/mutants/mux-resume-call.json +148 -0
- package/scripts/mutants/probe-ordering.json +0 -1037
- package/scripts/mutants/release-gate.json +35 -0
- package/scripts/mutants/resume-args.json +76 -0
- package/scripts/mutants/resume-launch-identity.json +96 -0
- package/scripts/mutants/v2-surface.json +58 -18
- package/scripts/mutants/v2-visible-resume.json +215 -0
- package/scripts/new-session-id.ts +9 -4
- package/scripts/smoke-acp-raw-turn-live.ts +1 -1
- package/scripts/smoke-agy-native-push-live.ts +6 -17
- package/scripts/smoke-entwurf-v2-matrix-live.ts +1 -1
- package/scripts/smoke-meta-honesty.sh +1 -1
- package/scripts/smoke-mux-fresh-call-live.ts +365 -0
- package/scripts/smoke-mux-lifecycle-live.ts +1136 -0
- package/scripts/smoke-pi-attach.ts +1 -1
- package/scripts/smoke-user-scope-citizen.sh +1 -1
- package/scripts/tsconfig.json +1 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-preflight.js +0 -160
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-spawn-production.js +0 -273
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-spawn.js +0 -216
- package/pi-extensions/lib/entwurf-v2-spawn-production.ts +0 -373
- package/pi-extensions/lib/entwurf-v2-spawn.ts +0 -323
- package/scripts/check-acp-sdk-surface.ts +0 -275
- package/scripts/check-entwurf-v2-spawn-production.ts +0 -551
- package/scripts/check-entwurf-v2-spawn.ts +0 -399
- package/scripts/smoke-entwurf-v2-spawn-live.ts +0 -188
- package/scripts/smoke-entwurf-v2-spawn-resume-live.ts +0 -467
|
@@ -53,13 +53,15 @@
|
|
|
53
53
|
// channel — 8d pins that wiring.
|
|
54
54
|
//
|
|
55
55
|
// Kill-proof, stated at its honest strength: scripts/mutants/probe-ordering.json
|
|
56
|
-
// qualifies
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
//
|
|
56
|
+
// now qualifies exactly ONE claim for THIS gate — the product-subject
|
|
57
|
+
// NO-PRODUCTION-PROMPT-CUTOFF replant, whose [QK:] signature appears EXACTLY
|
|
58
|
+
// once below and whose mutant check-gate-qualification proves dies there.
|
|
59
|
+
// Every [CHECK:<claim>] label below is a DIRECT assertion: enforced on every
|
|
60
|
+
// run, deliberately no longer replant-qualified (issue #70 verification
|
|
61
|
+
// subtraction — the dropped qualification replants are ledgered there; the
|
|
62
|
+
// instrument's assertions and behavior are unchanged). The remaining [QK:]
|
|
63
|
+
// token and its qualified claim stay 1:1, so "killed claim IDs, never
|
|
64
|
+
// assertion counts" stays readable.
|
|
63
65
|
// Properties that are review-pinned only (no deterministic mutant exists):
|
|
64
66
|
// - the write-CALLBACK timing of tools_list_response_forwarded (cross-process
|
|
65
67
|
// microsecond ordering; existence/attribution IS proven);
|
|
@@ -67,7 +69,7 @@
|
|
|
67
69
|
// in this handshake; the callback rejects and never stamps — source-visible);
|
|
68
70
|
// - the writer's SINGLE clock read (a two-read millisecond straddle is a rare
|
|
69
71
|
// race, so it is pinned in source and made loud by the parser's ts↔tsMs
|
|
70
|
-
// equality rule, which
|
|
72
|
+
// equality rule, which is directly asserted below).
|
|
71
73
|
|
|
72
74
|
import { strict as assert } from "node:assert";
|
|
73
75
|
import { type ChildProcessByStdio, spawn } from "node:child_process";
|
|
@@ -238,7 +240,7 @@ function makeRecordingConnection(calls: RecordedCall[]): AcpConnectionLike {
|
|
|
238
240
|
clientCapabilities: {},
|
|
239
241
|
clientInfo: { name: "entwurf", version: "s2d" },
|
|
240
242
|
},
|
|
241
|
-
"initialize params match backend.ts byte-shape [
|
|
243
|
+
"initialize params match backend.ts byte-shape [CHECK:PROBE-SEQ-ORDER]",
|
|
242
244
|
);
|
|
243
245
|
const newSessionParams = calls[1].params as { cwd: string; mcpServers: unknown; _meta?: unknown };
|
|
244
246
|
assert.equal(newSessionParams.cwd, "/scratch/gate", "newSession carries the run cwd");
|
|
@@ -327,7 +329,7 @@ function makeRecordingConnection(calls: RecordedCall[]): AcpConnectionLike {
|
|
|
327
329
|
setModelMs: timeoutOf("SET_MODEL_TIMEOUT_MS"),
|
|
328
330
|
},
|
|
329
331
|
"probe BOOTSTRAP timeouts EQUAL backend.ts's — a bootstrap-phase D is only readable against production " +
|
|
330
|
-
"boundaries [
|
|
332
|
+
"boundaries [CHECK:PROBE-BOOTSTRAP-TIMEOUTS-MATCH-PRODUCTION]",
|
|
331
333
|
);
|
|
332
334
|
|
|
333
335
|
// --- the prompt phase has NO production boundary to match --------------
|
|
@@ -349,7 +351,7 @@ function makeRecordingConnection(calls: RecordedCall[]): AcpConnectionLike {
|
|
|
349
351
|
);
|
|
350
352
|
assert.ok(
|
|
351
353
|
PROBE_PROMPT_OBSERVATION_MS > 0 && !("promptMs" in PROBE_PHASE_TIMEOUTS),
|
|
352
|
-
"[
|
|
354
|
+
"[CHECK:PROMPT-HORIZON-NOT-PRODUCTION] the prompt horizon lives OUTSIDE the production-pinned bootstrap set — it is " +
|
|
353
355
|
"the harness's own observation bound, and folding it back in would report a harness number as the turn contract",
|
|
354
356
|
);
|
|
355
357
|
|
|
@@ -421,7 +423,7 @@ function makeRecordingConnection(calls: RecordedCall[]): AcpConnectionLike {
|
|
|
421
423
|
const scanSites = RUNNER_SRC.split("scanStructuredNoSuchTool").length - 1;
|
|
422
424
|
assert.ok(
|
|
423
425
|
scanSites === 2 && !/collectedText \+= t;[^}]*scanStructured/s.test(RUNNER_SRC),
|
|
424
|
-
"No-such-tool is scanned ONLY off structured tool frames, never agent prose [
|
|
426
|
+
"No-such-tool is scanned ONLY off structured tool frames, never agent prose [CHECK:PROBE-NO-PROSE-ERROR-SCAN]",
|
|
425
427
|
);
|
|
426
428
|
|
|
427
429
|
// A broken event log is run-invalidating on BOTH doors: a malformed line could
|
|
@@ -439,7 +441,7 @@ function makeRecordingConnection(calls: RecordedCall[]): AcpConnectionLike {
|
|
|
439
441
|
// "deadline-sufficient". It is a constant, and no env may reach it.
|
|
440
442
|
assert.ok(
|
|
441
443
|
RUNNER_SRC.includes("const POST_DELAY_SLACK_MS = 5_000;") && !RUNNER_SRC.includes("PROBE_POST_DELAY_SLACK_MS"),
|
|
442
|
-
"the observation window's post-delay slack is a CONSTANT with no env override [
|
|
444
|
+
"the observation window's post-delay slack is a CONSTANT with no env override [CHECK:PROBE-WINDOW-SLACK-IS-CONSTANT]",
|
|
443
445
|
);
|
|
444
446
|
|
|
445
447
|
// The exit contract asks three separate questions. Failing the run on the
|
|
@@ -450,14 +452,14 @@ function makeRecordingConnection(calls: RecordedCall[]): AcpConnectionLike {
|
|
|
450
452
|
RUNNER_SRC.includes("do not read it as a complete series") &&
|
|
451
453
|
RUNNER_SRC.includes('classification.status.orderingMeasurement !== "measured"') &&
|
|
452
454
|
RUNNER_SRC.includes("NOT a claim about server wait behavior"),
|
|
453
|
-
"the runner's exit contract separates fatal validity from the two axes, and claims no server-wait conclusion [
|
|
455
|
+
"the runner's exit contract separates fatal validity from the two axes, and claims no server-wait conclusion [CHECK:RUNNER-EXIT-CONTRACT-SPLIT]",
|
|
454
456
|
);
|
|
455
457
|
|
|
456
458
|
assert.ok(
|
|
457
459
|
RUNNER_SRC.includes("if (malformed.length > 0 || sequenceViolations.length > 0) {") &&
|
|
458
460
|
RUNNER_SRC.includes("run INVALIDATED") &&
|
|
459
461
|
RUNNER_SRC.includes('verdict: "INVALIDATED"'),
|
|
460
|
-
"the runner refuses to judge a log with malformed lines OR per-writer order violations, and writes an INVALIDATED classification [
|
|
462
|
+
"the runner refuses to judge a log with malformed lines OR per-writer order violations, and writes an INVALIDATED classification [CHECK:PROBE-MALFORMED-INVALIDATES]",
|
|
461
463
|
);
|
|
462
464
|
}
|
|
463
465
|
|
|
@@ -615,7 +617,7 @@ const INIT_PARAMS = {
|
|
|
615
617
|
assert.equal(tools[0].name, "probe_nonce", "the tool is probe_nonce");
|
|
616
618
|
assert.ok(
|
|
617
619
|
tools[0].inputSchema?.required?.includes("probeRunId"),
|
|
618
|
-
"probe mode REQUIRES probeRunId [
|
|
620
|
+
"probe mode REQUIRES probeRunId [CHECK:PROBE-FIXTURE-RUNID-REQUIRED] — the §11-7 cross-layer join key",
|
|
619
621
|
);
|
|
620
622
|
|
|
621
623
|
const good = await fx.request({
|
|
@@ -657,7 +659,7 @@ const INIT_PARAMS = {
|
|
|
657
659
|
PROBE_EVENTS.fixtureToolsCallReceived,
|
|
658
660
|
PROBE_EVENTS.fixtureToolsCallReplied,
|
|
659
661
|
]) {
|
|
660
|
-
assert.ok(names.includes(expected), `fixture stamps ${expected} [
|
|
662
|
+
assert.ok(names.includes(expected), `fixture stamps ${expected} [CHECK:PROBE-FIXTURE-WIRE-MARKER]`);
|
|
661
663
|
}
|
|
662
664
|
const delayStart = events.find((e) => e.event === PROBE_EVENTS.fixtureDelayStart);
|
|
663
665
|
const delayEnd = events.find((e) => e.event === PROBE_EVENTS.fixtureDelayEnd);
|
|
@@ -756,7 +758,7 @@ const INIT_PARAMS = {
|
|
|
756
758
|
});
|
|
757
759
|
assert.ok(
|
|
758
760
|
refusedEveryKey && !existsSync(authPath),
|
|
759
|
-
"a payload carrying a reserved envelope key is REFUSED and nothing is written [
|
|
761
|
+
"a payload carrying a reserved envelope key is REFUSED and nothing is written [CHECK:PROBE-LOG-ENVELOPE-AUTHORITY]",
|
|
760
762
|
);
|
|
761
763
|
|
|
762
764
|
const STAMP_MS = 1_700_000_000_000;
|
|
@@ -769,7 +771,7 @@ const INIT_PARAMS = {
|
|
|
769
771
|
const vocab = readProbeEvents(vocabPath);
|
|
770
772
|
assert.ok(
|
|
771
773
|
vocab.events.length === 0 && vocab.malformed.length === 1,
|
|
772
|
-
"an unknown event name is a MISSING marker, never a quiet extra line [
|
|
774
|
+
"an unknown event name is a MISSING marker, never a quiet extra line [CHECK:PROBE-LOG-EVENT-VOCABULARY]",
|
|
773
775
|
);
|
|
774
776
|
|
|
775
777
|
// Structural envelope: the shared sort axis and its readable twin. A tsMs
|
|
@@ -792,7 +794,7 @@ const INIT_PARAMS = {
|
|
|
792
794
|
const broken = readProbeEvents(brokenPath);
|
|
793
795
|
assert.ok(
|
|
794
796
|
broken.events.length === 0 && broken.malformed.length === brokenLines.length,
|
|
795
|
-
"a JSON-valid line with a broken envelope is MALFORMED, never an event [
|
|
797
|
+
"a JSON-valid line with a broken envelope is MALFORMED, never an event [CHECK:PROBE-LOG-ENVELOPE-SCHEMA]",
|
|
796
798
|
);
|
|
797
799
|
|
|
798
800
|
// Payload contract: the envelope can be perfect and the line still a lie,
|
|
@@ -816,7 +818,7 @@ const INIT_PARAMS = {
|
|
|
816
818
|
const payloadBroken = readProbeEvents(payloadPath);
|
|
817
819
|
assert.ok(
|
|
818
820
|
payloadBroken.events.length === 0 && payloadBroken.malformed.length === badPayloads.length,
|
|
819
|
-
"a valid envelope with a payload the classifier cannot judge on is MALFORMED [
|
|
821
|
+
"a valid envelope with a payload the classifier cannot judge on is MALFORMED [CHECK:PROBE-LOG-PAYLOAD-SCHEMA]",
|
|
820
822
|
);
|
|
821
823
|
|
|
822
824
|
// …and the readings the writer legitimately omits are NOT malformed: the
|
|
@@ -852,7 +854,7 @@ const INIT_PARAMS = {
|
|
|
852
854
|
const wire = readProbeEvents(wirePath);
|
|
853
855
|
assert.ok(
|
|
854
856
|
wire.events.length === 0 && wire.malformed.length === wireLines.length,
|
|
855
|
-
"a wire marker that does not name the expected tool is not wire-availability [
|
|
857
|
+
"a wire marker that does not name the expected tool is not wire-availability [CHECK:PROBE-LOG-WIRE-MARKER-NAMES-TOOL]",
|
|
856
858
|
);
|
|
857
859
|
const goodWirePath = join(tmp, "payload-wire-ok.ndjson");
|
|
858
860
|
appendFileSync(
|
|
@@ -927,7 +929,7 @@ const INIT_PARAMS = {
|
|
|
927
929
|
const win = readProbeEvents(winPath);
|
|
928
930
|
assert.ok(
|
|
929
931
|
win.malformed.length === 2 && win.events.length === 1,
|
|
930
|
-
"an unknown window reason and a non-boolean markerSeen are MALFORMED; the closed vocabulary passes [
|
|
932
|
+
"an unknown window reason and a non-boolean markerSeen are MALFORMED; the closed vocabulary passes [CHECK:PROBE-LOG-WINDOW-REASON-VOCAB]",
|
|
931
933
|
);
|
|
932
934
|
}
|
|
933
935
|
|
|
@@ -967,7 +969,7 @@ const INIT_PARAMS = {
|
|
|
967
969
|
const dupSeq = stream([line(1, 5, 100), line(1, 5, 100)]);
|
|
968
970
|
assert.ok(
|
|
969
971
|
dupSeq.sequenceViolations.length === 1 && /seq 5 does not exceed/.test(dupSeq.sequenceViolations[0]),
|
|
970
|
-
"a repeated per-pid seq is a stream violation [
|
|
972
|
+
"a repeated per-pid seq is a stream violation [CHECK:PROBE-LOG-SEQ-STRICTLY-INCREASING]",
|
|
971
973
|
);
|
|
972
974
|
const backSeq = stream([line(1, 5, 100), line(1, 4, 101)]);
|
|
973
975
|
assert.equal(backSeq.sequenceViolations.length, 1, "a per-pid seq going backwards is a stream violation");
|
|
@@ -980,7 +982,7 @@ const INIT_PARAMS = {
|
|
|
980
982
|
const outOfOrderInFile = stream([line(1, 9, 900), line(1, 2, 200)]);
|
|
981
983
|
assert.ok(
|
|
982
984
|
outOfOrderInFile.sequenceViolations.length > 0,
|
|
983
|
-
"per-writer order is judged on the RAW file order, not after the sort has rewritten it [
|
|
985
|
+
"per-writer order is judged on the RAW file order, not after the sort has rewritten it [CHECK:PROBE-LOG-RAW-ORDER-BEFORE-SORT]",
|
|
984
986
|
);
|
|
985
987
|
assert.deepEqual(
|
|
986
988
|
outOfOrderInFile.events.map((e) => e.seq),
|
|
@@ -993,7 +995,7 @@ const INIT_PARAMS = {
|
|
|
993
995
|
const backTs = stream([line(1, 0, 500), line(1, 1, 499)]);
|
|
994
996
|
assert.ok(
|
|
995
997
|
backTs.sequenceViolations.length === 1 && /runs BACKWARDS/.test(backTs.sequenceViolations[0]),
|
|
996
|
-
"a per-pid tsMs regression is a stream violation [
|
|
998
|
+
"a per-pid tsMs regression is a stream violation [CHECK:PROBE-LOG-TS-NO-REGRESSION]",
|
|
997
999
|
);
|
|
998
1000
|
// Different pids are independent: cross-process stamps are not comparable this
|
|
999
1001
|
// way, and demanding it would flag every normal interleaving.
|
|
@@ -1016,7 +1018,7 @@ const INIT_PARAMS = {
|
|
|
1016
1018
|
assert.equal(
|
|
1017
1019
|
pidReuse.sequenceViolations.length,
|
|
1018
1020
|
0,
|
|
1019
|
-
"a reused pid restarting its counter in a LATER run is not a violation — the writer key is (runId, pid) [
|
|
1021
|
+
"a reused pid restarting its counter in a LATER run is not a violation — the writer key is (runId, pid) [CHECK:PROBE-LOG-WRITER-KEY-PER-RUN]",
|
|
1020
1022
|
);
|
|
1021
1023
|
// …but within one run the same pid is still held to the rule.
|
|
1022
1024
|
assert.equal(
|
|
@@ -1222,7 +1224,7 @@ function intervention(
|
|
|
1222
1224
|
}),
|
|
1223
1225
|
};
|
|
1224
1226
|
const res2 = classifyProbe([ctl2.record, d1.record], [...ctl2.events, ...d1.events]);
|
|
1225
|
-
assert.equal(res2.verdict, "P0", "control without the callability marker → P0 [
|
|
1227
|
+
assert.equal(res2.verdict, "P0", "control without the callability marker → P0 [CHECK:VERDICT-P0-CONTROL-FAIL]");
|
|
1226
1228
|
assert.equal(res2.control.p0Reason, "tool-unavailable", "P0 names tool-unavailable");
|
|
1227
1229
|
}
|
|
1228
1230
|
|
|
@@ -1231,7 +1233,7 @@ function intervention(
|
|
|
1231
1233
|
const ctl = passingControl();
|
|
1232
1234
|
const d1 = intervention("d1", 2000, 10_000, { failPhase: "initialize" });
|
|
1233
1235
|
const res = classifyProbe([ctl.record, d1.record], [...ctl.events, ...d1.events]);
|
|
1234
|
-
assert.equal(res.verdict, "I0", "intervention initialize failure → I0, never D [
|
|
1236
|
+
assert.equal(res.verdict, "I0", "intervention initialize failure → I0, never D [CHECK:VERDICT-I0-NEVER-D]");
|
|
1235
1237
|
}
|
|
1236
1238
|
|
|
1237
1239
|
// --- D: phase-qualified fail-loud readings ----------------------------------
|
|
@@ -1260,7 +1262,7 @@ function intervention(
|
|
|
1260
1262
|
assert.equal(
|
|
1261
1263
|
resA.verdict,
|
|
1262
1264
|
"inconclusive",
|
|
1263
|
-
"absence without the wire marker is a handshake/fixture/config candidate, never B [
|
|
1265
|
+
"absence without the wire marker is a handshake/fixture/config candidate, never B [CHECK:VERDICT-NOWIRE-CANDIDATE]",
|
|
1264
1266
|
);
|
|
1265
1267
|
assert.equal(resA.promotable, false, "…and never promotes");
|
|
1266
1268
|
|
|
@@ -1276,7 +1278,7 @@ function intervention(
|
|
|
1276
1278
|
assert.equal(
|
|
1277
1279
|
resB.verdict,
|
|
1278
1280
|
"B",
|
|
1279
|
-
"marker-complete absence reads B — the runtime No-such-tool ladder OWNS runtime-error runs; no other channel may stand in for it [
|
|
1281
|
+
"marker-complete absence reads B — the runtime No-such-tool ladder OWNS runtime-error runs; no other channel may stand in for it [CHECK:VERDICT-RUNTIME-B-LADDER-OWNS]",
|
|
1280
1282
|
);
|
|
1281
1283
|
assert.equal(resB.promotable, true, "exact measured-id No-such-tool promotes");
|
|
1282
1284
|
|
|
@@ -1295,7 +1297,7 @@ function intervention(
|
|
|
1295
1297
|
assert.equal(
|
|
1296
1298
|
resB2.verdict,
|
|
1297
1299
|
"inconclusive",
|
|
1298
|
-
"exact-id absence WITHOUT running ahead of wire-availability is not delta-B [
|
|
1300
|
+
"exact-id absence WITHOUT running ahead of wire-availability is not delta-B [CHECK:VERDICT-B-REQUIRES-RANAHEAD]",
|
|
1299
1301
|
);
|
|
1300
1302
|
assert.equal(resB2.promotable, false, "…and never promotes");
|
|
1301
1303
|
|
|
@@ -1309,7 +1311,7 @@ function intervention(
|
|
|
1309
1311
|
nonceEchoed: false,
|
|
1310
1312
|
});
|
|
1311
1313
|
const resC = classifyProbe([ctl.record, alias.record], [...ctl.events, ...alias.events]);
|
|
1312
|
-
assert.equal(resC.verdict, "inconclusive", "alias-mismatch absence is not B [
|
|
1314
|
+
assert.equal(resC.verdict, "inconclusive", "alias-mismatch absence is not B [CHECK:VERDICT-B-PROMOTION-RULES]");
|
|
1313
1315
|
assert.equal(resC.promotable, false, "alias mismatch never promotes");
|
|
1314
1316
|
}
|
|
1315
1317
|
|
|
@@ -1358,7 +1360,11 @@ function intervention(
|
|
|
1358
1360
|
nonceEchoed: true,
|
|
1359
1361
|
});
|
|
1360
1362
|
const one = classifyProbe([ctl.record, d1.record], [...ctl.events, ...d1.events]);
|
|
1361
|
-
assert.equal(
|
|
1363
|
+
assert.equal(
|
|
1364
|
+
one.verdict,
|
|
1365
|
+
"A-withheld",
|
|
1366
|
+
"one nonzero delay → wait verdict WITHHELD [CHECK:VERDICT-A-NEEDS-TWO-DELAYS]",
|
|
1367
|
+
);
|
|
1362
1368
|
const two = classifyProbe([ctl.record, d1.record, d2.record], [...ctl.events, ...d1.events, ...d2.events]);
|
|
1363
1369
|
assert.equal(two.verdict, "A", "two tracking delays → A");
|
|
1364
1370
|
|
|
@@ -1393,7 +1399,7 @@ function intervention(
|
|
|
1393
1399
|
assert.equal(
|
|
1394
1400
|
over.verdict,
|
|
1395
1401
|
"A-withheld",
|
|
1396
|
-
"excess overshooting the [0.8·D, D+slack] band is not tracking — A withheld [
|
|
1402
|
+
"excess overshooting the [0.8·D, D+slack] band is not tracking — A withheld [CHECK:VERDICT-A-TRACKING-BAND]",
|
|
1397
1403
|
);
|
|
1398
1404
|
|
|
1399
1405
|
// In-band per point but NOT growing with D (4.0s → 6.4s excess for 2s → 8s
|
|
@@ -1430,7 +1436,7 @@ function intervention(
|
|
|
1430
1436
|
assert.equal(
|
|
1431
1437
|
res.verdict,
|
|
1432
1438
|
"inconclusive",
|
|
1433
|
-
"a same-ms wire/newSession-end tie is unordered — neither kept nor ahead [
|
|
1439
|
+
"a same-ms wire/newSession-end tie is unordered — neither kept nor ahead [CHECK:VERDICT-SAMEMS-AMBIGUOUS]",
|
|
1434
1440
|
);
|
|
1435
1441
|
|
|
1436
1442
|
// A tie combined with an exact-id No-such-tool must not read B either —
|
|
@@ -1473,7 +1479,8 @@ function intervention(
|
|
|
1473
1479
|
const resNoWindow = classifyProbe([ctl.record, noWindow.record], [...ctl.events, ...noWindow.events]);
|
|
1474
1480
|
// Two independent nets cover this — the exactly-once inventory below AND the
|
|
1475
1481
|
// explicit windowReason guard in the classifier — so no SINGLE mutation can
|
|
1476
|
-
// kill it and it carries no [QK:] token. The inventory itself
|
|
1482
|
+
// kill it and it carries no [QK:] token. The inventory itself remains a
|
|
1483
|
+
// direct assertion below (no longer replant-qualified — issue #70 subtraction).
|
|
1477
1484
|
assert.ok(
|
|
1478
1485
|
resNoWindow.verdict === "INVALIDATED" && resNoWindow.interventions[0].invalidReason === "topology",
|
|
1479
1486
|
"a run with no observation-window marker is INVALIDATED for TOPOLOGY — absence cannot be told from our own teardown",
|
|
@@ -1483,7 +1490,7 @@ function intervention(
|
|
|
1483
1490
|
assert.deepEqual(
|
|
1484
1491
|
[...RUNNER_EXACTLY_ONCE].sort(),
|
|
1485
1492
|
[PROBE_EVENTS.observationWindowEnd, PROBE_EVENTS.runEnd, PROBE_EVENTS.runStart].sort(),
|
|
1486
|
-
"the runner-owned exactly-once marker set is exactly run_start, the window close, and run_end [
|
|
1493
|
+
"the runner-owned exactly-once marker set is exactly run_start, the window close, and run_end [CHECK:VERDICT-RUNNER-EXACTLY-ONCE-INVENTORY]",
|
|
1487
1494
|
);
|
|
1488
1495
|
|
|
1489
1496
|
// THE regression the first LIVE pair produced: D2's child was torn down while
|
|
@@ -1501,7 +1508,7 @@ function intervention(
|
|
|
1501
1508
|
assert.equal(
|
|
1502
1509
|
resCensored.interventions[0].invalidReason,
|
|
1503
1510
|
"observation-window-closed",
|
|
1504
|
-
"a window closed by child-exit with the marker unseen is CENSORED, not a handshake/fixture/config candidate [
|
|
1511
|
+
"a window closed by child-exit with the marker unseen is CENSORED, not a handshake/fixture/config candidate [CHECK:VERDICT-CENSORED-NOT-CANDIDATE]",
|
|
1505
1512
|
);
|
|
1506
1513
|
assert.equal(
|
|
1507
1514
|
resCensored.interventions[0].ordering,
|
|
@@ -1520,7 +1527,7 @@ function intervention(
|
|
|
1520
1527
|
assert.deepEqual(
|
|
1521
1528
|
resCensored.status.invalidRuns,
|
|
1522
1529
|
[{ runId: "w1", reason: "observation-window-closed" }],
|
|
1523
|
-
"a fatal status still names the discarded run and its reason [
|
|
1530
|
+
"a fatal status still names the discarded run and its reason [CHECK:VERDICT-STATUS-NAMES-INVALID-RUNS]",
|
|
1524
1531
|
);
|
|
1525
1532
|
|
|
1526
1533
|
// The SAME absence under a window we kept open to its deadline IS a reading:
|
|
@@ -1535,7 +1542,7 @@ function intervention(
|
|
|
1535
1542
|
assert.equal(
|
|
1536
1543
|
resSufficient.interventions[0].failure,
|
|
1537
1544
|
"candidate-handshake",
|
|
1538
|
-
"the same absence under a SUFFICIENT window is a handshake/fixture/config candidate (
|
|
1545
|
+
"the same absence under a SUFFICIENT window is a handshake/fixture/config candidate (one condition, directly asserted; its qualification replant was dropped — issue #70)",
|
|
1539
1546
|
);
|
|
1540
1547
|
assert.equal(resSufficient.verdict, "inconclusive", "…still not promotable, and still not B");
|
|
1541
1548
|
|
|
@@ -1549,7 +1556,7 @@ function intervention(
|
|
|
1549
1556
|
assert.equal(
|
|
1550
1557
|
resDup.verdict,
|
|
1551
1558
|
"INVALIDATED",
|
|
1552
|
-
"a duplicated runner-owned marker INVALIDATES the run [
|
|
1559
|
+
"a duplicated runner-owned marker INVALIDATES the run [CHECK:VERDICT-RUNNER-TOPOLOGY-EXACTLY-ONCE]",
|
|
1553
1560
|
);
|
|
1554
1561
|
assert.match(resDup.interventions[0].evidence, /run_end appears 2 times/, "…and the evidence names the duplicate");
|
|
1555
1562
|
|
|
@@ -1602,7 +1609,7 @@ function intervention(
|
|
|
1602
1609
|
assert.equal(
|
|
1603
1610
|
resLying.verdict,
|
|
1604
1611
|
"INVALIDATED",
|
|
1605
|
-
"a window close claiming markerSeen=true with no wire marker in the log is INVALIDATED, never a candidate [
|
|
1612
|
+
"a window close claiming markerSeen=true with no wire marker in the log is INVALIDATED, never a candidate [CHECK:VERDICT-WINDOW-MARKER-COHERENCE]",
|
|
1606
1613
|
);
|
|
1607
1614
|
assert.match(resLying.interventions[0].evidence, /contradicts its own evidence/, "…named as a self-contradiction");
|
|
1608
1615
|
|
|
@@ -1633,7 +1640,7 @@ function intervention(
|
|
|
1633
1640
|
const resLyingCtl = classifyProbe([lyingControl.record, d1ok.record], [...lyingControl.events, ...d1ok.events]);
|
|
1634
1641
|
assert.ok(
|
|
1635
1642
|
resLyingCtl.verdict === "INVALIDATED" && resLyingCtl.control.pass === false,
|
|
1636
|
-
"a CONTROL whose window close contradicts its own log is INVALIDATED before P0 is even considered — the baseline is held to the same bar [
|
|
1643
|
+
"a CONTROL whose window close contradicts its own log is INVALIDATED before P0 is even considered — the baseline is held to the same bar [CHECK:VERDICT-CONTROL-HELD-TO-COHERENCE]",
|
|
1637
1644
|
);
|
|
1638
1645
|
assert.equal(resLyingCtl.interventions.length, 0, "…and no intervention is judged against a baseline that lied");
|
|
1639
1646
|
|
|
@@ -1678,7 +1685,7 @@ function intervention(
|
|
|
1678
1685
|
assert.equal(
|
|
1679
1686
|
resTrans.verdict,
|
|
1680
1687
|
"INVALIDATED",
|
|
1681
|
-
"transposed phases are a topology violation even though every start/end pair is intact [
|
|
1688
|
+
"transposed phases are a topology violation even though every start/end pair is intact [CHECK:VERDICT-PHASE-SEQUENTIAL]",
|
|
1682
1689
|
);
|
|
1683
1690
|
assert.match(
|
|
1684
1691
|
resTrans.interventions[0].evidence,
|
|
@@ -1712,7 +1719,7 @@ function intervention(
|
|
|
1712
1719
|
assert.equal(
|
|
1713
1720
|
resHole.verdict,
|
|
1714
1721
|
"INVALIDATED",
|
|
1715
|
-
"a skipped phase is a topology violation — a failed run is a PREFIX of the production order, never a hole [
|
|
1722
|
+
"a skipped phase is a topology violation — a failed run is a PREFIX of the production order, never a hole [CHECK:VERDICT-PHASE-PRODUCTION-ORDER]",
|
|
1716
1723
|
);
|
|
1717
1724
|
assert.match(resHole.interventions[0].evidence, /prefix of the production order/, "…named as a prefix violation");
|
|
1718
1725
|
}
|
|
@@ -1747,7 +1754,7 @@ function intervention(
|
|
|
1747
1754
|
assert.equal(
|
|
1748
1755
|
res.ordering.summary,
|
|
1749
1756
|
"prompt-request-ahead-of-wire",
|
|
1750
|
-
"…and the (a) axis is reported on its OWN terms rather than being folded into that verdict [
|
|
1757
|
+
"…and the (a) axis is reported on its OWN terms rather than being folded into that verdict [CHECK:VERDICT-ORDERING-AXIS-REPORTED]",
|
|
1751
1758
|
);
|
|
1752
1759
|
// Diagnosability: §11-7-b's first artifact classified D1 correctly and still
|
|
1753
1760
|
// left a reader unable to SEE the ran-ahead or the turn time left after it.
|
|
@@ -1755,7 +1762,7 @@ function intervention(
|
|
|
1755
1762
|
assert.match(
|
|
1756
1763
|
r.evidence,
|
|
1757
1764
|
/\d+ms of turn remained after wire/,
|
|
1758
|
-
"the evidence exposes how much turn was left after the wire marker [
|
|
1765
|
+
"the evidence exposes how much turn was left after the wire marker [CHECK:VERDICT-EVIDENCE-EXPOSES-DELTAS]",
|
|
1759
1766
|
);
|
|
1760
1767
|
|
|
1761
1768
|
// The axis split is load-bearing for B/C, not cosmetic. Here the wire lands
|
|
@@ -1776,7 +1783,7 @@ function intervention(
|
|
|
1776
1783
|
assert.equal(
|
|
1777
1784
|
resBetween.verdict,
|
|
1778
1785
|
"inconclusive",
|
|
1779
|
-
"exact-id absence with the wire available before the prompt is NOT delta-B — B's window is promptStart, not newSession end [
|
|
1786
|
+
"exact-id absence with the wire available before the prompt is NOT delta-B — B's window is promptStart, not newSession end [CHECK:VERDICT-B-WINDOW-IS-PROMPT]",
|
|
1780
1787
|
);
|
|
1781
1788
|
assert.equal(
|
|
1782
1789
|
rb.ordering,
|
|
@@ -1831,7 +1838,7 @@ function intervention(
|
|
|
1831
1838
|
assert.equal(
|
|
1832
1839
|
await reasonOf({ [AMBIENT_OVERRIDE_ENV]: "/somewhere/claude" }, fakeBin),
|
|
1833
1840
|
"ambient-override-present",
|
|
1834
|
-
"an ambient CLAUDE_CODE_EXECUTABLE is REFUSED before resolution — claudeCliPath() would return it verbatim [
|
|
1841
|
+
"an ambient CLAUDE_CODE_EXECUTABLE is REFUSED before resolution — claudeCliPath() would return it verbatim [CHECK:PROBE-TARGET-AMBIENT-REFUSED]",
|
|
1835
1842
|
);
|
|
1836
1843
|
// KEY PRESENCE is the predicate: upstream's `??` treats "" as set and passes
|
|
1837
1844
|
// it on while a truthy check treats it as unset — the probe refuses the
|
|
@@ -1849,7 +1856,7 @@ function intervention(
|
|
|
1849
1856
|
assert.equal(
|
|
1850
1857
|
await reasonOf({}, fakeScript),
|
|
1851
1858
|
"target-script-suffix",
|
|
1852
|
-
"a script-suffixed target is refused — the SDK would take the node|bun branch, which this seam asserts against instead of reproducing [
|
|
1859
|
+
"a script-suffixed target is refused — the SDK would take the node|bun branch, which this seam asserts against instead of reproducing [CHECK:PROBE-TARGET-NATIVE-BRANCH-ONLY]",
|
|
1853
1860
|
);
|
|
1854
1861
|
assert.equal(
|
|
1855
1862
|
await reasonOf({}, join(tmp, "no-such-claude")),
|
|
@@ -1994,7 +2001,7 @@ function intervention(
|
|
|
1994
2001
|
Object.values(PROBE_SHIM_ENV).every((v) => SHIM_SCRUB_ENV_VARS.includes(v)) &&
|
|
1995
2002
|
SHIM_SCRUB_ENV_VARS.length === 1 + Object.values(PROBE_SHIM_ENV).length &&
|
|
1996
2003
|
SHIM_SCRUB_ENV_VARS.every((v) => /^[A-Z][A-Z0-9_]*$/.test(v)),
|
|
1997
|
-
"the shim scrub list is the exact enumerated allowlist — the override plus every probe-private var by literal name, no wildcard/prefix semantics [
|
|
2004
|
+
"the shim scrub list is the exact enumerated allowlist — the override plus every probe-private var by literal name, no wildcard/prefix semantics [CHECK:PROBE-SCRUB-EXACT-ALLOWLIST]",
|
|
1998
2005
|
);
|
|
1999
2006
|
// The shim env names must not collide with the fixture's — two processes,
|
|
2000
2007
|
// two channels, one shared log.
|
|
@@ -2005,18 +2012,19 @@ function intervention(
|
|
|
2005
2012
|
);
|
|
2006
2013
|
}
|
|
2007
2014
|
|
|
2008
|
-
// --- 8d) runner pins — one assert per claim,
|
|
2009
|
-
//
|
|
2015
|
+
// --- 8d) runner pins — one assert per claim, each under its own label, so a
|
|
2016
|
+
// source pin stays a DIRECT assertion naming exactly one contract
|
|
2017
|
+
// (bundling four claims under one token let one mutant
|
|
2010
2018
|
// stand in for all of them; GPT review 2026-07-29) ----------------------
|
|
2011
2019
|
{
|
|
2012
2020
|
assert.ok(
|
|
2013
2021
|
RUNNER_SRC.includes("assertNoAmbientOverride(spawnEnv, `composed acp child env for ${runId}`);"),
|
|
2014
|
-
"the COMPOSED spawn env of every ACP child is asserted override-free — launch defaults / overlay overrides could inject what process.env did not carry [
|
|
2022
|
+
"the COMPOSED spawn env of every ACP child is asserted override-free — launch defaults / overlay overrides could inject what process.env did not carry [CHECK:RUNNER-TARGET-PRECONDITION-PINNED]",
|
|
2015
2023
|
);
|
|
2016
2024
|
assert.ok(
|
|
2017
2025
|
RUNNER_SRC.includes("snapshotInstrumented: true") && !RUNNER_SRC.includes("snapshotInstrumented: false"),
|
|
2018
2026
|
"the snapshot channel is ARMED and no run is left declaring otherwise — a roster mixing armed and unarmed runs " +
|
|
2019
|
-
"would let a run whose shim never reported in pass as an ordinary absence [
|
|
2027
|
+
"would let a run whose shim never reported in pass as an ordinary absence [CHECK:RUNNER-SNAPSHOT-CHANNEL-ARMED]",
|
|
2020
2028
|
);
|
|
2021
2029
|
// Pinned as the CONTIGUOUS roster-record shape: the same two stamps also ride
|
|
2022
2030
|
// the run_start payload (forensics), so field-by-field includes() would stay
|
|
@@ -2025,13 +2033,13 @@ function intervention(
|
|
|
2025
2033
|
RUNNER_SRC.includes(
|
|
2026
2034
|
"snapshotInstrumented: true,\n\t\tcliTargetPath: CLI_TARGET.path,\n\t\tcliTargetSha256: CLI_TARGET.sha256,",
|
|
2027
2035
|
),
|
|
2028
|
-
"the pair's expected CLI target identity rides EVERY roster record so the classifier can consume it (condition 5) [
|
|
2036
|
+
"the pair's expected CLI target identity rides EVERY roster record so the classifier can consume it (condition 5) [CHECK:RUNNER-TARGET-IDENTITY-IN-ROSTER]",
|
|
2029
2037
|
);
|
|
2030
2038
|
assert.ok(
|
|
2031
2039
|
RUNNER_SRC.includes("rehash = hashFileSha256(CLI_TARGET.path);") &&
|
|
2032
2040
|
RUNNER_SRC.includes('reason: "cli-target-drift"') &&
|
|
2033
2041
|
RUNNER_SRC.includes('reason: "cli-target-unreadable"'),
|
|
2034
|
-
"the target is RE-HASHED after the pair, and both drift and unreadability write a named INVALIDATED classification [
|
|
2042
|
+
"the target is RE-HASHED after the pair, and both drift and unreadability write a named INVALIDATED classification [CHECK:RUNNER-DRIFT-REHASH-PINNED]",
|
|
2035
2043
|
);
|
|
2036
2044
|
assert.ok(
|
|
2037
2045
|
RUNNER_SRC.includes("CLI_TARGET = await resolveProbeCliTarget({") &&
|
|
@@ -2051,7 +2059,7 @@ function intervention(
|
|
|
2051
2059
|
"the ambient-override refusal runs against the env as PRODUCTION composed it, and the probe installs its own " +
|
|
2052
2060
|
"override only AFTER. Inverted, the checkpoint would inspect the override the probe itself just injected and " +
|
|
2053
2061
|
"REFUSE every run — loudly, but for the wrong reason, and the operator's ambient environment would never be " +
|
|
2054
|
-
"examined at all [
|
|
2062
|
+
"examined at all [CHECK:RUNNER-ARMING-ORDER]",
|
|
2055
2063
|
);
|
|
2056
2064
|
assert.ok(
|
|
2057
2065
|
RUNNER_SRC.includes(
|
|
@@ -2062,7 +2070,7 @@ function intervention(
|
|
|
2062
2070
|
),
|
|
2063
2071
|
"the injection is exactly four names: the override pointing at the SHIM, and the three probe-private vars the " +
|
|
2064
2072
|
"shim reads — the target it must exec (resolved HERE, never by the shim), the shared log, and this run's id. " +
|
|
2065
|
-
"All four are on the shim's scrub list, so none of them reach the real CLI [
|
|
2073
|
+
"All four are on the shim's scrub list, so none of them reach the real CLI [CHECK:RUNNER-SHIM-OVERRIDE-EXACT]",
|
|
2066
2074
|
);
|
|
2067
2075
|
assert.ok(
|
|
2068
2076
|
RUNNER_SRC.includes(
|
|
@@ -2071,7 +2079,7 @@ function intervention(
|
|
|
2071
2079
|
"the instrument passes the SAME precondition asserts as the stimulus — absolute, native branch, present regular " +
|
|
2072
2080
|
"file, executable — and a refusal is a NAMED classification on the artifact. A shim that fails any of those " +
|
|
2073
2081
|
"either never runs or runs on the OTHER launch branch, and the pair would measure something else " +
|
|
2074
|
-
"[
|
|
2082
|
+
"[CHECK:RUNNER-SHIM-PRECONDITION-PINNED]",
|
|
2075
2083
|
);
|
|
2076
2084
|
// The path the runner points at is checked on DISK too, not just in source: a
|
|
2077
2085
|
// pin proves the runner asks for the right file, not that the file can run.
|
|
@@ -2088,7 +2096,7 @@ function intervention(
|
|
|
2088
2096
|
RUNNER_SRC.includes("JSON.stringify(shimRehash) !== JSON.stringify(SHIM_RUNTIME)"),
|
|
2089
2097
|
"the instrument's runtime graph is pinned before the first run and RE-HASHED after the last, on its own axis " +
|
|
2090
2098
|
"with its own two names — an edit to the implementation landing between control and intervention is " +
|
|
2091
|
-
"invisible to every other check, including the shim's own boot marker [
|
|
2099
|
+
"invisible to every other check, including the shim's own boot marker [CHECK:RUNNER-SHIM-RUNTIME-PINNED]",
|
|
2092
2100
|
);
|
|
2093
2101
|
{
|
|
2094
2102
|
// The runner's list must equal the STATIC LOCAL IMPORT CLOSURE of the
|
|
@@ -2125,7 +2133,7 @@ function intervention(
|
|
|
2125
2133
|
[...closure].sort(),
|
|
2126
2134
|
"the runner's pinned instrument list is EXACTLY the launcher's static local-import closure — a helper added " +
|
|
2127
2135
|
"to the shim without being pinned would otherwise be free to change mid-pair, and a stale entry would " +
|
|
2128
|
-
"pin a file the instrument no longer reads [
|
|
2136
|
+
"pin a file the instrument no longer reads [CHECK:RUNNER-SHIM-RUNTIME-GRAPH-EXACT]",
|
|
2129
2137
|
);
|
|
2130
2138
|
}
|
|
2131
2139
|
// The path is read OUT OF THE RUNNER rather than restated here, so this
|
|
@@ -2141,7 +2149,7 @@ function intervention(
|
|
|
2141
2149
|
SDK_SCRIPT_SUFFIXES.every((suffix) => !shimPath.endsWith(suffix)),
|
|
2142
2150
|
"the shim the runner arms is present, executable and extensionless ON DISK — the pair is asserted onto the " +
|
|
2143
2151
|
"direct-spawn branch, and a script suffix (or a path pointing at nothing) would silently move the " +
|
|
2144
|
-
"instrument to `node|bun <path>` or break the spawn outright [
|
|
2152
|
+
"instrument to `node|bun <path>` or break the spawn outright [CHECK:RUNNER-SHIM-ON-DISK-NATIVE]",
|
|
2145
2153
|
);
|
|
2146
2154
|
}
|
|
2147
2155
|
}
|
|
@@ -2166,7 +2174,7 @@ function intervention(
|
|
|
2166
2174
|
const door = readProbeEvents(doorPath);
|
|
2167
2175
|
assert.ok(
|
|
2168
2176
|
door.malformed.length === 4 && door.events.length === 3,
|
|
2169
|
-
"shim payload rules hold at the door: missing target hash, ordinal<1, non-array tools, and receivedAtMs AFTER the envelope stamp are MALFORMED; the well-formed trio passes [
|
|
2177
|
+
"shim payload rules hold at the door: missing target hash, ordinal<1, non-array tools, and receivedAtMs AFTER the envelope stamp are MALFORMED; the well-formed trio passes [CHECK:PROBE-LOG-SNAPSHOT-PAYLOAD]",
|
|
2170
2178
|
);
|
|
2171
2179
|
}
|
|
2172
2180
|
|
|
@@ -2241,7 +2249,7 @@ function intervention(
|
|
|
2241
2249
|
assert.equal(
|
|
2242
2250
|
res.verdict,
|
|
2243
2251
|
"B-name-snapshot",
|
|
2244
|
-
"snapshot absence of the measured id + promptRanAhead + wire strictly before the interval + calibrated control → B-name-snapshot [
|
|
2252
|
+
"snapshot absence of the measured id + promptRanAhead + wire strictly before the interval + calibrated control → B-name-snapshot [CHECK:VERDICT-SNAPSHOT-PROMOTES]",
|
|
2245
2253
|
);
|
|
2246
2254
|
assert.ok(res.promotable && res.status.failureVerdict === "B-name-snapshot", "…and it is promotable on axis (b)");
|
|
2247
2255
|
assert.notEqual(
|
|
@@ -2263,7 +2271,7 @@ function intervention(
|
|
|
2263
2271
|
assert.equal(
|
|
2264
2272
|
res.control.p0Reason,
|
|
2265
2273
|
"snapshot-instrument-absent",
|
|
2266
|
-
"…and the reason NAMES the missing instrument (a hijacked/replaced override looks exactly like this) [
|
|
2274
|
+
"…and the reason NAMES the missing instrument (a hijacked/replaced override looks exactly like this) [CHECK:VERDICT-SNAPSHOT-INSTRUMENT-ABSENT]",
|
|
2267
2275
|
);
|
|
2268
2276
|
}
|
|
2269
2277
|
|
|
@@ -2282,7 +2290,7 @@ function intervention(
|
|
|
2282
2290
|
const res = classifyProbe([ctl.record, i1.record], [...ctl.events, ...i1.events]);
|
|
2283
2291
|
assert.ok(
|
|
2284
2292
|
res.verdict === "P0" && res.control.p0Reason === "snapshot-calibration",
|
|
2285
|
-
"a control snapshot that cannot SEE the measured id fails calibration — absence readings need a baseline that shows presence [
|
|
2293
|
+
"a control snapshot that cannot SEE the measured id fails calibration — absence readings need a baseline that shows presence [CHECK:VERDICT-SNAPSHOT-CALIBRATION]",
|
|
2286
2294
|
);
|
|
2287
2295
|
}
|
|
2288
2296
|
|
|
@@ -2298,7 +2306,7 @@ function intervention(
|
|
|
2298
2306
|
const res = classifyProbe([ctl.record, i1.record], [...ctl.events, ...i1.events]);
|
|
2299
2307
|
assert.ok(
|
|
2300
2308
|
res.verdict === "inconclusive" && !res.promotable,
|
|
2301
|
-
"snapshot absence WITHOUT promptRanAhead is not the delayed-window failure mode — never promoted [
|
|
2309
|
+
"snapshot absence WITHOUT promptRanAhead is not the delayed-window failure mode — never promoted [CHECK:VERDICT-SNAPSHOT-REQUIRES-RANAHEAD]",
|
|
2302
2310
|
);
|
|
2303
2311
|
}
|
|
2304
2312
|
|
|
@@ -2315,7 +2323,7 @@ function intervention(
|
|
|
2315
2323
|
res.verdict === "inconclusive" &&
|
|
2316
2324
|
!res.promotable &&
|
|
2317
2325
|
res.interventions[0].evidence.includes("INSIDE the snapshot interval"),
|
|
2318
|
-
"a wire marker inside the received↔forwarded interval is UNORDERED — only wire strictly before the interval reads as after [
|
|
2326
|
+
"a wire marker inside the received↔forwarded interval is UNORDERED — only wire strictly before the interval reads as after [CHECK:VERDICT-SNAPSHOT-INTERVAL-UNORDERED]",
|
|
2319
2327
|
);
|
|
2320
2328
|
}
|
|
2321
2329
|
|
|
@@ -2365,7 +2373,7 @@ function intervention(
|
|
|
2365
2373
|
res.verdict === "inconclusive" &&
|
|
2366
2374
|
!res.promotable &&
|
|
2367
2375
|
res.interventions[0].evidence.includes("snapshot-channel-violation"),
|
|
2368
|
-
"reinit/set-model re-emission making the binding ambiguous is a NAMED channel violation — the (b) reading is unavailable, never a pick-first promotion [
|
|
2376
|
+
"reinit/set-model re-emission making the binding ambiguous is a NAMED channel violation — the (b) reading is unavailable, never a pick-first promotion [CHECK:VERDICT-SNAPSHOT-ORDINAL-EXACTLY-ONE]",
|
|
2369
2377
|
);
|
|
2370
2378
|
assert.notEqual(res.status.orderingMeasurement, "unobserved", "…while axis (a) still carries its comparison");
|
|
2371
2379
|
}
|
|
@@ -2386,7 +2394,7 @@ function intervention(
|
|
|
2386
2394
|
const res = classifyProbe([ctl.record, i1.record], [...ctl.events, ...i1.events]);
|
|
2387
2395
|
assert.ok(
|
|
2388
2396
|
res.verdict === "inconclusive" && !res.promotable && res.status.failureVerdict !== "B-name-snapshot",
|
|
2389
|
-
"shim-shaped evidence in the log of an UNARMED run is ignored — the roster declares the instrument, evidence alone never promotes [
|
|
2397
|
+
"shim-shaped evidence in the log of an UNARMED run is ignored — the roster declares the instrument, evidence alone never promotes [CHECK:VERDICT-SNAPSHOT-NEEDS-INSTRUMENT-FLAG]",
|
|
2390
2398
|
);
|
|
2391
2399
|
}
|
|
2392
2400
|
|
|
@@ -2408,7 +2416,7 @@ function intervention(
|
|
|
2408
2416
|
res.verdict === "inconclusive" &&
|
|
2409
2417
|
!res.promotable &&
|
|
2410
2418
|
res.interventions[0].evidence.includes("snapshot-channel-violation"),
|
|
2411
|
-
"an init RECEIVED before the prompt frame is not a candidate even when its append lands after — the receive axis, not the append/callback axis, binds; zero candidates is a named violation [
|
|
2419
|
+
"an init RECEIVED before the prompt frame is not a candidate even when its append lands after — the receive axis, not the append/callback axis, binds; zero candidates is a named violation [CHECK:VERDICT-SNAPSHOT-BINDING-RECEIVE-AXIS]",
|
|
2412
2420
|
);
|
|
2413
2421
|
}
|
|
2414
2422
|
|
|
@@ -2426,7 +2434,7 @@ function intervention(
|
|
|
2426
2434
|
res.status.invalidRuns.some((r) => r.reason === "snapshot-topology") &&
|
|
2427
2435
|
res.ordering.summary === "unobserved" &&
|
|
2428
2436
|
res.status.orderingMeasurement !== "measured",
|
|
2429
|
-
"an armed intervention whose shim never reported in is INVALIDATED (snapshot-topology) and votes on NEITHER axis — not a (b)-only degradation [
|
|
2437
|
+
"an armed intervention whose shim never reported in is INVALIDATED (snapshot-topology) and votes on NEITHER axis — not a (b)-only degradation [CHECK:VERDICT-SNAPSHOT-STRUCTURAL-INVALIDATES]",
|
|
2430
2438
|
);
|
|
2431
2439
|
}
|
|
2432
2440
|
|
|
@@ -2444,7 +2452,7 @@ function intervention(
|
|
|
2444
2452
|
const res = classifyProbe([ctl.record, i1.record], [...ctl.events, ...i1.events]);
|
|
2445
2453
|
assert.ok(
|
|
2446
2454
|
res.verdict === "INVALIDATED" && res.status.invalidRuns.some((r) => r.reason === "snapshot-topology"),
|
|
2447
|
-
"a shim boot whose target path+sha does not match the roster's expected identity INVALIDATES the run — identity is verified, not merely recorded [
|
|
2455
|
+
"a shim boot whose target path+sha does not match the roster's expected identity INVALIDATES the run — identity is verified, not merely recorded [CHECK:VERDICT-SNAPSHOT-TARGET-IDENTITY]",
|
|
2448
2456
|
);
|
|
2449
2457
|
}
|
|
2450
2458
|
|
|
@@ -2464,7 +2472,7 @@ function intervention(
|
|
|
2464
2472
|
res.verdict === "inconclusive" &&
|
|
2465
2473
|
!res.promotable &&
|
|
2466
2474
|
res.interventions[0].evidence.includes("CONTAINS the measured id"),
|
|
2467
|
-
"a snapshot that CONTAINS the measured id reads model-compliance, never absence — the contains-id rung blocks promotion [
|
|
2475
|
+
"a snapshot that CONTAINS the measured id reads model-compliance, never absence — the contains-id rung blocks promotion [CHECK:VERDICT-SNAPSHOT-CONTAINS-ID-BLOCKS]",
|
|
2468
2476
|
);
|
|
2469
2477
|
}
|
|
2470
2478
|
}
|