@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.
Files changed (152) hide show
  1. package/AGENTS.md +48 -15
  2. package/BASELINE.md +3 -3
  3. package/CHANGELOG.md +45 -0
  4. package/CONTRIBUTING.md +13 -9
  5. package/DELIVERY.md +7 -6
  6. package/README.md +27 -27
  7. package/VERIFY.md +22 -14
  8. package/demo/README.md +1 -1
  9. package/demo/demo-baseline.sh +1 -3
  10. package/demo/demo.sh +2 -5
  11. package/docs/acp-backend-rail.md +9 -4
  12. package/docs/external-mcp-host.md +4 -5
  13. package/docs/setup-clean-host.md +8 -7
  14. package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +148 -28
  15. package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +8 -6
  16. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-control-rpc.js +7 -5
  17. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-core.js +13 -14
  18. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-resume-args.js +45 -40
  19. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +117 -95
  20. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-decider.js +23 -57
  21. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-lock.js +16 -7
  22. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-production.js +5 -53
  23. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-release.js +21 -36
  24. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-runner.js +3 -15
  25. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-send-fallback.js +12 -11
  26. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-send.js +2 -7
  27. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +30 -67
  28. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-visible-resume.js +256 -0
  29. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +91 -5
  30. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +258 -0
  31. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-launch.js +202 -0
  32. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-placement.js +289 -0
  33. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-resume-call.js +170 -0
  34. package/mcp/entwurf-bridge/dist/pi-extensions/lib/resume-launch-identity.js +136 -0
  35. package/mcp/entwurf-bridge/dist/pi-extensions/lib/session-id.js +8 -5
  36. package/mcp/entwurf-bridge/dist/pi-extensions/lib/socket-discovery.js +3 -3
  37. package/mcp/entwurf-bridge/dist/scripts/meta-facts.js +51 -0
  38. package/mcp/entwurf-bridge/dist/scripts/new-session-id.js +9 -4
  39. package/mcp/entwurf-bridge/src/index.ts +164 -28
  40. package/mcp/entwurf-bridge/start.sh +2 -2
  41. package/mcp/entwurf-bridge/test.sh +23 -9
  42. package/mcp/entwurf-bridge/tsconfig.build.json +11 -2
  43. package/package.json +22 -11
  44. package/pi-extensions/entwurf-control.ts +218 -40
  45. package/pi-extensions/lib/acp/backend.ts +71 -12
  46. package/pi-extensions/lib/acp/overlay.ts +8 -6
  47. package/pi-extensions/lib/entwurf-control-rpc.ts +7 -5
  48. package/pi-extensions/lib/entwurf-core.ts +15 -15
  49. package/pi-extensions/lib/entwurf-resume-args.ts +41 -52
  50. package/pi-extensions/lib/entwurf-v2-contract-schema.ts +1 -1
  51. package/pi-extensions/lib/entwurf-v2-contract.ts +120 -99
  52. package/pi-extensions/lib/entwurf-v2-decider.ts +30 -91
  53. package/pi-extensions/lib/entwurf-v2-lock.ts +16 -7
  54. package/pi-extensions/lib/entwurf-v2-production.ts +4 -78
  55. package/pi-extensions/lib/entwurf-v2-release.ts +25 -49
  56. package/pi-extensions/lib/entwurf-v2-runner.ts +6 -21
  57. package/pi-extensions/lib/entwurf-v2-send-fallback.ts +12 -11
  58. package/pi-extensions/lib/entwurf-v2-send.ts +2 -7
  59. package/pi-extensions/lib/entwurf-v2-surface.ts +36 -76
  60. package/pi-extensions/lib/entwurf-v2-visible-resume.ts +370 -0
  61. package/pi-extensions/lib/meta-session.ts +93 -5
  62. package/pi-extensions/lib/mux-fresh-call.ts +328 -0
  63. package/pi-extensions/lib/mux-launch.ts +267 -0
  64. package/pi-extensions/lib/mux-placement.ts +387 -0
  65. package/pi-extensions/lib/mux-resume-call.ts +221 -0
  66. package/pi-extensions/lib/resume-launch-identity.ts +162 -0
  67. package/pi-extensions/lib/session-id.js +8 -5
  68. package/pi-extensions/lib/socket-discovery.ts +3 -3
  69. package/run.sh +471 -201
  70. package/scripts/agy-bridge-config.py +5 -1
  71. package/scripts/check-acp-backend-preflight.ts +1 -1
  72. package/scripts/check-acp-overlay.ts +13 -3
  73. package/scripts/check-acp-stream-hooks.ts +504 -0
  74. package/scripts/check-elapsed.sh +25 -0
  75. package/scripts/check-entwurf-bridge-boot.ts +51 -4
  76. package/scripts/check-entwurf-bridge-pi-free.ts +6 -5
  77. package/scripts/check-entwurf-control-rpc.ts +4 -3
  78. package/scripts/check-entwurf-resume-args.ts +72 -70
  79. package/scripts/check-entwurf-session-identity.ts +14 -10
  80. package/scripts/check-entwurf-v2-contract.ts +34 -59
  81. package/scripts/check-entwurf-v2-decider.ts +17 -177
  82. package/scripts/check-entwurf-v2-lock.ts +5 -2
  83. package/scripts/check-entwurf-v2-matrix.ts +3 -53
  84. package/scripts/check-entwurf-v2-production.ts +2 -91
  85. package/scripts/check-entwurf-v2-release.ts +10 -105
  86. package/scripts/check-entwurf-v2-runner.ts +4 -85
  87. package/scripts/check-entwurf-v2-send-fallback.ts +5 -6
  88. package/scripts/check-entwurf-v2-send.ts +0 -28
  89. package/scripts/check-entwurf-v2-surface.ts +157 -128
  90. package/scripts/check-entwurf-v2-visible-resume.ts +445 -0
  91. package/scripts/check-fresh-cut-gate.sh +1 -1
  92. package/scripts/check-gate-qualification.ts +98 -7
  93. package/scripts/check-install-container.sh +10 -2
  94. package/scripts/check-install-surface.ts +1 -1
  95. package/scripts/check-keyset-overlap.py +1 -1
  96. package/scripts/check-meta-facts.ts +249 -0
  97. package/scripts/check-meta-identity-consumers.ts +1 -1
  98. package/scripts/check-meta-session.ts +169 -0
  99. package/scripts/check-mux-launch-tmux.ts +316 -0
  100. package/scripts/check-mux-launch.ts +288 -0
  101. package/scripts/check-mux-launcher-fence.ts +264 -0
  102. package/scripts/check-mux-parent-artifact.ts +195 -0
  103. package/scripts/check-mux-placement-tmux.ts +322 -0
  104. package/scripts/check-mux-placement.ts +323 -0
  105. package/scripts/check-mux-resume-call.ts +282 -0
  106. package/scripts/check-probe-cli-shim.ts +25 -22
  107. package/scripts/check-probe-ordering.ts +84 -76
  108. package/scripts/check-release-gate-outcomes.ts +127 -7
  109. package/scripts/check-resume-launch-identity.ts +244 -0
  110. package/scripts/check-socket-discovery.ts +1 -1
  111. package/scripts/fixtures/mux-parent-transcript.scrubbed.jsonl +3 -0
  112. package/scripts/inventory-verification-surface.ts +349 -0
  113. package/scripts/lib/claude-launcher-fence.ts +322 -0
  114. package/scripts/lib/mutation-qualify.ts +109 -3
  115. package/scripts/meta-bridge-doctor.sh +6 -8
  116. package/scripts/meta-facts.ts +60 -0
  117. package/scripts/mutants/acp-overlay.json +17 -0
  118. package/scripts/mutants/acp-stream-hooks.json +158 -0
  119. package/scripts/mutants/bridge-boot-resume.json +45 -0
  120. package/scripts/mutants/meta-facts.json +50 -0
  121. package/scripts/mutants/meta-identity.json +36 -0
  122. package/scripts/mutants/mux-boundary.json +196 -0
  123. package/scripts/mutants/mux-fresh-call.json +185 -0
  124. package/scripts/mutants/mux-launcher-fence.json +123 -0
  125. package/scripts/mutants/mux-parent-artifact.json +39 -0
  126. package/scripts/mutants/mux-resume-call.json +148 -0
  127. package/scripts/mutants/probe-ordering.json +0 -1037
  128. package/scripts/mutants/release-gate.json +35 -0
  129. package/scripts/mutants/resume-args.json +76 -0
  130. package/scripts/mutants/resume-launch-identity.json +96 -0
  131. package/scripts/mutants/v2-surface.json +58 -18
  132. package/scripts/mutants/v2-visible-resume.json +215 -0
  133. package/scripts/new-session-id.ts +9 -4
  134. package/scripts/smoke-acp-raw-turn-live.ts +1 -1
  135. package/scripts/smoke-agy-native-push-live.ts +6 -17
  136. package/scripts/smoke-entwurf-v2-matrix-live.ts +1 -1
  137. package/scripts/smoke-meta-honesty.sh +1 -1
  138. package/scripts/smoke-mux-fresh-call-live.ts +365 -0
  139. package/scripts/smoke-mux-lifecycle-live.ts +1136 -0
  140. package/scripts/smoke-pi-attach.ts +1 -1
  141. package/scripts/smoke-user-scope-citizen.sh +1 -1
  142. package/scripts/tsconfig.json +1 -0
  143. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-preflight.js +0 -160
  144. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-spawn-production.js +0 -273
  145. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-spawn.js +0 -216
  146. package/pi-extensions/lib/entwurf-v2-spawn-production.ts +0 -373
  147. package/pi-extensions/lib/entwurf-v2-spawn.ts +0 -323
  148. package/scripts/check-acp-sdk-surface.ts +0 -275
  149. package/scripts/check-entwurf-v2-spawn-production.ts +0 -551
  150. package/scripts/check-entwurf-v2-spawn.ts +0 -399
  151. package/scripts/smoke-entwurf-v2-spawn-live.ts +0 -188
  152. package/scripts/smoke-entwurf-v2-spawn-resume-live.ts +0 -467
