@junghanacs/entwurf 0.51.0 → 0.52.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/CHANGELOG.md +60 -0
- package/ENTWURF.json +10 -4
- package/README.md +4 -4
- package/VERIFY.md +1 -1
- package/demo/README.md +1 -1
- package/docs/acp-backend-rail.md +1 -1
- package/docs/setup-clean-host.md +52 -42
- package/mcp/entwurf-bridge/dist/ENTWURF.json +10 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-control-rpc.js +4 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-mailbox-body.js +1 -1
- package/package.json +11 -11
- package/pi/pi-durable/carrier/harness-setup.js +1 -1
- package/pi/pi-durable/carrier/subagent.js +1 -1
- package/pi/pi-durable/overlay/upstream-pin.json +15 -15
- package/pi-extensions/lib/entwurf-control-rpc.ts +5 -1
- package/pi-extensions/lib/meta-mailbox-body.ts +1 -1
- package/pi-extensions/meta-bridge-pi-durable.ts +1 -1
- package/run.sh +37 -34
- package/scripts/check-entwurf-v2-surface.ts +7 -21
- package/scripts/check-gate-qualification.ts +1 -1
- package/scripts/check-pi-durable-send.ts +4 -1
- package/scripts/lib/codex-fresh-source-receipts.ts +12 -6
- package/scripts/mutants/agent-guidance.json +2 -2
- package/scripts/mutants/codex-native.json +2 -2
- package/scripts/mutants/control-send-receipt.json +47 -7
- package/scripts/mutants/pack-install.json +4 -4
- package/scripts/mutants/pi-floor.json +8 -10
- package/scripts/mutants/v2-surface.json +4 -6
- package/scripts/smoke-acp-cortex-live.ts +1 -1
- package/scripts/smoke-acp-v2-send-live.ts +1 -1
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
{
|
|
83
83
|
"name": "harness-setup.js",
|
|
84
84
|
"source": "pi/pi-durable/src/experimental/durable/harness-setup.ts",
|
|
85
|
-
"blob": "
|
|
86
|
-
"sha256": "
|
|
85
|
+
"blob": "5a799bfbfbbedbec229761b26f639fbe2702b623",
|
|
86
|
+
"sha256": "70b50044ab14c1293a2ace53b375dc48ad940ea9eeacc131d498ccb1ce040617"
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
89
|
"name": "prompt.js",
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
{
|
|
101
101
|
"name": "subagent.js",
|
|
102
102
|
"source": "pi/pi-durable/src/experimental/durable/subagent.ts",
|
|
103
|
-
"blob": "
|
|
104
|
-
"sha256": "
|
|
103
|
+
"blob": "8c18e24a030f0b701167f15a33579195303f5ac5",
|
|
104
|
+
"sha256": "208618441e8e81813de2f44fa9ad5d5bdcdbb78a754679bb7a93d82480e7bece"
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
107
|
"name": "session-name.js",
|
|
@@ -138,18 +138,18 @@
|
|
|
138
138
|
]
|
|
139
139
|
},
|
|
140
140
|
"sdk": {
|
|
141
|
-
"comment": "The published library set the carrier runs against, derived from the 1.5.
|
|
141
|
+
"comment": "The published library set the carrier runs against, derived from the 1.5.2 declarations. members: the @earendil-works packages the carrier imports and every @earendil-works package those declare (1.5.0 adds pi-schema, declared by chord, pi-agent-core, pi-ai and pi-durable). direct: a third-party package a carrier file imports itself (sessions.ts: proper-lockfile, at the version pi-coding-agent 1.5.2 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.",
|
|
142
142
|
"members": {
|
|
143
|
-
"@earendil-works/chord": "1.5.
|
|
144
|
-
"@earendil-works/pi-agent-core": "1.5.
|
|
145
|
-
"@earendil-works/pi-ai": "1.5.
|
|
146
|
-
"@earendil-works/pi-codemode": "1.5.
|
|
147
|
-
"@earendil-works/pi-coding-agent": "1.5.
|
|
148
|
-
"@earendil-works/pi-durable": "1.5.
|
|
149
|
-
"@earendil-works/pi-mcp": "1.5.
|
|
150
|
-
"@earendil-works/pi-schema": "1.5.
|
|
151
|
-
"@earendil-works/pi-telemetry": "1.5.
|
|
152
|
-
"@earendil-works/pi-tui": "1.5.
|
|
143
|
+
"@earendil-works/chord": "1.5.2",
|
|
144
|
+
"@earendil-works/pi-agent-core": "1.5.2",
|
|
145
|
+
"@earendil-works/pi-ai": "1.5.2",
|
|
146
|
+
"@earendil-works/pi-codemode": "1.5.2",
|
|
147
|
+
"@earendil-works/pi-coding-agent": "1.5.2",
|
|
148
|
+
"@earendil-works/pi-durable": "1.5.2",
|
|
149
|
+
"@earendil-works/pi-mcp": "1.5.2",
|
|
150
|
+
"@earendil-works/pi-schema": "1.5.2",
|
|
151
|
+
"@earendil-works/pi-telemetry": "1.5.2",
|
|
152
|
+
"@earendil-works/pi-tui": "1.5.2"
|
|
153
153
|
},
|
|
154
154
|
"direct": {
|
|
155
155
|
"proper-lockfile": "4.1.2"
|
|
@@ -50,7 +50,11 @@ export interface SenderEnvelope {
|
|
|
50
50
|
* renders nothing (etiquette marker, not transport contract).
|
|
51
51
|
*/
|
|
52
52
|
export function formatSenderInfoBlock(sender: SenderEnvelope, wantsReply = false): string {
|
|
53
|
-
|
|
53
|
+
const replyGuidance =
|
|
54
|
+
sender.replyable === true
|
|
55
|
+
? "\n\n[entwurf: When a reply is requested, send the result via entwurf_v2 to the requested recipient (default: sender_info.sessionId); a local final is not delivery. Honor routing and no-send instructions; an absent or false wants_reply does not cancel a request. A replyable address alone needs no acknowledgment.]"
|
|
56
|
+
: "";
|
|
57
|
+
return `${replyGuidance}\n\n<sender_info>${JSON.stringify({
|
|
54
58
|
sessionId: sender.sessionId,
|
|
55
59
|
agentId: sender.agentId,
|
|
56
60
|
cwd: sender.cwd,
|
|
@@ -79,7 +79,7 @@ export function formatMetaMailboxBody(sender: MailboxSenderEnvelope, message: st
|
|
|
79
79
|
// SENDING host, so it is neither abbreviated against this host's HOME nor shown as a local path.
|
|
80
80
|
const remote = !replyable ? sender.remote : undefined;
|
|
81
81
|
const sessionLine = replyable
|
|
82
|
-
? `${sender.sessionId} (${kind}replyable — reply
|
|
82
|
+
? `${sender.sessionId} (${kind}replyable — when a reply is requested, send the result via entwurf_v2 (intent=fire-and-forget) to the requested recipient, defaulting to this sessionId; a local final is not delivery. Honor routing and no-send instructions; an absent or false wants_reply does not cancel a request. A replyable address alone needs no acknowledgment)`
|
|
83
83
|
: remote
|
|
84
84
|
? `${sender.sessionId} (remote via ${remote.via}; ${remote.replyRoute === "declared" ? "reply route declared, not probed" : "no reply route declared"})`
|
|
85
85
|
: isMeta
|
|
@@ -349,7 +349,7 @@ export interface PiDurableRoots {
|
|
|
349
349
|
// ---------------------------------------------------------------------------
|
|
350
350
|
// Durable surface, typed NARROWLY and locally — read at pi-durable 1.0.2 @cd32f77 (#129,
|
|
351
351
|
// `harness/types.ts`; historical coordinates, not re-anchored here). The current supply is the
|
|
352
|
-
// carrier emitted from Entwurf's owned source (pi/pi-durable/src, #141) against the 1.5.
|
|
352
|
+
// carrier emitted from Entwurf's owned source (pi/pi-durable/src, #141) against the 1.5.2 SDK set
|
|
353
353
|
// `pi/pi-durable/overlay/upstream-pin.json` names (origin `abe508e`). `[read 2026-10-13]` at
|
|
354
354
|
// v1.2.0 one shape typed below moved: `ToolExecutionResult.content` is now `output`, beside the new
|
|
355
355
|
// `structuredOutput` (`harness/types.ts`, its CHANGELOG's breaking changes). An omitted `output`
|
package/run.sh
CHANGED
|
@@ -1156,8 +1156,10 @@ check_control_send_receipt() {
|
|
|
1156
1156
|
# test titles `run_vitest` emits. Narrow file filter, same reason as check-entwurf-v2-send.
|
|
1157
1157
|
# It stays inside check:contracts even though the discovery door also runs this file — see
|
|
1158
1158
|
# check-release-gate-outcomes: a gate a mutant names must be reachable outside qualification.
|
|
1159
|
-
|
|
1160
|
-
|
|
1159
|
+
# #159 adds the three delivery-input seams here as a shared mutant coordinate; discovery remains
|
|
1160
|
+
# the beside glob. This reuses the existing gate instead of adding a second help/catalog surface.
|
|
1161
|
+
section "control-socket acceptance and received guidance (mutant execution coordinate)"
|
|
1162
|
+
run_vitest pi-extensions/lib/control-send-receipt.test.ts pi-extensions/entwurf-control.test.ts pi-extensions/lib/entwurf-v2-mailbox.test.ts pi-extensions/lib/entwurf-v2-native-push.test.ts
|
|
1161
1163
|
}
|
|
1162
1164
|
|
|
1163
1165
|
check_control_retire() {
|
|
@@ -2502,15 +2504,16 @@ assert.deepEqual(floorGaps, [],
|
|
|
2502
2504
|
// The published-scope regions' own oracle (see PUBLISHED-SCOPE REGIONS above). Checked after the
|
|
2503
2505
|
// four surfaces so a stranded closure row is still attributed to the claim above.
|
|
2504
2506
|
// PUBLISHED_ARTIFACT is the one published pair a region may name, copied from the artifact, not from
|
|
2505
|
-
// this checkout.
|
|
2506
|
-
//
|
|
2507
|
-
//
|
|
2507
|
+
// this checkout. Read 2026-11-11 from package/package.json in the preserved registry-accepted
|
|
2508
|
+
// 0.51.0 release TGZ (TGZ SHA256 04fcce26d0a6dec8b8bb9a7f14a843eee0defb313aedafa34080600853d36e4d;
|
|
2509
|
+
// raw manifest SHA256 b5043ba8edde6f2b9d13052a98c3cd808a3b30f1023da41b22ee022470a96120).
|
|
2510
|
+
// Its ten @earendil-works production dependencies are exact 1.5.0, independent of this checkout.
|
|
2508
2511
|
const PUBLISHED_ARTIFACT = {
|
|
2509
|
-
version: '0.
|
|
2512
|
+
version: '0.51.0',
|
|
2510
2513
|
dependencies: {
|
|
2511
|
-
'@earendil-works/chord': '1.
|
|
2512
|
-
'@earendil-works/pi-codemode': '1.
|
|
2513
|
-
'@earendil-works/pi-mcp': '1.
|
|
2514
|
+
'@earendil-works/chord': '1.5.0', '@earendil-works/pi-agent-core': '1.5.0', '@earendil-works/pi-ai': '1.5.0',
|
|
2515
|
+
'@earendil-works/pi-codemode': '1.5.0', '@earendil-works/pi-coding-agent': '1.5.0', '@earendil-works/pi-durable': '1.5.0',
|
|
2516
|
+
'@earendil-works/pi-mcp': '1.5.0', '@earendil-works/pi-schema': '1.5.0', '@earendil-works/pi-telemetry': '1.5.0', '@earendil-works/pi-tui': '1.5.0',
|
|
2514
2517
|
},
|
|
2515
2518
|
};
|
|
2516
2519
|
const publishedSdk = [...new Set(Object.values(PUBLISHED_ARTIFACT.dependencies))];
|
|
@@ -4129,7 +4132,7 @@ check_pack_win32_carrier() {
|
|
|
4129
4132
|
# which is exactly what property (1)'s `(_|$)` absorbs; all three shapes are fixtures
|
|
4130
4133
|
# below so a future suffix change cannot pass vacuously.)
|
|
4131
4134
|
pack_install_leaked_pi() {
|
|
4132
|
-
grep '^@earendil-works+' | grep -Ev '@1\.5\.
|
|
4135
|
+
grep '^@earendil-works+' | grep -Ev '@1\.5\.2(_|$)' || true
|
|
4133
4136
|
}
|
|
4134
4137
|
|
|
4135
4138
|
# Matcher self-test on SYNTHETIC lookalikes: a healthy install tree cannot exercise either
|
|
@@ -4146,18 +4149,18 @@ check_pack_pin_matcher() {
|
|
|
4146
4149
|
# Cell 1 — the version boundary. Every measured peer-hash shape is a fixture: the
|
|
4147
4150
|
# 0.84.4-era `_@modelcontextprotocol+sdk@…`, the `_ws@8.21.3` observed on a real
|
|
4148
4151
|
# 0.85.1 tree, and `[측정 2026-09-20]` the combined suffix a 0.86.0 install carries.
|
|
4149
|
-
# None may leak; the two lookalikes must — a PREFIX-EXTENDED version (`1.5.
|
|
4152
|
+
# None may leak; the two lookalikes must — a PREFIX-EXTENDED version (`1.5.2-beta.1`,
|
|
4150
4153
|
# the prerelease shape that an unanchored match would bless) and an off-pin version.
|
|
4151
4154
|
matcher_probe=$(printf '%s\n' \
|
|
4152
|
-
'@earendil-works+pi-ai@1.5.
|
|
4153
|
-
'@earendil-works+pi-ai@1.5.
|
|
4154
|
-
'@earendil-works+pi-ai@1.5.
|
|
4155
|
-
'@earendil-works+pi-ai@1.5.
|
|
4156
|
-
'@earendil-works+pi-ai@1.5.
|
|
4155
|
+
'@earendil-works+pi-ai@1.5.2' \
|
|
4156
|
+
'@earendil-works+pi-ai@1.5.2_@modelcontextprotocol+sdk@1.29.0_zod@4.3.6' \
|
|
4157
|
+
'@earendil-works+pi-ai@1.5.2_ws@8.21.3' \
|
|
4158
|
+
'@earendil-works+pi-ai@1.5.2_@modelcontextprotocol+sdk@1.29.0_zod@4.3.6__ws@8.21.3_zod@4.3.6' \
|
|
4159
|
+
'@earendil-works+pi-ai@1.5.2-beta.1' \
|
|
4157
4160
|
'@earendil-works+pi-agent-core@0.87.1' | pack_install_leaked_pi)
|
|
4158
|
-
if [ "$matcher_probe" != '@earendil-works+pi-ai@1.5.
|
|
4161
|
+
if [ "$matcher_probe" != '@earendil-works+pi-ai@1.5.2-beta.1
|
|
4159
4162
|
@earendil-works+pi-agent-core@0.87.1' ]; then
|
|
4160
|
-
fail "[QK:PACK-INSTALL-PIN-MATCHER-BOUNDED] the pin-leak matcher must flag the prefix-extended 1.5.
|
|
4163
|
+
fail "[QK:PACK-INSTALL-PIN-MATCHER-BOUNDED] the pin-leak matcher must flag the prefix-extended 1.5.2-beta.1 and the off-pin 0.87.1 lookalikes, and pass 1.5.2 bare or with any measured peer-hash — got: ${matcher_probe:-<nothing leaked>}"
|
|
4161
4164
|
return 1
|
|
4162
4165
|
fi
|
|
4163
4166
|
|
|
@@ -4165,9 +4168,9 @@ check_pack_pin_matcher() {
|
|
|
4165
4168
|
# (0.85.0 onward, still true at 0.99.1). An off-pin chord MUST leak; the pinned one must not. A matcher narrowed
|
|
4166
4169
|
# back to `^@earendil-works+pi-` sees nothing here and dies at this signature.
|
|
4167
4170
|
matcher_probe=$(printf '%s\n' \
|
|
4168
|
-
'@earendil-works+chord@1.5.
|
|
4171
|
+
'@earendil-works+chord@1.5.2' \
|
|
4169
4172
|
'@earendil-works+chord@0.87.1' \
|
|
4170
|
-
'@earendil-works+pi-ai@1.5.
|
|
4173
|
+
'@earendil-works+pi-ai@1.5.2' | pack_install_leaked_pi)
|
|
4171
4174
|
if [ "$matcher_probe" != '@earendil-works+chord@0.87.1' ]; then
|
|
4172
4175
|
fail "[QK:PACK-INSTALL-PIN-MATCHER-COVERS-CLOSURE] the pin-leak matcher must cover every @earendil-works closure member, not just the pi-* families — an off-pin @earendil-works/chord has to leak (it was a runtime dependency of pi-coding-agent, pi-agent-core, pi-client and pi-protocol — `[측정 2026-09-20]` at 0.86.0, re-measured `[측정 2026-09-22]` at 0.87.0, `[측정 2026-09-23]` at 0.87.1 and `[측정 2026-09-30]` at 0.99.1, where pi-coding-agent adds pi-codemode and pi-mcp beside them; `[측정 2026-10-13]` at 1.2.0 pi-durable alone declares it) — got: ${matcher_probe:-<nothing leaked>}"
|
|
4173
4176
|
return 1
|
|
@@ -5089,16 +5092,16 @@ _check_pack_install_impl() {
|
|
|
5089
5092
|
local install_log
|
|
5090
5093
|
install_log=$(cd "$tmp" && pnpm add \
|
|
5091
5094
|
"$tgz_path" \
|
|
5092
|
-
"@earendil-works/pi-ai@1.5.
|
|
5093
|
-
"@earendil-works/pi-coding-agent@1.5.
|
|
5094
|
-
"@earendil-works/pi-tui@1.5.
|
|
5095
|
-
"@earendil-works/pi-agent-core@1.5.
|
|
5096
|
-
"@earendil-works/pi-telemetry@1.5.
|
|
5097
|
-
"@earendil-works/chord@1.5.
|
|
5098
|
-
"@earendil-works/pi-codemode@1.5.
|
|
5099
|
-
"@earendil-works/pi-mcp@1.5.
|
|
5100
|
-
"@earendil-works/pi-durable@1.5.
|
|
5101
|
-
"@earendil-works/pi-schema@1.5.
|
|
5095
|
+
"@earendil-works/pi-ai@1.5.2" \
|
|
5096
|
+
"@earendil-works/pi-coding-agent@1.5.2" \
|
|
5097
|
+
"@earendil-works/pi-tui@1.5.2" \
|
|
5098
|
+
"@earendil-works/pi-agent-core@1.5.2" \
|
|
5099
|
+
"@earendil-works/pi-telemetry@1.5.2" \
|
|
5100
|
+
"@earendil-works/chord@1.5.2" \
|
|
5101
|
+
"@earendil-works/pi-codemode@1.5.2" \
|
|
5102
|
+
"@earendil-works/pi-mcp@1.5.2" \
|
|
5103
|
+
"@earendil-works/pi-durable@1.5.2" \
|
|
5104
|
+
"@earendil-works/pi-schema@1.5.2" \
|
|
5102
5105
|
--ignore-workspace --ignore-scripts 2>&1) || {
|
|
5103
5106
|
fail "[check-pack-install] pnpm add failed:"
|
|
5104
5107
|
echo "$install_log" | tail -10 | sed 's/^/ /' >&2
|
|
@@ -5107,17 +5110,17 @@ _check_pack_install_impl() {
|
|
|
5107
5110
|
|
|
5108
5111
|
# A pin is a wish until the resolved tree is read back. Assert it: EVERY
|
|
5109
5112
|
# @earendil-works package present — direct or transitive, top level or nested,
|
|
5110
|
-
# chord included — must be the pinned
|
|
5113
|
+
# chord included — must be the pinned 1.5.2. Anything else means an unpinned caret
|
|
5111
5114
|
# floated and the rest of this gate would be exercising a runtime nobody verified,
|
|
5112
|
-
# while still printing
|
|
5115
|
+
# while still printing a pinned runtime. Fail loud instead of proving the wrong floor.
|
|
5113
5116
|
local leaked_pi
|
|
5114
5117
|
leaked_pi=$(ls "$tmp/node_modules/.pnpm" 2>/dev/null | pack_install_leaked_pi)
|
|
5115
5118
|
if [ -n "$leaked_pi" ]; then
|
|
5116
|
-
fail "[check-pack-install] UNVERIFIED pi runtime resolved into the install tree (expected only 1.5.
|
|
5119
|
+
fail "[check-pack-install] UNVERIFIED pi runtime resolved into the install tree (expected only 1.5.2):"
|
|
5117
5120
|
printf '%s\n' "$leaked_pi" | sed 's/^/ /' >&2
|
|
5118
5121
|
return 1
|
|
5119
5122
|
fi
|
|
5120
|
-
echo "[check-pack-install] pi runtime tree pin verified: every @earendil-works package is 1.5.
|
|
5123
|
+
echo "[check-pack-install] pi runtime tree pin verified: every @earendil-works package is 1.5.2 (chord, pi-durable and pi-schema included)"
|
|
5121
5124
|
|
|
5122
5125
|
# Resolve the installed package.json and confirm pi.extensions
|
|
5123
5126
|
# arrived intact. If pi.extensions is empty or missing, the
|
|
@@ -92,7 +92,7 @@ function assertRailSemantics(tag: string, longDescRaw: string, intentDescRaw: st
|
|
|
92
92
|
);
|
|
93
93
|
ok(
|
|
94
94
|
`${tag} — long description names the THIRD result for an unsupported citizen`,
|
|
95
|
-
/mailbox-undeliverable/.test(longDesc) && /THIRD RESULT/.test(longDesc),
|
|
95
|
+
/mailbox-undeliverable/.test(longDesc) && /target without a live socket, the THIRD RESULT/.test(longDesc),
|
|
96
96
|
);
|
|
97
97
|
ok(
|
|
98
98
|
`${tag} — intent param names a rail's reject, not only its allow cell`,
|
|
@@ -139,30 +139,16 @@ function assertRailSemantics(tag: string, longDescRaw: string, intentDescRaw: st
|
|
|
139
139
|
* whose subject (two distinct OWNED rejects) left with the `owned-outcome` intent.
|
|
140
140
|
*
|
|
141
141
|
* After the visible-first cut a dormant socket-domain citizen rejects delivery by v2, and
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* an operator who read last week's docs with no way to find out what happened;
|
|
147
|
-
* - say it was `withdrawn`, ADJACENTLY to that name. Presence alone is not enough: naming a
|
|
148
|
-
* retired intent without the retirement verb beside it reads as an offer, which is exactly
|
|
149
|
-
* the "advertised as selectable" failure this claim exists to forbid;
|
|
150
|
-
* - carry NEITHER retired advertisement form (`owned-outcome = …` enum styling, or the old
|
|
151
|
-
* "DORMANT socket-domain citizen … never auto-converted" sentence that described picking it).
|
|
152
|
-
*
|
|
153
|
-
* ORDER IS LOAD-BEARING, and not for readability. `ok` throws on the FIRST failure, and the kill
|
|
154
|
-
* signature is read off the failing line — so the `[QK:…]` label must sit on the assertion this
|
|
155
|
-
* claim's mutant reaches FIRST. That mutant drops the reason AND the withdrawal in one edit; with
|
|
156
|
-
* the reason check leading, an UNLABELLED line would throw first and the kill would read as
|
|
157
|
-
* WRONG-REASON. The adjacency check therefore goes first and carries the only token; the other two
|
|
158
|
-
* run unlabelled behind it — still real assertions, just not this claim's signature.
|
|
142
|
+
* both caller-facing strings must independently name the actual dormant rejection and say that
|
|
143
|
+
* delivery never launches or resumes a process. Neither may advertise the retired offer. History
|
|
144
|
+
* belongs in the issue and literal amendment, not in the current caller contract. The labelled
|
|
145
|
+
* assertion comes first because qualification reads the first failing line as the kill signature.
|
|
159
146
|
*/
|
|
160
147
|
function assertDormantHonesty(tag: string, rawText: string): void {
|
|
161
148
|
const text = rawText;
|
|
162
|
-
const at = text.indexOf("owned-outcome");
|
|
163
149
|
ok(
|
|
164
|
-
`${tag} —
|
|
165
|
-
|
|
150
|
+
`${tag} — delivery never launches or resumes a process and names the dormant rejection [QK:V2SURF-DORMANT-HONESTY]`,
|
|
151
|
+
/This delivery verb never launches or resumes a process/.test(text) && /dormant-fire-forget-unsupported/.test(text),
|
|
166
152
|
);
|
|
167
153
|
ok(`${tag} — names the reason a dormant target actually returns`, /dormant-fire-forget-unsupported/.test(text));
|
|
168
154
|
ok(
|
|
@@ -3460,7 +3460,7 @@ let manifestCount: number;
|
|
|
3460
3460
|
"pi-retire-request": 6,
|
|
3461
3461
|
"retirement-event": 16,
|
|
3462
3462
|
"control-retire": 9,
|
|
3463
|
-
"control-send-receipt":
|
|
3463
|
+
"control-send-receipt": 23,
|
|
3464
3464
|
"codex-native": 95,
|
|
3465
3465
|
"native-push-paused": 1,
|
|
3466
3466
|
"chain-terminus-publication": 1,
|
|
@@ -900,7 +900,10 @@ async function cell(): Promise<void> {
|
|
|
900
900
|
hostReceiver.ownerKind === "pi-durable-host";
|
|
901
901
|
ok(
|
|
902
902
|
`[QK:${QK}-SENDER-REPLYABILITY] the host's receiver marker is armed and owned by the spawned host, and the landed body says what that predicts: replyable (armed ${hostArmed})`,
|
|
903
|
-
hostArmed &&
|
|
903
|
+
hostArmed &&
|
|
904
|
+
body.includes(
|
|
905
|
+
`session: ${hostGid} (meta-session, replyable — when a reply is requested, send the result via entwurf_v2`,
|
|
906
|
+
),
|
|
904
907
|
);
|
|
905
908
|
const hostRecords = fs
|
|
906
909
|
.readdirSync(dirs.sessions)
|
|
@@ -452,14 +452,20 @@ export function codexSourceToolReceipts(thread: unknown): SourceToolReceipt[] {
|
|
|
452
452
|
}
|
|
453
453
|
|
|
454
454
|
function exactSenderInfoSuffix(text: string, nonce: string): string | null {
|
|
455
|
-
|
|
455
|
+
// Independent expected frame: never import the producer's guidance as the receipt oracle.
|
|
456
|
+
const guidance =
|
|
457
|
+
"\n\n[entwurf: When a reply is requested, send the result via entwurf_v2 to the requested recipient (default: sender_info.sessionId); a local final is not delivery. Honor routing and no-send instructions; an absent or false wants_reply does not cancel a request. A replyable address alone needs no acknowledgment.]";
|
|
458
|
+
const open = "<sender_info>";
|
|
456
459
|
const suffix = "</sender_info>";
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
+
const at = text.lastIndexOf(open);
|
|
461
|
+
if (at < 0 || !text.endsWith(suffix)) return null;
|
|
462
|
+
const json = text.slice(at + open.length, -suffix.length);
|
|
463
|
+
if (json.includes("\n") || json.includes(open)) return null;
|
|
460
464
|
try {
|
|
461
|
-
const sender = JSON.parse(json) as { sessionId?: unknown };
|
|
462
|
-
|
|
465
|
+
const sender = JSON.parse(json) as { sessionId?: unknown; replyable?: unknown };
|
|
466
|
+
const prefix = `${nonce}${sender.replyable === true ? guidance : ""}\n\n${open}`;
|
|
467
|
+
if (!text.startsWith(prefix) || !text.endsWith(suffix)) return null;
|
|
468
|
+
return at === prefix.length - open.length && typeof sender.sessionId === "string" ? sender.sessionId : null;
|
|
463
469
|
} catch {
|
|
464
470
|
return null;
|
|
465
471
|
}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
"claim": "GUIDANCE-REVIEWED-REVISION",
|
|
7
7
|
"title": "a valid Root revision advances beyond the independently reviewed payload revision while every history entry and decoded tool string remains valid",
|
|
8
8
|
"subject": "ENTWURF.json",
|
|
9
|
-
"find": ["\t\"revision\":
|
|
10
|
-
"replace": ["\t\"revision\":
|
|
9
|
+
"find": ["\t\"revision\": 20,", "\t\"history\": ["],
|
|
10
|
+
"replace": ["\t\"revision\": 21,", "\t\"history\": ["],
|
|
11
11
|
"gate": ["bash", "run.sh", "check-agent-guidance-beside"],
|
|
12
12
|
"timeoutSeconds": 120,
|
|
13
13
|
"signature": "[QK:GUIDANCE-REVIEWED-REVISION]",
|
|
@@ -715,9 +715,9 @@
|
|
|
715
715
|
"claim": "CODEX-LIVE-RAW-CALLBACK-REQUIRED",
|
|
716
716
|
"title": "a Pi callback with arbitrary bytes after its sender envelope is accepted as exact",
|
|
717
717
|
"subject": "scripts/lib/codex-fresh-source-receipts.ts",
|
|
718
|
-
"find": ["\
|
|
718
|
+
"find": ["\tconst suffix = \"</sender_info>\";"],
|
|
719
719
|
"replace": [
|
|
720
|
-
"\
|
|
720
|
+
"\tconst suffix = \"</sender_info>\";\n\tconst suffixAt = text.indexOf(suffix);\n\tif (suffixAt >= 0) text = text.slice(0, suffixAt + suffix.length); // mutant: discard callback suffix"
|
|
721
721
|
],
|
|
722
722
|
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
723
723
|
"timeoutSeconds": 180,
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"gate": ["bash", "run.sh", "check-control-send-receipt"],
|
|
12
12
|
"timeoutSeconds": 600,
|
|
13
13
|
"signature": "[QK:SEND-RECEIPT-IDLE-IS-SENT]",
|
|
14
|
-
"signatureSource": "pi-extensions/lib/control-send-receipt.test.ts"
|
|
14
|
+
"signatureSource": "pi-extensions/lib/control-send-receipt.test.ts",
|
|
15
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
15
16
|
},
|
|
16
17
|
{
|
|
17
18
|
"claim": "SEND-RECEIPT-BUSY-STEER-IS-QUEUED",
|
|
@@ -22,7 +23,8 @@
|
|
|
22
23
|
"gate": ["bash", "run.sh", "check-control-send-receipt"],
|
|
23
24
|
"timeoutSeconds": 600,
|
|
24
25
|
"signature": "[QK:SEND-RECEIPT-BUSY-STEER-IS-QUEUED]",
|
|
25
|
-
"signatureSource": "pi-extensions/lib/control-send-receipt.test.ts"
|
|
26
|
+
"signatureSource": "pi-extensions/lib/control-send-receipt.test.ts",
|
|
27
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
26
28
|
},
|
|
27
29
|
{
|
|
28
30
|
"claim": "SEND-RECEIPT-BUSY-FOLLOWUP-IS-QUEUED",
|
|
@@ -33,7 +35,8 @@
|
|
|
33
35
|
"gate": ["bash", "run.sh", "check-control-send-receipt"],
|
|
34
36
|
"timeoutSeconds": 600,
|
|
35
37
|
"signature": "[QK:SEND-RECEIPT-BUSY-FOLLOWUP-IS-QUEUED]",
|
|
36
|
-
"signatureSource": "pi-extensions/lib/control-send-receipt.test.ts"
|
|
38
|
+
"signatureSource": "pi-extensions/lib/control-send-receipt.test.ts",
|
|
39
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
37
40
|
},
|
|
38
41
|
{
|
|
39
42
|
"claim": "SEND-RECEIPT-UNKNOWN-IS-ACCEPTED-NOT-SENT",
|
|
@@ -44,7 +47,8 @@
|
|
|
44
47
|
"gate": ["bash", "run.sh", "check-control-send-receipt"],
|
|
45
48
|
"timeoutSeconds": 600,
|
|
46
49
|
"signature": "[QK:SEND-RECEIPT-UNKNOWN-IS-ACCEPTED-NOT-SENT]",
|
|
47
|
-
"signatureSource": "pi-extensions/lib/control-send-receipt.test.ts"
|
|
50
|
+
"signatureSource": "pi-extensions/lib/control-send-receipt.test.ts",
|
|
51
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
48
52
|
},
|
|
49
53
|
{
|
|
50
54
|
"claim": "SEND-BOUNDARY-CARRIED",
|
|
@@ -194,7 +198,7 @@
|
|
|
194
198
|
"claim": "PI-CORE-PIN-TRACKS-FLOOR",
|
|
195
199
|
"title": "the queue oracle's pi-agent-core pin drifts off the floor the rest of the pi runtime is pinned to, so the oracle keeps answering honestly — about a pi nobody in this repo runs",
|
|
196
200
|
"subject": "package.json",
|
|
197
|
-
"find": ["\"@earendil-works/pi-agent-core\": \"1.5.
|
|
201
|
+
"find": ["\"@earendil-works/pi-agent-core\": \"1.5.2\","],
|
|
198
202
|
"replace": ["\"@earendil-works/pi-agent-core\": \"0.87.1\","],
|
|
199
203
|
"gate": ["bash", "run.sh", "check-dep-versions"],
|
|
200
204
|
"timeoutSeconds": 300,
|
|
@@ -240,15 +244,51 @@
|
|
|
240
244
|
"title": "the caller-facing outcome list drops the native-push rail, so a caller reading the one blurb it reads before dispatching is told the control rail's vocabulary covers a rail that answers with a direct injection instead",
|
|
241
245
|
"subject": "ENTWURF.json",
|
|
242
246
|
"find": [
|
|
243
|
-
"native-push INJECTION, a rejection, or lock-dirty.
|
|
247
|
+
"native-push INJECTION, a rejection, or lock-dirty. A receipt is not a reply or proof of reading. A local final is not delivery:"
|
|
244
248
|
],
|
|
245
249
|
"replace": [
|
|
246
|
-
"a rejection, or lock-dirty.
|
|
250
|
+
"a rejection, or lock-dirty. A receipt is not a reply or proof of reading. A local final is not delivery:"
|
|
247
251
|
],
|
|
248
252
|
"gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
|
|
249
253
|
"timeoutSeconds": 300,
|
|
250
254
|
"signature": "[QK:SEND-OUTCOME-LIST-NAMES-EVERY-RAIL]",
|
|
251
255
|
"signatureSource": "scripts/check-entwurf-v2-surface.ts"
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
"claim": "PI-RECEIVED-REPLY-GUIDANCE",
|
|
259
|
+
"title": "the Pi receiver omits guidance for a replyable sender, so a local final can be mistaken for a reply",
|
|
260
|
+
"subject": "pi-extensions/lib/entwurf-control-rpc.ts",
|
|
261
|
+
"find": ["sender.replyable === true"],
|
|
262
|
+
"replace": ["sender.replyable === false"],
|
|
263
|
+
"gate": ["bash", "run.sh", "check-control-send-receipt"],
|
|
264
|
+
"timeoutSeconds": 300,
|
|
265
|
+
"signature": "[QK:PI-RECEIVED-REPLY-GUIDANCE]",
|
|
266
|
+
"signatureSource": "pi-extensions/entwurf-control.test.ts",
|
|
267
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"claim": "MAILBOX-RECEIVED-REPLY-GUIDANCE",
|
|
271
|
+
"title": "the mailbox receiver's guidance drops the local-final boundary",
|
|
272
|
+
"subject": "pi-extensions/lib/meta-mailbox-body.ts",
|
|
273
|
+
"find": ["a local final is not delivery."],
|
|
274
|
+
"replace": ["a local final is delivery."],
|
|
275
|
+
"gate": ["bash", "run.sh", "check-control-send-receipt"],
|
|
276
|
+
"timeoutSeconds": 300,
|
|
277
|
+
"signature": "[QK:MAILBOX-RECEIVED-REPLY-GUIDANCE]",
|
|
278
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-mailbox.test.ts",
|
|
279
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"claim": "NATIVE-PUSH-RECEIVED-REPLY-GUIDANCE",
|
|
283
|
+
"title": "the native-push receiver's guidance drops the no-send boundary",
|
|
284
|
+
"subject": "pi-extensions/lib/meta-mailbox-body.ts",
|
|
285
|
+
"find": ["Honor routing and no-send instructions;"],
|
|
286
|
+
"replace": ["Ignore routing and no-send instructions;"],
|
|
287
|
+
"gate": ["bash", "run.sh", "check-control-send-receipt"],
|
|
288
|
+
"timeoutSeconds": 300,
|
|
289
|
+
"signature": "[QK:NATIVE-PUSH-RECEIVED-REPLY-GUIDANCE]",
|
|
290
|
+
"signatureSource": "pi-extensions/lib/entwurf-v2-native-push.test.ts",
|
|
291
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
252
292
|
}
|
|
253
293
|
]
|
|
254
294
|
}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
"claim": "PACK-INSTALL-PIN-MATCHER-BOUNDED",
|
|
7
7
|
"title": "the pin-leak matcher loses its version boundary and blesses substring lookalikes \u2014 @0.85.10 reads as the pinned 0.85.1 and the gate announces a verified tree it never verified (independent review, 2026-08-25)",
|
|
8
8
|
"subject": "run.sh",
|
|
9
|
-
"find": [" grep '^@earendil-works+' | grep -Ev '@1\\.5\\.
|
|
10
|
-
"replace": [" grep '^@earendil-works+' | grep -v '@1\\.5\\.
|
|
9
|
+
"find": [" grep '^@earendil-works+' | grep -Ev '@1\\.5\\.2(_|$)' || true"],
|
|
10
|
+
"replace": [" grep '^@earendil-works+' | grep -v '@1\\.5\\.2' || true"],
|
|
11
11
|
"gate": ["bash", "run.sh", "check-pack-pin-matcher"],
|
|
12
12
|
"timeoutSeconds": 120,
|
|
13
13
|
"signature": "[QK:PACK-INSTALL-PIN-MATCHER-BOUNDED]",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"claim": "PACK-INSTALL-PIN-MATCHER-COVERS-CLOSURE",
|
|
18
18
|
"title": "the pin-leak matcher narrows back to the pi-* families and goes blind to a non-pi member of the same runtime closure \u2014 @earendil-works/chord (new in pi 0.85.0, a runtime dependency of pi-coding-agent/pi-agent-core/pi-client/pi-protocol) floats unpinned while the gate prints a verified pin (measured 2026-09-06 on a real 0.85.1 install tree)",
|
|
19
19
|
"subject": "run.sh",
|
|
20
|
-
"find": [" grep '^@earendil-works+' | grep -Ev '@1\\.5\\.
|
|
21
|
-
"replace": [" grep '^@earendil-works+pi-' | grep -Ev '@1\\.5\\.
|
|
20
|
+
"find": [" grep '^@earendil-works+' | grep -Ev '@1\\.5\\.2(_|$)' || true"],
|
|
21
|
+
"replace": [" grep '^@earendil-works+pi-' | grep -Ev '@1\\.5\\.2(_|$)' || true"],
|
|
22
22
|
"gate": ["bash", "run.sh", "check-pack-pin-matcher"],
|
|
23
23
|
"timeoutSeconds": 120,
|
|
24
24
|
"signature": "[QK:PACK-INSTALL-PIN-MATCHER-COVERS-CLOSURE]",
|
|
@@ -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 || 1.5.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 || 1.5.2'"
|
|
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 || 1.4.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 || 1.5.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.5.
|
|
25
|
-
"replace": ["\"@earendil-works/pi-durable\": \"1.
|
|
24
|
+
"find": ["\"@earendil-works/pi-durable\": \"1.5.2\","],
|
|
25
|
+
"replace": ["\"@earendil-works/pi-durable\": \"1.5.0\","],
|
|
26
26
|
"gate": ["bash", "run.sh", "check-dep-versions"],
|
|
27
27
|
"timeoutSeconds": 300,
|
|
28
28
|
"signature": "[QK:PI-SDK-PRODUCTION-SET]",
|
|
@@ -33,7 +33,7 @@
|
|
|
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.5.
|
|
36
|
+
"replace": ["\"@biomejs/biome\": \"^2.4.13\",\n\t\t\"@earendil-works/pi-ai\": \"1.5.2\","],
|
|
37
37
|
"gate": ["bash", "run.sh", "check-dep-versions"],
|
|
38
38
|
"timeoutSeconds": 300,
|
|
39
39
|
"signature": "[QK:PI-SDK-NO-DUAL-DECLARATION]",
|
|
@@ -41,15 +41,13 @@
|
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
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.
|
|
44
|
+
"title": "a published-scope region in an operator doc names a package the frozen published manifest does not record, so the 1.5.0 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
45
|
"subject": "docs/setup-clean-host.md",
|
|
46
46
|
"find": [
|
|
47
|
-
"<!-- entwurf:published @junghanacs/entwurf@0.
|
|
48
|
-
"| Component | Requirement | Needed for |"
|
|
47
|
+
"| pi | optional-by-presence — published 0.51.0: <!-- entwurf:published @junghanacs/entwurf@0.51.0 pi 1.5.0 -->"
|
|
49
48
|
],
|
|
50
49
|
"replace": [
|
|
51
|
-
"<!-- entwurf:published @junghanacs/entwurf@0.
|
|
52
|
-
"| Component | Requirement | Needed for |"
|
|
50
|
+
"| pi | optional-by-presence — published 0.51.0: <!-- entwurf:published @junghanacs/entwurf@0.50.0 pi 1.5.0 -->"
|
|
53
51
|
],
|
|
54
52
|
"gate": ["bash", "run.sh", "check-dep-versions"],
|
|
55
53
|
"timeoutSeconds": 300,
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"title": "MCP long description reverts to the false \"socket paths take a per-target lock\" claim",
|
|
23
23
|
"subject": "ENTWURF.json",
|
|
24
24
|
"find": [
|
|
25
|
-
"
|
|
25
|
+
"A control-socket-DOMAIN dispatch takes a target lock; mailbox and native-push rails are lock-free. mode "
|
|
26
26
|
],
|
|
27
27
|
"replace": ["LOCK POLICY: socket paths take a per-target lock; the mailbox path does not. mode "],
|
|
28
28
|
"gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
|
|
@@ -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.
|
|
84
|
+
"A dormant socket rejects this delivery verb as dormant-fire-forget-unsupported. This delivery verb never launches or resumes a process. 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. "
|
|
@@ -132,11 +132,9 @@
|
|
|
132
132
|
"claim": "V2SURF-DESC-FITS-HOST-CAP",
|
|
133
133
|
"title": "the v2 tool description grows back past the host's 2048-char cap — the INTENT contract is silently cut off before the model that must choose an intent ever reads it",
|
|
134
134
|
"subject": "ENTWURF.json",
|
|
135
|
-
"find": [
|
|
136
|
-
"CANONICAL DELIVERY SURFACE for garden ids: message, reply, or hand off to whoever an id names. The id "
|
|
137
|
-
],
|
|
135
|
+
"find": ["Send, reply or hand off to an existing garden id; the decider selects the live rail "],
|
|
138
136
|
"replace": [
|
|
139
|
-
"
|
|
137
|
+
"Send, reply or hand off to an existing garden id; the decider selects the live rail PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING "
|
|
140
138
|
],
|
|
141
139
|
"gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
|
|
142
140
|
"timeoutSeconds": 60,
|
|
@@ -354,7 +354,7 @@ async function main(): Promise<void> {
|
|
|
354
354
|
ok(
|
|
355
355
|
"the landed sender session IS the resident's own garden id, replyable (anchored envelope line)",
|
|
356
356
|
new RegExp(
|
|
357
|
-
`^ {2}session: {5}${rx(senderGid)}
|
|
357
|
+
`^ {2}session: {5}${rx(senderGid)} ${rx("(replyable — when a reply is requested, send the result via entwurf_v2 (intent=fire-and-forget) to the requested recipient, defaulting to this sessionId; a local final is not delivery. Honor routing and no-send instructions; an absent or false wants_reply does not cancel a request. A replyable address alone needs no acknowledgment)")}$`,
|
|
358
358
|
"m",
|
|
359
359
|
).test(header),
|
|
360
360
|
);
|
|
@@ -345,7 +345,7 @@ async function main(): Promise<void> {
|
|
|
345
345
|
ok(
|
|
346
346
|
"the landed sender session IS the resident's own garden id, replyable (anchored envelope line)",
|
|
347
347
|
new RegExp(
|
|
348
|
-
`^ {2}session: {5}${rx(senderGid)}
|
|
348
|
+
`^ {2}session: {5}${rx(senderGid)} ${rx("(replyable — when a reply is requested, send the result via entwurf_v2 (intent=fire-and-forget) to the requested recipient, defaulting to this sessionId; a local final is not delivery. Honor routing and no-send instructions; an absent or false wants_reply does not cancel a request. A replyable address alone needs no acknowledgment)")}$`,
|
|
349
349
|
"m",
|
|
350
350
|
).test(header),
|
|
351
351
|
);
|