@junghanacs/entwurf 0.50.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.
Files changed (39) hide show
  1. package/AGENTS.md +2 -1
  2. package/CHANGELOG.md +140 -0
  3. package/ENTWURF.json +10 -4
  4. package/README.md +16 -8
  5. package/VERIFY.md +16 -9
  6. package/demo/README.md +1 -1
  7. package/docs/acp-backend-rail.md +1 -1
  8. package/docs/external-mcp-host.md +2 -2
  9. package/docs/setup-clean-host.md +92 -35
  10. package/mcp/entwurf-bridge/dist/ENTWURF.json +10 -4
  11. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-control-rpc.js +4 -1
  12. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +4 -4
  13. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-mailbox-body.js +1 -1
  14. package/package.json +11 -18
  15. package/pi/pi-durable/carrier/harness-setup.js +1 -1
  16. package/pi/pi-durable/carrier/runtime.js +221 -50
  17. package/pi/pi-durable/carrier/subagent.js +6 -3
  18. package/pi/pi-durable/carrier/tui.js +60 -22
  19. package/pi/pi-durable/overlay/upstream-pin.json +19 -18
  20. package/pi-extensions/lib/entwurf-control-rpc.ts +5 -1
  21. package/pi-extensions/lib/entwurf-v2-contract-schema.ts +73 -69
  22. package/pi-extensions/lib/entwurf-v2-contract.ts +4 -4
  23. package/pi-extensions/lib/meta-mailbox-body.ts +1 -1
  24. package/pi-extensions/meta-bridge-pi-durable.ts +1 -1
  25. package/run.sh +148 -46
  26. package/scripts/check-entwurf-v2-contract.ts +4 -4
  27. package/scripts/check-entwurf-v2-surface.ts +7 -21
  28. package/scripts/check-gate-qualification.ts +3 -3
  29. package/scripts/check-pi-durable-send.ts +4 -1
  30. package/scripts/lib/codex-fresh-source-receipts.ts +12 -6
  31. package/scripts/mutants/agent-guidance.json +2 -2
  32. package/scripts/mutants/codex-native.json +2 -2
  33. package/scripts/mutants/control-send-receipt.json +47 -7
  34. package/scripts/mutants/pack-install.json +4 -4
  35. package/scripts/mutants/pi-durable.json +189 -3
  36. package/scripts/mutants/pi-floor.json +20 -5
  37. package/scripts/mutants/v2-surface.json +4 -6
  38. package/scripts/smoke-acp-cortex-live.ts +1 -1
  39. package/scripts/smoke-acp-v2-send-live.ts +1 -1
@@ -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\\.4\\.0(_|$)' || true"],
10
- "replace": [" grep '^@earendil-works+' | grep -v '@1\\.4\\.0' || true"],
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\\.4\\.0(_|$)' || true"],
21
- "replace": [" grep '^@earendil-works+pi-' | grep -Ev '@1\\.4\\.0(_|$)' || true"],
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]",
@@ -525,7 +525,7 @@
525
525
  "claim": "PI-DURABLE-CARRIER-PIN-MATCHES",
526
526
  "title": "the pin records a digest the committed carrier file does not carry, so a carrier edited after emission would still be the declared one",
527
527
  "subject": "pi/pi-durable/overlay/upstream-pin.json",
528
- "find": ["\"sha256\": \"437834997b9870ab0383aea7d86ff7880ef7e2ebbbfe4c6360f67d8d36f777ec\""],
528
+ "find": ["\"sha256\": \"b47113364b7525abd3bf9286ecb0069f78ac96688b8a271bdbca3a54b9d864c5\""],
529
529
  "replace": ["\"sha256\": \"0000000000000000000000000000000000000000000000000000000000000000\""],
530
530
  "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
531
531
  "timeoutSeconds": 300,
@@ -1257,16 +1257,202 @@
1257
1257
  },