@@ -100,6 +100,41 @@
100
100
  "timeoutSeconds": 180,
101
101
  "signature": "[QK:NO-SILENT-AGGREGATE-OMISSION]",
102
102
  "signatureSource": "scripts/check-release-gate-outcomes.ts"
103
+ },
104
+ {
105
+ "claim": "QUALIFICATION-SCHEDULING-REACHABLE",
106
+ "title": "release_gate stops invoking check-gate-qualification — the discriminating-power step moved out of the default chain silently vanishes from the cut while VERIFY still promises it",
107
+ "subject": "run.sh",
108
+ "find": [" if (cd \"$REPO_DIR\" && bash \"$self\" check-gate-qualification); then"],
109
+ "replace": [" if (cd \"$REPO_DIR\" && true); then"],
110
+ "gate": ["bash", "run.sh", "check-release-gate-outcomes"],
111
+ "timeoutSeconds": 180,
112
+ "signature": "[QK:QUALIFICATION-SCHEDULING-REACHABLE]",
113
+ "signatureSource": "scripts/check-release-gate-outcomes.ts"
114
+ },
115
+ {
116
+ "claim": "CI-FULL-FLOOR-QUALIFIED",
117
+ "title": "the CI check job is downgraded from the full deterministic floor back to the ≤60s everyday core — the #70 tier rename regression, where qualification still runs once on every push but now certifies kill-power over a floor no candidate ships on, and the hermetic/package tiers reach machine time nowhere",
118
+ "subject": ".github/workflows/ci.yml",
119
+ "find": [" - run: pnpm run check:full"],
120
+ "replace": [" - run: pnpm check"],
121
+ "gate": ["bash", "run.sh", "check-release-gate-outcomes"],
122
+ "timeoutSeconds": 180,
123
+ "signature": "[QK:CI-FULL-FLOOR-QUALIFIED]",
124
+ "signatureSource": "scripts/check-release-gate-outcomes.ts"
125
+ },
126
+ {
127
+ "claim": "MUX-LIFECYCLE-IS-RELEASE-MUST",
128
+ "title": "the integrated mux lifecycle stays listed but bypasses run_live_step, so a missing prerequisite returns SKIP into a branch that never classifies it and the cut reads green",
129
+ "subject": "run.sh",
130
+ "find": [
131
+ " run_live_step \"smoke-mux-lifecycle-live (mux public-harness lifecycle: fresh -> send -> dormant -> same-id visible resume -> recall)\" gate bash \"$self\" smoke-mux-lifecycle-live"
132
+ ],
133
+ "replace": [" bash \"$self\" smoke-mux-lifecycle-live"],
134
+ "gate": ["bash", "run.sh", "check-release-gate-outcomes"],
135
+ "timeoutSeconds": 180,
136
+ "signature": "[QK:MUX-LIFECYCLE-IS-RELEASE-MUST]",
137
+ "signatureSource": "scripts/check-release-gate-outcomes.ts"
103
138
  }
