@junghanacs/entwurf 0.45.0 → 0.51.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 +5 -3
- package/BASELINE.md +110 -1
- package/CHANGELOG.md +249 -0
- package/CONTRIBUTING.md +1 -1
- package/ENTWURF-CLI.json +1229 -0
- package/ENTWURF.json +63 -15
- package/FAQ.md +4 -4
- package/README.md +132 -188
- package/VERIFY.md +18 -11
- package/demo/README.md +1 -1
- package/docs/acp-backend-rail.md +1 -1
- package/docs/external-mcp-host.md +4 -4
- package/docs/setup-clean-host.md +94 -22
- package/mcp/entwurf-bridge/dist/ENTWURF.json +63 -15
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +19 -8
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +4 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-visible-resume.js +483 -18
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-dispatch.js +47 -10
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-fresh-call.js +613 -33
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-resume-call.js +497 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +3 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-resume-call.js +50 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-fresh-preflight.js +7 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-location.js +347 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-owner-fence.js +1132 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-runtime.js +1 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/resume-launch-identity.js +18 -11
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-pi-durable.js +30 -15
- package/mcp/entwurf-bridge/dist/scripts/herdr-rails.mjs +40 -7
- package/mcp/entwurf-bridge/dist/scripts/meta-bridge-fresh-cut.js +1 -27
- package/mcp/entwurf-bridge/dist/scripts/meta-bridge-prune.js +1 -1
- package/mcp/entwurf-bridge/dist/scripts/meta-facts.js +1 -1
- package/mcp/entwurf-bridge/dist/scripts/peer-facts.js +1 -1
- package/mcp/entwurf-bridge/src/index.ts +28 -8
- package/mcp/entwurf-bridge/tsconfig.build.json +7 -1
- package/native/win32-x64/manifest.json +1 -1
- package/package.json +16 -20
- package/pi/pi-durable/bootstrap.mjs +179 -6
- package/pi/pi-durable/carrier/runtime.js +327 -57
- package/pi/pi-durable/carrier/session-name.js +11 -0
- package/pi/pi-durable/carrier/sessions.js +96 -20
- package/pi/pi-durable/carrier/subagent.js +5 -2
- package/pi/pi-durable/carrier/tui.js +60 -22
- package/pi/pi-durable/overlay/upstream-pin.json +26 -19
- package/pi-extensions/lib/entwurf-v2-contract-schema.ts +73 -69
- package/pi-extensions/lib/entwurf-v2-contract.ts +4 -4
- package/pi-extensions/lib/entwurf-v2-visible-resume.ts +710 -38
- package/pi-extensions/lib/fresh-call-dispatch.ts +64 -12
- package/pi-extensions/lib/herdr-fresh-call.ts +919 -40
- package/pi-extensions/lib/herdr-resume-call.ts +810 -0
- package/pi-extensions/lib/meta-session.ts +13 -8
- package/pi-extensions/lib/mux-resume-call.ts +77 -4
- package/pi-extensions/lib/pi-durable-fresh-preflight.ts +9 -2
- package/pi-extensions/lib/pi-durable-location.ts +446 -0
- package/pi-extensions/lib/pi-durable-owner-fence.ts +1461 -0
- package/pi-extensions/lib/pi-durable-runtime.ts +4 -0
- package/pi-extensions/lib/resume-launch-identity.ts +31 -12
- package/pi-extensions/meta-bridge-pi-durable.ts +30 -16
- package/run.sh +552 -699
- package/scripts/check-claude-launch.ts +341 -0
- package/scripts/check-entwurf-v2-contract.ts +4 -4
- package/scripts/check-entwurf-v2-surface.ts +2 -2
- package/scripts/check-fresh-call-dispatch.ts +70 -9
- package/scripts/check-fresh-cut-gate.sh +23 -9
- package/scripts/check-gate-qualification.ts +19 -14
- package/scripts/check-herdr-activation.ts +301 -23
- package/scripts/check-herdr-fresh-call.ts +161 -25
- package/scripts/check-herdr-plugin-build.ts +173 -1
- package/scripts/check-herdr-plugin.ts +28 -2
- package/scripts/check-herdr-runtime-bootstrap.ts +136 -0
- package/scripts/check-install-surface.ts +1236 -6
- package/scripts/check-meta-doctor-oracle.sh +1 -1
- package/scripts/check-meta-facts.ts +20 -1
- package/scripts/check-mux-resume-call.ts +28 -0
- package/scripts/check-peer-facts.ts +39 -2
- package/scripts/cli-help.mjs +222 -0
- package/scripts/dev-bin.sh +39 -2
- package/scripts/herdr-activation.mjs +28 -6
- package/scripts/herdr-operator-link.mjs +389 -0
- package/scripts/herdr-plugin-activate.mjs +5 -0
- package/scripts/herdr-plugin-deactivate.mjs +18 -5
- package/scripts/herdr-rails.mjs +43 -7
- package/scripts/herdr-runtime.mjs +27 -0
- package/scripts/meta-bridge-fresh-cut.ts +1 -27
- package/scripts/meta-bridge-prune.ts +1 -1
- package/scripts/meta-facts.ts +1 -1
- package/scripts/mutants/agent-guidance.json +4 -4
- package/scripts/mutants/claude-launch.json +142 -0
- package/scripts/mutants/cli-help-source.json +420 -0
- package/scripts/mutants/control-send-receipt.json +1 -1
- package/scripts/mutants/dev-gate-dispatch.json +109 -0
- package/scripts/mutants/fresh-call-dispatch.json +38 -2
- package/scripts/mutants/fresh-cut.json +15 -0
- package/scripts/mutants/herdr-activation.json +128 -0
- package/scripts/mutants/herdr-fresh-call.json +278 -5
- package/scripts/mutants/herdr-operator-link.json +318 -0
- package/scripts/mutants/herdr-plugin-build.json +55 -0
- package/scripts/mutants/herdr-plugin.json +17 -0
- package/scripts/mutants/herdr-resume-call.json +288 -0
- package/scripts/mutants/herdr-runtime-bootstrap.json +48 -0
- package/scripts/mutants/meta-facts.json +15 -0
- package/scripts/mutants/mux-resume-call.json +63 -2
- package/scripts/mutants/pack-install.json +4 -4
- package/scripts/mutants/peer-facts.json +15 -0
- package/scripts/mutants/pi-durable.json +1167 -3
- package/scripts/mutants/pi-floor.json +22 -5
- package/scripts/mutants/source-install.json +35 -0
- package/scripts/mutants/v2-surface.json +2 -2
- package/scripts/mutants/v2-visible-resume.json +255 -6
- package/scripts/peer-facts.ts +1 -1
- package/scripts/smoke-agy-install-state.sh +66 -0
- package/scripts/smoke-meta-prune.sh +23 -0
- package/scripts/smoke-omp-fresh-live.ts +12 -3
- package/scripts/smoke-omp-receive-live.ts +7 -1
- package/scripts/smoke-pi-durable-fresh-live.ts +12 -2
- package/team.json.example +39 -0
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
"title": "one row of the pnpm workspace closure is left on the previous floor while every other surface moved — the shape a version bump actually fails in. Nothing else reads that file, so the stranded row surfaces only at install time, in a different command, far from the change that stranded it",
|
|
8
8
|
"subject": "pnpm-workspace.yaml",
|
|
9
9
|
"find": [
|
|
10
|
-
" - '@earendil-works/pi-telemetry@0.85.0 || 0.85.1 || 0.86.0 || 0.87.0 || 0.87.1 || 0.99.1 || 0.99.2 || 1.0.0 || 1.0.2 || 1.0.4 || 1.1.0 || 1.2.0 || 1.3.0 || 1.4.0'"
|
|
10
|
+
" - '@earendil-works/pi-telemetry@0.85.0 || 0.85.1 || 0.86.0 || 0.87.0 || 0.87.1 || 0.99.1 || 0.99.2 || 1.0.0 || 1.0.2 || 1.0.4 || 1.1.0 || 1.2.0 || 1.3.0 || 1.4.0 || 1.5.0'"
|
|
11
11
|
],
|
|
12
12
|
"replace": [
|
|
13
|
-
" - '@earendil-works/pi-telemetry@0.85.0 || 0.85.1 || 0.86.0 || 0.87.0 || 0.87.1 || 0.99.1 || 0.99.2 || 1.0.0 || 1.0.2 || 1.0.4 || 1.1.0 || 1.2.0 || 1.3.0'"
|
|
13
|
+
" - '@earendil-works/pi-telemetry@0.85.0 || 0.85.1 || 0.86.0 || 0.87.0 || 0.87.1 || 0.99.1 || 0.99.2 || 1.0.0 || 1.0.2 || 1.0.4 || 1.1.0 || 1.2.0 || 1.3.0 || 1.4.0'"
|
|
14
14
|
],
|
|
15
15
|
"gate": ["bash", "run.sh", "check-dep-versions"],
|
|
16
16
|
"timeoutSeconds": 300,
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"claim": "PI-SDK-PRODUCTION-SET",
|
|
22
22
|
"title": "the durable library's production pin falls one release behind the SDK set the pin declares, so the carrier would bind a pi-durable nobody verified it against",
|
|
23
23
|
"subject": "package.json",
|
|
24
|
-
"find": ["\"@earendil-works/pi-durable\": \"1.
|
|
25
|
-
"replace": ["\"@earendil-works/pi-durable\": \"1.
|
|
24
|
+
"find": ["\"@earendil-works/pi-durable\": \"1.5.0\","],
|
|
25
|
+
"replace": ["\"@earendil-works/pi-durable\": \"1.4.0\","],
|
|
26
26
|
"gate": ["bash", "run.sh", "check-dep-versions"],
|
|
27
27
|
"timeoutSeconds": 300,
|
|
28
28
|
"signature": "[QK:PI-SDK-PRODUCTION-SET]",
|
|
@@ -33,11 +33,28 @@
|
|
|
33
33
|
"title": "an @earendil-works package returns as a dev dependency beside its production pin, one name in two dependency classes",
|
|
34
34
|
"subject": "package.json",
|
|
35
35
|
"find": ["\"@biomejs/biome\": \"^2.4.13\","],
|
|
36
|
-
"replace": ["\"@biomejs/biome\": \"^2.4.13\",\n\t\t\"@earendil-works/pi-ai\": \"1.
|
|
36
|
+
"replace": ["\"@biomejs/biome\": \"^2.4.13\",\n\t\t\"@earendil-works/pi-ai\": \"1.5.0\","],
|
|
37
37
|
"gate": ["bash", "run.sh", "check-dep-versions"],
|
|
38
38
|
"timeoutSeconds": 300,
|
|
39
39
|
"signature": "[QK:PI-SDK-NO-DUAL-DECLARATION]",
|
|
40
40
|
"signatureSource": "run.sh"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"claim": "PI-FLOOR-PUBLISHED-SCOPE",
|
|
44
|
+
"title": "a published-scope region in an operator doc names a package the frozen published manifest does not record, so the 1.4 instructions inside it would be held to a pairing no artifact ships — the doc can no longer prove which published package its install steps belong to",
|
|
45
|
+
"subject": "docs/setup-clean-host.md",
|
|
46
|
+
"find": [
|
|
47
|
+
"<!-- entwurf:published @junghanacs/entwurf@0.50.0 pi 1.4.0 -->",
|
|
48
|
+
"| Component | Requirement | Needed for |"
|
|
49
|
+
],
|
|
50
|
+
"replace": [
|
|
51
|
+
"<!-- entwurf:published @junghanacs/entwurf@0.49.0 pi 1.4.0 -->",
|
|
52
|
+
"| Component | Requirement | Needed for |"
|
|
53
|
+
],
|
|
54
|
+
"gate": ["bash", "run.sh", "check-dep-versions"],
|
|
55
|
+
"timeoutSeconds": 300,
|
|
56
|
+
"signature": "[QK:PI-FLOOR-PUBLISHED-SCOPE]",
|
|
57
|
+
"signatureSource": "run.sh"
|
|
41
58
|
}
|
|
42
59
|
]
|
|
43
60
|
}
|
|
@@ -93,6 +93,41 @@
|
|
|
93
93
|
"timeoutSeconds": 300,
|
|
94
94
|
"signature": "[QK:SOURCE-MANIFEST-UNREADABLE-REFUSED]",
|
|
95
95
|
"signatureSource": "scripts/smoke-agy-install-state.sh"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"claim": "INSTALLED-DEVBIN-MUTATION-REFUSED",
|
|
99
|
+
"title": "the installed-package test never matches, so an installed root's dev-bin expose/remove again takes over a developer's links and state (#153, measured before the guard)",
|
|
100
|
+
"subject": "scripts/dev-bin.sh",
|
|
101
|
+
"find": [" */node_modules/*)"],
|
|
102
|
+
"replace": [" */node_modules/*/never-an-install/*)"],
|
|
103
|
+
"gate": ["bash", "run.sh", "smoke-agy-install-state"],
|
|
104
|
+
"timeoutSeconds": 300,
|
|
105
|
+
"signatureSource": "scripts/smoke-agy-install-state.sh",
|
|
106
|
+
"signature": "[QK:INSTALLED-DEVBIN-MUTATION-REFUSED]"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"claim": "INSTALLED-DEVBIN-PUBLIC-STOPS",
|
|
110
|
+
"title": "the public expose-dev-bin ignores the helper's installed-package refusal and goes on to verify, exclusive and the package-manager queries",
|
|
111
|
+
"subject": "run.sh",
|
|
112
|
+
"find": [" [ \"$rc\" -eq 4 ] && return 4"],
|
|
113
|
+
"replace": [" : # the installed-package refusal no longer stops the wrapper"],
|
|
114
|
+
"gate": ["bash", "run.sh", "smoke-agy-install-state"],
|
|
115
|
+
"timeoutSeconds": 300,
|
|
116
|
+
"signatureSource": "scripts/smoke-agy-install-state.sh",
|
|
117
|
+
"signature": "[QK:INSTALLED-DEVBIN-PUBLIC-STOPS]"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"claim": "SOURCE-DEVBIN-MOVED-CHECKOUT",
|
|
121
|
+
"title": "the moved-checkout rule is dropped while closing the installed path, so a developer's link no longer follows its own checkout to another one",
|
|
122
|
+
"subject": "scripts/dev-bin.sh",
|
|
123
|
+
"find": [
|
|
124
|
+
" [ \"$(state_link \"$sf\")\" = \"$link\" ] && [ \"$cur\" = \"$(state_target \"$sf\")\" ] && return 0"
|
|
125
|
+
],
|
|
126
|
+
"replace": [" :"],
|
|
127
|
+
"gate": ["bash", "run.sh", "smoke-agy-install-state"],
|
|
128
|
+
"timeoutSeconds": 300,
|
|
129
|
+
"signatureSource": "scripts/smoke-agy-install-state.sh",
|
|
130
|
+
"signature": "[QK:SOURCE-DEVBIN-MOVED-CHECKOUT]"
|
|
96
131
|
}
|
|
97
132
|
]
|
|
98
133
|
}
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"title": "MCP long description advertises owned-outcome as a selectable dormant verb again and drops the reason a dormant target actually returns",
|
|
82
82
|
"subject": "ENTWURF.json",
|
|
83
83
|
"find": [
|
|
84
|
-
"A dormant socket rejects this delivery verb as dormant-fire-forget-unsupported. owned-outcome was withdrawn. Only on an explicit operator request, entwurf_resume_call may visibly reopen a proven-dormant Pi or Claude Code citizen under the same id, submitting no prompt; that lifecycle is separate from delivery. "
|
|
84
|
+
"A dormant socket rejects this delivery verb as dormant-fire-forget-unsupported. owned-outcome was withdrawn. Only on an explicit operator request, entwurf_resume_call may visibly reopen a proven-dormant Pi, pi-durable or Claude Code citizen under the same id, submitting no prompt; that lifecycle is separate from delivery. "
|
|
85
85
|
],
|
|
86
86
|
"replace": [
|
|
87
87
|
"owned-outcome wakes a DORMANT socket-domain citizen by spawn-bg resume ONLY and is never auto-converted. "
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"title": "entwurf_peers drops the dead-row sentence, so a dormant citizen is listed with nothing saying it is unreachable",
|
|
121
121
|
"subject": "ENTWURF.json",
|
|
122
122
|
"find": [
|
|
123
|
-
"row. A `dead` socket row is a REPORTED FACT: no entwurf_v2 delivery is available while it is dormant. Listing it grants no action and is not an invitation to dispatch. Only on an explicit operator request, the separate entwurf_resume_call may visibly reopen a proven-dormant Pi or Claude Code citizen under the same id, submitting no prompt. In particular"
|
|
123
|
+
"row. A `dead` socket row is a REPORTED FACT: no entwurf_v2 delivery is available while it is dormant. Listing it grants no action and is not an invitation to dispatch. Only on an explicit operator request, the separate entwurf_resume_call may visibly reopen a proven-dormant Pi, pi-durable or Claude Code citizen under the same id, submitting no prompt. In particular"
|
|
124
124
|
],
|
|
125
125
|
"replace": ["row. In particular"],
|
|
126
126
|
"gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
|
|
@@ -114,8 +114,8 @@
|
|
|
114
114
|
"claim": "V2RESUME-ARGV-FROM-RECORD",
|
|
115
115
|
"title": "the launcher is handed the caller's own directory instead of the record's, so the citizen returns in the wrong project",
|
|
116
116
|
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
117
|
-
"find": ["\t\tconst launched = deps.launch({ backend: \"pi\", cwd: identity.cwd, runtimeArgs });"],
|
|
118
|
-
"replace": ["\t\tconst launched = deps.launch({ backend: \"pi\", cwd: process.cwd(), runtimeArgs });"],
|
|
117
|
+
"find": ["\t\tconst launched = await deps.launch({ backend: \"pi\", cwd: identity.cwd, runtimeArgs });"],
|
|
118
|
+
"replace": ["\t\tconst launched = await deps.launch({ backend: \"pi\", cwd: process.cwd(), runtimeArgs });"],
|
|
119
119
|
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
120
120
|
"timeoutSeconds": 60,
|
|
121
121
|
"signature": "[QK:V2RESUME-ARGV-FROM-RECORD]",
|
|
@@ -201,10 +201,10 @@
|
|
|
201
201
|
"title": "the backend is re-derived instead of taken from the typed error, which is the second read this rail refuses",
|
|
202
202
|
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
203
203
|
"find": [
|
|
204
|
-
"\t\t\t\t\t\t`${targetGardenId} is a ${err.backend} citizen; only pi and Claude Code citizens can be reopened ` +"
|
|
204
|
+
"\t\t\t\t\t\t`${targetGardenId} is a ${err.backend} citizen; only pi, pi-durable and Claude Code citizens can be reopened ` +"
|
|
205
205
|
],
|
|
206
206
|
"replace": [
|
|
207
|
-
"\t\t\t\t\t\t`${targetGardenId} is a citizen of another backend; only pi and Claude Code citizens can be reopened ` +"
|
|
207
|
+
"\t\t\t\t\t\t`${targetGardenId} is a citizen of another backend; only pi, pi-durable and Claude Code citizens can be reopened ` +"
|
|
208
208
|
],
|
|
209
209
|
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
210
210
|
"timeoutSeconds": 60,
|
|
@@ -338,10 +338,10 @@
|
|
|
338
338
|
"claim": "V2RESUME-PI-NEVER-READS-RECEIVER",
|
|
339
339
|
"title": "the pi path consults a Claude Code receiver marker, mixing the two backends' dormancy proofs",
|
|
340
340
|
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
341
|
-
"find": ["\t\tconst launched = deps.launch({ backend: \"pi\", cwd: identity.cwd, runtimeArgs });"],
|
|
341
|
+
"find": ["\t\tconst launched = await deps.launch({ backend: \"pi\", cwd: identity.cwd, runtimeArgs });"],
|
|
342
342
|
"replace": [
|
|
343
343
|
"\t\tdeps.inspectReceiver(targetGardenId);",
|
|
344
|
-
"\t\tconst launched = deps.launch({ backend: \"pi\", cwd: identity.cwd, runtimeArgs });"
|
|
344
|
+
"\t\tconst launched = await deps.launch({ backend: \"pi\", cwd: identity.cwd, runtimeArgs });"
|
|
345
345
|
],
|
|
346
346
|
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
347
347
|
"timeoutSeconds": 60,
|
|
@@ -502,6 +502,255 @@
|
|
|
502
502
|
"timeoutSeconds": 60,
|
|
503
503
|
"signature": "[QK:V2RESUME-REJECT-HINTS-FROM-ROOT]",
|
|
504
504
|
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
"claim": "V2RESUME-LAUNCH-AWAITED",
|
|
508
|
+
"title": "the pi launch stops being awaited, so a herdr launch that answers through a promise reads as a refusal with no reason while the tab it opened is on screen",
|
|
509
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
510
|
+
"find": ["\t\tconst launched = await deps.launch({ backend: \"pi\", cwd: identity.cwd, runtimeArgs });"],
|
|
511
|
+
"replace": [
|
|
512
|
+
"\t\tconst launched = deps.launch({ backend: \"pi\", cwd: identity.cwd, runtimeArgs }) as VisibleResumeLaunchOutcome;"
|
|
513
|
+
],
|
|
514
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
515
|
+
"timeoutSeconds": 60,
|
|
516
|
+
"signature": "[QK:V2RESUME-LAUNCH-AWAITED]",
|
|
517
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
"claim": "V2RESUME-HERDR-RENDER",
|
|
521
|
+
"title": "the herdr branch of the renderer is dropped, so a herdr launch is printed as a tmux window with undefined runtime, window and pane pid",
|
|
522
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
523
|
+
"find": ["\tif (h.rail === \"herdr\") return renderHerdrPiResume(result, h, actor);"],
|
|
524
|
+
"replace": [""],
|
|
525
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
526
|
+
"timeoutSeconds": 60,
|
|
527
|
+
"signature": "[QK:V2RESUME-HERDR-RENDER]",
|
|
528
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
"claim": "V2RESUME-POST-CREATE-FAILURE-NAMED",
|
|
532
|
+
"title": "a launch failure after the tab create is folded into launch-refused, so the operator is told no window was opened over a tab that may be holding the citizen",
|
|
533
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
534
|
+
"find": ["\treturn \"failure\" in launched"],
|
|
535
|
+
"replace": ["\treturn \"failureNever\" in launched"],
|
|
536
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
537
|
+
"timeoutSeconds": 60,
|
|
538
|
+
"signature": "[QK:V2RESUME-POST-CREATE-FAILURE-NAMED]",
|
|
539
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
"claim": "V2RESUME-LAUNCH-FAILED-HEADER-HONEST",
|
|
543
|
+
"title": "the header of a tab create herdr declined by name claims the tab was created, sending the operator to look for a tab that never existed",
|
|
544
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
545
|
+
"find": ["\t\t\t? \"entwurf_resume_call failed at the herdr tab create step\""],
|
|
546
|
+
"replace": ["\t\t\t? \"entwurf_resume_call failed after the herdr tab was created\""],
|
|
547
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
548
|
+
"timeoutSeconds": 60,
|
|
549
|
+
"signature": "[QK:V2RESUME-LAUNCH-FAILED-HEADER-HONEST]",
|
|
550
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
"claim": "V2RESUME-CC-JOIN-HANDLE-ONLY",
|
|
554
|
+
"title": "the guard that admits only a handle carrying the opened pane's direct child is disabled, so a herdr agent-start or pi-durable layout handle reaches the join with no pid and the wiring defect no longer fails by name",
|
|
555
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
556
|
+
"find": ["\tif (handle.rail !== \"tmux\" && handle.rail !== \"herdr-layout-claude\") {"],
|
|
557
|
+
"replace": ["\tif (handle.rail !== \"tmux\" && handle.rail !== \"herdr-layout-claude\" && false) {"],
|
|
558
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
559
|
+
"timeoutSeconds": 60,
|
|
560
|
+
"signature": "[QK:V2RESUME-CC-JOIN-HANDLE-ONLY]",
|
|
561
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
562
|
+
},
|
|
563
|
+
{
|
|
564
|
+
"claim": "V2RESUME-PD-ADOPT-LAUNCH",
|
|
565
|
+
"title": "the adopt launch normalizes the reservation's raw profile, so the child's SDK reads another profile string than the one its reservation recorded and adopt row 5 refuses every resume",
|
|
566
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
567
|
+
"find": ["\t\t\tPI_CODING_AGENT_DIR: reservation.profile,"],
|
|
568
|
+
"replace": ["\t\t\tPI_CODING_AGENT_DIR: path.resolve(reservation.profile),"],
|
|
569
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
570
|
+
"timeoutSeconds": 60,
|
|
571
|
+
"signature": "[QK:V2RESUME-PD-ADOPT-LAUNCH]",
|
|
572
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
"claim": "V2RESUME-PD-WITHDRAW-NONE-CREATED",
|
|
576
|
+
"title": "a launch failure whose recovery is none no longer withdraws, so a herdr decline that created nothing leaves the citizen reserved by a live bridge",
|
|
577
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
578
|
+
"find": ["\t\tconst noneCreated = !(\"failure\" in launched) || launched.failure.recovery.outcome === \"none\";"],
|
|
579
|
+
"replace": ["\t\tconst noneCreated = !(\"failure\" in launched);"],
|
|
580
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
581
|
+
"timeoutSeconds": 60,
|
|
582
|
+
"signature": "[QK:V2RESUME-PD-WITHDRAW-NONE-CREATED]",
|
|
583
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
"claim": "V2RESUME-PD-KEEP-POSSIBLY-CREATED",
|
|
587
|
+
"title": "an unknown or orphaned launch outcome is read as none-created and the reservation is withdrawn while a child may still adopt it",
|
|
588
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
589
|
+
"find": ["\t\tconst noneCreated = !(\"failure\" in launched) || launched.failure.recovery.outcome === \"none\";"],
|
|
590
|
+
"replace": [
|
|
591
|
+
"\t\tconst noneCreated = !(\"failure\" in launched) || launched.failure.recovery.outcome !== \"closed\";"
|
|
592
|
+
],
|
|
593
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
594
|
+
"timeoutSeconds": 60,
|
|
595
|
+
"signature": "[QK:V2RESUME-PD-KEEP-POSSIBLY-CREATED]",
|
|
596
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
"claim": "V2RESUME-PD-THROW-KEEPS",
|
|
600
|
+
"title": "a launcher that threw withdraws the reservation, though a window may exist whose child can still adopt it",
|
|
601
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
602
|
+
"find": [
|
|
603
|
+
"\t\t\t`entwurf-v2-visible-resume: the pi-durable launch of ${targetGardenId} threw: ${messageOf(err)}${kept}`,"
|
|
604
|
+
],
|
|
605
|
+
"replace": [
|
|
606
|
+
"\t\t\t`entwurf-v2-visible-resume: the pi-durable launch of ${targetGardenId} threw: ${messageOf(err)}${await withdraw()}`,"
|
|
607
|
+
],
|
|
608
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
609
|
+
"timeoutSeconds": 60,
|
|
610
|
+
"signature": "[QK:V2RESUME-PD-THROW-KEEPS]",
|
|
611
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
"claim": "V2RESUME-PD-WITHDRAW-FAILURE-REPORTED",
|
|
615
|
+
"title": "a failed withdrawal is silently retried, so the answer stops being the outcome of the one withdrawal this call made",
|
|
616
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
617
|
+
"find": ["\t\t\tawait deps.withdrawPiDurable(reservation);"],
|
|
618
|
+
"replace": ["\t\t\tawait deps.withdrawPiDurable(reservation).catch(() => deps.withdrawPiDurable(reservation));"],
|
|
619
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
620
|
+
"timeoutSeconds": 60,
|
|
621
|
+
"signature": "[QK:V2RESUME-PD-WITHDRAW-FAILURE-REPORTED]",
|
|
622
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
"claim": "V2RESUME-PD-RESERVE-LIVE-REFUSED",
|
|
626
|
+
"title": "a live holder's reserve refusal is no longer named target-live and surfaces as a raw fence error",
|
|
627
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
628
|
+
"find": ["\tif (err.reason === \"owner-live\") {"],
|
|
629
|
+
"replace": ["\tif (err.reason === \"withdraw-not-own\") {"],
|
|
630
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
631
|
+
"timeoutSeconds": 60,
|
|
632
|
+
"signature": "[QK:V2RESUME-PD-RESERVE-LIVE-REFUSED]",
|
|
633
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
"claim": "V2RESUME-PD-OBSERVE-BOUNDED-WAIT",
|
|
637
|
+
"title": "the adoption observation reads once and gives up, so a child that adopts a second later is reported not-yet-adopted",
|
|
638
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
639
|
+
"find": [
|
|
640
|
+
"\t\tif (deps.now() - started >= timeoutMs) return { kind: \"not-yet-adopted\", waitedMs: deps.now() - started };"
|
|
641
|
+
],
|
|
642
|
+
"replace": [
|
|
643
|
+
"\t\tif (deps.now() - started >= 0) return { kind: \"not-yet-adopted\", waitedMs: deps.now() - started };"
|
|
644
|
+
],
|
|
645
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
646
|
+
"timeoutSeconds": 60,
|
|
647
|
+
"signature": "[QK:V2RESUME-PD-OBSERVE-BOUNDED-WAIT]",
|
|
648
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
"claim": "V2RESUME-PD-OBSERVE-CLASSES",
|
|
652
|
+
"title": "an unreadable D claim is reported as reservation-lost instead of unobserved with its cause",
|
|
653
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
654
|
+
"find": [
|
|
655
|
+
"\t\t\treturn { kind: \"unobserved\", reason: seen.reason, detail: seen.detail, waitedMs: deps.now() - started };"
|
|
656
|
+
],
|
|
657
|
+
"replace": ["\t\t\treturn { kind: \"reservation-lost\", waitedMs: deps.now() - started };"],
|
|
658
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
659
|
+
"timeoutSeconds": 60,
|
|
660
|
+
"signature": "[QK:V2RESUME-PD-OBSERVE-CLASSES]",
|
|
661
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
"claim": "V2RESUME-PD-RENDER",
|
|
665
|
+
"title": "the adopted receipt stops saying an adoption is not readiness, so it reads as the citizen being back",
|
|
666
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
667
|
+
"find": ["adoption of this reservation. That is not ` +"],
|
|
668
|
+
"replace": ["adoption of this reservation. That is ` +"],
|
|
669
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
670
|
+
"timeoutSeconds": 60,
|
|
671
|
+
"signature": "[QK:V2RESUME-PD-RENDER]",
|
|
672
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
"claim": "V2RESUME-PD-LAUNCH-FAILED-STEP",
|
|
676
|
+
"title": "a pi-durable layout.apply failure is rendered as the pi rail's tab create failure, sending the operator to a tab create step that never ran and to a control socket pi-durable does not have",
|
|
677
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
678
|
+
"find": ["\tconst layout = f.rail === \"herdr-layout\";"],
|
|
679
|
+
"replace": ["\tconst layout = false && f.rail === \"herdr-layout\";"],
|
|
680
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
681
|
+
"timeoutSeconds": 60,
|
|
682
|
+
"signature": "[QK:V2RESUME-PD-LAUNCH-FAILED-STEP]",
|
|
683
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
"claim": "V2RESUME-PD-RESERVED-HOLDER-NOT-ADDRESS",
|
|
687
|
+
"title": "a reservation's live parent is answered as a running holder, so the caller is pointed at a process entwurf_v2 cannot reach",
|
|
688
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
689
|
+
"find": ["\t\tif (err.holderState === \"reserved\") {"],
|
|
690
|
+
"replace": ["\t\tif (err.holderState === \"closed\") {"],
|
|
691
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
692
|
+
"timeoutSeconds": 60,
|
|
693
|
+
"signature": "[QK:V2RESUME-PD-RESERVED-HOLDER-NOT-ADDRESS]",
|
|
694
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
"claim": "V2RESUME-PD-RESERVE-WRITTEN-THEN-FAILED",
|
|
698
|
+
"title": "a reserve that wrote its reservation and then failed a lock release surfaces as a bare release error that names no reservation",
|
|
699
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
700
|
+
"find": [
|
|
701
|
+
"\t\t\tif (err.written !== undefined) throw new Error(piDurableReservedThenFailed(targetGardenId, err, err.written));"
|
|
702
|
+
],
|
|
703
|
+
"replace": ["\t\t\tvoid piDurableReservedThenFailed;"],
|
|
704
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
705
|
+
"timeoutSeconds": 60,
|
|
706
|
+
"signature": "[QK:V2RESUME-PD-RESERVE-WRITTEN-THEN-FAILED]",
|
|
707
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
"claim": "V2RESUME-PD-WITHDRAW-PARTIAL-STATE",
|
|
711
|
+
"title": "a withdrawal that wrote the donor's row and then left its transaction file is reported as if it had written nothing",
|
|
712
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
713
|
+
"find": ["\tif (err instanceof PiDurableOwnerFenceError && err.written !== undefined) {"],
|
|
714
|
+
"replace": ["\tif (err instanceof PiDurableOwnerFenceError && err.written === null) {"],
|
|
715
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
716
|
+
"timeoutSeconds": 60,
|
|
717
|
+
"signature": "[QK:V2RESUME-PD-WITHDRAW-PARTIAL-STATE]",
|
|
718
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
"claim": "V2RESUME-CC-HERDR-JOIN",
|
|
722
|
+
"title": "the herdr Claude Code observation joins the marker owner to herdr's pane VIEW id instead of the pane's direct-child pid, so a real return is never seen",
|
|
723
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
724
|
+
"find": [
|
|
725
|
+
"\tconst panePid = handle.rail === \"tmux\" ? handle.panePid : (handle.paneChild as { pid: string }).pid;"
|
|
726
|
+
],
|
|
727
|
+
"replace": ["\tconst panePid = handle.rail === \"tmux\" ? handle.panePid : handle.herdrPaneId;"],
|
|
728
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
729
|
+
"timeoutSeconds": 60,
|
|
730
|
+
"signature": "[QK:V2RESUME-CC-HERDR-JOIN]",
|
|
731
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
"claim": "V2RESUME-CC-HERDR-PROCESS-UNREAD",
|
|
735
|
+
"title": "a herdr launch whose pane child herdr did not report goes on to wait for a marker joined to no pid, and ends as a quiet resume-unobserved instead of naming herdr's cause",
|
|
736
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
737
|
+
"find": ["\tif (handle.rail === \"herdr-layout-claude\" && \"unread\" in handle.paneChild) {"],
|
|
738
|
+
"replace": ["\tif (handle.rail === \"herdr-layout-claude\" && \"unread\" in handle.paneChild && false) {"],
|
|
739
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
740
|
+
"timeoutSeconds": 60,
|
|
741
|
+
"signature": "[QK:V2RESUME-CC-HERDR-PROCESS-UNREAD]",
|
|
742
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
743
|
+
},
|
|
744
|
+
{
|
|
745
|
+
"claim": "V2RESUME-CC-HERDR-RENDER",
|
|
746
|
+
"title": "the herdr Claude Code receipt drops the pane child pid it joined, so the operator cannot tell which process the observation was about",
|
|
747
|
+
"subject": "pi-extensions/lib/entwurf-v2-visible-resume.ts",
|
|
748
|
+
"find": ["\t\t\t` child: ${child}\\n` +"],
|
|
749
|
+
"replace": ["\t\t\t\"\" +"],
|
|
750
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-visible-resume"],
|
|
751
|
+
"timeoutSeconds": 60,
|
|
752
|
+
"signature": "[QK:V2RESUME-CC-HERDR-RENDER]",
|
|
753
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-visible-resume.test.ts"
|
|
505
754
|
}
|
|
506
755
|
]
|
|
507
756
|
}
|
package/scripts/peer-facts.ts
CHANGED
|
@@ -84,7 +84,7 @@ const arg = process.argv[2];
|
|
|
84
84
|
// A dash argv is a flag this command does not have, not a store directory — treating it as
|
|
85
85
|
// a path would answer `--help` with "empty store, exit 0", a silent wrong fact.
|
|
86
86
|
if (process.argv.length > 3 || (arg !== undefined && arg.startsWith("-"))) {
|
|
87
|
-
console.error("
|
|
87
|
+
console.error("peer-facts: see `entwurf help peer-facts` (from that checkout's root: `./run.sh help peer-facts`)");
|
|
88
88
|
process.exit(2);
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -697,6 +697,72 @@ if bash "$DEVBIN" expose entwurf-bridge >/dev/null 2>&1; then die "dev-bin migra
|
|
|
697
697
|
ok "dev-bin migrate: foreign legacy refused (linkPath basename != entwurf-bridge)"
|
|
698
698
|
rm -f "$LEGACY" "$DLINK" "$DSTATE"
|
|
699
699
|
bash "$DEVBIN" remove >/dev/null 2>&1
|
|
700
|
+
# J-6 (#153): dev-bin mutation is a SOURCE checkout's authority. The moved-checkout rule lets a
|
|
701
|
+
# developer's link follow its own checkout (D1 → D2); an INSTALLED package must not inherit it —
|
|
702
|
+
# measured before this guard: a node_modules-shaped root's public expose-dev-bin retargeted every
|
|
703
|
+
# managed link and state a dev checkout had made. The installed root is judged by where dev-bin.sh
|
|
704
|
+
# itself lives (symlinks and directory aliases resolved), never by cwd or a target override. The
|
|
705
|
+
# copies below carry THIS checkout's run.sh/dev-bin.sh/package.json bytes, so the cells test them.
|
|
706
|
+
OVERRIDES=(-u ENTWURF_OPERATOR_TARGET -u ENTWURF_BRIDGE_TARGET -u ENTWURF_AGY_STATUSLINE_TARGET -u ENTWURF_AGY_IMPRINT_TARGET -u ENTWURF_COPILOT_STATUSLINE_TARGET)
|
|
707
|
+
make_root() { # $1 = root dir: the three real files plus no-op helper targets
|
|
708
|
+
mkdir -p "$1/scripts" "$1/mcp/entwurf-bridge"
|
|
709
|
+
cp "$REPO_DIR/run.sh" "$1/run.sh"; cp "$DEVBIN" "$1/scripts/dev-bin.sh"; cp "$REPO_DIR/package.json" "$1/package.json"
|
|
710
|
+
for _t in mcp/entwurf-bridge/start.sh scripts/agy-statusline.sh scripts/agy-imprint.sh scripts/copilot-statusline.sh; do
|
|
711
|
+
printf '#!/bin/sh\nexit 0\n' > "$1/$_t"; chmod +x "$1/$_t"
|
|
712
|
+
done
|
|
713
|
+
chmod +x "$1/run.sh" "$1/scripts/dev-bin.sh"; unset _t
|
|
714
|
+
}
|
|
715
|
+
devbin_world() { # every link in the bin dir, every dev-bin state body, and the profile bytes
|
|
716
|
+
{ for _f in "$DBIN_DIR"/* "$XDG_DATA_HOME"/entwurf/dev-bin/*; do
|
|
717
|
+
[ -e "$_f" ] || [ -L "$_f" ] || continue
|
|
718
|
+
if [ -L "$_f" ]; then printf 'L %s -> %s\n' "$_f" "$(readlink "$_f")"; else printf 'F %s %s\n' "$_f" "$(sha256sum < "$_f")"; fi
|
|
719
|
+
done
|
|
720
|
+
printf 'P %s\n' "$(sha256sum < "$HOME/.profile")"; } 2>/dev/null; unset _f
|
|
721
|
+
}
|
|
722
|
+
D1="$SB/src-d1"; D2="$SB/src-d2"; INST="$SB/inst/node_modules/@junghanacs/entwurf"
|
|
723
|
+
make_root "$D1"; make_root "$D2"; make_root "$INST"
|
|
724
|
+
printf '# smoke profile seed\n' > "$HOME/.profile"
|
|
725
|
+
env "${OVERRIDES[@]}" bash "$D1/scripts/dev-bin.sh" expose >/dev/null 2>&1 # a dev checkout's five links + states
|
|
726
|
+
printf '{"schemaVersion":1,"linkPath":"%s","target":"%s","detectMode":"created-new","stampedAt":"x"}\n' \
|
|
727
|
+
"$DBIN_DIR/entwurf-bridge" "$D1/mcp/entwurf-bridge/start.sh" > "$XDG_DATA_HOME/entwurf/dev-bin/install-state.json" # a legacy state migration would act on
|
|
728
|
+
ln -s "$INST" "$SB/inst-alias"; ln -s "$INST/scripts/dev-bin.sh" "$SB/dev-bin-link.sh"
|
|
729
|
+
WORLD_BEFORE="$(devbin_world)"
|
|
730
|
+
set +e
|
|
731
|
+
bash "$INST/scripts/dev-bin.sh" expose >"$SB/j6-direct.out" 2>&1; RC_DIRECT=$? # target overrides still set
|
|
732
|
+
env "${OVERRIDES[@]}" bash "$SB/inst-alias/scripts/dev-bin.sh" expose entwurf >/dev/null 2>&1; RC_ALIAS=$?
|
|
733
|
+
env "${OVERRIDES[@]}" bash "$SB/dev-bin-link.sh" expose entwurf >/dev/null 2>&1; RC_LINK=$?
|
|
734
|
+
set -e
|
|
735
|
+
WORLD_AFTER_EXPOSE="$(devbin_world)"
|
|
736
|
+
# an installed-root link and state that DO match the installed target: remove still refuses
|
|
737
|
+
rm -f "$OLINK"; ln -s "$INST/run.sh" "$OLINK"
|
|
738
|
+
printf '{"schemaVersion":1,"linkPath":"%s","target":"%s","detectMode":"created-new","stampedAt":"x"}\n' "$OLINK" "$INST/run.sh" > "$OSTATE"
|
|
739
|
+
WORLD_BEFORE_REMOVE="$(devbin_world)"
|
|
740
|
+
set +e; env "${OVERRIDES[@]}" bash "$INST/scripts/dev-bin.sh" remove entwurf >/dev/null 2>&1; RC_REMOVE=$?; set -e
|
|
741
|
+
want "installed dev-bin: expose (direct, alias, symlinked script) and remove refuse with 4 before any write — no link, state, legacy migration or profile change, even for a link the installed root's own target matches [QK:INSTALLED-DEVBIN-MUTATION-REFUSED]" \
|
|
742
|
+
"[ '$RC_DIRECT' -eq 4 ] && [ '$RC_ALIAS' -eq 4 ] && [ '$RC_LINK' -eq 4 ] && [ '$RC_REMOVE' -eq 4 ] && grep -qF 'REFUSE expose: this dev-bin.sh belongs to an installed package' '$SB/j6-direct.out' && [ \"\$WORLD_BEFORE\" = \"\$WORLD_AFTER_EXPOSE\" ] && [ \"\$WORLD_BEFORE_REMOVE\" = \"\$(devbin_world)\" ] && [ -f '$XDG_DATA_HOME/entwurf/dev-bin/install-state.json' ]"
|
|
743
|
+
rm -f "$OLINK"; ln -s "$D1/run.sh" "$OLINK"
|
|
744
|
+
printf '{"schemaVersion":1,"linkPath":"%s","target":"%s","detectMode":"created-new","stampedAt":"x"}\n' "$OLINK" "$D1/run.sh" > "$OSTATE"
|
|
745
|
+
rm -f "$XDG_DATA_HOME/entwurf/dev-bin/install-state.json"
|
|
746
|
+
# the public verbs: the refusal propagates, and nothing after it runs — no verify, no exclusive,
|
|
747
|
+
# no package-manager query (a recording pnpm/npm in front of the fixture ones).
|
|
748
|
+
PM_TRACE="$SB/j6-pm.trace"; : > "$PM_TRACE"; PM_REC="$SB/j6-pm"; mkdir -p "$PM_REC"
|
|
749
|
+
for _pm in pnpm npm; do printf '#!/usr/bin/env bash\necho "%s $*" >> "%s"\nexec "%s/%s" "$@"\n' "$_pm" "$PM_TRACE" "$FAKE_PM" "$_pm" > "$PM_REC/$_pm"; chmod +x "$PM_REC/$_pm"; done; unset _pm
|
|
750
|
+
WORLD_BEFORE="$(devbin_world)"
|
|
751
|
+
set +e
|
|
752
|
+
OUT="$(env "${OVERRIDES[@]}" PATH="$PM_REC:$DBIN_DIR:$PATH" bash "$INST/run.sh" expose-dev-bin 2>&1)"; RC=$?
|
|
753
|
+
env "${OVERRIDES[@]}" PATH="$PM_REC:$DBIN_DIR:$PATH" bash "$INST/run.sh" remove-dev-bin >/dev/null 2>&1; RC_PREMOVE=$?
|
|
754
|
+
set -e
|
|
755
|
+
want "installed public expose-dev-bin/remove-dev-bin exit 4 with the named refusal, and nothing follows it: no verify, no exclusive, no package-manager query, no change [QK:INSTALLED-DEVBIN-PUBLIC-STOPS]" \
|
|
756
|
+
"[ '$RC' -eq 4 ] && [ '$RC_PREMOVE' -eq 4 ] && printf '%s' \"\$OUT\" | grep -qF 'REFUSE expose: this dev-bin.sh belongs to an installed package' && ! printf '%s' \"\$OUT\" | grep -qE 'dev-bin verify|dev-bin exclusive|PATH winner' && [ ! -s '$PM_TRACE' ] && [ \"\$WORLD_BEFORE\" = \"\$(devbin_world)\" ]"
|
|
757
|
+
# the developer's own authority is kept: a link a source checkout made follows it to another one
|
|
758
|
+
set +e; env "${OVERRIDES[@]}" bash "$D2/scripts/dev-bin.sh" expose entwurf >"$SB/j6-d2.out" 2>&1; RC=$?; set -e
|
|
759
|
+
want "source dev-bin keeps the moved-checkout rule: the D1 link and state move to D2 as refresh-ours [QK:SOURCE-DEVBIN-MOVED-CHECKOUT]" \
|
|
760
|
+
"[ '$RC' -eq 0 ] && [ \"\$(readlink '$OLINK')\" = '$D2/run.sh' ] && grep -q 'refresh-ours' '$SB/j6-d2.out' && python3 -c 'import json,sys; sys.exit(0 if json.load(open(sys.argv[1]))[\"target\"]==sys.argv[2] else 1)' '$OSTATE' '$D2/run.sh'"
|
|
761
|
+
env "${OVERRIDES[@]}" bash "$D2/scripts/dev-bin.sh" remove entwurf >/dev/null 2>&1
|
|
762
|
+
env "${OVERRIDES[@]}" bash "$D1/scripts/dev-bin.sh" remove >/dev/null 2>&1
|
|
763
|
+
rm -rf "$D1" "$D2" "$SB/inst" "$SB/inst-alias" "$SB/dev-bin-link.sh" "$PM_REC" "$PM_TRACE" "$HOME/.profile"
|
|
764
|
+
want "installed dev-bin cells leave no managed link or state behind" "[ -z \"\$(ls -A '$DBIN_DIR' 2>/dev/null)\" ] && [ ! -d '$XDG_DATA_HOME/entwurf/dev-bin' ]"
|
|
765
|
+
|
|
700
766
|
unset ENTWURF_DEV_BIN_DIR ENTWURF_OPERATOR_TARGET ENTWURF_BRIDGE_TARGET ENTWURF_AGY_STATUSLINE_TARGET
|
|
701
767
|
export PATH="$DEVBIN_ORIG_PATH"
|
|
702
768
|
unset ENTWURF_AGY_IMPRINT_TARGET ENTWURF_COPILOT_STATUSLINE_TARGET
|
|
@@ -166,6 +166,29 @@ OUT3="$(node --experimental-strip-types "$PRUNE" "$STORE" --ttl-days 100 2>&1)"
|
|
|
166
166
|
set -e
|
|
167
167
|
echo "$OUT3" | grep -q "STALE recordUpdatedAt>100d (0):" && echo "$OUT3" | grep -q "KEEP (live/recent): 2 record" && ok "--ttl-days widens keep window" || bad "--ttl-days did not move stale boundary"
|
|
168
168
|
|
|
169
|
+
# the leaf's usage is now only the address of the description (#153): --help keeps exit 0 and an
|
|
170
|
+
# unknown flag keeps exit 2 with its cause line, both with nothing on stdout. These two children get
|
|
171
|
+
# their own scratch HOME, XDG roots, PI dir and store under $TMP, never the operator's.
|
|
172
|
+
PRUNE_HOME="$TMP/help-home"
|
|
173
|
+
prune_env=(HOME="$PRUNE_HOME" XDG_DATA_HOME="$PRUNE_HOME/.local/share" XDG_STATE_HOME="$PRUNE_HOME/.local/state"
|
|
174
|
+
XDG_CACHE_HOME="$PRUNE_HOME/.cache" XDG_CONFIG_HOME="$PRUNE_HOME/.config" PI_CODING_AGENT_DIR="$PRUNE_HOME/.pi/agent"
|
|
175
|
+
ENTWURF_META_SESSIONS_DIR="$PRUNE_HOME/store")
|
|
176
|
+
PRUNE_POINTER='meta-bridge-prune: see `entwurf help meta-bridge-prune` (from that checkout'"'"'s root: `./run.sh help meta-bridge-prune`)'
|
|
177
|
+
set +e
|
|
178
|
+
env "${prune_env[@]}" node --experimental-strip-types "$PRUNE" --help >"$TMP/help.out" 2>"$TMP/help.err"
|
|
179
|
+
HELP_CODE=$?
|
|
180
|
+
env "${prune_env[@]}" node --experimental-strip-types "$PRUNE" --bogus >"$TMP/bogus.out" 2>"$TMP/bogus.err"
|
|
181
|
+
BOGUS_CODE=$?
|
|
182
|
+
set -e
|
|
183
|
+
if [ "$HELP_CODE" = "0" ] && [ ! -s "$TMP/help.out" ] && [ "$(cat "$TMP/help.err")" = "$PRUNE_POINTER" ] \
|
|
184
|
+
&& [ "$(wc -l <"$TMP/help.err")" = 1 ] \
|
|
185
|
+
&& [ "$BOGUS_CODE" = "2" ] && [ ! -s "$TMP/bogus.out" ] \
|
|
186
|
+
&& [ "$(cat "$TMP/bogus.err")" = "unknown flag: --bogus"$'\n'"$PRUNE_POINTER" ] && [ "$(wc -l <"$TMP/bogus.err")" = 2 ]; then
|
|
187
|
+
ok "--help (exit 0) and --bogus (exit 2, after its cause line) print nothing on stdout and point at \`entwurf help meta-bridge-prune\`"
|
|
188
|
+
else
|
|
189
|
+
bad "[QK:PRUNE-HELP-POINTER] the leaf's usage is not exactly the pointer line: help rc=$HELP_CODE stderr=$(head -c 300 "$TMP/help.err") stdout=$(head -c 200 "$TMP/help.out") | bogus rc=$BOGUS_CODE stderr=$(head -c 300 "$TMP/bogus.err") stdout=$(head -c 200 "$TMP/bogus.out")"
|
|
190
|
+
fi
|
|
191
|
+
|
|
169
192
|
if [ "$fail" = "0" ]; then
|
|
170
193
|
echo "smoke-meta-prune PASS"
|
|
171
194
|
else
|
|
@@ -221,8 +221,12 @@ ok("the caller is a record-backed citizen with an armed mailbox and a sender mar
|
|
|
221
221
|
|
|
222
222
|
const citizensBefore = new Set(
|
|
223
223
|
(
|
|
224
|
-
JSON.parse(
|
|
225
|
-
.
|
|
224
|
+
JSON.parse(
|
|
225
|
+
execFileSync("bash", [path.join(REPO, "run.sh"), "meta-facts"], {
|
|
226
|
+
encoding: "utf8",
|
|
227
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
228
|
+
}),
|
|
229
|
+
).citizens as Array<{
|
|
226
230
|
gardenId: string;
|
|
227
231
|
}>
|
|
228
232
|
).map((c) => c.gardenId),
|
|
@@ -356,7 +360,12 @@ ok(
|
|
|
356
360
|
);
|
|
357
361
|
|
|
358
362
|
// ── 7. that id is a real omp citizen, and the ONLY one this step minted ──────
|
|
359
|
-
const facts = JSON.parse(
|
|
363
|
+
const facts = JSON.parse(
|
|
364
|
+
execFileSync("bash", [path.join(REPO, "run.sh"), "meta-facts"], {
|
|
365
|
+
encoding: "utf8",
|
|
366
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
367
|
+
}),
|
|
368
|
+
);
|
|
360
369
|
const citizen = (facts.citizens as Array<Record<string, unknown>>).find((c) => c.gardenId === siblingGid);
|
|
361
370
|
ok(
|
|
362
371
|
"the callback id resolves to a V3 record whose backend is omp",
|
|
@@ -279,7 +279,13 @@ ok(
|
|
|
279
279
|
// This closes a real gap rather than a cosmetic one. `entwurf_inbox_read` takes a
|
|
280
280
|
// CALLER-SUPPLIED garden id and does not verify it against the caller's identity, so
|
|
281
281
|
// `lastReadAt` alone proves a read happened — not that THIS session performed it.
|
|
282
|
-
const record = JSON.parse(
|
|
282
|
+
const record = JSON.parse(
|
|
283
|
+
execFileSync("bash", [path.join(REPO, "run.sh"), "meta-facts"], {
|
|
284
|
+
encoding: "utf8",
|
|
285
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
286
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
287
|
+
}),
|
|
288
|
+
);
|
|
283
289
|
const citizen = (record.citizens as Array<Record<string, unknown>>).find((c) => c.gardenId === gardenId);
|
|
284
290
|
ok("the citizen's V3 record names a transcript for this session", typeof citizen?.transcriptPath === "string");
|
|
285
291
|
const transcriptPath = citizen?.transcriptPath as string;
|
|
@@ -258,7 +258,12 @@ receipts["1-fixture"] = `gardenId=${fixtureGid} backend=claude-code (collector o
|
|
|
258
258
|
|
|
259
259
|
const citizensBefore = new Set(
|
|
260
260
|
(
|
|
261
|
-
JSON.parse(
|
|
261
|
+
JSON.parse(
|
|
262
|
+
execFileSync("bash", [path.join(REPO, "run.sh"), "meta-facts"], {
|
|
263
|
+
encoding: "utf8",
|
|
264
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
265
|
+
}),
|
|
266
|
+
) as {
|
|
262
267
|
citizens: Array<{ gardenId: string }>;
|
|
263
268
|
}
|
|
264
269
|
).citizens.map((c) => c.gardenId),
|
|
@@ -453,7 +458,12 @@ ok(
|
|
|
453
458
|
JSON.stringify(pdMarker),
|
|
454
459
|
);
|
|
455
460
|
|
|
456
|
-
const facts = JSON.parse(
|
|
461
|
+
const facts = JSON.parse(
|
|
462
|
+
execFileSync("bash", [path.join(REPO, "run.sh"), "meta-facts"], {
|
|
463
|
+
encoding: "utf8",
|
|
464
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
465
|
+
}),
|
|
466
|
+
) as {
|
|
457
467
|
citizens: Array<{ gardenId: string }>;
|
|
458
468
|
};
|
|
459
469
|
// Other siblings may mint citizens in the operator's garden meanwhile; this step's are the ones in its scratch cwd.
|