create-walle 0.10.2 → 0.10.3

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 (488) hide show
  1. package/README.md +3 -1
  2. package/lib/release-schema.json +2 -2
  3. package/lib/runtime-closure-policy.json +8 -7
  4. package/package.json +1 -1
  5. package/template/coding-task-manager/api-prompts.js +45 -7
  6. package/template/coding-task-manager/bin/claude-hook.js +55 -1
  7. package/template/coding-task-manager/bin/ctm-relay-client.js +35 -12
  8. package/template/coding-task-manager/bin/land.js +2069 -0
  9. package/template/coding-task-manager/bin/memory-census.js +4 -2
  10. package/template/coding-task-manager/bin/memory-sync-verify.js +151 -0
  11. package/template/coding-task-manager/bin/probe-refusal-scope.js +530 -0
  12. package/template/coding-task-manager/db.js +156 -32
  13. package/template/coding-task-manager/lib/acp/acp-client.js +383 -0
  14. package/template/coding-task-manager/lib/acp/dsh-context-truth.js +176 -0
  15. package/template/coding-task-manager/lib/acp/dsh-launch-model.js +302 -0
  16. package/template/coding-task-manager/lib/acp/dsh-mcp-servers.js +194 -0
  17. package/template/coding-task-manager/lib/acp/dsh-prompt-lane.js +616 -0
  18. package/template/coding-task-manager/lib/acp/dsh-route-patch.js +308 -0
  19. package/template/coding-task-manager/lib/acp/dsh-session-runtime.js +522 -0
  20. package/template/coding-task-manager/lib/acp/dsh-transcript.js +395 -0
  21. package/template/coding-task-manager/lib/acp/dsh-usage-log.js +162 -0
  22. package/template/coding-task-manager/lib/acp/ndjson-stdio-transport.js +225 -0
  23. package/template/coding-task-manager/lib/adopted-host-redial.js +47 -11
  24. package/template/coding-task-manager/lib/adopted-launch-environment.js +123 -0
  25. package/template/coding-task-manager/lib/agent-auto-update-runtime.js +0 -3
  26. package/template/coding-task-manager/lib/agent-auto-update.js +26 -10
  27. package/template/coding-task-manager/lib/agent-bundle/build.js +657 -0
  28. package/template/coding-task-manager/lib/agent-bundle/codex-install.js +558 -0
  29. package/template/coding-task-manager/lib/agent-bundle/drift.js +120 -0
  30. package/template/coding-task-manager/lib/agent-bundle/gc.js +522 -0
  31. package/template/coding-task-manager/lib/agent-bundle/inventory.js +346 -0
  32. package/template/coding-task-manager/lib/agent-bundle/push.js +717 -0
  33. package/template/coding-task-manager/lib/agent-bundle/skill-transfer.js +724 -0
  34. package/template/coding-task-manager/lib/agent-bundle/spawn.js +119 -0
  35. package/template/coding-task-manager/lib/agent-bundle/store.js +568 -0
  36. package/template/coding-task-manager/lib/agent-capabilities.js +142 -12
  37. package/template/coding-task-manager/lib/agent-cli-cache.js +30 -5
  38. package/template/coding-task-manager/lib/agent-definitions.js +19 -0
  39. package/template/coding-task-manager/lib/agent-hooks-codex-toml.js +28 -16
  40. package/template/coding-task-manager/lib/agent-hooks-codex-workspace.js +9 -1
  41. package/template/coding-task-manager/lib/agent-hooks-installer.js +23 -8
  42. package/template/coding-task-manager/lib/agent-hooks-prune.js +37 -11
  43. package/template/coding-task-manager/lib/agent-hooks-shim.js +105 -0
  44. package/template/coding-task-manager/lib/agent-presets.js +84 -1
  45. package/template/coding-task-manager/lib/agent-upgrade-jobs.js +12 -1
  46. package/template/coding-task-manager/lib/agent-version-service.js +74 -11
  47. package/template/coding-task-manager/lib/all-sessions-query.js +6 -2
  48. package/template/coding-task-manager/lib/api/agent-bundles.js +436 -0
  49. package/template/coding-task-manager/lib/api/backup-retention.js +83 -0
  50. package/template/coding-task-manager/lib/api/conversation-sync-routes.js +124 -0
  51. package/template/coding-task-manager/lib/api/diagnostics.js +549 -69
  52. package/template/coding-task-manager/lib/api/fleet.js +118 -0
  53. package/template/coding-task-manager/lib/api/hub-bridge.js +243 -0
  54. package/template/coding-task-manager/lib/api/ingress.js +9 -1
  55. package/template/coding-task-manager/lib/api/landing.js +403 -0
  56. package/template/coding-task-manager/lib/api/machines.js +691 -2
  57. package/template/coding-task-manager/lib/api/memory-sync-routes.js +335 -0
  58. package/template/coding-task-manager/lib/api/misc-ops.js +8 -3
  59. package/template/coding-task-manager/lib/api/remote-sessions.js +1326 -0
  60. package/template/coding-task-manager/lib/api/session-attach.js +623 -0
  61. package/template/coding-task-manager/lib/api/session-messages.js +1384 -0
  62. package/template/coding-task-manager/lib/api/sessions.js +77 -51
  63. package/template/coding-task-manager/lib/api/setup-network.js +544 -16
  64. package/template/coding-task-manager/lib/api/setup-wizard-handlers.js +884 -0
  65. package/template/coding-task-manager/lib/api/setup.js +829 -10
  66. package/template/coding-task-manager/lib/api/walle-bridge.js +9 -1
  67. package/template/coding-task-manager/lib/attachment-reconciler-wiring.js +5 -2
  68. package/template/coding-task-manager/lib/auth-rate-limit.js +23 -0
  69. package/template/coding-task-manager/lib/auth-rules.js +292 -21
  70. package/template/coding-task-manager/lib/background-stop.js +369 -0
  71. package/template/coding-task-manager/lib/best-of-attempts.js +4 -1
  72. package/template/coding-task-manager/lib/best-of-launch-plan.js +52 -0
  73. package/template/coding-task-manager/lib/box-keep-awake.js +89 -0
  74. package/template/coding-task-manager/lib/broadcast-reason-stats.js +152 -0
  75. package/template/coding-task-manager/lib/broadcast-serialize.js +5 -0
  76. package/template/coding-task-manager/lib/build-info.js +4 -2
  77. package/template/coding-task-manager/lib/claude-model-truth.js +13 -2
  78. package/template/coding-task-manager/lib/claude-transcript-terminal-renderer.js +17 -13
  79. package/template/coding-task-manager/lib/client-diag-handler.js +64 -2
  80. package/template/coding-task-manager/lib/codex-app-server-client.js +14 -16
  81. package/template/coding-task-manager/lib/codex-configuration-history.js +55 -0
  82. package/template/coding-task-manager/lib/codex-harness-qualification.js +43 -20
  83. package/template/coding-task-manager/lib/codex-rollout-history.js +743 -0
  84. package/template/coding-task-manager/lib/coding-agent-models.js +27 -12
  85. package/template/coding-task-manager/lib/coding-cli-skill-installer.js +44 -14
  86. package/template/coding-task-manager/lib/coding-session-model-adapters.js +43 -2
  87. package/template/coding-task-manager/lib/coding-session-model-owner.js +1 -1
  88. package/template/coding-task-manager/lib/coding-session-model-public.js +7 -1
  89. package/template/coding-task-manager/lib/coding-session-model-runtime.js +23 -4
  90. package/template/coding-task-manager/lib/coding-session-model-scan.js +31 -0
  91. package/template/coding-task-manager/lib/coding-session-model-state.js +7 -0
  92. package/template/coding-task-manager/lib/conversation-freshness-diagnostics.js +280 -0
  93. package/template/coding-task-manager/lib/conversation-item-clock.js +261 -0
  94. package/template/coding-task-manager/lib/conversation-source-registry.js +5 -0
  95. package/template/coding-task-manager/lib/conversation-store-v2.js +44 -0
  96. package/template/coding-task-manager/lib/conversation-sync.js +355 -0
  97. package/template/coding-task-manager/lib/create/resolve-launch-params.js +96 -12
  98. package/template/coding-task-manager/lib/create/worker-role-profile.js +4 -4
  99. package/template/coding-task-manager/lib/create-intent-lease.js +51 -0
  100. package/template/coding-task-manager/lib/ctm-session-context-api.js +97 -6
  101. package/template/coding-task-manager/lib/db-domain-tables.js +1 -0
  102. package/template/coding-task-manager/lib/db-domains.js +1 -0
  103. package/template/coding-task-manager/lib/db-owner-dispatch-probe.js +32 -0
  104. package/template/coding-task-manager/lib/db-owner-request-counts.js +178 -0
  105. package/template/coding-task-manager/lib/db-owner-worker-client.js +68 -14
  106. package/template/coding-task-manager/lib/db-schema-source-files.js +5 -0
  107. package/template/coding-task-manager/lib/deferred-restore-attempt.js +6 -2
  108. package/template/coding-task-manager/lib/feature-manifest.js +4 -0
  109. package/template/coding-task-manager/lib/fleet-conversation-route.js +97 -0
  110. package/template/coding-task-manager/lib/fleet-fanout.js +78 -0
  111. package/template/coding-task-manager/lib/fleet-hub.js +762 -0
  112. package/template/coding-task-manager/lib/fleet-origin-follower.js +252 -0
  113. package/template/coding-task-manager/lib/fleet-resolver-effects.js +147 -0
  114. package/template/coding-task-manager/lib/fleet-resolver-tick.js +148 -0
  115. package/template/coding-task-manager/lib/fleet-resolver.js +454 -0
  116. package/template/coding-task-manager/lib/fleet-session-list-routes.js +114 -0
  117. package/template/coding-task-manager/lib/fleet-session-lists.js +672 -0
  118. package/template/coding-task-manager/lib/fleet-update.js +798 -0
  119. package/template/coding-task-manager/lib/fs-watcher-root-watch.js +141 -0
  120. package/template/coding-task-manager/lib/fs-watcher.js +58 -42
  121. package/template/coding-task-manager/lib/harness-history-transition.js +50 -9
  122. package/template/coding-task-manager/lib/headless-term-service.js +84 -8
  123. package/template/coding-task-manager/lib/hermetic-agent-launch-guard.js +10 -0
  124. package/template/coding-task-manager/lib/history-transition-read-op.js +175 -8
  125. package/template/coding-task-manager/lib/host-cpu-categories.js +310 -0
  126. package/template/coding-task-manager/lib/host-fseventsd-sampler.js +399 -0
  127. package/template/coding-task-manager/lib/host-handoff.js +16 -19
  128. package/template/coding-task-manager/lib/host-stats.js +150 -3
  129. package/template/coding-task-manager/lib/hosted-sync-worker.js +43 -320
  130. package/template/coding-task-manager/lib/hub-bridge-access.js +798 -0
  131. package/template/coding-task-manager/lib/hub-bridge-box.js +409 -0
  132. package/template/coding-task-manager/lib/hub-bridge-mcp.js +380 -0
  133. package/template/coding-task-manager/lib/hub-bridge-mesh.js +313 -0
  134. package/template/coding-task-manager/lib/hub-bridge-ops.js +721 -0
  135. package/template/coding-task-manager/lib/hub-bridge.js +398 -0
  136. package/template/coding-task-manager/lib/idle-notify.js +491 -0
  137. package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +8 -0
  138. package/template/coding-task-manager/lib/instance-manifest.js +5 -1
  139. package/template/coding-task-manager/lib/instance-sync-status.js +18 -8
  140. package/template/coding-task-manager/lib/landing/agent-rule.txt +1 -0
  141. package/template/coding-task-manager/lib/landing/batch-runner.js +366 -0
  142. package/template/coding-task-manager/lib/landing/config.js +536 -0
  143. package/template/coding-task-manager/lib/landing/ctm-view.js +256 -0
  144. package/template/coding-task-manager/lib/landing/gate.js +360 -0
  145. package/template/coding-task-manager/lib/landing/git.js +344 -0
  146. package/template/coding-task-manager/lib/landing/lease.js +247 -0
  147. package/template/coding-task-manager/lib/landing/merge-delta.js +380 -0
  148. package/template/coding-task-manager/lib/landing/proof.js +223 -0
  149. package/template/coding-task-manager/lib/landing/queue.js +998 -0
  150. package/template/coding-task-manager/lib/landing/radar.js +489 -0
  151. package/template/coding-task-manager/lib/landing/resolve-cli.js +424 -0
  152. package/template/coding-task-manager/lib/landing/state.js +263 -0
  153. package/template/coding-task-manager/lib/landing/stop.js +49 -0
  154. package/template/coding-task-manager/lib/landing/sync-cli.js +475 -0
  155. package/template/coding-task-manager/lib/landing/sync.js +456 -0
  156. package/template/coding-task-manager/lib/landing/train.js +885 -0
  157. package/template/coding-task-manager/lib/landing/window.js +57 -0
  158. package/template/coding-task-manager/lib/launch-environment.js +121 -0
  159. package/template/coding-task-manager/lib/launch-model-override.js +36 -10
  160. package/template/coding-task-manager/lib/launch-plan-pool.js +2 -1
  161. package/template/coding-task-manager/lib/launch-plan-warm-cache.js +6 -0
  162. package/template/coding-task-manager/lib/lead-model-observer.js +57 -1
  163. package/template/coding-task-manager/lib/lead-model-options.js +160 -3
  164. package/template/coding-task-manager/lib/lead-model-restore-reconciliation.js +106 -24
  165. package/template/coding-task-manager/lib/lead-model-switch-runtime.js +352 -68
  166. package/template/coding-task-manager/lib/lead-model-switch.js +114 -10
  167. package/template/coding-task-manager/lib/lead-model-transition-runtime.js +14 -2
  168. package/template/coding-task-manager/lib/lead-model-transition-store.js +24 -6
  169. package/template/coding-task-manager/lib/lead-route-preflight.js +179 -0
  170. package/template/coding-task-manager/lib/lead-switch-history-mode.js +110 -0
  171. package/template/coding-task-manager/lib/lead-wire-agent.js +7 -0
  172. package/template/coding-task-manager/lib/lifecycle-wake-experiment.js +9 -2
  173. package/template/coding-task-manager/lib/live-defer-announce.js +45 -0
  174. package/template/coding-task-manager/lib/machine-registry.js +750 -5
  175. package/template/coding-task-manager/lib/macos-capabilities.js +32 -15
  176. package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +433 -53
  177. package/template/coding-task-manager/lib/mainloop-observability.js +14 -9
  178. package/template/coding-task-manager/lib/media-draft-owner.js +16 -3
  179. package/template/coding-task-manager/lib/memory-join.js +337 -0
  180. package/template/coding-task-manager/lib/memory-sync-verify.js +393 -0
  181. package/template/coding-task-manager/lib/memory-sync.js +565 -0
  182. package/template/coding-task-manager/lib/migrations/v57-delegate-pref-mirror-opencode.js +68 -0
  183. package/template/coding-task-manager/lib/migrations/v58-subagent-launch-native-subagents.js +42 -0
  184. package/template/coding-task-manager/lib/migrations/v59-coding-session-model-state-dsh.js +73 -0
  185. package/template/coding-task-manager/lib/migrations/v60-delegate-pref-mirror-dsh.js +78 -0
  186. package/template/coding-task-manager/lib/migrations/v61-conversation-item-clock.js +71 -0
  187. package/template/coding-task-manager/lib/model-availability.js +727 -0
  188. package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +4 -6
  189. package/template/coding-task-manager/lib/model-host-receipt.js +6 -3
  190. package/template/coding-task-manager/lib/model-id-rule.js +19 -0
  191. package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
  192. package/template/coding-task-manager/lib/model-proxy/auto-mode-review.js +110 -23
  193. package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
  194. package/template/coding-task-manager/lib/model-proxy/generation-probe.js +60 -17
  195. package/template/coding-task-manager/lib/model-proxy/historical-tool-declarations.js +37 -0
  196. package/template/coding-task-manager/lib/model-proxy/lead-request-validation.js +1 -0
  197. package/template/coding-task-manager/lib/model-proxy/lead-token-admin.js +130 -0
  198. package/template/coding-task-manager/lib/model-proxy/refusal-scope.js +151 -0
  199. package/template/coding-task-manager/lib/model-proxy/request-budget-store.js +11 -2
  200. package/template/coding-task-manager/lib/model-proxy/tokens.js +69 -5
  201. package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
  202. package/template/coding-task-manager/lib/native-agent-model-args.js +25 -22
  203. package/template/coding-task-manager/lib/native-history-control.js +6 -4
  204. package/template/coding-task-manager/lib/native-lead-settings-client.js +44 -4
  205. package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +173 -36
  206. package/template/coding-task-manager/lib/online-backup-worker-client.js +2 -0
  207. package/template/coding-task-manager/lib/opencode-cli.js +480 -0
  208. package/template/coding-task-manager/lib/opencode-launch-model.js +471 -0
  209. package/template/coding-task-manager/lib/opencode-v1-plugin/model-carrier.mjs +35 -0
  210. package/template/coding-task-manager/lib/opencode-v2-plugin/server.js +118 -0
  211. package/template/coding-task-manager/lib/owner-action-manifest-data.json +1 -1
  212. package/template/coding-task-manager/lib/park-composer-draft.js +54 -0
  213. package/template/coding-task-manager/lib/park-fresh-relaunch.js +41 -10
  214. package/template/coding-task-manager/lib/perf-phase-trace.js +72 -0
  215. package/template/coding-task-manager/lib/perf-summary.js +7 -0
  216. package/template/coding-task-manager/lib/perf-tracker.js +63 -2
  217. package/template/coding-task-manager/lib/project-config.js +7 -0
  218. package/template/coding-task-manager/lib/prompt-purge-v2.js +52 -1
  219. package/template/coding-task-manager/lib/provider-login-broker.js +72 -15
  220. package/template/coding-task-manager/lib/provider-login-tab.js +10 -2
  221. package/template/coding-task-manager/lib/read-pool-client.js +89 -2
  222. package/template/coding-task-manager/lib/read-pool-worker-handle.js +29 -4
  223. package/template/coding-task-manager/lib/recent-catalog-query.js +15 -0
  224. package/template/coding-task-manager/lib/recent-session-catalog-response.js +67 -10
  225. package/template/coding-task-manager/lib/recovery-evidence.js +26 -11
  226. package/template/coding-task-manager/lib/relay-client.js +57 -3
  227. package/template/coding-task-manager/lib/relink-audit.js +34 -5
  228. package/template/coding-task-manager/lib/remote-machine-catalog.js +321 -26
  229. package/template/coding-task-manager/lib/remote-machine-create.js +576 -36
  230. package/template/coding-task-manager/lib/remote-machine-link.js +546 -59
  231. package/template/coding-task-manager/lib/remote-machine-proxy.js +143 -9
  232. package/template/coding-task-manager/lib/remote-session-forward.js +65 -7
  233. package/template/coding-task-manager/lib/remote-terminal-target.js +9 -2
  234. package/template/coding-task-manager/lib/restart-guard.js +18 -6
  235. package/template/coding-task-manager/lib/restore-seed-modes.js +87 -0
  236. package/template/coding-task-manager/lib/restored-scrollback-hydration-runtime.js +22 -2
  237. package/template/coding-task-manager/lib/resume-admission.js +17 -3
  238. package/template/coding-task-manager/lib/review-repo-registry.js +58 -19
  239. package/template/coding-task-manager/lib/root-delivery-runtime.js +2 -2
  240. package/template/coding-task-manager/lib/root-prompt-flow.js +1 -1
  241. package/template/coding-task-manager/lib/runtime-contract.js +3 -1
  242. package/template/coding-task-manager/lib/schema-indexes.js +1 -0
  243. package/template/coding-task-manager/lib/session-context-locator.js +742 -0
  244. package/template/coding-task-manager/lib/session-create/attachment.js +2 -2
  245. package/template/coding-task-manager/lib/session-create/create-phases.js +118 -0
  246. package/template/coding-task-manager/lib/session-create/delegate-worker.js +86 -16
  247. package/template/coding-task-manager/lib/session-create/dsh-session.js +930 -0
  248. package/template/coding-task-manager/lib/session-create/lead-route-launch.js +186 -13
  249. package/template/coding-task-manager/lib/session-create/native-lead-lifetime.js +55 -3
  250. package/template/coding-task-manager/lib/session-create/opencode-lead-provider.js +50 -0
  251. package/template/coding-task-manager/lib/session-create/prepared.js +162 -38
  252. package/template/coding-task-manager/lib/session-create/provider-process.js +160 -28
  253. package/template/coding-task-manager/lib/session-create/response.js +7 -7
  254. package/template/coding-task-manager/lib/session-create/structured-session.js +27 -0
  255. package/template/coding-task-manager/lib/session-create/subagent-pick-table.js +3 -1
  256. package/template/coding-task-manager/lib/session-create/subagent-pick.js +458 -9
  257. package/template/coding-task-manager/lib/session-create/transcript.js +1 -1
  258. package/template/coding-task-manager/lib/session-create/worker-budget-setup.js +21 -2
  259. package/template/coding-task-manager/lib/session-create/worker-continuation.js +7 -1
  260. package/template/coding-task-manager/lib/session-create/worker-launch-sandbox.js +39 -10
  261. package/template/coding-task-manager/lib/session-create/worker-observability.js +2 -2
  262. package/template/coding-task-manager/lib/session-empty.js +13 -10
  263. package/template/coding-task-manager/lib/session-host-manager.js +60 -0
  264. package/template/coding-task-manager/lib/session-jobs.js +3 -1
  265. package/template/coding-task-manager/lib/session-lifecycle.js +10 -4
  266. package/template/coding-task-manager/lib/session-model-action-preconditions.js +6 -2
  267. package/template/coding-task-manager/lib/session-model-intent-contract.js +11 -8
  268. package/template/coding-task-manager/lib/session-park.js +738 -0
  269. package/template/coding-task-manager/lib/session-path-grant.js +13 -4
  270. package/template/coding-task-manager/lib/session-status-ledger.js +106 -4
  271. package/template/coding-task-manager/lib/session-transport.js +17 -0
  272. package/template/coding-task-manager/lib/session-workspace-projection.js +54 -5
  273. package/template/coding-task-manager/lib/session-workspace-tracking-runtime.js +213 -1
  274. package/template/coding-task-manager/lib/skill-autocomplete-query.js +120 -3
  275. package/template/coding-task-manager/lib/skill-autocomplete.js +15 -1
  276. package/template/coding-task-manager/lib/sqlite-file-set.js +39 -0
  277. package/template/coding-task-manager/lib/standup-search-adapter.js +16 -2
  278. package/template/coding-task-manager/lib/state-sync/client-ledger.js +12 -0
  279. package/template/coding-task-manager/lib/state-sync/frame-emitter.js +319 -100
  280. package/template/coding-task-manager/lib/storage/coding-session-model-store.js +4 -1
  281. package/template/coding-task-manager/lib/storage/delegate-pref-mirror-store.js +32 -9
  282. package/template/coding-task-manager/lib/structured-session-boot-sweep.js +235 -0
  283. package/template/coding-task-manager/lib/submission-ack.js +90 -2
  284. package/template/coding-task-manager/lib/systemd-scope.js +115 -0
  285. package/template/coding-task-manager/lib/telemetry-receiver.js +39 -0
  286. package/template/coding-task-manager/lib/terminal-attach-geometry.js +985 -0
  287. package/template/coding-task-manager/lib/terminal-bootstrap.js +30 -0
  288. package/template/coding-task-manager/lib/terminal-draft-operation.js +357 -0
  289. package/template/coding-task-manager/lib/terminal-input-admission.js +17 -1
  290. package/template/coding-task-manager/lib/terminal-input-prepared.js +563 -0
  291. package/template/coding-task-manager/lib/transcript-cache-temps.js +171 -0
  292. package/template/coding-task-manager/lib/transcript-frame-cache.js +8 -3
  293. package/template/coding-task-manager/lib/transcript-source.js +36 -4
  294. package/template/coding-task-manager/lib/transcript-store.js +9 -0
  295. package/template/coding-task-manager/lib/typing-interaction-trace.js +106 -3
  296. package/template/coding-task-manager/lib/usage-ledger/backfill.js +40 -5
  297. package/template/coding-task-manager/lib/usage-ledger/client.js +4 -1
  298. package/template/coding-task-manager/lib/usage-ledger/dsh-parse.js +152 -0
  299. package/template/coding-task-manager/lib/usage-ledger/dsh-read.js +73 -0
  300. package/template/coding-task-manager/lib/usage-ledger/ingest.js +34 -6
  301. package/template/coding-task-manager/lib/usage-ledger/live.js +35 -8
  302. package/template/coding-task-manager/lib/usage-ledger/read.js +29 -20
  303. package/template/coding-task-manager/lib/usage-ledger/schema.js +61 -1
  304. package/template/coding-task-manager/lib/usage-ledger/task-coordinator.js +4 -2
  305. package/template/coding-task-manager/lib/wake-skip-reasons.js +1 -0
  306. package/template/coding-task-manager/lib/walle/turn.js +1 -1
  307. package/template/coding-task-manager/lib/walle-history-serve.js +838 -0
  308. package/template/coding-task-manager/lib/walle-kill-authority.js +2 -2
  309. package/template/coding-task-manager/lib/walle-log-rotation.js +164 -1
  310. package/template/coding-task-manager/lib/walle-mcp-auto-config.js +56 -2
  311. package/template/coding-task-manager/lib/walle-row-history.js +495 -0
  312. package/template/coding-task-manager/lib/walle-supervisor.js +33 -14
  313. package/template/coding-task-manager/lib/watch-worker-client.js +203 -0
  314. package/template/coding-task-manager/lib/worker-terminal-output.js +5 -2
  315. package/template/coding-task-manager/lib/ws/hub-bridge.js +35 -0
  316. package/template/coding-task-manager/lib/ws/lifecycle.js +6 -11
  317. package/template/coding-task-manager/lib/ws/misc.js +1 -1
  318. package/template/coding-task-manager/lib/ws/state-sync.js +106 -4
  319. package/template/coding-task-manager/lib/ws/terminal-attach.js +91 -0
  320. package/template/coding-task-manager/oauth-proxy.js +112 -115
  321. package/template/coding-task-manager/package-lock.json +10 -94
  322. package/template/coding-task-manager/package.json +4 -3
  323. package/template/coding-task-manager/protocol/message-table.json +10 -0
  324. package/template/coding-task-manager/protocol/messages.js +10 -0
  325. package/template/coding-task-manager/protocol/ws-schema.json +20 -0
  326. package/template/coding-task-manager/protocol/ws-schema.md +2 -0
  327. package/template/coding-task-manager/public/css/app.css +170 -0
  328. package/template/coding-task-manager/public/css/walle-session.css +4 -0
  329. package/template/coding-task-manager/public/index.html +473 -243
  330. package/template/coding-task-manager/public/js/agent-command.js +86 -0
  331. package/template/coding-task-manager/public/js/app/backups-panel.js +111 -5
  332. package/template/coding-task-manager/public/js/app/coding-agent-upgrade.js +103 -4
  333. package/template/coding-task-manager/public/js/app/machines-page.js +1328 -8
  334. package/template/coding-task-manager/public/js/app/models-tab.js +113 -38
  335. package/template/coding-task-manager/public/js/app/restart-banner.js +53 -0
  336. package/template/coding-task-manager/public/js/app/worktrees-panel.js +184 -2
  337. package/template/coding-task-manager/public/js/background-work.js +196 -27
  338. package/template/coding-task-manager/public/js/coding-session-model-presentation.js +138 -10
  339. package/template/coding-task-manager/public/js/core/active-session-groups.js +179 -0
  340. package/template/coding-task-manager/public/js/core/pending-create.js +238 -0
  341. package/template/coding-task-manager/public/js/core/recent-machine-source.js +228 -0
  342. package/template/coding-task-manager/public/js/core/session-commands.js +180 -14
  343. package/template/coding-task-manager/public/js/dashboard-client-function-order.json +8 -0
  344. package/template/coding-task-manager/public/js/document-review-links.js +9 -1
  345. package/template/coding-task-manager/public/js/file-resolution-client.js +52 -1
  346. package/template/coding-task-manager/public/js/history-app-seam.js +22 -2
  347. package/template/coding-task-manager/public/js/machine-pool-shared.js +558 -3
  348. package/template/coding-task-manager/public/js/message-renderer.js +4 -3
  349. package/template/coding-task-manager/public/js/model-picker.js +3 -1
  350. package/template/coding-task-manager/public/js/native-subagent-review.js +15 -2
  351. package/template/coding-task-manager/public/js/new-session-agent-grid.js +346 -0
  352. package/template/coding-task-manager/public/js/pasted-content.js +236 -0
  353. package/template/coding-task-manager/public/js/pe-private-content-lifetime.js +39 -7
  354. package/template/coding-task-manager/public/js/private-model-lifetime.js +6 -2
  355. package/template/coding-task-manager/public/js/prompts.js +11 -10
  356. package/template/coding-task-manager/public/js/protocol.js +10 -0
  357. package/template/coding-task-manager/public/js/restart-banner-policy.js +29 -1
  358. package/template/coding-task-manager/public/js/session-model-picker.js +447 -57
  359. package/template/coding-task-manager/public/js/session-search-utils.js +18 -2
  360. package/template/coding-task-manager/public/js/session-usage-view.js +2 -1
  361. package/template/coding-task-manager/public/js/session-workspace-tracking.js +51 -1
  362. package/template/coding-task-manager/public/js/state-sync-client.js +10 -1
  363. package/template/coding-task-manager/public/js/stream-view.js +6 -5
  364. package/template/coding-task-manager/public/js/terminal/conv-only-session.js +287 -0
  365. package/template/coding-task-manager/public/js/terminal/runtime-09.js +2 -0
  366. package/template/coding-task-manager/public/js/terminal/runtime-10.js +5 -5
  367. package/template/coding-task-manager/public/js/terminal/runtime-12.js +8 -1
  368. package/template/coding-task-manager/public/js/terminal/runtime-16.js +4 -0
  369. package/template/coding-task-manager/public/js/terminal/runtime-20.js +1 -1
  370. package/template/coding-task-manager/public/js/terminal-attachment-draft.js +67 -13
  371. package/template/coding-task-manager/public/js/terminal-image-orchestration.js +52 -6
  372. package/template/coding-task-manager/public/js/terminal-wheel.js +23 -3
  373. package/template/coding-task-manager/public/js/walle/chat-conversation.js +4 -4
  374. package/template/coding-task-manager/public/js/walle.js +6 -0
  375. package/template/coding-task-manager/public/js/ws/live-dispatch.js +10 -0
  376. package/template/coding-task-manager/public/m/app.css +140 -0
  377. package/template/coding-task-manager/public/m/app.js +507 -68
  378. package/template/coding-task-manager/public/m/index.html +17 -0
  379. package/template/coding-task-manager/public/m/machines.js +838 -4
  380. package/template/coding-task-manager/public/m/private-api.js +31 -1
  381. package/template/coding-task-manager/public/usage.html +1 -0
  382. package/template/coding-task-manager/scripts/dev-route-fixture/synthetic-route-upstream.js +104 -0
  383. package/template/coding-task-manager/scripts/dev-route-fixture.js +339 -0
  384. package/template/coding-task-manager/scripts/opencode-lead-route-probe.js +195 -0
  385. package/template/coding-task-manager/scripts/opencode-v2-contract-probe/fake-anthropic.js +168 -0
  386. package/template/coding-task-manager/scripts/opencode-v2-contract-probe/probe-plugin/server.js +95 -0
  387. package/template/coding-task-manager/scripts/opencode-v2-contract-probe.js +673 -0
  388. package/template/coding-task-manager/server.js +1950 -11679
  389. package/template/coding-task-manager/session-integrity.js +64 -4
  390. package/template/coding-task-manager/workers/db-owner-worker.js +19 -2
  391. package/template/coding-task-manager/workers/online-backup-worker.js +1 -0
  392. package/template/coding-task-manager/workers/read-pool-model-collector.js +51 -3
  393. package/template/coding-task-manager/workers/read-pool-worker.js +76 -6
  394. package/template/coding-task-manager/workers/session-host-pool-process.js +6 -6
  395. package/template/coding-task-manager/workers/session-host-process.js +5 -5
  396. package/template/coding-task-manager/workers/watch-worker.js +105 -0
  397. package/template/coding-task-manager/workers/worktree-worker.js +168 -33
  398. package/template/ctm-relay/lib/protocol.js +14 -1
  399. package/template/package-lock.json +2 -2
  400. package/template/package.json +1 -1
  401. package/template/shared/backup-retention.js +82 -0
  402. package/template/shared/conversation-admission.js +2 -0
  403. package/template/shared/conversation-provenance.js +3 -7
  404. package/template/shared/conversation-storage-v2-contract.js +5 -0
  405. package/template/shared/linked-worktree.js +51 -0
  406. package/template/shared/macos-fda-target.js +57 -0
  407. package/template/shared/orphan-parents.js +55 -0
  408. package/template/shared/release-schema.json +2 -2
  409. package/template/shared/storage/contract.js +3 -0
  410. package/template/wall-e/adapters/imessage.js +12 -0
  411. package/template/wall-e/agent.js +71 -4
  412. package/template/wall-e/api-walle.js +21 -1
  413. package/template/wall-e/bin/train-gemma-e4b-tooluse.js +2 -2
  414. package/template/wall-e/bin/walle-mcp-stdio.js +5 -5
  415. package/template/wall-e/brain/brain-join.js +859 -0
  416. package/template/wall-e/brain/brain-sync-membership.js +20 -0
  417. package/template/wall-e/brain/brain-sync-store.js +131 -77
  418. package/template/wall-e/brain/brain-sync-v2-schema.js +203 -0
  419. package/template/wall-e/brain/brain-sync-v2.js +578 -0
  420. package/template/wall-e/brain/delegate-model-prefs-store.js +13 -4
  421. package/template/wall-e/brain/deterministic-id.js +51 -0
  422. package/template/wall-e/brain/memories.js +2 -2
  423. package/template/wall-e/brain/migrations.js +40 -6
  424. package/template/wall-e/brain/model-identity-migration.js +1 -1
  425. package/template/wall-e/brain/owner-call-whitelist.js +23 -7
  426. package/template/wall-e/brain/schema.js +45 -85
  427. package/template/wall-e/brain.js +171 -35
  428. package/template/wall-e/chat.js +3 -3
  429. package/template/wall-e/coding/agent-shell-env.js +7 -2
  430. package/template/wall-e/coding/prompt-bundle.js +66 -21
  431. package/template/wall-e/config/main-loop-exemptions.json +2 -2
  432. package/template/wall-e/http/admin-api.js +37 -0
  433. package/template/wall-e/http/gws-api.js +4 -0
  434. package/template/wall-e/http/helper-rules-api.js +7 -1
  435. package/template/wall-e/http/model-admin.js +8 -1
  436. package/template/wall-e/http/model-delegate-pref-admin.js +3 -3
  437. package/template/wall-e/http/model-proxy-providers.js +174 -1
  438. package/template/wall-e/http/model-route-health.js +157 -0
  439. package/template/wall-e/http/sync-api.js +278 -464
  440. package/template/wall-e/jobs/job-runner.js +28 -1
  441. package/template/wall-e/lib/brain-owner-op-priority.js +9 -1
  442. package/template/wall-e/lib/ctm-data-dir.js +26 -0
  443. package/template/wall-e/lib/derivation-home.js +147 -0
  444. package/template/wall-e/lib/helper-rules/evaluate.js +50 -9
  445. package/template/wall-e/lib/helper-rules/grade.js +51 -8
  446. package/template/wall-e/lib/helper-rules/lead-call-hook.js +38 -5
  447. package/template/wall-e/lib/helper-rules/store.js +4 -2
  448. package/template/wall-e/lib/landing-mcp-tools.js +170 -0
  449. package/template/wall-e/lib/mcp-client-config.js +133 -14
  450. package/template/wall-e/lib/mcp-gateway-migrate.js +28 -64
  451. package/template/wall-e/lib/mcp-integration.js +58 -13
  452. package/template/wall-e/lib/parent-death.js +7 -1
  453. package/template/wall-e/lib/scheduler-worker-jobs.js +6 -4
  454. package/template/wall-e/llm/delegate-lead-prefs.js +16 -1
  455. package/template/wall-e/llm/delegate-vendor-default.js +12 -5
  456. package/template/wall-e/llm/model-roles.js +1 -1
  457. package/template/wall-e/llm/native-delegate-selection.js +56 -8
  458. package/template/wall-e/llm/worker-delegate-args.js +72 -7
  459. package/template/wall-e/llm/worker-mcp-routing.js +66 -17
  460. package/template/wall-e/loops/brain-custom-writes.js +19 -0
  461. package/template/wall-e/loops/ingest.js +17 -1
  462. package/template/wall-e/loops/think.js +19 -4
  463. package/template/wall-e/mcp-contract.js +222 -6
  464. package/template/wall-e/mcp-protocol-contract.js +40 -5
  465. package/template/wall-e/mcp-server.js +128 -29
  466. package/template/wall-e/mcp-worker-schemas.js +5 -5
  467. package/template/wall-e/memory/ctm-context-client.js +85 -0
  468. package/template/wall-e/memory/ctm-session-context.js +9 -3
  469. package/template/wall-e/memory/hub-bridge-client.js +388 -0
  470. package/template/wall-e/memory/replica-origin.js +56 -0
  471. package/template/wall-e/memory/session-pool.js +135 -0
  472. package/template/wall-e/runtime/live-capabilities.js +8 -3
  473. package/template/wall-e/server.js +4 -2
  474. package/template/wall-e/shared/release-schema.json +2 -2
  475. package/template/wall-e/shared/sqlite-file-set.js +39 -0
  476. package/template/wall-e/shared/storage/contract.js +3 -0
  477. package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
  478. package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +7 -1
  479. package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +4 -4
  480. package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +6 -6
  481. package/template/wall-e/skills/_templates/fleet-sync/VERSION +1 -0
  482. package/template/wall-e/skills/_templates/fleet-sync/released-sha256.json +16 -0
  483. package/template/wall-e/skills/_templates/fleet-sync/templates/claude/SKILL.md +64 -0
  484. package/template/wall-e/skills/_templates/fleet-sync/templates/codex/SKILL.md +64 -0
  485. package/template/wall-e/tools/chrome-automation.js +6 -0
  486. package/template/wall-e/training/setup-cuda-train-env.sh +2 -2
  487. package/template/wall-e/workers/brain-owner-worker.js +18 -4
  488. package/template/wall-e/workers/mcp-gateway-process.js +5 -5