104
139
  ]
105
140
  }
@@ -0,0 +1,76 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "lane": "resume-args",
4
+ "mutants": [
5
+ {
6
+ "claim": "RESUMEARGS-NO-HEADLESS",
7
+ "title": "the headless prefix comes back — the shape that puts a JSON stream in the operator's window instead of a session",
8
+ "subject": "pi-extensions/lib/entwurf-resume-args.ts",
9
+ "find": ["\tconst args: string[] = [\"--entwurf-control\"];"],
10
+ "replace": ["\tconst args: string[] = [\"--mode\", \"json\", \"-p\", \"--entwurf-control\"];"],
11
+ "gate": ["bash", "run.sh", "check-entwurf-resume-args"],
12
+ "timeoutSeconds": 60,
13
+ "signature": "[QK:RESUMEARGS-NO-HEADLESS]",
14
+ "signatureSource": "scripts/check-entwurf-resume-args.ts"
15
+ },
16
+ {
17
+ "claim": "RESUMEARGS-CONTROL-FIRST",
18
+ "title": "the control flag stops leading the argv, so the resumed session's socket posture depends on argv order",
19
+ "subject": "pi-extensions/lib/entwurf-resume-args.ts",
20
+ "find": ["\tconst args: string[] = [\"--entwurf-control\"];\n\targs.push(...input.explicitExtensionArgs);"],
21
+ "replace": [
22
+ "\tconst args: string[] = [];\n\targs.push(...input.explicitExtensionArgs);\n\targs.push(\"--entwurf-control\");"
23
+ ],
24
+ "gate": ["bash", "run.sh", "check-entwurf-resume-args"],
25
+ "timeoutSeconds": 60,
26
+ "signature": "[QK:RESUMEARGS-CONTROL-FIRST]",
27
+ "signatureSource": "scripts/check-entwurf-resume-args.ts"
28
+ },
29
+ {
30
+ "claim": "RESUMEARGS-EXT-ONCE-BEFORE-SESSION",
31
+ "title": "the bridge args are emitted twice — a different broken argv than dropping them, and just as invisible",
32
+ "subject": "pi-extensions/lib/entwurf-resume-args.ts",
33
+ "find": ["\targs.push(...input.explicitExtensionArgs);\n\targs.push(\"--session\", input.sessionFile);"],
34
+ "replace": [
35
+ "\targs.push(...input.explicitExtensionArgs);\n\targs.push(...input.explicitExtensionArgs);\n\targs.push(\"--session\", input.sessionFile);"
36
+ ],
37
+ "gate": ["bash", "run.sh", "check-entwurf-resume-args"],
38
+ "timeoutSeconds": 60,
39
+ "signature": "[QK:RESUMEARGS-EXT-ONCE-BEFORE-SESSION]",
40
+ "signatureSource": "scripts/check-entwurf-resume-args.ts"
41
+ },
42
+ {
43
+ "claim": "RESUMEARGS-SESSION-IS-FILE",
44
+ "title": "--session-id returns, which CREATES the id when missing and mints an empty session instead of resuming one",
45
+ "subject": "pi-extensions/lib/entwurf-resume-args.ts",
46
+ "find": ["\targs.push(\"--session\", input.sessionFile);"],
47
+ "replace": ["\targs.push(\"--session-id\", input.sessionFile);"],
48
+ "gate": ["bash", "run.sh", "check-entwurf-resume-args"],
49
+ "timeoutSeconds": 60,
50
+ "signature": "[QK:RESUMEARGS-SESSION-IS-FILE]",
51
+ "signatureSource": "scripts/check-entwurf-resume-args.ts"
52
+ },
53
+ {
54
+ "claim": "RESUMEARGS-PROVIDER-OPTIONAL",
55
+ "title": "an absent provider is emitted as an empty flag value instead of no flag",
56
+ "subject": "pi-extensions/lib/entwurf-resume-args.ts",
57
+ "find": ["\tif (input.provider) args.push(\"--provider\", input.provider);"],
58
+ "replace": ["\targs.push(\"--provider\", input.provider ?? \"\");"],
59
+ "gate": ["bash", "run.sh", "check-entwurf-resume-args"],
60
+ "timeoutSeconds": 60,
61
+ "signature": "[QK:RESUMEARGS-PROVIDER-OPTIONAL]",
62
+ "signatureSource": "scripts/check-entwurf-resume-args.ts"
63
+ },
64
+ {
65
+ "claim": "RESUMEARGS-NO-PROMPT-TAIL",
66
+ "title": "a positional rides after the model again — a resume that runs a turn instead of just reopening the window",
67
+ "subject": "pi-extensions/lib/entwurf-resume-args.ts",
68
+ "find": ["\targs.push(\"--model\", input.model);"],
69
+ "replace": ["\targs.push(\"--model\", input.model, \"continue\");"],
70
+ "gate": ["bash", "run.sh", "check-entwurf-resume-args"],
71
+ "timeoutSeconds": 60,
72
+ "signature": "[QK:RESUMEARGS-NO-PROMPT-TAIL]",
73
+ "signatureSource": "scripts/check-entwurf-resume-args.ts"
74
+ }
75
+ ]
76
+ }
@@ -0,0 +1,96 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "lane": "resume-launch-identity",
4
+ "mutants": [
5
+ {
6
+ "claim": "RESUME-ID-HEADER-INTEGRITY",
7
+ "title": "the C3 integrity check is dropped, so a stale or foreign transcriptPath resumes another being's session",
8
+ "subject": "pi-extensions/lib/resume-launch-identity.ts",
9
+ "find": [
10
+ "\tif (identity.sessionId !== record.nativeSessionId) {",
11
+ "\t\tthrow new Error(",
12
+ "\t\t\t`resume-launch-identity: ${gardenId} transcript header id \"${identity.sessionId ?? \"(none)\"}\" ` +",
13
+ "\t\t\t\t`does not match the record's nativeSessionId \"${record.nativeSessionId}\" — the recorded transcriptPath ` +",
14
+ "\t\t\t\t`is stale or points at a foreign session file; refusing to resume another being's transcript.`,",
15
+ "\t\t);",
16
+ "\t}"
17
+ ],
18
+ "replace": ["\t// integrity check removed"],
19
+ "gate": ["bash", "run.sh", "check-resume-launch-identity"],
20
+ "timeoutSeconds": 60,
21
+ "signature": "[QK:RESUME-ID-HEADER-INTEGRITY]",
22
+ "signatureSource": "scripts/check-resume-launch-identity.ts"
23
+ },
24
+ {
25
+ "claim": "RESUME-ID-ADDRESSABLE-READ",
26
+ "title": "the leaf is \"simplified\" back to the plain targeted read, so two records sharing one native session both resolve and resume one transcript under two locks (#52)",
27
+ "subject": "pi-extensions/lib/resume-launch-identity.ts",
28
+ "find": ["import { readAddressableMetaIdentity } from \"./meta-session.ts\";"],
29
+ "replace": ["import { readMetaIdentityByGardenId as readAddressableMetaIdentity } from \"./meta-session.ts\";"],
30
+ "gate": ["bash", "run.sh", "check-resume-launch-identity"],
31
+ "timeoutSeconds": 60,
32
+ "signature": "[QK:RESUME-ID-ADDRESSABLE-READ]",
33
+ "signatureSource": "scripts/check-resume-launch-identity.ts"
34
+ },
35
+ {
36
+ "claim": "RESUME-ID-MISSING-TRANSCRIPT-CAUSE",
37
+ "title": "the transcript existence guard is removed, so a deleted transcript falls through readSessionIdentity's ENOENT swallow and is reported as \"no recorded model\" (F7)",
38
+ "subject": "pi-extensions/lib/resume-launch-identity.ts",
39
+ "find": [
40
+ "\tif (!existsSync(sessionFile)) {",
41
+ "\t\tthrow new Error(",
42
+ "\t\t\t`resume-launch-identity: ${gardenId} recorded transcriptPath \"${sessionFile}\" ` +",
43
+ "\t\t\t\t`does not exist on disk — the transcript was deleted, or the record carries a phantom ` +",
44
+ "\t\t\t\t`path from a pre-guard birth; nothing to resume.`,",
45
+ "\t\t);",
46
+ "\t}"
47
+ ],
48
+ "replace": ["\t// existence guard removed"],
49
+ "gate": ["bash", "run.sh", "check-resume-launch-identity"],
50
+ "timeoutSeconds": 60,
51
+ "signature": "[QK:RESUME-ID-MISSING-TRANSCRIPT-CAUSE]",
52
+ "signatureSource": "scripts/check-resume-launch-identity.ts"
53
+ },
54
+ {
55
+ "claim": "RESUME-ID-GATE-SSOT",
56
+ "title": "the preserved leaf's header stops naming the gate that certifies it, so a consumer-zero identity module ships on prose again",
57
+ "subject": "pi-extensions/lib/resume-launch-identity.ts",
58
+ "find": [
59
+ " * So this leaf is preserved deliberately, with no consumer in the shipped tree today.",
60
+ " * `check-resume-launch-identity` holds its contract so the record-integrity rules below —"
61
+ ],
62
+ "replace": [
63
+ " * So this leaf is preserved deliberately for the later visible lane.",
64
+ " * The record-integrity rules below —"
65
+ ],
66
+ "gate": ["bash", "run.sh", "check-resume-launch-identity"],
67
+ "timeoutSeconds": 60,
68
+ "signature": "[QK:RESUME-ID-GATE-SSOT]",
69
+ "signatureSource": "scripts/check-resume-launch-identity.ts"
70
+ },
71
+ {
72
+ "claim": "RESUME-ID-BACKEND-TYPED-REFUSAL",
73
+ "title": "the backend miss degrades to a bare Error, so callers must parse a sentence or read the record twice to learn it was a capability boundary",
74
+ "subject": "pi-extensions/lib/resume-launch-identity.ts",
75
+ "find": ["\t\tthrow new ResumeBackendUnsupportedError(gardenId, record.backend);"],
76
+ "replace": [
77
+ "\t\tthrow new Error(`resume-launch-identity: ${gardenId} is a ${record.backend} citizen — resume is pi-only.`);"
78
+ ],
79
+ "gate": ["bash", "run.sh", "check-resume-launch-identity"],
80
+ "timeoutSeconds": 60,
81
+ "signature": "[QK:RESUME-ID-BACKEND-TYPED-REFUSAL]",
82
+ "signatureSource": "scripts/check-resume-launch-identity.ts"
83
+ },
84
+ {
85
+ "claim": "RESUME-ID-SESSION-ABSOLUTE",
86
+ "title": "a relative recorded transcriptPath is accepted, so --session resolves inside the window's own cwd and a different transcript is reopened under a correct-looking receipt",
87
+ "subject": "pi-extensions/lib/resume-launch-identity.ts",
88
+ "find": ["\tif (!path.isAbsolute(sessionFile)) {"],
89
+ "replace": ["\tif (path.isAbsolute(sessionFile) && false) {"],
90
+ "gate": ["bash", "run.sh", "check-resume-launch-identity"],
91
+ "timeoutSeconds": 60,
92
+ "signature": "[QK:RESUME-ID-SESSION-ABSOLUTE]",
93
+ "signatureSource": "scripts/check-resume-launch-identity.ts"
94
+ }
95
+ ]
96
+ }
@@ -7,14 +7,10 @@
7
7
  "title": "MCP long description reverts to the false \"socket paths take a per-target lock\" claim",
