@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.
Files changed (91) hide show
  1. package/AGENTS.md +1 -1
  2. package/BASELINE.md +7 -5
  3. package/CHANGELOG.md +426 -0
  4. package/DELIVERY.md +37 -20
  5. package/README.md +83 -81
  6. package/VERIFY.md +10 -10
  7. package/demo/README.md +1 -1
  8. package/docs/acp-backend-rail.md +1 -1
  9. package/docs/external-mcp-host.md +1 -1
  10. package/docs/setup-clean-host.md +95 -29
  11. package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +14 -11
  12. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-self-address.js +10 -0
  13. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +23 -2
  14. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-decider.js +7 -1
  15. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +3 -0
  16. package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +21 -10
  17. package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-fresh-call.js +4 -2
  18. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +5 -0
  19. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +6 -4
  20. package/mcp/entwurf-bridge/dist/pi-extensions/lib/native-push/register.js +13 -2
  21. package/mcp/entwurf-bridge/dist/pi-extensions/lib/omp-fresh-preflight.js +2 -2
  22. package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-fresh-preflight.js +1 -1
  23. package/mcp/entwurf-bridge/dist/pi-extensions/lib/remote-pair-receive.js +25 -17
  24. package/mcp/entwurf-bridge/dist/pi-extensions/lib/remote-pair-send.js +94 -28
  25. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-omp.js +57 -7
  26. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-pi-durable.js +2 -2
  27. package/mcp/entwurf-bridge/dist/scripts/remote-pair-receive.js +12 -12
  28. package/mcp/entwurf-bridge/src/index.ts +14 -11
  29. package/native/win32-x64/entwurf_win.node +0 -0
  30. package/native/win32-x64/manifest.json +2 -2
  31. package/package.json +15 -14
  32. package/pi/pi-durable/carrier/tui.js +18 -3
  33. package/pi/pi-durable/overlay/upstream-pin.json +12 -12
  34. package/pi-extensions/lib/acp/backend-adapter.ts +5 -3
  35. package/pi-extensions/lib/acp/backend.ts +12 -9
  36. package/pi-extensions/lib/entwurf-self-address.ts +13 -0
  37. package/pi-extensions/lib/entwurf-v2-contract.ts +25 -2
  38. package/pi-extensions/lib/entwurf-v2-decider.ts +7 -0
  39. package/pi-extensions/lib/entwurf-v2-surface.ts +3 -0
  40. package/pi-extensions/lib/fresh-call-composition.ts +21 -10
  41. package/pi-extensions/lib/herdr-fresh-call.ts +4 -2
  42. package/pi-extensions/lib/meta-sender-identity.ts +4 -0
  43. package/pi-extensions/lib/mux-fresh-call.ts +6 -4
  44. package/pi-extensions/lib/native-push/register.ts +17 -2
  45. package/pi-extensions/lib/omp-fresh-preflight.ts +2 -2
  46. package/pi-extensions/lib/pi-durable-fresh-preflight.ts +1 -1
  47. package/pi-extensions/lib/remote-pair-receive.ts +27 -19
  48. package/pi-extensions/lib/remote-pair-send.ts +117 -30
  49. package/pi-extensions/meta-bridge-omp.ts +69 -7
  50. package/pi-extensions/meta-bridge-pi-durable.ts +3 -3
  51. package/run.sh +218 -49
  52. package/scripts/check-agy-sender-identity.ts +6 -4
  53. package/scripts/check-entwurf-self-address.ts +34 -3
  54. package/scripts/check-entwurf-v2-contract.ts +24 -2
  55. package/scripts/check-entwurf-v2-production.ts +45 -31
  56. package/scripts/check-gate-qualification.ts +11 -9
  57. package/scripts/check-native-push-adapter.ts +4 -0
  58. package/scripts/check-native-push-register.ts +32 -82
  59. package/scripts/check-remote-pair-installed.ts +2 -2
  60. package/scripts/dev-bin.sh +112 -1
  61. package/scripts/lib/chain-terminus-publication.ts +58 -0
  62. package/scripts/lib/codex-fresh-live-protocol.ts +33 -2
  63. package/scripts/lib/codex-fresh-source-receipts.ts +112 -3
  64. package/scripts/lib/pi-durable-fresh-live-receipts.ts +29 -1
  65. package/scripts/mutants/chain-terminus-publication.json +17 -0
  66. package/scripts/mutants/codex-native.json +98 -0
  67. package/scripts/mutants/control-send-receipt.json +3 -3
  68. package/scripts/mutants/mux-fresh-call.json +16 -1
  69. package/scripts/mutants/native-push-paused.json +17 -0
  70. package/scripts/mutants/omp-fresh.json +13 -2
  71. package/scripts/mutants/pack-install.json +50 -4
  72. package/scripts/mutants/pi-durable.json +60 -0
  73. package/scripts/mutants/pi-floor.json +5 -5
  74. package/scripts/mutants/remote-pair-display.json +3 -3
  75. package/scripts/mutants/remote-pair-receive.json +41 -11
  76. package/scripts/mutants/remote-pair-roundtrip.json +67 -7
  77. package/scripts/mutants/remote-pair-send.json +156 -17
  78. package/scripts/mutants/remote-pair-transport.json +4 -4
  79. package/scripts/mutants/source-install.json +66 -0
  80. package/scripts/remote-pair-receive.ts +12 -12
  81. package/scripts/smoke-agy-install-state.sh +121 -0
  82. package/scripts/smoke-agy-native-push-live.ts +13 -0
  83. package/scripts/smoke-codex-fresh-live.ts +52 -28
  84. package/scripts/smoke-entwurf-chain-live.ts +7 -9
  85. package/scripts/smoke-herdr-fresh-call-live.ts +4 -4
  86. package/scripts/smoke-herdr-plugin-build-live.ts +179 -50
  87. package/scripts/smoke-herdr-raw-install-live.sh +10 -3
  88. package/scripts/smoke-mux-lifecycle-live.ts +140 -8
  89. package/scripts/smoke-omp-fresh-live.ts +5 -4
  90. package/scripts/smoke-pi-durable-fresh-live.ts +29 -7
  91. package/scripts/smoke-setup-verdict.sh +27 -2