@@ -83,6 +83,11 @@ function serializeSessionListEnvelope(payload) {
83
83
  type: payload?.type,
84
84
  restoring: payload?.restoring,
85
85
  sessions: Array.isArray(payload?.sessions) ? payload.sessions : [],
86
+ // Box-owned sessions WP-5: the hub's "a registered box has not delivered its catalog yet" count
87
+ // rides the sessions frame (server.js _finishBroadcast adds it only when a machine is enabled).
88
+ // Carry it when present so the off-main path matches the sliced on-main one byte for byte;
89
+ // a zero-machine envelope stays the exact three-key object it has always been.
90
+ ...(payload && payload.machinesPending !== undefined ? { machinesPending: payload.machinesPending } : {}),
86
91
  });
87
92
  }
88
93
 
@@ -80,10 +80,12 @@ function resetBuildInfoCache() {
80
80
  // and process-wide memoization make it a poor fit for "resolve once, fail closed to 'unknown'".
81
81
  // Wrapped so ANY failure (no git binary, cwd outside a repo, detached HEAD, timeout, ...) yields
82
82
  // 'unknown' rather than throwing — this must never block or delay boot.
83
- function resolveBootBuildSha(repoRoot, execFileSyncImpl) {
83
+ // `full: true` returns the 40-hex commit: fleet status compares the RUNNING commit against a full
84
+ // target sha (lib/fleet-hub.js), so an abbreviation there reads as "never restarted onto it".
85
+ function resolveBootBuildSha(repoRoot, execFileSyncImpl, { full = false } = {}) {
84
86
  try {
85
87
  const run = typeof execFileSyncImpl === 'function' ? execFileSyncImpl : execFileSync;
86
- const out = run('git', ['rev-parse', '--short', 'HEAD'], {
88
+ const out = run('git', full ? ['rev-parse', 'HEAD'] : ['rev-parse', '--short', 'HEAD'], {
87
89
  cwd: repoRoot || path.resolve(__dirname, '..', '..'),
88
90
  encoding: 'utf8',
89
91
  stdio: ['ignore', 'pipe', 'ignore'],
@@ -257,20 +257,28 @@ function createClaudeModelTruth({ now = Date.now } = {}) {
257
257
  const EMPTY_CLAUDE_TRUTH = Object.freeze({
258
258
  selected: null, resolved: null, context1m: false, lastTurn: null, effort: null,
259
259
  source: null, observedAtMs: 0, lastTurnAtMs: 0,
260
+ // WP-1/D-1: the newest REFUSED turn the transcript recorded, as { status, atMs, turnId, requestId },
261
+ // or null. It is carried for the lead-model switch's failure branch only -- it names no model, so no
262
+ // consumer of `resolved`/`selected`/`lastTurn`/`effort` may read it as one.
263
+ lastTurnFailure: null,
260
264
  });
261
265
 
262
266
  /**
263
- * Assemble the flat truth shape from the two transcript facts a Claude Code JSONL carries
267
+ * Assemble the flat truth shape from the transcript facts a Claude Code JSONL carries
264
268
  * (D-4): the identity record is the verbatim "set to" selection, assistant rows are what
265
269
  * actually served. An identity that names no served model ('opusplan') still sets `selected`
266
270
  * while `resolved` falls back to the last turn.
271
+ *
272
+ * WP-1 adds the third fact: `failure` ({ status, atMs, turnId, requestId } | null) is copied
273
+ * verbatim and changes nothing else about the shape.
267
274
  */
268
- function truthFromTranscriptFacts(identity, turn) {
275
+ function truthFromTranscriptFacts(identity, turn, failure = null) {
269
276
  const truth = {
270
277
  ...EMPTY_CLAUDE_TRUTH,
271
278
  lastTurn: turn ? turn.model : null,
272
279
  lastTurnAtMs: turn ? (turn.observedAtMs || 0) : 0,
273
280
  effort: turn ? (turn.effort || null) : null,
281
+ lastTurnFailure: failure || null,
274
282
  };
275
283
  const identityNorm = identity ? normalizeClaudeModelId(identity.modelId) : null;
276
284
  if (identity) truth.selected = identity.modelId;
@@ -302,6 +310,9 @@ function viewToTruth(view, fallback = EMPTY_CLAUDE_TRUTH) {
302
310
  source: resolved ? resolved.source : fallback.source,
303
311
  observedAtMs: resolved ? resolved.observedAtMs : fallback.observedAtMs,
304
312
  lastTurnAtMs: lastTurn ? lastTurn.observedAtMs : fallback.lastTurnAtMs,
313
+ // WP-1: the failure provenance is not ledger evidence (the ledger has no slot for it), so it
314
+ // passes straight through from the transcript facts that produced this view.
315
+ lastTurnFailure: fallback.lastTurnFailure || null,
305
316
  };
306
317
  }
307
318
 
@@ -51,10 +51,13 @@ const {
51
51
  const { _jsonlContentText } = require('./jsonl-conversation-parser');
52
52
  const {
53
53
  COMMAND_ENVELOPE_RE, LOCAL_COMMAND_STDOUT_RE, PEER_RELAY_PREFIX_RE, UNKNOWN_TAG_RE,
54
- SYSTEM_REMINDER_RE, PASTED_CONTENT_RE, IDE_SELECTION_RE,
54
+ SYSTEM_REMINDER_RE, IDE_SELECTION_RE,
55
55
  TASK_NOTIFICATION_RE, TASK_NOTIFICATION_SUMMARY_RE,
56
56
  BASH_INPUT_RE, BASH_STDOUT_RE, BASH_STDERR_RE,
57
57
  } = require('../../shared/conversation-provenance');
58
+ // D-5: the ONE strict paste-wrapper recogniser (line-exact opener/closer pair, 4 lowercase
59
+ // hex ids) lives in public/js/pasted-content.js. Nothing here re-derives it.
60
+ const PastedContent = require('../public/js/pasted-content');
58
61
  // WP-1 (rule D-9): wrap/measure/pad through the ONE width authority that matches the xterm.js
59
62
  // pane this renders into, not a hand-written East-Asian-Width table -- `wrapToCells`/
60
63
  // `stringCellWidth`/`truncateToCells` no longer flow from the codex renderer into this one.
@@ -184,18 +187,19 @@ function _bashStdoutOnly(text) {
184
187
  return null;
185
188
  }
186
189
 
187
- // Corrected 2026-09-27 (WP-3 live capture, fix round 1): the real screen shows a
188
- // `<pasted_content>` block VERBATIM, inline with the rest of the message -- never the
189
- // "[Pasted text #n +N lines]" placeholder this used to invent (a real bracketed paste, sent
190
- // through the same input path a real keystroke takes and confirmed present in the JSONL, showed
191
- // as ordinary wrapped prompt lines: "❯ line one" / " line two" / ... / " summarize the pasted
192
- // text in one line", with no collapse marker anywhere). D-8 branch 6: strip the tags, keep the
193
- // inner text, dropping exactly one leading/trailing blank line the tag wrapping usually
194
- // introduces (same trim the old placeholder's line count used).
190
+ // Corrected 2026-09-27 (WP-3 live capture, fix round 1): the real screen shows a pasted
191
+ // block VERBATIM, inline with the rest of the message -- never the "[Pasted text #n +N lines]"
192
+ // placeholder this used to invent (a real bracketed paste, sent through the same input path a
193
+ // real keystroke takes and confirmed present in the JSONL, showed as ordinary wrapped prompt
194
+ // lines: "❯ line one" / " line two" / ... / " summarize the pasted text in one line", with no
195
+ // collapse marker anywhere). D-8 branch 6: strip the wrapper, keep the inner text.
196
+ //
197
+ // D-5 (WP-2): recognition is NOT re-derived here any more -- the strict rule (a line that is
198
+ // exactly the opener with a 4-lowercase-hex id, matched by the same-id closer line) lives in
199
+ // public/js/pasted-content.js; `PastedContent.unwrap` drops the wrapper and keeps the body
200
+ // verbatim, so the escaped/unknown-tag handling below sees body text only.
195
201
  function _replacePastedContent(text) {
196
- return String(text || '').replace(PASTED_CONTENT_RE, (whole, inner) => (
197
- inner.replace(/^\n+/, '').replace(/\n+$/, '')
198
- ));
202
+ return PastedContent.unwrap(text);
199
203
  }
200
204
 
201
205
  // D-10 (WP-3 live capture): a raw tool_use name is not always what the TUI displays -- see
@@ -557,7 +561,7 @@ function parseClaudeTranscript(records, opts = {}) {
557
561
  const bashStdoutOnly = _bashStdoutOnly(text);
558
562
  if (bashStdoutOnly) { flushTools(); turns.push({ kind: 'local_stdout', uuid: rec.uuid, ts: rec.timestamp, lines: bashStdoutOnly }); continue; }
559
563
 
560
- // 6/7/9/10/11: strip <pasted_content> to a placeholder, drop <ide_selection> and
564
+ // 6/7/9/10/11: strip the paste wrapper, drop <ide_selection> and
561
565
  // <system-reminder> entirely, then fall back to a plain prompt; an unmatched leading
562
566
  // tag on what's left is recorded (never hidden) via stats.unknownEnvelopes.
563
567
  let working = _replacePastedContent(text);
@@ -44,6 +44,15 @@ function resolveDiagClientId(ws) {
44
44
  // while still capping memory if a client rotates clientId to evade this.
45
45
  const MAX_DIAG_THROTTLE_KEYS = 512;
46
46
 
47
+ // WP-0 (docs/box-session-client-diag-and-reader-jump-2026-11-01.html §5 R-1/R-2): a box-owned
48
+ // "mirror" session has no entry in the hub's local `sessions` Map, so `getSession(id)` is null for
49
+ // it and every client-diag frame from a hub viewer on that session was dropped before recording —
50
+ // even though the hub is the observer that owns the browser and telemetry.db. Mirror ids now get a
51
+ // per-id holder object (throttle state only — nothing but the terminal-authority branch reads local
52
+ // session fields, and mirrors skip that branch) from this bounded map. FIFO eviction keeps a long-
53
+ // lived hub process from pinning one holder per mirror it has ever seen.
54
+ const MAX_MIRROR_DIAG_HOLDERS = 256;
55
+
47
56
  // Cap on the generic (unlisted-event) detail passthrough below. 32 rather than 24 because the
48
57
  // history-seam-crossing beacon carries up to 27 non-null keys (joinDup/joinBlk included), and a
49
58
  // 24-key cut silently dropped its trailing distPx/exitBy/provider fields.
@@ -68,6 +77,9 @@ function clientDiagHostSnapshot() {
68
77
 
69
78
  function createClientDiagHandler(deps = {}) {
70
79
  const getSession = deps.getSession || (() => null);
80
+ // WP-0 R-1: (id) => truthy for a box-owned mirror session id, else null. Default keeps every
81
+ // existing caller byte-identical (a mirror id stays dropped).
82
+ const getMirrorSession = typeof deps.getMirrorSession === 'function' ? deps.getMirrorSession : () => null;
71
83
  const isSubscribed = typeof deps.isSubscribed === 'function' ? deps.isSubscribed : () => false;
72
84
  const recordDiagnostic = deps.recordDiagnostic || (() => {});
73
85
  const recordAuthority = deps.recordAuthority || (() => {});
@@ -79,14 +91,59 @@ function createClientDiagHandler(deps = {}) {
79
91
  // A socket close is page-scoped rather than session-scoped, so it alone may use the bounded
80
92
  // global pseudo-session. Terminal/render recovery events must name a real session.
81
93
  let globalDiagSession = null;
94
+ // WP-0 (§6.4, D-8) review fix: a create-ready frame names a PENDING CREATE id, which is not
95
+ // necessarily a session this machine knows — outcome 'failed'/'expired' never became one, and
96
+ // on the hub a successfully created session is owned by the box, so getSession(msg.id) is
97
+ // empty here. It is therefore answered BEFORE the session gate (the client-ws-close-observed
98
+ // escape is the same idea) and needs its own bounded 1 s window, since the per-session
99
+ // throttle map below is unreachable for a session-less id.
100
+ const createReadyAtByKey = new Map();
101
+ // WP-0 R-1: per-mirror-id throttle holders, newest-last (Map insertion order), FIFO-evicted at
102
+ // MAX_MIRROR_DIAG_HOLDERS. Scoped per handler instance so one hub process's churn cannot affect
103
+ // another's (and so a test harness gets a fresh map).
104
+ const mirrorDiagHolders = new Map();
82
105
 
83
- return function handleClientDiag(ws, msg) {
106
+ function handleClientDiag(ws, msg) {
84
107
  if (!msg || !msg.id) return;
85
108
  const event = String(msg.event || '');
109
+ if (event === 'create-ready') {
110
+ const at = now();
111
+ const throttleKey = `${event} ${resolveDiagClientId(ws)} ${msg.id}`;
112
+ const lastEventAt = Number(createReadyAtByKey.get(throttleKey)) || 0;
113
+ if (lastEventAt && at - lastEventAt < 1000) return;
114
+ createReadyAtByKey.delete(throttleKey);
115
+ createReadyAtByKey.set(throttleKey, at);
116
+ while (createReadyAtByKey.size > MAX_DIAG_THROTTLE_KEYS) {
117
+ createReadyAtByKey.delete(createReadyAtByKey.keys().next().value);
118
+ }
119
+ // Display only: the numbers come from the client's own clock, so they are coerced
120
+ // (non-finite → -1) and the strings cut before they reach the log.
121
+ const d = msg.details && typeof msg.details === 'object' ? msg.details : {};
122
+ const num = (value) => (Number.isFinite(Number(value)) ? Number(value) : -1);
123
+ const text = (value, max) => (typeof value === 'string' ? value.slice(0, max) : '');
124
+ console.log(
125
+ `[create-client] id=${text(msg.id, 160)} machine=${text(d.machine, 160)} outcome=${text(d.outcome, 40)} ` +
126
+ `clickToAcceptedMs=${num(d.clickToAcceptedMs)} clickToSettledMs=${num(d.clickToSettledMs)}`
127
+ );
128
+ return;
129
+ }
86
130
  let session = getSession(msg.id);
131
+ // WP-0 R-2: a mirror session skips only terminal-authority (recordAuthority reads LOCAL session
132
+ // fields and drives local wedge remediation); every other branch records as normal.
133
+ let isMirror = false;
87
134
  if (!session) {
88
135
  if (msg.id === 'global' && event === 'client-ws-close-observed') {
89
136
  session = globalDiagSession || (globalDiagSession = {});
137
+ } else if (getMirrorSession(msg.id)) {
138
+ isMirror = true;
139
+ session = mirrorDiagHolders.get(msg.id);
140
+ if (!session) {
141
+ session = {};
142
+ mirrorDiagHolders.set(msg.id, session);
143
+ while (mirrorDiagHolders.size > MAX_MIRROR_DIAG_HOLDERS) {
144
+ mirrorDiagHolders.delete(mirrorDiagHolders.keys().next().value);
145
+ }
146
+ }
90
147
  } else {
91
148
  return;
92
149
  }
@@ -109,6 +166,7 @@ function createClientDiagHandler(deps = {}) {
109
166
  session._clientDiagAtByEvent.delete(session._clientDiagAtByEvent.keys().next().value);
110
167
  }
111
168
  if (event === 'terminal-authority') {
169
+ if (isMirror) return;
112
170
  if (msg.details && typeof msg.details === 'object') {
113
171
  recordAuthority(ws, session, msg.id, msg.details);
114
172
  }
@@ -211,7 +269,11 @@ function createClientDiagHandler(deps = {}) {
211
269
  }
212
270
  }
213
271
  recordDiagnostic(msg.id, `client-${event}`, details);
214
- };
272
+ }
273
+
274
+ // WP-0 AC-0e: test-only probe for the mirror holder bound. Production callers never read it.
275
+ handleClientDiag._mirrorHolderCount = () => mirrorDiagHolders.size;
276
+ return handleClientDiag;
215
277
  }
216
278
 
217
279
  module.exports = { createClientDiagHandler };
@@ -21,27 +21,25 @@
21
21
  // half of this claim so a stray production `require` here is caught.
22
22
 
23
23
  const { spawn } = require('child_process');
24
+ const { spawnNdjsonTransport } = require('./acp/ndjson-stdio-transport');
24
25
  const bridge = require('./codex-approval-bridge');
25
26
 
26
27
  // A transport is { write(jsonString), onLine(cb), close() }. The default spawns codex;
27
- // tests inject a fake one to drive the client deterministically.
28
- function spawnCodexTransport({ cwd, env, spawnFn = spawn, command = 'codex', args = ['app-server'] } = {}) {
29
- const child = spawnFn(command, args, { stdio: ['pipe', 'pipe', 'pipe'], cwd, env });
30
- let buf = '';
31
- let lineCb = null;
32
- child.stdout.on('data', (d) => {
33
- buf += d.toString();
34
- let i;
35
- while ((i = buf.indexOf('\n')) >= 0) {
36
- const line = buf.slice(0, i); buf = buf.slice(i + 1);
37
- if (line.trim() && lineCb) lineCb(line);
38
- }
28
+ // tests inject a fake one to drive the client deterministically. The framing itself moved
29
+ // to lib/acp/ndjson-stdio-transport.js (WP-1) so the ACP client shares one implementation.
30
+ function spawnCodexTransport(o = {}) {
31
+ const t = spawnNdjsonTransport({
32
+ command: o.command || 'codex',
33
+ args: o.args || ['app-server'],
34
+ cwd: o.cwd,
35
+ env: o.env,
36
+ spawnFn: o.spawnFn || spawn,
39
37
  });
40
38
  return {
41
- write: (s) => { try { child.stdin.write(s + '\n'); } catch (error) { void error; } },
42
- onLine: (cb) => { lineCb = cb; },
43
- close: () => { try { child.kill(); } catch (error) { void error; } },
44
- _child: child,
39
+ write: t.write,
40
+ onLine: t.onLine,
41
+ close: () => t.kill(),
42
+ _child: t._child,
45
43
  };
46
44
  }
47
45
 
@@ -0,0 +1,55 @@
1
+ 'use strict';
2
+
3
+ // D-7 (docs/codex-upgrades-without-version-approval-2026-10-28.html §configuration-followup): Codex
4
+ // 0.165.0 persists a harness-authored reasoning-configuration control record in the rollout as
5
+ // `response_item` / `configuration_update`. The tagged release source
6
+ // (codex-rs/protocol/src/models/configuration_update.rs -> ConfigurationReasoning { effort },
7
+ // codex-rs/core/src/client.rs:596-599,935-939 @ rust-v0.165.0) enables the update only for native
8
+ // OpenAI targets that advertise it and REMOVES configuration updates from the outgoing request copy
9
+ // for every other target, so the record is source history CTM classifies (and never rewrites) --
10
+ // the selected effort is the source model's own setting and is never adopted as CTM's.
11
+ //
12
+ // This module is the ONE shape definition for that record. It is PURE: no file effects, no runtime
13
+ // version check, no enum/version list. The scanner (lib/history-transition-read-op.js) uses it to
14
+ // classify the record into its own history kind; the planner
15
+ // (lib/harness-history-transition.js) decides where that kind may travel.
16
+ const ENVELOPE_KEYS = new Set(['type', 'payload', 'timestamp', 'ordinal', 'metadata']);
17
+ const PAYLOAD_KEYS = new Set(['type', 'reasoning']);
18
+ const METADATA_KEYS = new Set(['client_authored', 'harness_authored_configuration']);
19
+
20
+ function isRecord(value) {
21
+ return !!value && typeof value === 'object' && !Array.isArray(value);
22
+ }
23
+
24
+ // A record is a native configuration update only when every measured field is exact: the envelope
25
+ // carries no unknown key, `type` is the `response_item` envelope, the payload holds exactly
26
+ // `type`/`reasoning` with a nonblank effort STRING (never an enum or version list), and the payload
27
+ // matches the native harness-authored marker the REQUIRED `harness_authored_configuration: true`
28
+ // names. This is SHAPE validation, not cryptographic authentication: the marker only has to match
29
+ // the value the native harness writes. Any other shape returns false so the caller's existing
30
+ // refusal fires unchanged.
31
+ function isNativeConfigurationUpdate(record) {
32
+ if (!isRecord(record)) return false;
33
+ if (Object.keys(record).some((key) => !ENVELOPE_KEYS.has(key))) return false;
34
+ if (record.type !== 'response_item') return false;
35
+ if (Object.hasOwn(record, 'timestamp') && typeof record.timestamp !== 'string') return false;
36
+ if (record.ordinal !== undefined && record.ordinal !== null
37
+ && (!Number.isSafeInteger(record.ordinal) || record.ordinal < 0)) return false;
38
+ if (!Object.hasOwn(record, 'metadata') || !isRecord(record.metadata)) return false;
39
+ const metadata = record.metadata;
40
+ if (Object.keys(metadata).some((key) => !METADATA_KEYS.has(key))) return false;
41
+ if (metadata.harness_authored_configuration !== true) return false;
42
+ if (Object.hasOwn(metadata, 'client_authored') && metadata.client_authored !== false) return false;
43
+ if (!isRecord(record.payload)) return false;
44
+ const payload = record.payload;
45
+ if (Object.keys(payload).length !== PAYLOAD_KEYS.size) return false;
46
+ if (Object.keys(payload).some((key) => !PAYLOAD_KEYS.has(key))) return false;
47
+ if (payload.type !== 'configuration_update') return false;
48
+ if (!isRecord(payload.reasoning)) return false;
49
+ const reasoningKeys = Object.keys(payload.reasoning);
50
+ if (reasoningKeys.length !== 1 || reasoningKeys[0] !== 'effort') return false;
51
+ const effort = payload.reasoning.effort;
52
+ return typeof effort === 'string' && effort.trim().length > 0;
53
+ }
54
+
55
+ module.exports = { isNativeConfigurationUpdate };
@@ -1,25 +1,34 @@
1
1
  'use strict';
2
2
 
3
- // WP-0 of docs/codex-harness-version-qualification-2026-10-19.html (§5 D-1/D-4/D-5, §6).
3
+ // HISTORICAL DIAGNOSTIC EVIDENCE, NOT ADMISSION (docs/codex-upgrades-without-version-approval-2026-10-28.html
4
+ // §5 D-5). Originally WP-0 of docs/codex-harness-version-qualification-2026-10-19.html (§5 D-1/D-4/D-5, §6).
4
5
  //
5
- // The ONE table of Codex CLI versions a human qualified for CTM's Codex adapters. Every
6
- // runtime gate and every test fixture reads this module; `bin/codex-version-literal-lint.js`
7
- // fails any other `coding-task-manager/lib/**` file carrying a Codex version literal, so this
8
- // file is the only place a version string may be written by hand.
6
+ // This table records what a human once MEASURED on a Codex CLI version. It has NO runtime
7
+ // authority: nothing in CTM's launch, upgrade, planner, fork or history paths may read it to admit
8
+ // or refuse a version, and a new Codex release does NOT need a row here before the user can install
9
+ // it, switch to it or run it. `bin/codex-version-literal-lint.js` fails any other
10
+ // `coding-task-manager/lib/**` file that pins a Codex version literal or references these
11
+ // identifiers, so an approval gate cannot quietly grow back.
9
12
  //
10
- // Two contracts share this table, and they are NOT the same contract:
11
- // - the catalog contract (what Codex reads from the catalog CTM writes) is measured per
12
- // launch by the profile probe (WP-1) and is not gated by this table;
13
- // - the history/native-fork contract (app-server shapes and rollout record shapes) cannot be
14
- // probed per launch, so it is gated by exact membership here (D-4: an allowlist that is
15
- // also a floor — nothing below the first row is ever qualified).
13
+ // Two contracts this evidence used to stand in for are now checked where they actually operate:
14
+ // - the catalog contract (what Codex reads from the catalog CTM writes) is measured per launch by
15
+ // the profile probe and fails on the concrete mismatch;
16
+ // - the history/native-fork contract (app-server shapes and rollout record shapes) is checked by
17
+ // the record scanner against the records themselves, which is the failure the 2026-10-20
18
+ // incident showed membership could not predict.
19
+ //
20
+ // The rows are retained for `bin/qualify-codex.js` (optional evidence) and for its regression
21
+ // tests. Membership semantics are frozen history: rows are never edited, and no release is required
22
+ // to add one.
16
23
 
17
- // Leaf import on purpose: agent-version-service reads this table for its status row (WP-2), so
18
- // requiring it here would be a two-file cycle; both read the compare from lib/semver-compare.js.
24
+ // Leaf import on purpose: the diagnostic (bin/qualify-codex.js) and the lib modules that carry the
25
+ // adapter/schema identity constants require this module, so an import back into any of them would be
26
+ // a cycle; the version compare lives in the leaf lib/semver-compare.js that both read.
19
27
  const { compareSemver } = require('./semver-compare');
20
28
 
21
- // One row per Codex CLI version a human qualified with bin/qualify-codex.js output.
22
- // Keys are exact `codex --version` strings. Never edit a row's evidence by hand.
29
+ // One row per Codex CLI version a human once measured with bin/qualify-codex.js output.
30
+ // Keys are exact `codex --version` strings. Never edit a row's evidence by hand, and never treat
31
+ // the absence of a row as a reason to refuse a version.
23
32
  const CODEX_QUALIFIED_VERSIONS = Object.freeze({
24
33
  '0.162.1': Object.freeze({
25
34
  qualifiedOn: '2026-10-14',
@@ -31,14 +40,26 @@ const CODEX_QUALIFIED_VERSIONS = Object.freeze({
31
40
  by: 'docs/codex-harness-version-qualification-2026-10-19.html §1c-§1d',
32
41
  evidence: 'catalog probe identical to 0.162.1 (38 keys, 1625 B); models-manager diff empty; app-server-protocol/v2 diff turn.rs +3; 21 rollouts, record types ⊆ 0.162.1 set, 0 encrypted_content on non-reasoning items',
33
42
  }),
43
+ '0.164.0': Object.freeze({
44
+ qualifiedOn: '2026-10-27',
45
+ by: 'docs/codex-0164-historical-tools-safe-handoff-2026-10-27.html §8 WP-3 (AC-3a/AC-3b)',
46
+ evidence: 'AC-3a brokered real Codex slow file 18/18: WP-4B authenticated CTM proxy target path /v1/responses, source declaration id absent upstream, inherited source prompt present, current top-level tools 10; AC-3b qualifier exit 0: catalog probe 37 entry keys/6 checked, 64 version-matched rollouts all complete with no schema failures, tagged rust-v0.163.0..rust-v0.164.0 diff resolved',
47
+ }),
34
48
  });
35
- // The highest qualified version, never a hardcoded literal (a new row moves it, D-1).
49
+ // The newest measured row, derived rather than hardcoded. Diagnostic use only (see the header):
50
+ // it is the comparison baseline bin/qualify-codex.js reports against, not an admission ceiling.
36
51
  const LATEST_QUALIFIED_CODEX_VERSION = Object.keys(CODEX_QUALIFIED_VERSIONS)
37
52
  .sort((a, b) => compareSemver(b, a))[0];
38
- // The floor is the FIRST row and is never lowered (D-4/P-3): versions below it are not qualified.
53
+ // The FIRST row, never lowered: the oldest version a measurement exists for.
39
54
  const CODEX_QUALIFIED_FLOOR = '0.162.1';
40
55
  // Identity ids name CTM's own adapter behaviour, not the installed Codex (D-5); `q1` bumps only
41
56
  // when what CTM sends/reads changes. They carry no version, so a Codex upgrade cannot stale them.
57
+ // The version floor for the native sub-agent deny prefix (codex-native-subagent-pick-enforcement
58
+ // 2026-10-28 D-2b): `features.multi_agent_v2.disable_native_tools` exists from rust-v0.163.0
59
+ // (codex-rs/features/src/feature_configs.rs) and not at rust-v0.162.1; an older Codex exits 1 at
60
+ // config load (`data did not match any variant of untagged enum FeatureToml`). Below the qualified
61
+ // floor is impossible, but 0.162.1 is qualified AND below this key, so the deny has its own floor.
62
+ const CODEX_NATIVE_SUBAGENT_DENY_MIN_VERSION = '0.163.0';
42
63
  const CODEX_CONTROL_ADAPTER = 'codex-app-server-q1';
43
64
  const CODEX_COMPACTION_SCHEMA_RECEIPT = 'codex-model-info-comp-hash-nullable-q1';
44
65
  const CODEX_PRE_TURN_COMPACTION_SCHEMA = 'codex-pre-turn-compaction-q1';
@@ -54,13 +75,14 @@ function isNonElevatedCyberAccessProgram(value) {
54
75
  return NON_ELEVATED_CYBER_ACCESS_PROGRAMS.includes(value);
55
76
  }
56
77
 
57
- // Exact membership (D-4). Never a prefix/range match: '0.162.10' is not '0.162.1'.
78
+ // Exact membership against the measured rows. Never a prefix/range match: '0.162.10' is not
79
+ // '0.162.1'. A false result means "no measurement here", never "this version may not run".
58
80
  function isQualifiedCodexVersion(version) {
59
81
  return typeof version === 'string' && Object.hasOwn(CODEX_QUALIFIED_VERSIONS, version);
60
82
  }
61
83
 
62
- // The status-row shape (D-6): why a version may be missing from the table, and whether it is
63
- // ahead of the newest measured row (the updater defers exactly that case).
84
+ // Diagnostic status shape: whether a version appears among the measured rows, and whether it is
85
+ // newer than the newest one. No runtime path reads this to admit or defer a version.
64
86
  function codexQualification(version) {
65
87
  if (!version) return { state: 'unknown', latestQualified: LATEST_QUALIFIED_CODEX_VERSION };
66
88
  return {
@@ -71,6 +93,7 @@ function codexQualification(version) {
71
93
  }
72
94
 
73
95
  module.exports = {
96
+ CODEX_NATIVE_SUBAGENT_DENY_MIN_VERSION,
74
97
  CODEX_QUALIFIED_VERSIONS,
75
98
  LATEST_QUALIFIED_CODEX_VERSION,
76
99
  CODEX_QUALIFIED_FLOOR,