8
8
  "subject": "mcp/entwurf-bridge/src/index.ts",
9
9
  "find": [
10
- "\t\t\"native-push-no-resume-authority. LOCK: taken for a control-socket-DOMAIN dispatch the live send AND \" +",
11
- "\t\t\"the dormant cell's spawn-bg resume, a separate transport that still runs under that domain's lock. The \" +",
10
+ "\t\t\"LOCK: taken for a control-socket-DOMAIN dispatch. The \" +",
12
11
  "\t\t\"mailbox and native-push rails are lock-free — deliverability and the adapter probe guard them. mode \" +"
13
12
  ],
14
- "replace": [
15
- "\t\t\"native-push-no-resume-authority. LOCK POLICY: socket paths take a per-target lock; the mailbox path \" +",
16
- "\t\t\"does not. mode \" +"
17
- ],
13
+ "replace": ["\t\t\"LOCK POLICY: socket paths take a per-target lock; the mailbox path does not. mode \" +"],
18
14
  "gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
19
15
  "timeoutSeconds": 60,
20
16
  "signature": "[QK:V2SURF-MCP-LOCK-DOMAIN]",
@@ -25,12 +21,10 @@
25
21
  "title": "pi-native mode param reverts to \"Delivery mode for a live send\" (false for native-push)",