1258
1258
  {
1259
1259
  "claim": "PI-DURABLE-TASK-BLOCKED-REASON",
1260
- "title": "every blocked task is said to be parked by the restart limit, whatever reason the SDK gave",
1260
+ "title": "every blocked task is said to lack its definition, whatever reason the SDK gave",
1261
1261
  "subject": "pi/pi-durable/carrier/tui.js",
1262
1262
  "find": ["\t\tnode.blocked !== undefined ? `blocked:${node.blocked}` : \"\","],
1263
- "replace": ["\t\tnode.blocked !== undefined ? `blocked:restart_limit` : \"\","],
1263
+ "replace": ["\t\tnode.blocked !== undefined ? `blocked:missing_task` : \"\","],
1264
1264
  "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1265
1265
  "timeoutSeconds": 300,
1266
1266
  "signature": "[QK:PI-DURABLE-TASK-BLOCKED-REASON]",
1267
1267
  "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1268
1268
  "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1269
1269
  },
1270
+ {
1271
+ "claim": "PDF-CLOSE-SESSION-END-KIND",
1272
+ "title": "the owned close reads the Session's end by pi 1.4's `reason`, absent on SDK 1.5, so a failed end whose close resolved is recorded as a verified close",
1273
+ "subject": "pi/pi-durable/carrier/runtime.js",
1274
+ "find": ["\t\t\t\t\t\tif (state.failure === undefined && end.kind !== \"failed\") storage = \"closed\";"],
1275
+ "replace": ["\t\t\t\t\t\tif (state.failure === undefined && end.reason !== \"failed\") storage = \"closed\";"],
1276
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1277
+ "timeoutSeconds": 300,
1278
+ "signature": "[QK:PDF-CLOSE-SESSION-END-KIND]",
1279
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1280
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1281
+ },
1282
+ {
1283
+ "claim": "PI-DURABLE-REPORT-ERROR-TEXT",
1284
+ "title": "a reported error is shown as the SDK 1.5 Report object itself, so every notice reads [object Object] instead of what failed",
1285
+ "subject": "pi/pi-durable/carrier/runtime.js",
1286
+ "find": ["\t\t\tconst message = causeOf(reported.error);"],
1287
+ "replace": ["\t\t\tconst message = causeOf(reported);"],
1288
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1289
+ "timeoutSeconds": 300,
1290
+ "signature": "[QK:PI-DURABLE-REPORT-ERROR-TEXT]",
1291
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1292
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1293
+ },
1294
+ {
1295
+ "claim": "PI-DURABLE-ACTIVE-SEED",
1296
+ "title": "the transcript is seeded from the SDK's newest-50 window instead of the active range, so an open or a switch back shows only the last 50 entries",
1297
+ "subject": "pi/pi-durable/carrier/runtime.js",
1298
+ "find": ["\t\t\tconst read = await conversation.context(context);"],
1299
+ "replace": ["\t\t\tconst read = (await conversation.watch(context)).value;"],
1300
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1301
+ "timeoutSeconds": 300,
1302
+ "signature": "[QK:PI-DURABLE-ACTIVE-SEED]",
1303
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1304
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1305
+ },
1306
+ {
1307
+ "claim": "PI-DURABLE-ACTIVE-ATTACH",
1308
+ "title": "the watch's first value is not taken, so an entry committed between the read and the attach is missing until something else is committed",
1309
+ "subject": "pi/pi-durable/carrier/runtime.js",
1310
+ "find": ["\t\t\tadvance(next.watch.value);"],
1311
+ "replace": ["\t\t\tvoid next.watch.value;"],
1312
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1313
+ "timeoutSeconds": 300,
1314
+ "signature": "[QK:PI-DURABLE-ACTIVE-ATTACH]",
1315
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1316
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1317
+ },
1318
+ {
1319
+ "claim": "PI-DURABLE-ACTIVE-ONCE",
1320
+ "title": "every watch value's whole window is appended, so entries a later value still holds are shown again",
1321
+ "subject": "pi/pi-durable/carrier/runtime.js",
1322
+ "find": ["\t\t\tconst fresh = view.entries.filter((entry) => entry.id > shown.newest);"],
1323
+ "replace": ["\t\t\tconst fresh = view.entries;"],
1324
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1325
+ "timeoutSeconds": 300,
1326
+ "signature": "[QK:PI-DURABLE-ACTIVE-ONCE]",
1327
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1328
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1329
+ },
1330
+ {
1331
+ "claim": "PI-DURABLE-ACTIVE-GAP",
1332
+ "title": "a window that starts past the newest entry shown is appended as it is, so the entries it dropped are skipped for good",
1333
+ "subject": "pi/pi-durable/carrier/runtime.js",
1334
+ "find": ["\t\t\tconst skipped = view.before !== undefined && view.before > shown.newest;"],
1335
+ "replace": ["\t\t\tconst skipped = false;"],
1336
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1337
+ "timeoutSeconds": 300,
1338
+ "signature": "[QK:PI-DURABLE-ACTIVE-GAP]",
1339
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1340
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1341
+ },
1342
+ {
1343
+ "claim": "PI-DURABLE-ACTIVE-HEAD",
1344
+ "title": "a head marker is appended like any entry, so a compaction or reset keeps what it left behind and its marker lands last",
1345
+ "subject": "pi/pi-durable/carrier/runtime.js",
1346
+ "find": ["\t\t\tconst restarts = fresh.some((entry) => entry.head !== undefined);"],
1347
+ "replace": ["\t\t\tconst restarts = false;"],
1348
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1349
+ "timeoutSeconds": 300,
1350
+ "signature": "[QK:PI-DURABLE-ACTIVE-HEAD]",
1351
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1352
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1353
+ },
1354
+ {
1355
+ "claim": "PI-DURABLE-ACTIVE-FENCE",
1356
+ "title": "a read that lands after a switch away is installed anyway, so the screen jumps back to the conversation the user left",
1357
+ "subject": "pi/pi-durable/carrier/runtime.js",
1358
+ "find": ["\t\t\t\t\tif (watch !== trigger) {"],
1359
+ "replace": ["\t\t\t\t\tif (false) {"],
1360
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1361
+ "timeoutSeconds": 300,
1362
+ "signature": "[QK:PI-DURABLE-ACTIVE-FENCE]",
1363
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1364
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1365
+ },
1366
+ {
1367
+ "claim": "PI-DURABLE-ACTIVE-STALL",
1368
+ "title": "a failed read of a new active range is swallowed, so the transcript stops updating while looking healthy",
1369
+ "subject": "pi/pi-durable/carrier/runtime.js",
1370
+ "find": ["\t\t\t\t\tupdate({ stalled: { ...state.stalled, conversation: causeOf(error) } });"],
1371
+ "replace": ["\t\t\t\t\tvoid error;"],
1372
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1373
+ "timeoutSeconds": 300,
1374
+ "signature": "[QK:PI-DURABLE-ACTIVE-STALL]",
1375
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1376
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1377
+ },
1378
+ {
1379
+ "claim": "PI-DURABLE-ACTIVE-CLOSED",
1380
+ "title": "a read landing after the close is installed anyway, so the closed screen is patched and starting its ended watch throws unhandled",
1381
+ "subject": "pi/pi-durable/carrier/runtime.js",
1382
+ "find": ["\t\t\tif (closing !== undefined || state.failure !== undefined) {"],
1383
+ "replace": ["\t\t\tif (false) {"],
1384
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1385
+ "timeoutSeconds": 300,
1386
+ "signature": "[QK:PI-DURABLE-ACTIVE-CLOSED]",
1387
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1388
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1389
+ },
1390
+ {
1391
+ "claim": "PI-DURABLE-RUN-FAILURE-ONCE",
1392
+ "title": "the input a failed run settled also raises its own notice, so the same missing answer is said twice",
1393
+ "subject": "pi/pi-durable/carrier/runtime.js",
1394
+ "find": ["\t\t\t\t\tif (live?.runFailure?.inputs.includes(submission.id)) return;"],
1395
+ "replace": ["\t\t\t\t\tvoid live;"],
1396
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1397
+ "timeoutSeconds": 300,
1398
+ "signature": "[QK:PI-DURABLE-RUN-FAILURE-ONCE]",
1399
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1400
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1401
+ },
1402
+ {
1403
+ "claim": "PI-DURABLE-COMPACTION-TRIGGER-SHOWN",
1404
+ "title": "a retained compaction failure is named by pi 1.4's `reason`, absent on SDK 1.5, so the line says (undefined) instead of what started it",
1405
+ "subject": "pi/pi-durable/carrier/tui.js",
1406
+ "find": [
1407
+ "\t\tlines.push({ level: \"error\", message: `Compaction failed (${compaction.trigger}): ${compaction.error}` });"
1408
+ ],
1409
+ "replace": [
1410
+ "\t\tlines.push({ level: \"error\", message: `Compaction failed (${compaction.reason}): ${compaction.error}` });"
1411
+ ],
1412
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1413
+ "timeoutSeconds": 300,
1414
+ "signature": "[QK:PI-DURABLE-COMPACTION-TRIGGER-SHOWN]",
1415
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1416
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1417
+ },
1418
+ {
1419
+ "claim": "PI-DURABLE-RUN-FAILURE-SHOWN",
1420
+ "title": "the run failure line is drawn only for an aborted run, so a run that ended without an answer leaves no lasting line while the user's own stop gets one",
1421
+ "subject": "pi/pi-durable/carrier/tui.js",
1422
+ "find": ["\tif (run !== undefined && run.reason !== \"aborted\") {"],
1423
+ "replace": ["\tif (run !== undefined && run.reason === \"aborted\") {"],
1424
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1425
+ "timeoutSeconds": 300,
1426
+ "signature": "[QK:PI-DURABLE-RUN-FAILURE-SHOWN]",
1427
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1428
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1429
+ },
1430
+ {
1431
+ "claim": "PI-DURABLE-WATCH-STALL-SHOWN",
1432
+ "title": "a watch that stopped updating draws no line, so a frozen conversation or task panel looks healthy",
1433
+ "subject": "pi/pi-durable/carrier/tui.js",
1434
+ "find": ["\tfor (const [part, error] of Object.entries(view.stalled ?? {})) {"],
1435
+ "replace": ["\tfor (const [part, error] of Object.entries({})) {"],
1436
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1437
+ "timeoutSeconds": 300,
1438
+ "signature": "[QK:PI-DURABLE-WATCH-STALL-SHOWN]",
1439
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1440
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1441
+ },
1442
+ {
1443
+ "claim": "PI-DURABLE-SUBAGENT-SCHEMA-OPEN",
1444
+ "title": "the subagent schema takes pi-schema's closed-object default, so the model sees a stricter input than the TypeBox object it replaced",
1445
+ "subject": "pi/pi-durable/carrier/subagent.js",
1446
+ "find": [
1447
+ "\t\t\tparameters: obj({ task: str({ description: \"What the subagent should do\" }) }, { open: true }),"
1448
+ ],
1449
+ "replace": ["\t\t\tparameters: obj({ task: str({ description: \"What the subagent should do\" }) }),"],
1450
+ "gate": ["bash", "run.sh", "check-pi-durable-carrier"],
1451
+ "timeoutSeconds": 300,
1452
+ "signature": "[QK:PI-DURABLE-SUBAGENT-SCHEMA-OPEN]",
1453
+ "signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
1454
+ "build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
1455
+ },
1270
1456
  {
1271
1457
  "claim": "PI-DURABLE-TEST-FIXTURES-NOT-SHIPPED",
1272
1458
  "title": "package.json drops its fixture negation, so every published tarball carries the test goldens under pi-extensions/**/fixtures/",
@@ -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 || 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'"
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.4.0\","],
25
- "replace": ["\"@earendil-works/pi-durable\": \"1.3.0\","],
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,11 +33,26 @@
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.4.0\","],
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]",
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.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
+ "subject": "docs/setup-clean-host.md",
46
+ "find": [
47
+ "| pi | optional-by-presence — published 0.51.0: <!-- entwurf:published @junghanacs/entwurf@0.51.0 pi 1.5.0 -->"
48
+ ],
49
+ "replace": [
50
+ "| pi | optional-by-presence — published 0.51.0: <!-- entwurf:published @junghanacs/entwurf@0.50.0 pi 1.5.0 -->"
51
+ ],
52
+ "gate": ["bash", "run.sh", "check-dep-versions"],
53
+ "timeoutSeconds": 300,
54
+ "signature": "[QK:PI-FLOOR-PUBLISHED-SCOPE]",
55
+ "signatureSource": "run.sh"
41
56
  }
42
57
  ]
43
58
  }
@@ -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
- "LOCK: taken for a control-socket-DOMAIN dispatch. The mailbox and native-push rails are lock-free — deliverability and the adapter probe guard them. mode "
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. 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. "
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
- "CANONICAL DELIVERY SURFACE for garden ids: message, reply, or hand off to whoever an id names. The id PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING "
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)} \\(replyable — reply via entwurf_v2 to this sessionId, intent=fire-and-forget\\)$`,
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)} \\(replyable — reply via entwurf_v2 to this sessionId, intent=fire-and-forget\\)$`,
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
  );