@@ -10,9 +10,9 @@
10
10
  *
11
11
  * fixture a record-backed self-fetch COLLECTOR (claude-code backend, armed mailbox, sender marker).
12
12
  * It only launches and collects; it never stands in for the existing citizen.
13
- * 1. fixture → `entwurf_fresh_call(pi)` → a real visible Pi; Pi's first action calls back (nonce A).
13
+ * 1. fixture → `entwurf_fresh_call(pi)` → a real visible Pi; before its task Pi calls back (nonce A).
14
14
  * 2. Pi's live turn → `entwurf_fresh_call(pi-durable, <model>)` → the managed `entwurf pi-durable`
15
- * verb opens the durable host; ITS first action calls back into Pi (nonce B, read from Pi's
15
+ * verb opens the durable host; before ITS task it calls back into Pi (nonce B, read from Pi's
16
16
  * own transcript). Clauses 1, 2, 5 and 6 through the product surface; no raw tmux launch.
17
17
  * 3. fixture → Pi (one instruction). Pi's live turn → `entwurf_v2` → pd: receipt 1, existing → new.
18
18
  * pd's doorbell admits the notice; pd's live turn drains it with `entwurf_inbox_read` (addressed
@@ -50,6 +50,7 @@ import { FRESH_CALL_BACKENDS } from "../pi-extensions/lib/mux-fresh-call.ts";
50
50
  import { splitPiDurableModel } from "../pi-extensions/lib/pi-durable-fresh-preflight.ts";
51
51
  import { checkPiDurableRuntime, piDurablePackageLayout } from "../pi-extensions/lib/pi-durable-runtime.ts";
52
52
  import {
53
+ assertBootstrapOrder,
53
54
  mailboxCallbacks,
54
55
  parseJsonLines,
55
56
  parseMetaMailboxBody,
@@ -63,6 +64,7 @@ import {
63
64
  type PdNativeSubmissionRow,
64
65
  pdDoorbellSubmission,
65
66
  pdRootView,
67
+ pdSourceToolReceipts,
66
68
  piExactDeliveryRow,
67
69
  } from "./lib/pi-durable-fresh-live-receipts.ts";
68
70
 
@@ -412,7 +414,7 @@ const piEntries = (): unknown[] => {
412
414
  };
413
415
  const piTools = (): SourceToolReceipt[] => piSourceToolReceipts(piEntries());
414
416
 
415
- // ── 5. hop 2: Pi's live turn opens pi-durable; pd's first action calls back into Pi ──
417
+ // ── 5. hop 2: Pi's live turn opens pi-durable; before its task pd calls back into Pi ──
416
418
  const pdLaunch = await until("Pi's own entwurf_fresh_call(pi-durable) result", TURN_WAIT_MS, () =>
417
419
  piTools().find(
418
420
  (t) => t.toolName === "entwurf_fresh_call" && t.arguments.backend === "pi-durable" && t.status !== "pending",
@@ -434,7 +436,7 @@ const pdGid = await until("pi-durable's callback into Pi (Pi's own transcript)",
434
436
  return senders.length === 1 ? senders[0] : null;
435
437
  });
436
438
  ok(
437
- "pi-durable's FIRST action called back into Pi with the exact nonce; the sender envelope names its garden id",
439
+ "pi-durable called back into Pi with the exact nonce; the sender envelope names its garden id (correlation and sender identity — the bootstrap ORDER is judged on pd's own root rows below)",
438
440
  GARDEN_ID.test(pdGid),
439
441
  );
440
442
  ok("the address came from the callback, not the launch receipt", !pdLaunch.text.includes(pdGid));
@@ -597,10 +599,30 @@ ok(
597
599
  receipts["6-native-model"],
598
600
  );
599
601
  receipts["6-native-tool-calls"] = JSON.stringify(view.calls);
602
+ // THE BOOTSTRAP ORDER, on pd's own root rows. `[GLG 직접, 2026-10-24]` a fresh sibling may check its
603
+ // caller with the read-only listing the framing offers, then calls back, then works — so the literal
604
+ // "first root call is the callback" rule refused the legal `peers → callback`. The order leaf admits
605
+ // only successful exact `entwurf_peers` checks as a prefix (each answered before the callback was
606
+ // called, by native entry id), then requires the zero-argument callback exactly once and successfully,
607
+ // recorded before every later call. The verified prefix count is the receipt, not a guess.
608
+ let pdBootstrap = "";
609
+ let pdTaskCalls: SourceToolReceipt[] = [];
610
+ try {
611
+ const pdSources = pdSourceToolReceipts(view.calls);
612
+ pdTaskCalls = assertBootstrapOrder(
613
+ pdSources,
614
+ { peersArguments: {}, callback: { toolName: "entwurf_callback", arguments: {} } },
615
+ "pd bootstrap order",
616
+ );
617
+ pdBootstrap = `peers prefix=${pdSources.length - pdTaskCalls.length - 1} → entwurf_callback {} (native entry-id order)`;
618
+ } catch (error) {
619
+ pdBootstrap = `REFUSED: ${error instanceof Error ? error.message : String(error)}`;
620
+ }
621
+ receipts["6-pd-bootstrap-order"] = pdBootstrap;
600
622
  ok(
601
- "pd's FIRST root tool call is entwurf_callback, and it is the only one",
602
- view.calls[0]?.name === "entwurf_callback" && view.calls.filter((c) => c.name === "entwurf_callback").length === 1,
603
- receipts["6-native-tool-calls"],
623
+ "pd's root bootstrap order: only successful exact entwurf_peers checks before ONE successful zero-argument entwurf_callback; peers results before callback; callback result before task calls",
624
+ !pdBootstrap.startsWith("REFUSED") && pdBootstrap !== "",
625
+ `${pdBootstrap}\n${receipts["6-native-tool-calls"]}`,
604
626
  );
605
627
  ok(
606
628
  "pd's root entwurf_inbox_read is for its OWN garden id and settled without error",
@@ -73,7 +73,21 @@ export XDG_CACHE_HOME="$SB/home/.cache"
73
73
  export XDG_CONFIG_HOME="$SB/home/.config"
74
74
  export PI_CODING_AGENT_DIR="$SB/home/.pi/agent"
75
75
  export ENTWURF_DEV_BIN_DIR="$SB/bin"
76
- export PATH="$SB/bin:$PATH"
76
+ # Source setup's bins step refuses any other root under a package bin name in PATH or the pnpm/npm
77
+ # global bin dir, so the host's own entrypoints (a real ~/.local/bin/entwurf into some checkout)
78
+ # must not reach the verdict: drop every host PATH dir carrying a package bin name. The fixture
79
+ # package managers below answer the global-bin query with sandbox dirs.
80
+ _hermetic=""
81
+ IFS=':' read -r -a _dirs <<<"$PATH"
82
+ for _d in "${_dirs[@]}"; do
83
+ [ -n "$_d" ] || continue
84
+ for _b in $(python3 -c 'import json,sys; print(" ".join(json.load(open(sys.argv[1]))["bin"]))' "$REPO_DIR/package.json"); do
85
+ { [ -e "$_d/$_b" ] || [ -L "$_d/$_b" ]; } && continue 2
86
+ done
87
+ _hermetic="${_hermetic:+$_hermetic:}$_d"
88
+ done
89
+ export PATH="$SB/bin:$_hermetic"
90
+ unset _hermetic _dirs _d _b
77
91
  mkdir -p "$HOME" "$PI_CODING_AGENT_DIR" "$SB/bin" "$SB/harness" "$SB/bootstrap-bin"
78
92
  cat > "$SB/bootstrap-bin/pnpm" <<'SH'
79
93
  #!/bin/sh
@@ -85,10 +99,21 @@ if [ "$#" -eq 2 ] && [ "$1" = run ] && [ "$2" = build-bridge ]; then
85
99
  # directly so the production lock wrapper cannot leave its ignored parent dir.
86
100
  exec bash scripts/build-bridge.sh
87
101
  fi
88
- echo "fixture pnpm accepts only: install --frozen-lockfile | run build-bridge" >&2
102
+ if [ "$*" = "bin -g" ]; then
103
+ echo "${SB_PM_ROOT:?}/pnpm-bin"
104
+ exit 0
105
+ fi
106
+ echo "fixture pnpm accepts only: install --frozen-lockfile | run build-bridge | bin -g" >&2
89
107
  exit 64
90
108
  SH
91
109
  chmod +x "$SB/bootstrap-bin/pnpm"
110
+ cat > "$SB/bootstrap-bin/npm" <<'SH'
111
+ #!/bin/sh
112
+ [ "$*" = "prefix -g" ] || { echo "fixture npm accepts only: prefix -g" >&2; exit 64; }
113
+ echo "${SB_PM_ROOT:?}/npm-prefix"
114
+ SH
115
+ chmod +x "$SB/bootstrap-bin/npm"
116
+ export SB_PM_ROOT="$SB/pm"
92
117
  export PATH="$SB/bootstrap-bin:$PATH"
93
118
 
94
119
  # Presence pins: default every harness to a definitely-absent path; each cell