26
22
  "subject": "pi-extensions/entwurf-control.ts",
27
23
  "find": [
28
- "\t\t\t\tdescription:",
29
24
  "\t\t\t\t\t\"Injection style for a CONTROL-SOCKET send only: steer (immediate) or follow_up (after task). \" +",
30
- "\t\t\t\t\t\"The mailbox, native-push, and spawn-bg plans carry no mode, so it has no effect on those rails.\","
25
+ "\t\t\t\t\t\"The mailbox and native-push plans carry no mode, so it has no effect on those rails.\","
31
26
  ],
32
27
  "replace": [
33
- "\t\t\t\tdescription:",
34
28
  "\t\t\t\t\t\"Delivery mode for a live send: steer (immediate, interrupt the current turn) or follow_up \" +",
35
29
  "\t\t\t\t\t\"(queued after the current task finishes running to completion).\","
36
30
  ],
@@ -61,22 +55,68 @@
61
55
  "signatureSource": "scripts/check-entwurf-v2-surface.ts"
62
56
  },
63
57
  {
64
- "claim": "V2SURF-MERGED-REJECT",
65
- "title": "MCP long description merges the two owned rejects back under backend-liveness-unsupported",
58
+ "claim": "V2SURF-DORMANT-HONESTY",
59
+ "title": "MCP long description advertises owned-outcome as a selectable dormant verb again and drops the reason a dormant target actually returns",
66
60
  "subject": "mcp/entwurf-bridge/src/index.ts",
67
61
  "find": [
68
- "\t\t\"owned-outcome wakes a DORMANT socket-domain citizen by spawn-bg resume ONLY live target → \" +",
69
- "\t\t\"owned-live-no-autosend, self-fetch backend-liveness-unsupported, native-push \" +",
70
- "\t\t\"native-push-no-resume-authority. LOCK: taken for a control-socket-DOMAIN dispatch the live send AND \" +"
62
+ "\t\t\"DORMANT IS UNREACHABLE: a socket-domain citizen that is not running gets dormant-fire-forget-unsupported \" +",
63
+ "\t\t\" same receiver rule as the mailbox, no active drainer means no delivery. \" +",
64
+ "\t\t\"The intent that used to answer there, owned-outcome, resumed it by launching a hidden background child \" +",
65
+ "\t\t\"and was withdrawn under the visible-first rule — re-open the session yourself, then dispatch again. \" +"
71
66
  ],
72
67
  "replace": [
73
- "\t\t\"owned-outcome wakes a DORMANT socket-domain citizen by spawn-bg resume ONLY live target \" +",
74
- "\t\t\"owned-live-no-autosend, and on self-fetch and native-push alike it is rejected as \" +",
75
- "\t\t\"backend-liveness-unsupported. LOCK: taken for a control-socket-DOMAIN dispatch — the live send AND \" +"
68
+ "\t\t\"owned-outcome wakes a DORMANT socket-domain citizen by spawn-bg resume ONLY and is never auto-converted. \" +"
69
+ ],
70
+ "gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
71
+ "timeoutSeconds": 60,
72
+ "signature": "[QK:V2SURF-DORMANT-HONESTY]",
73
+ "signatureSource": "scripts/check-entwurf-v2-surface.ts"
74
+ },
75
+ {
76
+ "claim": "V2SURF-INDETERMINATE-NO-START",
77
+ "title": "the indeterminate hint reverts to a socket that \"answered\" and drops the no-start facts — overclaiming a reply that a permission-refused or timed-out probe never got",
78
+ "subject": "pi-extensions/lib/entwurf-v2-surface.ts",
79
+ "find": [
80
+ "\t\tcase \"indeterminate-no-spawn\":",
81
+ "\t\t\t// The socket probe did not settle, so liveness is UNKNOWN — an unestablished probe",
82
+ "\t\t\t// is not a measured death, and dispatching into it could double-deliver. Say",
83
+ "\t\t\t// \"the PROBE was inconclusive\", never \"the socket answered inconclusively\":",
84
+ "\t\t\t// `indeterminate` also covers a probe that got no answer at all, was refused by",
85
+ "\t\t\t// permissions, or timed out, and \"answered\" claims a reply that may never have",
86
+ "\t\t\t// existed. The wire id is FROZEN and still spells \"-no-spawn\"; it names the rule",
87
+ "\t\t\t// (never dispatch into an indeterminate target), not a capability that still",
88
+ "\t\t\t// exists. So the hint's job is to say plainly what did NOT happen: nothing",
89
+ "\t\t\t// delivered, nothing started.",
90
+ "\t\t\treturn (",
91
+ "\t\t\t\t\"the control-socket probe was inconclusive, so the target's liveness is UNKNOWN — this is not a \" +",
92
+ "\t\t\t\t\"measured death. NOTHING was delivered and NO process was started (the reason id keeps its frozen \" +",
93
+ "\t\t\t\t\"'-no-spawn' wire spelling from an era when one could be; entwurf_v2 starts nothing on any rail). \" +",
94
+ "\t\t\t\t\"Re-run entwurf_peers to re-probe; if it stays indeterminate, check for a stale socket file left at \" +",
95
+ "\t\t\t\t\"that garden id by a session that died without cleaning up.\"",
96
+ "\t\t\t);"
97
+ ],
98
+ "replace": [
99
+ "\t\tcase \"indeterminate-no-spawn\":",
100
+ "\t\t\treturn \"the target's control socket answered inconclusively; retry.\";"
101
+ ],
102
+ "gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
103
+ "timeoutSeconds": 60,
104
+ "signature": "[QK:V2SURF-INDETERMINATE-NO-START]",
105
+ "signatureSource": "scripts/check-entwurf-v2-surface.ts"
106
+ },
107
+ {
108
+ "claim": "V2SURF-PEERS-DEAD-ROW",
109
+ "title": "entwurf_peers drops the dead-row sentence, so a dormant citizen is listed with nothing saying it is unreachable",
110
+ "subject": "mcp/entwurf-bridge/src/index.ts",
111
+ "find": [
112
+ "\t\t\"row. A `dead` row is a REPORTED FACT and nothing more: that citizen is dormant and is \" +",
113
+ "\t\t\"currently unreachable by any verb, so listing it grants no action — appearing here is not \" +",
114
+ "\t\t\"an invitation to dispatch. In particular `unsupported` does NOT mean mailbox: it means this backend has no \" +"
76
115
  ],
116
+ "replace": ["\t\t\"row. In particular `unsupported` does NOT mean mailbox: it means this backend has no \" +"],
77
117
  "gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
78
118
  "timeoutSeconds": 60,
79
- "signature": "[QK:V2SURF-MERGED-REJECT]",
119
+ "signature": "[QK:V2SURF-PEERS-DEAD-ROW]",
80
120
  "signatureSource": "scripts/check-entwurf-v2-surface.ts"
81
121
  },
