@junghanacs/entwurf 0.41.0 → 0.41.2
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 +1 -1
- package/BASELINE.md +7 -5
- package/CHANGELOG.md +426 -0
- package/DELIVERY.md +37 -20
- package/README.md +83 -81
- package/VERIFY.md +10 -10
- package/demo/README.md +1 -1
- package/docs/acp-backend-rail.md +1 -1
- package/docs/external-mcp-host.md +1 -1
- package/docs/setup-clean-host.md +95 -29
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +14 -11
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-self-address.js +10 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +23 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-decider.js +7 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +3 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +21 -10
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-fresh-call.js +4 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +5 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +6 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/native-push/register.js +13 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/omp-fresh-preflight.js +2 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-fresh-preflight.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/remote-pair-receive.js +25 -17
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/remote-pair-send.js +94 -28
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-omp.js +57 -7
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-pi-durable.js +2 -2
- package/mcp/entwurf-bridge/dist/scripts/remote-pair-receive.js +12 -12
- package/mcp/entwurf-bridge/src/index.ts +14 -11
- package/native/win32-x64/entwurf_win.node +0 -0
- package/native/win32-x64/manifest.json +2 -2
- package/package.json +15 -14
- package/pi/pi-durable/carrier/tui.js +18 -3
- package/pi/pi-durable/overlay/upstream-pin.json +12 -12
- package/pi-extensions/lib/acp/backend-adapter.ts +5 -3
- package/pi-extensions/lib/acp/backend.ts +12 -9
- package/pi-extensions/lib/entwurf-self-address.ts +13 -0
- package/pi-extensions/lib/entwurf-v2-contract.ts +25 -2
- package/pi-extensions/lib/entwurf-v2-decider.ts +7 -0
- package/pi-extensions/lib/entwurf-v2-surface.ts +3 -0
- package/pi-extensions/lib/fresh-call-composition.ts +21 -10
- package/pi-extensions/lib/herdr-fresh-call.ts +4 -2
- package/pi-extensions/lib/meta-sender-identity.ts +4 -0
- package/pi-extensions/lib/mux-fresh-call.ts +6 -4
- package/pi-extensions/lib/native-push/register.ts +17 -2
- package/pi-extensions/lib/omp-fresh-preflight.ts +2 -2
- package/pi-extensions/lib/pi-durable-fresh-preflight.ts +1 -1
- package/pi-extensions/lib/remote-pair-receive.ts +27 -19
- package/pi-extensions/lib/remote-pair-send.ts +117 -30
- package/pi-extensions/meta-bridge-omp.ts +69 -7
- package/pi-extensions/meta-bridge-pi-durable.ts +3 -3
- package/run.sh +218 -49
- package/scripts/check-agy-sender-identity.ts +6 -4
- package/scripts/check-entwurf-self-address.ts +34 -3
- package/scripts/check-entwurf-v2-contract.ts +24 -2
- package/scripts/check-entwurf-v2-production.ts +45 -31
- package/scripts/check-gate-qualification.ts +11 -9
- package/scripts/check-native-push-adapter.ts +4 -0
- package/scripts/check-native-push-register.ts +32 -82
- package/scripts/check-remote-pair-installed.ts +2 -2
- package/scripts/dev-bin.sh +112 -1
- package/scripts/lib/chain-terminus-publication.ts +58 -0
- package/scripts/lib/codex-fresh-live-protocol.ts +33 -2
- package/scripts/lib/codex-fresh-source-receipts.ts +112 -3
- package/scripts/lib/pi-durable-fresh-live-receipts.ts +29 -1
- package/scripts/mutants/chain-terminus-publication.json +17 -0
- package/scripts/mutants/codex-native.json +98 -0
- package/scripts/mutants/control-send-receipt.json +3 -3
- package/scripts/mutants/mux-fresh-call.json +16 -1
- package/scripts/mutants/native-push-paused.json +17 -0
- package/scripts/mutants/omp-fresh.json +13 -2
- package/scripts/mutants/pack-install.json +50 -4
- package/scripts/mutants/pi-durable.json +60 -0
- package/scripts/mutants/pi-floor.json +5 -5
- package/scripts/mutants/remote-pair-display.json +3 -3
- package/scripts/mutants/remote-pair-receive.json +41 -11
- package/scripts/mutants/remote-pair-roundtrip.json +67 -7
- package/scripts/mutants/remote-pair-send.json +156 -17
- package/scripts/mutants/remote-pair-transport.json +4 -4
- package/scripts/mutants/source-install.json +66 -0
- package/scripts/remote-pair-receive.ts +12 -12
- package/scripts/smoke-agy-install-state.sh +121 -0
- package/scripts/smoke-agy-native-push-live.ts +13 -0
- package/scripts/smoke-codex-fresh-live.ts +52 -28
- package/scripts/smoke-entwurf-chain-live.ts +7 -9
- package/scripts/smoke-herdr-fresh-call-live.ts +4 -4
- package/scripts/smoke-herdr-plugin-build-live.ts +179 -50
- package/scripts/smoke-herdr-raw-install-live.sh +10 -3
- package/scripts/smoke-mux-lifecycle-live.ts +140 -8
- package/scripts/smoke-omp-fresh-live.ts +5 -4
- package/scripts/smoke-pi-durable-fresh-live.ts +29 -7
- package/scripts/smoke-setup-verdict.sh +27 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@junghanacs/entwurf",
|
|
3
|
-
"version": "0.41.
|
|
3
|
+
"version": "0.41.2",
|
|
4
4
|
"description": "Visible sibling sessions across independent agent harnesses: launch in Herdr or tmux, retire on request and reopen pi or Claude Code in tmux, and deliver messages by garden id; native bridges and Claude/Cortex ACP adapters.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -89,7 +89,8 @@
|
|
|
89
89
|
"CHANGELOG.md",
|
|
90
90
|
"!**/__pycache__",
|
|
91
91
|
"!**/*.pyc",
|
|
92
|
-
"!pi-extensions/**/*.test.ts"
|
|
92
|
+
"!pi-extensions/**/*.test.ts",
|
|
93
|
+
"!pi-extensions/**/fixtures/**"
|
|
93
94
|
],
|
|
94
95
|
"engines": {
|
|
95
96
|
"node": ">=24.0.0"
|
|
@@ -101,15 +102,15 @@
|
|
|
101
102
|
"@agentclientprotocol/claude-agent-acp": "0.90.0",
|
|
102
103
|
"@agentclientprotocol/sdk": "1.8.0",
|
|
103
104
|
"@anthropic-ai/sdk": "0.100.1",
|
|
104
|
-
"@earendil-works/chord": "1.
|
|
105
|
-
"@earendil-works/pi-agent-core": "1.
|
|
106
|
-
"@earendil-works/pi-ai": "1.
|
|
107
|
-
"@earendil-works/pi-codemode": "1.
|
|
108
|
-
"@earendil-works/pi-coding-agent": "1.
|
|
109
|
-
"@earendil-works/pi-durable": "1.
|
|
110
|
-
"@earendil-works/pi-mcp": "1.
|
|
111
|
-
"@earendil-works/pi-telemetry": "1.
|
|
112
|
-
"@earendil-works/pi-tui": "1.
|
|
105
|
+
"@earendil-works/chord": "1.4.0",
|
|
106
|
+
"@earendil-works/pi-agent-core": "1.4.0",
|
|
107
|
+
"@earendil-works/pi-ai": "1.4.0",
|
|
108
|
+
"@earendil-works/pi-codemode": "1.4.0",
|
|
109
|
+
"@earendil-works/pi-coding-agent": "1.4.0",
|
|
110
|
+
"@earendil-works/pi-durable": "1.4.0",
|
|
111
|
+
"@earendil-works/pi-mcp": "1.4.0",
|
|
112
|
+
"@earendil-works/pi-telemetry": "1.4.0",
|
|
113
|
+
"@earendil-works/pi-tui": "1.4.0",
|
|
113
114
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
114
115
|
"proper-lockfile": "4.1.2",
|
|
115
116
|
"smol-toml": "^1.8.0",
|
|
@@ -195,10 +196,10 @@
|
|
|
195
196
|
"check:full": "bash scripts/check-elapsed.sh check:full check:core check:hermetic check:package",
|
|
196
197
|
"check:core": "pnpm run check:toolchain && pnpm run check:vitest && pnpm run check:contracts",
|
|
197
198
|
"check:toolchain": "pnpm lint && pnpm typecheck",
|
|
198
|
-
"check:vitest": "./run.sh check-mux-fresh-call && ./run.sh check-acp-sdk-surface && ./run.sh check-pi-queue-oracle && ./run.sh check-tests-beside-behavior && ./run.sh check-remote-pair-installed-audit",
|
|
199
|
-
"check:contracts": "./run.sh check-demo-reproducibility && ./run.sh check-shell-quote && ./run.sh check-entwurf-session-identity && ./run.sh check-meta-session && ./run.sh check-meta-v3-record && ./run.sh check-mailbox-receipt-state && ./run.sh check-entwurf-capabilities && ./run.sh check-harness-admission-parity && ./run.sh check-capability-bundle-reach && ./run.sh check-meta-mailbox-state-write && ./run.sh check-meta-receiver-marker && ./run.sh check-meta-capability-source && ./run.sh check-model-lock && ./run.sh check-dep-versions && ./run.sh check-node-floor-coherence && ./run.sh check-claude-floor-coherence && ./run.sh check-copilot-statusline && ./run.sh check-pi-import-surface && ./run.sh check-env-namespace && ./run.sh check-pi-runtime-version && ./run.sh check-pi-preflight && ./run.sh check-project-trust-handler && ./run.sh check-entwurf-v2-contract && ./run.sh check-entwurf-v2-send && ./run.sh check-entwurf-v2-runner && ./run.sh check-control-send-receipt && ./run.sh check-control-retire && ./run.sh check-pi-retire-request && ./run.sh check-cc-retire-pidfd && ./run.sh check-cc-retire-request && ./run.sh check-retirement-event && ./run.sh check-entwurf-v2-retire && ./run.sh check-compaction-send-guard && ./run.sh check-entwurf-resume-args && ./run.sh check-entwurf-v2-native-push && ./run.sh check-entwurf-v2-production && ./run.sh check-entwurf-v2-surface && ./run.sh check-entwurf-bridge-pi-free && ./run.sh check-resume-launch-identity && ./run.sh check-mux-placement && ./run.sh check-mux-launch && ./run.sh check-mux-resume-call && ./run.sh check-mux-parent-artifact && ./run.sh check-mux-launcher-fence && ./run.sh check-entwurf-v2-visible-resume && ./run.sh check-control-socket-path && ./run.sh check-win32-preview && ./run.sh check-pack-win32-carrier && ./run.sh check-meta-listing && ./run.sh check-entwurf-fact-provider && ./run.sh check-herdr-placement && ./run.sh check-herdr-fresh-call && ./run.sh check-herdr-supply && ./run.sh check-fresh-call-dispatch && ./run.sh check-fresh-call-provider && ./run.sh check-entwurf-peers-surface && ./run.sh check-entwurf-self-address && ./run.sh check-entwurf-deliverability && ./run.sh check-native-push-adapter && ./run.sh check-native-push-register && ./run.sh check-auth-boundary && ./run.sh check-acp-overlay && ./run.sh check-acp-tool-surface && ./run.sh check-acp-event-mapper && ./run.sh check-acp-prompt-builder && ./run.sh check-acp-config && ./run.sh check-acp-session-store && ./run.sh check-acp-carrier-augment && ./run.sh check-acp-foreground-only && ./run.sh check-acp-set-model-readback && ./run.sh check-acp-vendor-rejection && ./run.sh check-codex-sender-identity && ./run.sh check-codex-native-push && ./run.sh check-pi-durable-beside && ./run.sh check-pi-durable-carrier && ./run.sh check-pi-durable-native-module",
|
|
199
|
+
"check:vitest": "./run.sh check-mux-fresh-call && ./run.sh check-acp-sdk-surface && ./run.sh check-pi-queue-oracle && ./run.sh check-tests-beside-behavior && ./run.sh check-remote-pair-installed-audit && ./run.sh check-chain-terminus-publication",
|
|
200
|
+
"check:contracts": "./run.sh check-demo-reproducibility && ./run.sh check-shell-quote && ./run.sh check-entwurf-session-identity && ./run.sh check-meta-session && ./run.sh check-meta-v3-record && ./run.sh check-mailbox-receipt-state && ./run.sh check-entwurf-capabilities && ./run.sh check-harness-admission-parity && ./run.sh check-capability-bundle-reach && ./run.sh check-meta-mailbox-state-write && ./run.sh check-meta-receiver-marker && ./run.sh check-meta-capability-source && ./run.sh check-model-lock && ./run.sh check-dep-versions && ./run.sh check-node-floor-coherence && ./run.sh check-claude-floor-coherence && ./run.sh check-copilot-statusline && ./run.sh check-pi-import-surface && ./run.sh check-env-namespace && ./run.sh check-pi-runtime-version && ./run.sh check-pi-preflight && ./run.sh check-project-trust-handler && ./run.sh check-entwurf-v2-contract && ./run.sh check-entwurf-v2-send && ./run.sh check-entwurf-v2-runner && ./run.sh check-control-send-receipt && ./run.sh check-control-retire && ./run.sh check-pi-retire-request && ./run.sh check-cc-retire-pidfd && ./run.sh check-cc-retire-request && ./run.sh check-retirement-event && ./run.sh check-entwurf-v2-retire && ./run.sh check-compaction-send-guard && ./run.sh check-entwurf-resume-args && ./run.sh check-entwurf-v2-native-push && ./run.sh check-entwurf-v2-production && ./run.sh check-entwurf-v2-surface && ./run.sh check-entwurf-bridge-pi-free && ./run.sh check-resume-launch-identity && ./run.sh check-mux-placement && ./run.sh check-mux-launch && ./run.sh check-mux-resume-call && ./run.sh check-mux-parent-artifact && ./run.sh check-mux-launcher-fence && ./run.sh check-entwurf-v2-visible-resume && ./run.sh check-control-socket-path && ./run.sh check-win32-preview && ./run.sh check-pack-win32-carrier && ./run.sh check-meta-listing && ./run.sh check-entwurf-fact-provider && ./run.sh check-herdr-placement && ./run.sh check-herdr-fresh-call && ./run.sh check-herdr-supply && ./run.sh check-fresh-call-dispatch && ./run.sh check-fresh-call-provider && ./run.sh check-entwurf-peers-surface && ./run.sh check-entwurf-self-address && ./run.sh check-entwurf-deliverability && ./run.sh check-native-push-adapter && ./run.sh check-native-push-register && ./run.sh check-native-push-paused && ./run.sh check-auth-boundary && ./run.sh check-acp-overlay && ./run.sh check-acp-tool-surface && ./run.sh check-acp-event-mapper && ./run.sh check-acp-prompt-builder && ./run.sh check-acp-config && ./run.sh check-acp-session-store && ./run.sh check-acp-carrier-augment && ./run.sh check-acp-foreground-only && ./run.sh check-acp-set-model-readback && ./run.sh check-acp-vendor-rejection && ./run.sh check-codex-sender-identity && ./run.sh check-codex-native-push && ./run.sh check-pi-durable-beside && ./run.sh check-pi-durable-carrier && ./run.sh check-pi-durable-native-module && ./run.sh check-remote-pair-beside",
|
|
200
201
|
"check:hermetic": "./run.sh check-bridge-delivery && ./run.sh smoke-pi-attach && ./run.sh check-fresh-cut-gate && ./run.sh check-hook-launch-topology && ./run.sh check-meta-hook-session-switch && ./run.sh check-copilot-birth-hook && ./run.sh check-copilot-receive-arm && ./run.sh check-copilot-launch && ./run.sh check-pi-launch && ./run.sh check-codex-app-server-launch && ./run.sh check-meta-identity-consumers && ./run.sh check-socket-probe && ./run.sh smoke-meta-honesty && ./run.sh check-meta-doctor-oracle && ./run.sh check-agy-permission-matrix && ./run.sh smoke-agy-statusline-state && ./run.sh smoke-copilot-statusline-state && ./run.sh smoke-copilot-mcp-state && ./run.sh smoke-omp-bridge-state && ./run.sh smoke-omp-mcp-state && ./run.sh smoke-omp-receive-state && ./run.sh check-omp-birth-hook && ./run.sh check-omp-receive-arm && ./run.sh check-omp-fresh-preflight && ./run.sh smoke-agy-hooks-state && ./run.sh smoke-pi-provider-state && ./run.sh smoke-user-scope-citizen && ./run.sh smoke-meta-prune && ./run.sh smoke-meta-keyset-guard && ./run.sh check-meta-manifest-schema && ./run.sh check-entwurf-control-rpc && ./run.sh check-entwurf-bridge-boot && ./run.sh check-probe-bridge-command && ./run.sh check-meta-facts && ./run.sh check-peer-facts && ./run.sh check-herdr-plugin && ./run.sh check-herdr-plugin-profile && ./run.sh check-herdr-plugin-build && ./run.sh check-herdr-runtime-bootstrap && ./run.sh check-herdr-activation && ./run.sh check-agy-sender-identity && ./run.sh check-acp-provider-surface && ./run.sh check-acp-stop-reason && ./run.sh check-acp-prompt-lifecycle && ./run.sh check-acp-usage-accounting && ./run.sh check-acp-launch-namespace && ./run.sh check-acp-stream-hooks && ./run.sh check-acp-backend-preflight && ./run.sh check-acp-session-reuse && ./run.sh check-typing-call-fence && ./run.sh check-gate-manifests && ./run.sh check-release-gate-outcomes && ./run.sh check-probe-ordering && ./run.sh check-probe-cli-shim && ./run.sh check-acp-cortex && ./run.sh check-codex-bridge-identity && ./run.sh check-pi-bridge-sender && ./run.sh check-pi-mcp-register && ./run.sh check-pi-mcp-bridge && ./run.sh check-codex-birth-hook && ./run.sh smoke-codex-config-state && ./run.sh smoke-codex-birth && ./run.sh check-herdr-sandbox",
|
|
201
|
-
"check:package": "./run.sh check-install-surface && ./run.sh smoke-meta-install-state && ./run.sh smoke-agy-install-state && ./run.sh smoke-setup-verdict && ./run.sh check-pack-pin-matcher && ./run.sh check-pack-consumer-roots && ./run.sh check-package-source-routing && ./run.sh check-install-preflight && ./run.sh check-pack"
|
|
202
|
+
"check:package": "./run.sh check-install-surface && ./run.sh smoke-meta-install-state && ./run.sh smoke-agy-install-state && ./run.sh smoke-setup-verdict && ./run.sh check-pack-pin-matcher && ./run.sh check-pack-argv-matcher && ./run.sh check-pack-consumer-roots && ./run.sh check-package-source-routing && ./run.sh check-install-preflight && ./run.sh check-pack"
|
|
202
203
|
},
|
|
203
204
|
"pi": {
|
|
204
205
|
"extensions": [
|
|
@@ -219,6 +219,7 @@ export class TaskBadge {
|
|
|
219
219
|
...tally("aborting", (node) => node.abortRequested),
|
|
220
220
|
...tally("completing", (node) => !node.abortRequested && node.state.status === "completing"),
|
|
221
221
|
...tally("waiting", (node) => !node.abortRequested && node.state.status === "waiting"),
|
|
222
|
+
...tally("sleeping", (node) => !node.abortRequested && node.state.status === "sleeping"),
|
|
222
223
|
...tally("pending", (node) => !node.abortRequested && node.state.status === "pending"),
|
|
223
224
|
].join(", ");
|
|
224
225
|
}
|
|
@@ -621,19 +622,33 @@ class DurableTui {
|
|
|
621
622
|
}
|
|
622
623
|
}
|
|
623
624
|
|
|
624
|
-
|
|
625
|
+
/** A task's line in the tasks panel: a sleeping task says when it wakes, a blocked one why it cannot run. */
|
|
626
|
+
export function describeTask(node ) {
|
|
625
627
|
const state = node.state;
|
|
626
628
|
const status =
|
|
627
629
|
state.status === "waiting"
|
|
628
630
|
? `waiting on ${state.on.join(", ")}`
|
|
629
631
|
: state.status === "completing"
|
|
630
632
|
? `completing (${state.outcome})`
|
|
631
|
-
:
|
|
632
|
-
|
|
633
|
+
: state.status === "sleeping"
|
|
634
|
+
? `sleeping ${state.phase} until ${localTime(state.until)}`
|
|
635
|
+
: `${state.status} ${state.phase}`;
|
|
636
|
+
const flags = [
|
|
637
|
+
node.background ? "background" : "",
|
|
638
|
+
node.abortRequested ? "aborting" : "",
|
|
639
|
+
node.blocked !== undefined ? `blocked:${node.blocked}` : "",
|
|
640
|
+
].filter(Boolean);
|
|
633
641
|
const owned = node.conversations.length > 0 ? ` owns conversation ${node.conversations.join(", ")}` : "";
|
|
634
642
|
return `${node.kind} #${node.id}: ${status}${flags.length > 0 ? ` [${flags.join(", ")}]` : ""}${owned}`;
|
|
635
643
|
}
|
|
636
644
|
|
|
645
|
+
/** Epoch milliseconds as local wall-clock time, `YYYY-MM-DD HH:MM:SS`. */
|
|
646
|
+
function localTime(epoch ) {
|
|
647
|
+
const at = new Date(epoch);
|
|
648
|
+
const pad = (n ) => String(n).padStart(2, "0");
|
|
649
|
+
return `${at.getFullYear()}-${pad(at.getMonth() + 1)}-${pad(at.getDate())} ${pad(at.getHours())}:${pad(at.getMinutes())}:${pad(at.getSeconds())}`;
|
|
650
|
+
}
|
|
651
|
+
|
|
637
652
|
function userText(content ) {
|
|
638
653
|
if (typeof content === "string") return content;
|
|
639
654
|
return content
|
|
@@ -76,8 +76,8 @@
|
|
|
76
76
|
{
|
|
77
77
|
"name": "tui.js",
|
|
78
78
|
"source": "pi/pi-durable/src/experimental/durable/tui.ts",
|
|
79
|
-
"blob": "
|
|
80
|
-
"sha256": "
|
|
79
|
+
"blob": "405600f6ba1558bf6bf22d144afdcf3f1295c282",
|
|
80
|
+
"sha256": "d4bf4e2861bde917e1dcdea6f063bdc3e101ab500107a9c5fab0e3ce97fb2c4a"
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
"name": "harness-setup.js",
|
|
@@ -132,17 +132,17 @@
|
|
|
132
132
|
]
|
|
133
133
|
},
|
|
134
134
|
"sdk": {
|
|
135
|
-
"comment": "The published library set the carrier runs against, derived from the 1.
|
|
135
|
+
"comment": "The published library set the carrier runs against, derived from the 1.4.0 declarations. members: the @earendil-works packages the carrier imports and every @earendil-works package those declare. direct: a third-party package a carrier file imports itself (sessions.ts: proper-lockfile, at the version pi-coding-agent 1.4.0 pins). Each is an exact production dependency in package.json. Since 1.3.0 the members' own edges are exact too (upstream #10865), and the installed physical edges are still what must equal these versions.",
|
|
136
136
|
"members": {
|
|
137
|
-
"@earendil-works/chord": "1.
|
|
138
|
-
"@earendil-works/pi-agent-core": "1.
|
|
139
|
-
"@earendil-works/pi-ai": "1.
|
|
140
|
-
"@earendil-works/pi-codemode": "1.
|
|
141
|
-
"@earendil-works/pi-coding-agent": "1.
|
|
142
|
-
"@earendil-works/pi-durable": "1.
|
|
143
|
-
"@earendil-works/pi-mcp": "1.
|
|
144
|
-
"@earendil-works/pi-telemetry": "1.
|
|
145
|
-
"@earendil-works/pi-tui": "1.
|
|
137
|
+
"@earendil-works/chord": "1.4.0",
|
|
138
|
+
"@earendil-works/pi-agent-core": "1.4.0",
|
|
139
|
+
"@earendil-works/pi-ai": "1.4.0",
|
|
140
|
+
"@earendil-works/pi-codemode": "1.4.0",
|
|
141
|
+
"@earendil-works/pi-coding-agent": "1.4.0",
|
|
142
|
+
"@earendil-works/pi-durable": "1.4.0",
|
|
143
|
+
"@earendil-works/pi-mcp": "1.4.0",
|
|
144
|
+
"@earendil-works/pi-telemetry": "1.4.0",
|
|
145
|
+
"@earendil-works/pi-tui": "1.4.0"
|
|
146
146
|
},
|
|
147
147
|
"direct": {
|
|
148
148
|
"proper-lockfile": "4.1.2"
|
|
@@ -239,9 +239,11 @@ export interface AcpBackendAdapter {
|
|
|
239
239
|
|
|
240
240
|
/** OPTIONAL capability (#127): recognise a typed vendor rejection of `session/prompt`
|
|
241
241
|
* whose raw text must not become pi's `errorMessage`. pi decides a whole-prompt replay
|
|
242
|
-
* from `errorMessage` alone, and a vendor's "Internal error"
|
|
243
|
-
*
|
|
244
|
-
* from a cold session.
|
|
242
|
+
* from `errorMessage` alone, and a vendor's "Internal error" reads as transient
|
|
243
|
+
* (pi-ai's `internal.?error` term), so a turn whose tools already ran would be resent
|
|
244
|
+
* from a cold session. Through pi-ai 1.3 a digit run inside the ids it carries (`…8503…`)
|
|
245
|
+
* read as an HTTP status too; pi-ai 1.4 bounds the status terms (upstream #11057), so
|
|
246
|
+
* the ids no longer trigger it — the "Internal error" text alone still does. A recognised rejection returns a fixed, authored verdict for
|
|
245
247
|
* `errorMessage`; backend.ts keeps the raw rejection as a pi diagnostic instead.
|
|
246
248
|
*
|
|
247
249
|
* ABSENT means every failure of this backend keeps the verbatim-first `errorMessage`.
|
|
@@ -668,13 +668,15 @@ async function settleChildEnd(latch: ChildEndLatch, ms: number): Promise<void> {
|
|
|
668
668
|
* may appear here, or a dead child would put a full cold prompt replay back on
|
|
669
669
|
* the table — with the tool side effects this turn already produced.
|
|
670
670
|
*
|
|
671
|
-
* That pattern is a
|
|
672
|
-
*
|
|
673
|
-
* "502", "503", "504"
|
|
674
|
-
* CHILD_END_SETTLE_MS made this line say "within 500ms", which pi read as an
|
|
675
|
-
*
|
|
676
|
-
*
|
|
677
|
-
*
|
|
671
|
+
* That pattern is a substring alternation (`new RegExp(terms.join("|"), "i")` — NO word
|
|
672
|
+
* boundaries on its word terms). Through pi-ai 1.3 its HTTP status terms ("429", "500",
|
|
673
|
+
* "502", "503", "504", "520", "524") were bare substrings too, and rendering
|
|
674
|
+
* CHILD_END_SETTLE_MS made this line say "within 500ms", which pi read as an HTTP 500 and
|
|
675
|
+
* classified as transient. pi-ai 1.4 bounds only those status terms (upstream #11057), so
|
|
676
|
+
* "500ms" no longer matches; the word terms above are still unbounded. The settle bound
|
|
677
|
+
* stays deliberately NOT interpolated: naming the window in prose keeps a later change of
|
|
678
|
+
* that constant, or of the classifier, from silently re-arming the replay — do not
|
|
679
|
+
* "improve" this by putting the number back; the bound belongs in the code and the gate.
|
|
678
680
|
*
|
|
679
681
|
* The three endings are kept DISTINCT on purpose (issue #72 Done-when): an
|
|
680
682
|
* exit code, a signal, and "we waited and it never said" are three different
|
|
@@ -1468,8 +1470,9 @@ export function streamAcpTurn(
|
|
|
1468
1470
|
// the turn-scoped full-transcript-replay cause.
|
|
1469
1471
|
const hint = aborted ? undefined : actionableAcpBackendHint(full);
|
|
1470
1472
|
// #127: pi's retry and overflow classifiers read `errorMessage` ALONE, and a
|
|
1471
|
-
// vendor's "Internal error"
|
|
1472
|
-
//
|
|
1473
|
+
// vendor's "Internal error" reads as transient — a replay of a turn whose tools
|
|
1474
|
+
// already ran. (Through pi-ai 1.3 a digit run in its ids/stderr did too; 1.4 bounds
|
|
1475
|
+
// the status terms, upstream #11057.) A rejection the adapter names gets
|
|
1473
1476
|
// its fixed verdict there; every raw part rides one diagnostic, appended after any
|
|
1474
1477
|
// existing ones. An abort keeps the abort path.
|
|
1475
1478
|
const rejection = aborted ? undefined : adapter?.readPromptRejection?.(err);
|
|
@@ -77,6 +77,8 @@ export interface SelfAddressabilityFacts {
|
|
|
77
77
|
watchArmed?: boolean;
|
|
78
78
|
/** meta-session (native-push): an adapter probe found this citizen's live native conversation. */
|
|
79
79
|
probeAlive?: boolean;
|
|
80
|
+
/** meta-session (native-push): #152 — this backend's native-push is paused, so no probe ran. */
|
|
81
|
+
nativePushPaused?: boolean;
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
export interface SelfAddressabilityResult {
|
|
@@ -118,6 +120,17 @@ export function computeSelfAddressability(facts: SelfAddressabilityFacts): SelfA
|
|
|
118
120
|
// default fail-closed row).
|
|
119
121
|
switch (facts.metaDeliveryDomain) {
|
|
120
122
|
case "native-push": {
|
|
123
|
+
// #152 policy, decided BEFORE the pure record+probe predicate and kept out of it:
|
|
124
|
+
// only a record-backed citizen can be "paused" (a record-less one keeps its own
|
|
125
|
+
// reason), and no probe was run for this answer, so none is reported.
|
|
126
|
+
if (facts.recordBacked === true && facts.nativePushPaused === true) {
|
|
127
|
+
return {
|
|
128
|
+
replyable: false,
|
|
129
|
+
socketState: "none",
|
|
130
|
+
reason:
|
|
131
|
+
"native-push unreachable — native-push for this backend is paused (#152); no probe ran for this answer",
|
|
132
|
+
};
|
|
133
|
+
}
|
|
121
134
|
const push = nativePushDeliverable({ recordBacked: facts.recordBacked, probeAlive: facts.probeAlive });
|
|
122
135
|
return {
|
|
123
136
|
replyable: push.deliverable,
|
|
@@ -134,6 +134,26 @@ export function nativePushSupported(backend: string): backend is NativePushBacke
|
|
|
134
134
|
return (NATIVE_PUSH_BACKENDS as readonly string[]).includes(backend);
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
// ── Paused native-push backends (#152) ─────────────────────────────────────
|
|
138
|
+
// A native-push backend whose SEND is paused by product policy. On the external send path
|
|
139
|
+
// entwurf measured, Antigravity's language server refused the `agentapi` call with
|
|
140
|
+
// `Unauthenticated: missing CSRF token` (agy 1.2.16 in #128; agy 1.4.6 again for #152).
|
|
141
|
+
// Whether a first-party own-tool shell holds a token entwurf could legitimately present is
|
|
142
|
+
// UNMEASURED, not ruled out. So instead of probing a port that refused on that path and
|
|
143
|
+
// reporting it as an inconclusive liveness, the three public entries that would reach the agy LS —
|
|
144
|
+
// v2 dispatch, a sender's own `replyable`, and `entwurf_register_native` — refuse by name
|
|
145
|
+
// BEFORE any probe. This is a fixed constant, not a flag: no env, config or runtime toggle
|
|
146
|
+
// can lift it. The backend stays in NATIVE_PUSH_BACKENDS, so existing agy records, the V3
|
|
147
|
+
// reader and the peers listing are unchanged; only the native-push traffic stops.
|
|
148
|
+
// The one probe that is NOT behind this guard is the fresh-cut quiescence check
|
|
149
|
+
// (scripts/meta-bridge-fresh-cut.ts), which protects an operator-named archive and must keep
|
|
150
|
+
// failing closed rather than read the pause as a departed host.
|
|
151
|
+
export const NATIVE_PUSH_PAUSED_BACKENDS: readonly NativePushBackend[] = ["antigravity"];
|
|
152
|
+
|
|
153
|
+
export function nativePushPaused(backend: string): boolean {
|
|
154
|
+
return (NATIVE_PUSH_PAUSED_BACKENDS as readonly string[]).includes(backend);
|
|
155
|
+
}
|
|
156
|
+
|
|
137
157
|
// NativePushLiveness = the 3-value liveness the native-push adapter probe yields.
|
|
138
158
|
// The SAME three values as SocketLiveness, reused so there is ONE 3-value liveness
|
|
139
159
|
// vocabulary — but these are NOT socket-bound (봉인 2: "주석만 socket-전용 오독 정정"):
|
|
@@ -173,6 +193,7 @@ export const ENTWURF_V2_REJECT_REASONS = [
|
|
|
173
193
|
"mailbox-undeliverable", // F-mailbox: fire-and-forget to an unsupported citizen whose mailbox is not deliverable (fail-closed; future pi-backend non-drainable mailbox)
|
|
174
194
|
"native-push-target-dead", // 봉인 1: fire-and-forget to a native-push (agy) target whose adapter probe found NO live conversation. Post-probe; observedLiveness = dead.
|
|
175
195
|
"native-push-probe-indeterminate", // 봉인 1: fire-and-forget to a native-push target whose adapter probe was inconclusive (agy alive but no port served the conv, or a probe error). Post-probe; observedLiveness = indeterminate. Never coerced to dead.
|
|
196
|
+
"native-push-paused", // #152: fire-and-forget to a native-push backend whose send is paused by product policy (NATIVE_PUSH_PAUSED_BACKENDS — antigravity). Pre-probe, observedLiveness = null: nothing was probed, so no liveness is claimed — never coerced to dead or indeterminate.
|
|
176
197
|
"bad-target", // R2: absent/typo garden-id (no existing citizen); fresh creation out of v2 scope
|
|
177
198
|
"record-less-socket", // #50 C4: a gid-shaped non-symlink control socket exists but NO meta-record claims it. The record is the sole address authority (목표 ②), so a bare socket is not an addressable citizen — it is a diagnostic state, refused for EVERY intent before any lock/probe (pre-probe, observedLiveness=null). NOT `bad-target`: something real answers to this gid, and mislabeling it absent would hide the very state the reject exists to surface.
|
|
178
199
|
"target-locked", // R5 pre-claim for bucket B F2 per-gid lockfile conflict
|
|
@@ -181,12 +202,13 @@ export const ENTWURF_V2_REJECT_REASONS = [
|
|
|
181
202
|
export type EntwurfV2RejectReason = (typeof ENTWURF_V2_REJECT_REASONS)[number];
|
|
182
203
|
|
|
183
204
|
// ── Pre-probe reject reasons (?6 — observedLiveness = null) ────────────────
|
|
184
|
-
// These
|
|
205
|
+
// These five rejects are decided BEFORE any liveness probe runs, so there is no
|
|
185
206
|
// honest 4-value FactLiveness to stamp: `bad-target` (no citizen/backend),
|
|
186
207
|
// `target-locked` (5a lock conflict, before lstat/connect), `target-address-conflict`
|
|
187
208
|
// (address-subject conflict → probing is forbidden), `record-less-socket` (#50 C4:
|
|
188
209
|
// no record ⇒ not a citizen ⇒ no in-domain probe ever runs — the presence hint is
|
|
189
|
-
// a single lstat, not a liveness measurement)
|
|
210
|
+
// a single lstat, not a liveness measurement), `native-push-paused` (#152: the backend's
|
|
211
|
+
// native-push send is paused by policy, so its adapter is never probed). `indeterminate` means an
|
|
190
212
|
// in-domain probe was inconclusive (≠ "not looked yet"); `unsupported` means the
|
|
191
213
|
// backend has no predicate (≠ "pre-probe"). So a pre-probe reject's
|
|
192
214
|
// observedLiveness is `null`, NOT one of the four values. Every OTHER reject —
|
|
@@ -203,6 +225,7 @@ export const PRE_PROBE_REJECT_REASONS = [
|
|
|
203
225
|
"target-locked",
|
|
204
226
|
"target-address-conflict",
|
|
205
227
|
"record-less-socket",
|
|
228
|
+
"native-push-paused",
|
|
206
229
|
] as const satisfies readonly EntwurfV2RejectReason[];
|
|
207
230
|
export type PreProbeRejectReason = (typeof PRE_PROBE_REJECT_REASONS)[number];
|
|
208
231
|
|
|
@@ -52,6 +52,7 @@ import {
|
|
|
52
52
|
isLivenessSupported,
|
|
53
53
|
makeRejectReceipt,
|
|
54
54
|
type NativePushBackend,
|
|
55
|
+
nativePushPaused,
|
|
55
56
|
nativePushSupported,
|
|
56
57
|
resolveDispatch,
|
|
57
58
|
resolveNativePushDispatch,
|
|
@@ -306,6 +307,12 @@ export async function decideDispatch(input: DispatchInput, deps: DispatchDecider
|
|
|
306
307
|
// branch is LOCK-FREE (봉인 4): the pi in-domain lock closes a socket TOCTOU, but a
|
|
307
308
|
// volatile probe route has no lock meaning (a duplicate-send idempotency is a D8 future).
|
|
308
309
|
if (nativePushSupported(identity.backend)) {
|
|
310
|
+
// #152: a paused native-push backend is refused by name BEFORE its adapter is probed —
|
|
311
|
+
// on the measured external path that language server refused the call (missing CSRF token),
|
|
312
|
+
// and a refusal must not be reported as a measured liveness. Pre-probe, observedLiveness null.
|
|
313
|
+
if (nativePushPaused(identity.backend)) {
|
|
314
|
+
return reject(makeRejectReceipt("native-push-paused", null));
|
|
315
|
+
}
|
|
309
316
|
const probe = await deps.nativePushProbe(identity);
|
|
310
317
|
const receipt = resolveNativePushDispatch(input.intent, probe.status);
|
|
311
318
|
if (!receipt.ok) return reject(receipt);
|
|
@@ -107,6 +107,9 @@ export function actionableRejectHint(reason: string): string | undefined {
|
|
|
107
107
|
// Native host up, but nothing served this conversation/thread — inconclusive, not a
|
|
108
108
|
// hard dead. Backend-neutral for the same reason as the dead cell above.
|
|
109
109
|
return "the native host (harness process or app-server) is up, but nothing served this conversation/thread, so the probe is INCONCLUSIVE — not a measured death. Retry once it is loaded, or verify the conversation/thread id.";
|
|
110
|
+
case "native-push-paused":
|
|
111
|
+
// #152: a policy refusal, not a liveness verdict — this dispatch probed and sent nothing.
|
|
112
|
+
return "native-push for this backend is paused (#152): its language server refused entwurf's measured external calls for a missing CSRF token, so this dispatch probed and sent nothing. The citizen and its record are kept; reach it from inside its own harness instead.";
|
|
110
113
|
case "record-less-socket":
|
|
111
114
|
// #50 C4: name the true cause AND the fix — a bare socket is a diagnostic
|
|
112
115
|
// state, not an addressable citizen (the record is the address).
|
|
@@ -67,7 +67,7 @@ export const FRESH_CALL_CALLBACK_TOOL: Record<FreshCallBackend, string> = {
|
|
|
67
67
|
copilot: "entwurf-bridge-entwurf_callback",
|
|
68
68
|
omp: "mcp__entwurf_bridge_entwurf_callback",
|
|
69
69
|
// Codex's tool process is the operator app-server, not the pane: the no-arg
|
|
70
|
-
// verb refuses there by name.
|
|
70
|
+
// verb refuses there by name. Its callback stays the delivery verb with args.
|
|
71
71
|
codex: "mcp__entwurf_bridge__entwurf_v2",
|
|
72
72
|
// The durable contact registers the bridge verbs as its OWN tools under their bare names, and the
|
|
73
73
|
// app offers a tool to the model by its registered name (`durable/harness/registry.ts:99`
|
|
@@ -381,8 +381,8 @@ export function composeBackendArgs(
|
|
|
381
381
|
* PLACEMENT SENTENCE. The first line names where the sibling was opened, and only the RAIL knows
|
|
382
382
|
* that — "the operator's tmux session" is true of a `new-window` launch and false of a herdr
|
|
383
383
|
* pane. It is therefore supplied by the caller rather than composed here. Everything BELOW that
|
|
384
|
-
* line is rail-independent and stays the contract: the callback
|
|
385
|
-
*
|
|
384
|
+
* line is rail-independent and stays the contract: the callback comes before the task, an optional
|
|
385
|
+
* read-only check of the caller may come before the callback, and the steering is stated as fact.
|
|
386
386
|
*/
|
|
387
387
|
/**
|
|
388
388
|
* The first-turn framing, WITHOUT the task.
|
|
@@ -394,8 +394,13 @@ export function composeBackendArgs(
|
|
|
394
394
|
* the halves separate is what lets the framing stay plain prose on both rails while the operator's
|
|
395
395
|
* task text keeps every byte it was written with.
|
|
396
396
|
*
|
|
397
|
-
* Order is the contract: the callback
|
|
398
|
-
*
|
|
397
|
+
* Order is the contract: the callback comes BEFORE THE TASK, so a sibling that gets stuck in the
|
|
398
|
+
* task has already told the caller who it is. It is not the literal first tool call. `[GLG 직접,
|
|
399
|
+
* 2026-10-24]` checking the caller and then calling back is the right order, and the framing used
|
|
400
|
+
* to say both "FIRST ACTION … call back" and "you can corroborate the caller first" — two
|
|
401
|
+
* sentences that cannot both be obeyed. What may come before the callback is the one read-only
|
|
402
|
+
* check offered below (and, where a dialect needs it, loading the tools); reading files, running
|
|
403
|
+
* commands or starting the task may not.
|
|
399
404
|
*
|
|
400
405
|
* WHAT THIS SAYS AND WHY IT STOPPED SAYING THE REST (#116). Until 2026-09-17 this framing carried
|
|
401
406
|
* three prohibitions, including "Do not inspect environment variables, do not call entwurf_self".
|
|
@@ -433,7 +438,7 @@ export function composeFreshCallFraming(params: {
|
|
|
433
438
|
const firstAction =
|
|
434
439
|
params.backend === "codex"
|
|
435
440
|
? [
|
|
436
|
-
`
|
|
441
|
+
`BEFORE THE TASK, and before reading files or running commands: call ${birthTool} with ` +
|
|
437
442
|
`target=${params.callerGardenId}, intent=fire-and-forget, wants_reply=false, and ` +
|
|
438
443
|
`message set to exactly ${params.nonce} — that string alone, nothing added.`,
|
|
439
444
|
`${params.nonce} is a correlation tag this caller minted for this one launch: it names no`,
|
|
@@ -443,7 +448,7 @@ export function composeFreshCallFraming(params: {
|
|
|
443
448
|
"entwurf_callback is refused on this rail: the tool process is the operator app-server, not this pane.",
|
|
444
449
|
]
|
|
445
450
|
: [
|
|
446
|
-
`
|
|
451
|
+
`BEFORE THE TASK, and before reading files or running commands: call ${birthTool} with no arguments.`,
|
|
447
452
|
"That call is how the caller learns the garden id you were born with. There are no",
|
|
448
453
|
"parameters: a target or message you type would be a second address axis.",
|
|
449
454
|
"Your own record does not carry the caller's address, so reporting your identity here does not reach it — that tool call does.",
|
|
@@ -453,9 +458,15 @@ export function composeFreshCallFraming(params: {
|
|
|
453
458
|
"",
|
|
454
459
|
...firstAction,
|
|
455
460
|
"",
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
461
|
+
// THE CHECK IS THE SIBLING'S, AND SO IS ITS VERDICT. `[GLG 직접, 2026-10-24]` a capped listing that
|
|
462
|
+
// does not show the caller proves nothing about the caller, but a sibling whose check does not hold
|
|
463
|
+
// up may say so and hold back. Entwurf decides nothing here — no trust store, no fallback, no
|
|
464
|
+
// watcher — and the cost of holding back is stated, not hidden: no callback, no address.
|
|
465
|
+
`You may corroborate the caller before that call: ${peersTool} is a read-only listing of`,
|
|
466
|
+
`this garden's citizens and ${params.callerGardenId} is one of them. That listing is capped, so not`,
|
|
467
|
+
"seeing the caller in it does not show the caller is absent. If what you can check is not enough,",
|
|
468
|
+
"or it conflicts with this message, you may say so here and hold the callback and the task; the",
|
|
469
|
+
"caller then has no address for you.",
|
|
459
470
|
...hintBlock,
|
|
460
471
|
"",
|
|
461
472
|
// WHERE THE RESULT GOES, said once, as topology. `[GLG 직접, 2026-09-18]` a Sonnet sibling
|
|
@@ -1232,10 +1232,12 @@ export function renderHerdrFreshCall(result: HerdrFreshCallResult): { text: stri
|
|
|
1232
1232
|
`mean the sibling is running, that its first turn ran, or that the task was delivered. The tab and pane ` +
|
|
1233
1233
|
`coordinates are a view and can change under the sibling — they are not an address and nothing may be ` +
|
|
1234
1234
|
`dispatched to them.\n` +
|
|
1235
|
-
`The sibling's garden id arrives separately — its
|
|
1235
|
+
`The sibling's garden id arrives separately — before its task it calls the zero-argument callback verb ` +
|
|
1236
|
+
`(a read-only look at the caller may come first), and ` +
|
|
1236
1237
|
`the sender envelope of THAT message is the address. The nonce above is the correlation tag it carries; ` +
|
|
1237
1238
|
`the sibling reads it from its own launch env, never from this receipt. Nothing is polling for it; if it ` +
|
|
1238
|
-
`never comes,
|
|
1239
|
+
`never comes — not started, stuck, or held back after its check; this receipt cannot tell which — the ` +
|
|
1240
|
+
`pane is visible and can be read directly.`,
|
|
1239
1241
|
isError: false,
|
|
1240
1242
|
};
|
|
1241
1243
|
}
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
* a backend listed there is one whose hook writes a pid marker, and codex birth writes none.
|
|
48
48
|
*/
|
|
49
49
|
|
|
50
|
+
import { nativePushPaused } from "./entwurf-v2-contract.ts";
|
|
50
51
|
import {
|
|
51
52
|
defaultMetaSessionsDir,
|
|
52
53
|
describe,
|
|
@@ -229,6 +230,9 @@ export async function probeNativeSenderAlive(
|
|
|
229
230
|
identity: Pick<MetaIdentity, "backend" | "nativeSessionId">,
|
|
230
231
|
deps: { resolveAdapter?: (id: string) => Pick<NativePushAdapter, "probe"> } = {},
|
|
231
232
|
): Promise<boolean> {
|
|
233
|
+
// #152: a paused native-push backend cannot receive a reply, so its `replyable` is false by
|
|
234
|
+
// POLICY — no adapter is resolved or probed. This is not a liveness verdict about the citizen.
|
|
235
|
+
if (nativePushPaused(identity.backend)) return false;
|
|
232
236
|
const resolveAdapter = deps.resolveAdapter ?? resolveNativePushAdapter;
|
|
233
237
|
const probe = await resolveAdapter(identity.backend).probe(identity.nativeSessionId);
|
|
234
238
|
return probe.status === "alive";
|
|
@@ -709,11 +709,13 @@ export function renderFreshCall(result: FreshCallResult): { text: string; isErro
|
|
|
709
709
|
`\n` +
|
|
710
710
|
`This is a LAUNCH receipt: tmux created that window and was asked to start the runtime with the model above. It does ` +
|
|
711
711
|
`NOT mean the sibling is running, that its first turn ran, or that the task was delivered.\n` +
|
|
712
|
-
`The sibling's garden id arrives separately — its
|
|
713
|
-
`(codex is the one arm that still sends the nonce as arguments
|
|
712
|
+
`The sibling's garden id arrives separately — before its task it calls the zero-argument callback verb ` +
|
|
713
|
+
`(codex is the one arm that still sends the nonce as arguments; a read-only look at the caller may come ` +
|
|
714
|
+
`first), and the sender envelope of THAT ` +
|
|
714
715
|
`message is the address. The nonce above is the correlation tag it carries; the sibling reads it ` +
|
|
715
|
-
`from its own launch env, never from this receipt. Nothing is polling for it; if it never comes
|
|
716
|
-
`the window is visible
|
|
716
|
+
`from its own launch env, never from this receipt. Nothing is polling for it; if it never comes — ` +
|
|
717
|
+
`not started, stuck, or held back after its check; this receipt cannot tell which — the window is visible ` +
|
|
718
|
+
`and can be read directly.`,
|
|
717
719
|
isError: false,
|
|
718
720
|
};
|
|
719
721
|
}
|
|
@@ -19,10 +19,12 @@
|
|
|
19
19
|
* deliverability semantics. `check-native-push-register` asserts this file references no
|
|
20
20
|
* receiver-marker writer. (A dedicated register-provenance slot is a future concern.)
|
|
21
21
|
*
|
|
22
|
-
* LEAF-adjacent + pi-free: imports only the native-push adapter (pi-free)
|
|
23
|
-
* upsert (pi-free), so the harness-neutral MCP
|
|
22
|
+
* LEAF-adjacent + pi-free: imports only the native-push adapter (pi-free), the meta-session
|
|
23
|
+
* upsert (pi-free) and the pure v2 contract's paused-backend policy, so the harness-neutral MCP
|
|
24
|
+
* bridge can reach it at boot.
|
|
24
25
|
*/
|
|
25
26
|
|
|
27
|
+
import { nativePushPaused } from "../entwurf-v2-contract.ts";
|
|
26
28
|
import { type MetaCitizenBackend, type UpsertAction, upsertMetaSession } from "../meta-session.ts";
|
|
27
29
|
import { type NativePushAdapter, resolveNativePushAdapter } from "./adapter.ts";
|
|
28
30
|
|
|
@@ -62,6 +64,19 @@ export async function registerNativeConversation(
|
|
|
62
64
|
input: RegisterNativeConversationInput,
|
|
63
65
|
deps: RegisterNativeConversationDeps = {},
|
|
64
66
|
): Promise<RegisterNativeConversationResult> {
|
|
67
|
+
// #152: a paused native-push backend is refused by name BEFORE any adapter is resolved or
|
|
68
|
+
// probed — registration would otherwise reach a language server that refused the measured
|
|
69
|
+
// external calls (missing CSRF token).
|
|
70
|
+
// Nothing is probed and no record is written.
|
|
71
|
+
if (nativePushPaused(input.backend)) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
`entwurf_register_native: refusing to register ${input.backend} conversation ${JSON.stringify(
|
|
74
|
+
input.nativeSessionId,
|
|
75
|
+
)} — native-push for ${input.backend} is paused (#152: its language server refused ` +
|
|
76
|
+
"entwurf's measured external calls for a missing CSRF token). Nothing was probed and no garden id was minted; " +
|
|
77
|
+
"existing records stay readable.",
|
|
78
|
+
);
|
|
79
|
+
}
|
|
65
80
|
const resolveAdapter = deps.resolveAdapter ?? resolveNativePushAdapter;
|
|
66
81
|
const adapter = resolveAdapter(input.backend);
|
|
67
82
|
const probe = await adapter.probe(input.nativeSessionId);
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
* callback callable — THE OMP-SPECIFIC ONE. `tools.xdev` defaults to TRUE, which mounts MCP
|
|
21
21
|
* tools as `xd://` devices whose schemas never reach the prompt. The tool
|
|
22
22
|
* would be configured, the bridge would be running, and the model still
|
|
23
|
-
* could not call `mcp__entwurf_bridge_entwurf_v`. Step 9 clause 5
|
|
24
|
-
* callback the
|
|
23
|
+
* could not call `mcp__entwurf_bridge_entwurf_v`. Step 9 clause 5 puts the
|
|
24
|
+
* callback before the task, so a fresh call onto a default-config host
|
|
25
25
|
* opens a window that can never name itself. `[측정]` #87 A-lane: the
|
|
26
26
|
* vendor default wrapped the send tool and produced a false delivery report.
|
|
27
27
|
*
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* provider spelled out (the bootstrap refuses a model resolved by inference), so
|
|
16
16
|
* the model here is `<provider>/<model id>` split at the FIRST `/` — a catalog id
|
|
17
17
|
* that itself contains `/` keeps it. A model with no provider part is refused.
|
|
18
|
-
* first input the whole framing (callback
|
|
18
|
+
* first input the whole framing (callback before the task) rides the bootstrap's closed
|
|
19
19
|
* `{v:2,task}` payload, whose decoder caps `task` at 16000 characters. A framed
|
|
20
20
|
* task over that cap would open a window whose bootstrap refuses its own argv.
|
|
21
21
|
*
|