82
122
  {
@@ -0,0 +1,215 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "lane": "v2-visible-resume",
4
+ "mutants": [
5
+ {
6
+ "claim": "V2RESUME-LIVE-REFUSED",
7
+ "title": "the live check inverts, so a running citizen gets a second window on its own transcript",
8
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
9
+ "find": ["\t\tif (mapped.liveness === \"alive\") {"],
10
+ "replace": ["\t\tif (mapped.liveness === \"dead\") {"],
11
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
12
+ "timeoutSeconds": 60,
13
+ "signature": "[QK:V2RESUME-LIVE-REFUSED]",
14
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
15
+ },
16
+ {
17
+ "claim": "V2RESUME-INDETERMINATE-NO-START",
18
+ "title": "an inconclusive probe stops being a refusal, so a citizen that may be running is resumed anyway",
19
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
20
+ "find": ["\t\tif (mapped.liveness === \"indeterminate\") {"],
21
+ "replace": ["\t\tif (mapped.liveness === \"alive\") {"],
22
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
23
+ "timeoutSeconds": 60,
24
+ "signature": "[QK:V2RESUME-INDETERMINATE-NO-START]",
25
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
26
+ },
27
+ {
28
+ "claim": "V2RESUME-CONFLICT-NO-START",
29
+ "title": "a corrupt control-socket address stops being a refusal and a citizen is stood up behind it",
30
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
31
+ "find": ["\t\tif (\"addressConflict\" in mapped) {"],
32
+ "replace": ["\t\tif (\"addressConflictNever\" in mapped) {"],
33
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
34
+ "timeoutSeconds": 60,
35
+ "signature": "[QK:V2RESUME-CONFLICT-NO-START]",
36
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
37
+ },
38
+ {
39
+ "claim": "V2RESUME-LOCKED-NO-RESOLVE",
40
+ "title": "a lock conflict is read as success, so the record is opened behind another holder's lock",
41
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
42
+ "find": ["\tif (!acquired.ok) {"],
43
+ "replace": ["\tif (!acquired.ok && acquired.conflict.reason !== \"target-locked\") {"],
44
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
45
+ "timeoutSeconds": 60,
46
+ "signature": "[QK:V2RESUME-LOCKED-NO-RESOLVE]",
47
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
48
+ },
49
+ {
50
+ "claim": "V2RESUME-NO-TRANSCRIPT-FAILS-LOUD",
51
+ "title": "the leaf's cause-rich throw is swallowed into a placeholder identity, so an unresumable citizen opens a window anyway",
52
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
53
+ "find": [
54
+ "\t\tlet identity: LaunchIdentity;",
55
+ "\t\ttry {",
56
+ "\t\t\tidentity = deps.resolveIdentity(targetGardenId);",
57
+ "\t\t} catch (err) {"
58
+ ],
59
+ "replace": [
60
+ "\t\tlet identity: LaunchIdentity;",
61
+ "\t\ttry {",
62
+ "\t\t\tidentity = deps.resolveIdentity(targetGardenId);",
63
+ "\t\t} catch (err) {",
64
+ "\t\t\tif (!(err instanceof ResumeBackendUnsupportedError))",
65
+ "\t\t\t\treturn { ok: false, reason: \"target-invalid\", detail: String(err) };"
66
+ ],
67
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
68
+ "timeoutSeconds": 60,
69
+ "signature": "[QK:V2RESUME-NO-TRANSCRIPT-FAILS-LOUD]",
70
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
71
+ },
72
+ {
73
+ "claim": "V2RESUME-OBSERVE-IS-BOUNDED-WAIT",
74
+ "title": "the observation becomes a single immediate probe, which reports every real resume as unobserved (the socket answers ~2-4s later)",
75
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
76
+ "find": ["\t\tawait deps.sleep(intervalMs);"],
77
+ "replace": ["\t\treturn { kind: \"resume-unobserved\", socketPath, waitedMs: deps.now() - started };"],
78
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
79
+ "timeoutSeconds": 60,
80
+ "signature": "[QK:V2RESUME-OBSERVE-IS-BOUNDED-WAIT]",
81
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
82
+ },
83
+ {
84
+ "claim": "V2RESUME-UNOBSERVED-IS-REAL",
85
+ "title": "a timeout claims the socket answered, turning the one fact that says the citizen is back into a guess",
86
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
87
+ "find": ["\t\t\treturn { kind: \"resume-unobserved\", socketPath, waitedMs: deps.now() - started };"],
88
+ "replace": ["\t\t\treturn { kind: \"socket-alive\", socketPath, waitedMs: deps.now() - started };"],
89
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
90
+ "timeoutSeconds": 60,
91
+ "signature": "[QK:V2RESUME-UNOBSERVED-IS-REAL]",
92
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
93
+ },
94
+ {
95
+ "claim": "V2RESUME-RELEASE-FAILURE-LOUD",
96
+ "title": "a release that did not release is folded into a green receipt, leaving a held lock nobody is told about",
97
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
98
+ "find": ["\t\tif (outcome !== \"released\") {"],
99
+ "replace": ["\t\tif (outcome !== \"released\" && outcome !== \"not-owned\" && outcome !== \"absent\") {"],
100
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
101
+ "timeoutSeconds": 60,
102
+ "signature": "[QK:V2RESUME-RELEASE-FAILURE-LOUD]",
103
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
104
+ },
105
+ {
106
+ "claim": "V2RESUME-ARGV-FROM-RECORD",
107
+ "title": "the launcher is handed the caller's own directory instead of the record's, so the citizen returns in the wrong project",
108
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
109
+ "find": ["\t\tconst launched = deps.launch({ cwd: identity.cwd, runtimeArgs });"],
110
+ "replace": ["\t\tconst launched = deps.launch({ cwd: process.cwd(), runtimeArgs });"],
111
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
112
+ "timeoutSeconds": 60,
113
+ "signature": "[QK:V2RESUME-ARGV-FROM-RECORD]",
114
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
115
+ },
116
+ {
117
+ "claim": "V2RESUME-RECEIPTS-SEPARATE",
118
+ "title": "the launch receipt absorbs the observation, so 'a window opened' and 'the citizen is back' become one claim",
119
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
120
+ "find": ["\t\t\tlaunch: { targetGardenId, sessionFile: identity.sessionFile, handle: launched.handle },"],
121
+ "replace": [
122
+ "\t\t\tlaunch: { targetGardenId, sessionFile: identity.sessionFile, handle: launched.handle, kind: observation.kind } as ResumeLaunchReceipt,"
123
+ ],
124
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
125
+ "timeoutSeconds": 60,
126
+ "signature": "[QK:V2RESUME-RECEIPTS-SEPARATE]",
127
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
128
+ },
129
+ {
130
+ "claim": "V2RESUME-RENDER-SEPARATES",
131
+ "title": "the rendered text merges the two receipts into one sentence, so a reader cannot tell which fact is missing",
132
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
133
+ "find": [
134
+ "\t\t\t`LAUNCH receipt: tmux created that window and was asked to start pi on the transcript above.\\n` +"
135
+ ],
136
+ "replace": ["\t\t\t`Resume complete.\\n` +"],
137
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
138
+ "timeoutSeconds": 60,
139
+ "signature": "[QK:V2RESUME-RENDER-SEPARATES]",
140
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
141
+ },
142
+ {
143
+ "claim": "V2RESUME-IDENTITY-BEFORE-WINDOW",
144
+ "title": "the liveness preflight runs BEFORE the record is read, so dormancy is judged for a citizen whose transcript has not been proven resumable yet",
145
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
146
+ "find": ["\t\tlet identity: LaunchIdentity;"],
147
+ "replace": ["\t\tawait deps.inspectSocket(targetGardenId);", "\t\tlet identity: LaunchIdentity;"],
148
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
149
+ "timeoutSeconds": 60,
150
+ "signature": "[QK:V2RESUME-IDENTITY-BEFORE-WINDOW]",
151
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
152
+ },
153
+ {
154
+ "claim": "V2RESUME-TIMEOUT-RELEASES",
155
+ "title": "the timeout path launches a second time — the relaunch this rail refuses, hidden inside what reads as one bounded wait",
156
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
157
+ "find": ["\t\t\treturn { kind: \"resume-unobserved\", socketPath, waitedMs: deps.now() - started };"],
158
+ "replace": [
159
+ "\t\t\t(deps as VisibleResumeDeps).launch({ cwd: \"/tmp\", runtimeArgs: [] });\n\t\t\treturn { kind: \"resume-unobserved\", socketPath, waitedMs: deps.now() - started };"
160
+ ],
161
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
162
+ "timeoutSeconds": 60,
163
+ "signature": "[QK:V2RESUME-TIMEOUT-RELEASES]",
164
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
165
+ },
166
+ {
167
+ "claim": "V2RESUME-LOCK-BEFORE-LIVENESS",
168
+ "title": "the lock stops being taken first, so a competing resume can pass its own dead check while this one is launching",
169
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
170
+ "find": ["\tconst acquired = deps.acquireLock(targetGardenId);"],
171
+ "replace": ["\tawait deps.inspectSocket(targetGardenId);\n\tconst acquired = deps.acquireLock(targetGardenId);"],
172
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
173
+ "timeoutSeconds": 60,
174
+ "signature": "[QK:V2RESUME-LOCK-BEFORE-LIVENESS]",
175
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
176
+ },
177
+ {
178
+ "claim": "V2RESUME-NOT-PI-REFUSED",
179
+ "title": "an out-of-domain backend is reported as an error instead of a named refusal, so a fine record reads as a broken one",
180
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
181
+ "find": ["\t\t\tif (err instanceof ResumeBackendUnsupportedError) {"],
182
+ "replace": ["\t\t\tif (false && err instanceof ResumeBackendUnsupportedError) {"],
183
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
184
+ "timeoutSeconds": 60,
185
+ "signature": "[QK:V2RESUME-NOT-PI-REFUSED]",
186
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
187
+ },
188
+ {
189
+ "claim": "V2RESUME-NOT-PI-BY-FIELD",
190
+ "title": "the backend is re-derived instead of taken from the typed error, which is the second read this rail refuses",
191
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
192
+ "find": [
193
+ "\t\t\t\t\t\t`${targetGardenId} is a ${err.backend} citizen; only pi citizens stand a control socket up, ` +"
194
+ ],
195
+ "replace": [
196
+ "\t\t\t\t\t\t`${targetGardenId} is a citizen of another backend; only pi citizens stand a control socket up, ` +"
197
+ ],
198
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
199
+ "timeoutSeconds": 60,
200
+ "signature": "[QK:V2RESUME-NOT-PI-BY-FIELD]",
201
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
202
+ },
203
+ {
204
+ "claim": "V2RESUME-SHARED-ID-GRAMMAR",
205
+ "title": "the address grammar is re-implemented locally, where it can drift from the record, the lock path and the socket filename it becomes",
206
+ "subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
207
+ "find": ["\tif (!isValidSessionId(targetGardenId)) {"],
208
+ "replace": ["\tif (!/^\\d{8}T\\d{6}-[0-9a-f]{6}$/.test(targetGardenId)) {"],
209
+ "gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
210
+ "timeoutSeconds": 60,
211
+ "signature": "[QK:V2RESUME-SHARED-ID-GRAMMAR]",
212
+ "signatureSource": "scripts/check-entwurf-v2-visible-resume.ts"
213
+ }
214
+ ]
215
+ }
@@ -1,11 +1,16 @@
1
1
  /**
2
2
  * new-session-id — print one fresh garden-native sessionId and exit.
3
3
  *
4
- * The garden launcher (operator alias / wrapper) calls this so every
5
- * `--entwurf-control` session is born a garden citizen:
4
+ * NOT a launcher contract. #50 C2 retired the injection form
5
+ * (`pi --session-id "$(./run.sh new-session-id)" --entwurf-control …`): pi mints its
6
+ * own session id (a `uuidv7` is normal), `session_start` attaches that session to its
7
+ * meta-record, and the RECORD mints the garden id and keys the control socket on it.
8
+ * Injecting a garden-shaped id gives a session two address-shaped strings of which only
9
+ * one is an address. Launch is plain `pi --entwurf-control` (README §Garden launcher).
6
10
  *
7
- * pi --session-id "$(./run.sh new-session-id)" --entwurf-control \
8
- * --emacs-agent-socket server
11
+ * What survives is this: the operator-facing generator for the same id grammar the
12
+ * record layer itself uses — one fresh id on stdout, for a caller that needs to mint a
13
+ * token deliberately, never as a launch argument.
9
14
  *
10
15
  * The id is `generateSessionId()` from entwurf-core — the single SSOT for the
11
16
  * locked `YYYYMMDDTHHMMSS-[0-9a-f]{6}` grammar. Do NOT reimplement the format in
@@ -3,7 +3,7 @@
3
3
  // LIVE=1 ./run.sh smoke-acp-raw-turn-live
4
4
  //
5
5
  // What this proves (and ONLY this): the pinned Claude ACP adapter
6
- // (@agentclientprotocol/claude-agent-acp@0.64.0) spawns, speaks the ACP wire
6
+ // (@agentclientprotocol/claude-agent-acp@0.66.0) spawns, speaks the ACP wire
7
7
  // protocol over stdio NDJSON, and returns one real model turn. It is the
8
8
  // bytes-flow proof that the S2a dep surface is not just installable but
9
9
  // actually drivable — before any provider/overlay/streamSimple code (S2b+).
@@ -4,11 +4,11 @@
4
4
  * adapter (pgrep/ss/`agentapi get-conversation-metadata`+`send-message`), the register core,
5
5
  * and `runEntwurfV2` with production deps — against a REAL, already-running agy conversation,
6
6
  * and asserts the rail end to end: probe finds the volatile route, register create/re-attach is
7
- * idempotent, a fire-and-forget dispatches over native-push (delivered), an owned-outcome is
8
- * rejected (no resume authority), and a bogus conversation is rejected (probe-indeterminate).
7
+ * idempotent, a fire-and-forget dispatches over native-push (delivered), and a bogus conversation
8
+ * is rejected (probe-indeterminate).
9
9
  *
10
10
  * This automates what the GPT manual L1~L5 pass proved by hand (register create/attach, v2
11
- * native-push delivered ×2, owned reject, mailbox/marker/pi-domain non-intrusion) — same
11
+ * native-push delivered ×2, mailbox/marker/pi-domain non-intrusion) — same
12
12
  * production MCP surface, now a repeatable gate.
13
13
  *
14
14
  * STORE ISOLATION (페블-approved): only the agy CONVERSATION round-trip is real (that is the
@@ -189,20 +189,9 @@ async function main(): Promise<void> {
189
189
  const post = await antigravityAdapter.probe(conversationId);
190
190
  ok("post-send re-probe still alive (delivery target reachable, D7 partial)", post.status === "alive");
191
191
 
192
- // ── 5. owned-outcome rejected: a native-push backend has no resume authority ──
193
- const owned: EntwurfV2RunResult = await runEntwurfV2(
194
- { target: reg1.gardenId, intent: "owned-outcome", message: "should be rejected" },
195
- prodDeps,
196
- );
197
- ok(
198
- "owned-outcome rejected as native-push-no-resume-authority",
199
- owned.kind === "rejected" && owned.receipt.reason === "native-push-no-resume-authority",
200
- );
201
- ok(
202
- "owned reject stamped observedLiveness (post-probe, non-null)",
203
- owned.kind === "rejected" && owned.receipt.observedLiveness !== null,
204
- );
205
-
192
+ // ── 5. (retired) the owned-outcome × native-push refusal cell. The intent was removed
193
+ // from the contract in the visible-first cut, so there is no longer a call to make here:
194
+ // a caller cannot declare it, and the reason it produced left the taxonomy with it. ──
206
195
  // ── 6. bogus conversation → rejected native-push-probe-indeterminate ──
207
196
  // agy is alive but no LS port serves this fabricated conv id → INDETERMINATE (never coerced
208
197
  // to dead). A meta-record is upserted DIRECTLY (register would refuse a non-live probe), so
@@ -260,7 +260,7 @@ async function main(): Promise<void> {
260
260
  const up = await waitForSocket(sockPath, BOOT_TIMEOUT_MS);
261
261
  ok("C1b real record-less `pi --entwurf-control` stood up a control socket", up);
262
262
 
263
- for (const intent of ["fire-and-forget", "owned-outcome"] as const) {
263
+ for (const intent of ["fire-and-forget"] as const) {
264
264
  const result: EntwurfV2RunResult = await runEntwurfV2(
265
265
  { target: c1bGid, intent, message: `matrix-live C1b record-less probe (${intent})` },
266
266
  prodDeps(smokeSender(c1bGid, tmp)),
@@ -17,7 +17,7 @@
17
17
  # alarm), and must log sender-marker evidence so send-side replyable identity
18
18
  # is not silently lost.
19
19
  #
20
- # Deterministic + offline (no `claude -p`, no network). Safe for pnpm check /
20
+ # Deterministic + offline (no `claude -p`, no network). Safe for pnpm run check:full /
21
21
  # pre-commit. Isolates its store via PI_CODING_AGENT_DIR in a temp dir.
22
22
  #
23
23
  # RUNTIME DEPS: bash + node (the hook runs under `node --experimental-strip-types`)