create-walle 0.10.1 → 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 (681) hide show
  1. package/README.md +7 -1
  2. package/lib/owner-write-safety.js +135 -0
  3. package/lib/public-runtime.js +13 -5
  4. package/lib/release-schema.json +3 -2
  5. package/lib/runtime-closure-policy.json +11 -8
  6. package/package.json +1 -1
  7. package/template/bin/deps-doctor.js +1 -1
  8. package/template/bin/node-bin.sh +11 -0
  9. package/template/coding-task-manager/api-prompts.js +55 -29
  10. package/template/coding-task-manager/bin/claude-hook.js +62 -4
  11. package/template/coding-task-manager/bin/claude-table-parity.js +307 -0
  12. package/template/coding-task-manager/bin/conversation-storage-auto-migration-lib.js +16 -1
  13. package/template/coding-task-manager/bin/conversation-storage-generation-evidence.js +9 -2
  14. package/template/coding-task-manager/bin/conversation-storage-service-entry-lib.js +16 -1
  15. package/template/coding-task-manager/bin/conversation-storage-walle-owner.js +247 -0
  16. package/template/coding-task-manager/bin/ctm-machine-pair.js +160 -0
  17. package/template/coding-task-manager/bin/ctm-relay-client.js +35 -12
  18. package/template/coding-task-manager/bin/land.js +2069 -0
  19. package/template/coding-task-manager/bin/lead-wait-census.js +1348 -0
  20. package/template/coding-task-manager/bin/memory-census.js +4 -2
  21. package/template/coding-task-manager/bin/memory-sync-verify.js +151 -0
  22. package/template/coding-task-manager/bin/probe-refusal-scope.js +530 -0
  23. package/template/coding-task-manager/bin/repair-foreign-clone.js +564 -0
  24. package/template/coding-task-manager/bin/repair-resume-echo-titles.js +248 -0
  25. package/template/coding-task-manager/bin/write-lock-bench.js +111 -0
  26. package/template/coding-task-manager/db.js +860 -317
  27. package/template/coding-task-manager/git-utils.js +44 -0
  28. package/template/coding-task-manager/lib/acp/acp-client.js +383 -0
  29. package/template/coding-task-manager/lib/acp/dsh-context-truth.js +176 -0
  30. package/template/coding-task-manager/lib/acp/dsh-launch-model.js +302 -0
  31. package/template/coding-task-manager/lib/acp/dsh-mcp-servers.js +194 -0
  32. package/template/coding-task-manager/lib/acp/dsh-prompt-lane.js +616 -0
  33. package/template/coding-task-manager/lib/acp/dsh-route-patch.js +308 -0
  34. package/template/coding-task-manager/lib/acp/dsh-session-runtime.js +522 -0
  35. package/template/coding-task-manager/lib/acp/dsh-transcript.js +395 -0
  36. package/template/coding-task-manager/lib/acp/dsh-usage-log.js +162 -0
  37. package/template/coding-task-manager/lib/acp/ndjson-stdio-transport.js +225 -0
  38. package/template/coding-task-manager/lib/adopted-host-redial.js +47 -7
  39. package/template/coding-task-manager/lib/adopted-launch-environment.js +123 -0
  40. package/template/coding-task-manager/lib/agent-auto-update-runtime.js +0 -3
  41. package/template/coding-task-manager/lib/agent-auto-update.js +26 -10
  42. package/template/coding-task-manager/lib/agent-bundle/build.js +657 -0
  43. package/template/coding-task-manager/lib/agent-bundle/codex-install.js +558 -0
  44. package/template/coding-task-manager/lib/agent-bundle/drift.js +120 -0
  45. package/template/coding-task-manager/lib/agent-bundle/gc.js +522 -0
  46. package/template/coding-task-manager/lib/agent-bundle/inventory.js +346 -0
  47. package/template/coding-task-manager/lib/agent-bundle/push.js +717 -0
  48. package/template/coding-task-manager/lib/agent-bundle/skill-transfer.js +724 -0
  49. package/template/coding-task-manager/lib/agent-bundle/spawn.js +119 -0
  50. package/template/coding-task-manager/lib/agent-bundle/store.js +568 -0
  51. package/template/coding-task-manager/lib/agent-capabilities.js +142 -12
  52. package/template/coding-task-manager/lib/agent-cli-cache.js +30 -5
  53. package/template/coding-task-manager/lib/agent-definitions.js +19 -0
  54. package/template/coding-task-manager/lib/agent-hooks-codex-toml.js +28 -16
  55. package/template/coding-task-manager/lib/agent-hooks-codex-workspace.js +9 -1
  56. package/template/coding-task-manager/lib/agent-hooks-installer.js +23 -8
  57. package/template/coding-task-manager/lib/agent-hooks-prune.js +37 -11
  58. package/template/coding-task-manager/lib/agent-hooks-shim.js +105 -0
  59. package/template/coding-task-manager/lib/agent-presets.js +99 -1
  60. package/template/coding-task-manager/lib/agent-title-apply.js +88 -0
  61. package/template/coding-task-manager/lib/agent-title-backfill-read.js +92 -0
  62. package/template/coding-task-manager/lib/agent-upgrade-jobs.js +12 -1
  63. package/template/coding-task-manager/lib/agent-version-service.js +74 -11
  64. package/template/coding-task-manager/lib/all-sessions-query.js +6 -2
  65. package/template/coding-task-manager/lib/api/agent-bundles.js +436 -0
  66. package/template/coding-task-manager/lib/api/backup-retention.js +83 -0
  67. package/template/coding-task-manager/lib/api/conversation-sync-routes.js +124 -0
  68. package/template/coding-task-manager/lib/api/diagnostics.js +549 -69
  69. package/template/coding-task-manager/lib/api/fleet.js +118 -0
  70. package/template/coding-task-manager/lib/api/host-stats.js +98 -0
  71. package/template/coding-task-manager/lib/api/hub-bridge.js +243 -0
  72. package/template/coding-task-manager/lib/api/ingress.js +43 -12
  73. package/template/coding-task-manager/lib/api/landing.js +403 -0
  74. package/template/coding-task-manager/lib/api/machine-pairing.js +285 -0
  75. package/template/coding-task-manager/lib/api/machine-pool.js +307 -0
  76. package/template/coding-task-manager/lib/api/machines.js +1150 -0
  77. package/template/coding-task-manager/lib/api/memory-sync-routes.js +335 -0
  78. package/template/coding-task-manager/lib/api/misc-ops.js +25 -5
  79. package/template/coding-task-manager/lib/api/providers.js +53 -6
  80. package/template/coding-task-manager/lib/api/remote-sessions.js +1326 -0
  81. package/template/coding-task-manager/lib/api/resume-from-store.js +25 -0
  82. package/template/coding-task-manager/lib/api/session-attach.js +623 -0
  83. package/template/coding-task-manager/lib/api/session-messages.js +1384 -0
  84. package/template/coding-task-manager/lib/api/sessions.js +237 -59
  85. package/template/coding-task-manager/lib/api/setup-network.js +544 -16
  86. package/template/coding-task-manager/lib/api/setup-wizard-handlers.js +884 -0
  87. package/template/coding-task-manager/lib/api/setup.js +829 -10
  88. package/template/coding-task-manager/lib/api/transcript-history.js +17 -4
  89. package/template/coding-task-manager/lib/api/walle-bridge.js +9 -1
  90. package/template/coding-task-manager/lib/api/worktrees.js +38 -37
  91. package/template/coding-task-manager/lib/approval-drift.js +16 -1
  92. package/template/coding-task-manager/lib/approval-logical-frame.js +5 -1
  93. package/template/coding-task-manager/lib/approval-scope.js +68 -4
  94. package/template/coding-task-manager/lib/attachment-reconciler-wiring.js +5 -2
  95. package/template/coding-task-manager/lib/auth-context.js +32 -2
  96. package/template/coding-task-manager/lib/auth-rate-limit.js +64 -1
  97. package/template/coding-task-manager/lib/auth-rules.js +474 -62
  98. package/template/coding-task-manager/lib/background-stop.js +369 -0
  99. package/template/coding-task-manager/lib/best-of-attempts.js +4 -1
  100. package/template/coding-task-manager/lib/best-of-launch-plan.js +52 -0
  101. package/template/coding-task-manager/lib/box-keep-awake.js +89 -0
  102. package/template/coding-task-manager/lib/broadcast-reason-stats.js +152 -0
  103. package/template/coding-task-manager/lib/broadcast-serialize.js +7 -1
  104. package/template/coding-task-manager/lib/browser-session-broker.js +9 -1
  105. package/template/coding-task-manager/lib/browser-use-adapter.js +33 -2
  106. package/template/coding-task-manager/lib/build-info.js +4 -2
  107. package/template/coding-task-manager/lib/claude-markdown-ansi.js +27 -85
  108. package/template/coding-task-manager/lib/claude-model-truth.js +13 -2
  109. package/template/coding-task-manager/lib/claude-session-title.js +6 -30
  110. package/template/coding-task-manager/lib/claude-table-layout.js +322 -0
  111. package/template/coding-task-manager/lib/claude-transcript-terminal-renderer.js +17 -13
  112. package/template/coding-task-manager/lib/client-diag-handler.js +69 -2
  113. package/template/coding-task-manager/lib/codex-app-server-client.js +14 -16
  114. package/template/coding-task-manager/lib/codex-config-guard.js +33 -3
  115. package/template/coding-task-manager/lib/codex-configuration-history.js +55 -0
  116. package/template/coding-task-manager/lib/codex-harness-qualification.js +55 -20
  117. package/template/coding-task-manager/lib/codex-launch-health.js +29 -2
  118. package/template/coding-task-manager/lib/codex-link-preparation.js +9 -8
  119. package/template/coding-task-manager/lib/codex-paths.js +2 -1
  120. package/template/coding-task-manager/lib/codex-rollout-history.js +743 -0
  121. package/template/coding-task-manager/lib/coding-agent-models.js +48 -42
  122. package/template/coding-task-manager/lib/coding-cli-skill-installer.js +44 -14
  123. package/template/coding-task-manager/lib/coding-session-model-adapters.js +70 -4
  124. package/template/coding-task-manager/lib/coding-session-model-owner.js +1 -1
  125. package/template/coding-task-manager/lib/coding-session-model-projection.js +5 -0
  126. package/template/coding-task-manager/lib/coding-session-model-public.js +7 -1
  127. package/template/coding-task-manager/lib/coding-session-model-runtime.js +24 -6
  128. package/template/coding-task-manager/lib/coding-session-model-scan.js +31 -0
  129. package/template/coding-task-manager/lib/coding-session-model-state.js +17 -0
  130. package/template/coding-task-manager/lib/coding-session-model-sync-state.js +0 -1
  131. package/template/coding-task-manager/lib/conversation-freshness-diagnostics.js +280 -0
  132. package/template/coding-task-manager/lib/conversation-import/cursor-guard-owner.js +10 -0
  133. package/template/coding-task-manager/lib/conversation-item-clock.js +261 -0
  134. package/template/coding-task-manager/lib/conversation-source-registry.js +5 -0
  135. package/template/coding-task-manager/lib/conversation-store-v2.js +44 -0
  136. package/template/coding-task-manager/lib/conversation-sync.js +355 -0
  137. package/template/coding-task-manager/lib/create/resolve-launch-params.js +104 -13
  138. package/template/coding-task-manager/lib/create/worker-role-profile.js +4 -4
  139. package/template/coding-task-manager/lib/create-intent-lease.js +51 -0
  140. package/template/coding-task-manager/lib/ctm-boot-lifecycle.js +17 -1
  141. package/template/coding-task-manager/lib/ctm-session-context-api.js +97 -6
  142. package/template/coding-task-manager/lib/db-domain-tables.js +8 -0
  143. package/template/coding-task-manager/lib/db-domains.js +22 -2
  144. package/template/coding-task-manager/lib/db-owner-dispatch-probe.js +32 -0
  145. package/template/coding-task-manager/lib/db-owner-op-registry.js +7 -0
  146. package/template/coding-task-manager/lib/db-owner-request-counts.js +178 -0
  147. package/template/coding-task-manager/lib/db-owner-worker-client.js +68 -14
  148. package/template/coding-task-manager/lib/db-schema-source-files.js +6 -0
  149. package/template/coding-task-manager/lib/deferred-restore-attempt.js +6 -2
  150. package/template/coding-task-manager/lib/feature-manifest.js +5 -1
  151. package/template/coding-task-manager/lib/fleet-conversation-route.js +97 -0
  152. package/template/coding-task-manager/lib/fleet-fanout.js +78 -0
  153. package/template/coding-task-manager/lib/fleet-hub.js +762 -0
  154. package/template/coding-task-manager/lib/fleet-origin-follower.js +252 -0
  155. package/template/coding-task-manager/lib/fleet-resolver-effects.js +147 -0
  156. package/template/coding-task-manager/lib/fleet-resolver-tick.js +148 -0
  157. package/template/coding-task-manager/lib/fleet-resolver.js +454 -0
  158. package/template/coding-task-manager/lib/fleet-session-list-routes.js +114 -0
  159. package/template/coding-task-manager/lib/fleet-session-lists.js +672 -0
  160. package/template/coding-task-manager/lib/fleet-update.js +798 -0
  161. package/template/coding-task-manager/lib/fs-watcher-root-watch.js +141 -0
  162. package/template/coding-task-manager/lib/fs-watcher.js +61 -44
  163. package/template/coding-task-manager/lib/harness-history-transition.js +52 -11
  164. package/template/coding-task-manager/lib/headless-inflight-ops.js +203 -0
  165. package/template/coding-task-manager/lib/headless-missing-reply.js +42 -0
  166. package/template/coding-task-manager/lib/headless-term-service.js +139 -25
  167. package/template/coding-task-manager/lib/hermetic-agent-launch-guard.js +10 -0
  168. package/template/coding-task-manager/lib/history-transition-read-op.js +175 -8
  169. package/template/coding-task-manager/lib/host-control-dial.js +167 -0
  170. package/template/coding-task-manager/lib/host-cpu-categories.js +310 -0
  171. package/template/coding-task-manager/lib/host-fseventsd-sampler.js +399 -0
  172. package/template/coding-task-manager/lib/host-handoff-orchestrator.js +16 -2
  173. package/template/coding-task-manager/lib/host-handoff.js +50 -15
  174. package/template/coding-task-manager/lib/host-health-ledger.js +164 -12
  175. package/template/coding-task-manager/lib/host-self-truth-watchdog.js +4 -0
  176. package/template/coding-task-manager/lib/host-stats.js +475 -0
  177. package/template/coding-task-manager/lib/host-threadpool-evacuation.js +160 -0
  178. package/template/coding-task-manager/lib/host-threadpool-monitor.js +14 -1
  179. package/template/coding-task-manager/lib/hosted-input-dispatch.js +203 -0
  180. package/template/coding-task-manager/lib/hosted-sync-worker.js +141 -310
  181. package/template/coding-task-manager/lib/hub-bridge-access.js +798 -0
  182. package/template/coding-task-manager/lib/hub-bridge-box.js +409 -0
  183. package/template/coding-task-manager/lib/hub-bridge-mcp.js +380 -0
  184. package/template/coding-task-manager/lib/hub-bridge-mesh.js +313 -0
  185. package/template/coding-task-manager/lib/hub-bridge-ops.js +721 -0
  186. package/template/coding-task-manager/lib/hub-bridge.js +398 -0
  187. package/template/coding-task-manager/lib/idle-notify.js +491 -0
  188. package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +12 -0
  189. package/template/coding-task-manager/lib/instance-manifest-runtime.js +3 -0
  190. package/template/coding-task-manager/lib/instance-manifest.js +18 -2
  191. package/template/coding-task-manager/lib/instance-sync-status.js +33 -8
  192. package/template/coding-task-manager/lib/landing/agent-rule.txt +1 -0
  193. package/template/coding-task-manager/lib/landing/batch-runner.js +366 -0
  194. package/template/coding-task-manager/lib/landing/config.js +536 -0
  195. package/template/coding-task-manager/lib/landing/ctm-view.js +256 -0
  196. package/template/coding-task-manager/lib/landing/gate.js +360 -0
  197. package/template/coding-task-manager/lib/landing/git.js +344 -0
  198. package/template/coding-task-manager/lib/landing/lease.js +247 -0
  199. package/template/coding-task-manager/lib/landing/merge-delta.js +380 -0
  200. package/template/coding-task-manager/lib/landing/proof.js +223 -0
  201. package/template/coding-task-manager/lib/landing/queue.js +998 -0
  202. package/template/coding-task-manager/lib/landing/radar.js +489 -0
  203. package/template/coding-task-manager/lib/landing/resolve-cli.js +424 -0
  204. package/template/coding-task-manager/lib/landing/state.js +263 -0
  205. package/template/coding-task-manager/lib/landing/stop.js +49 -0
  206. package/template/coding-task-manager/lib/landing/sync-cli.js +475 -0
  207. package/template/coding-task-manager/lib/landing/sync.js +456 -0
  208. package/template/coding-task-manager/lib/landing/train.js +885 -0
  209. package/template/coding-task-manager/lib/landing/window.js +57 -0
  210. package/template/coding-task-manager/lib/launch-environment.js +121 -0
  211. package/template/coding-task-manager/lib/launch-model-override.js +193 -8
  212. package/template/coding-task-manager/lib/launch-plan-pool.js +2 -1
  213. package/template/coding-task-manager/lib/launch-plan-warm-cache.js +6 -0
  214. package/template/coding-task-manager/lib/launch-plan-worker.js +59 -2
  215. package/template/coding-task-manager/lib/lead-model-observer.js +57 -1
  216. package/template/coding-task-manager/lib/lead-model-options.js +160 -3
  217. package/template/coding-task-manager/lib/lead-model-restore-reconciliation.js +106 -24
  218. package/template/coding-task-manager/lib/lead-model-switch-runtime.js +409 -72
  219. package/template/coding-task-manager/lib/lead-model-switch.js +115 -10
  220. package/template/coding-task-manager/lib/lead-model-transition-runtime.js +14 -2
  221. package/template/coding-task-manager/lib/lead-model-transition-store.js +85 -9
  222. package/template/coding-task-manager/lib/lead-route-preflight.js +179 -0
  223. package/template/coding-task-manager/lib/lead-switch-history-mode.js +110 -0
  224. package/template/coding-task-manager/lib/lead-wire-agent.js +7 -0
  225. package/template/coding-task-manager/lib/legacy-draft-cancellation-recovery.js +111 -0
  226. package/template/coding-task-manager/lib/lifecycle-wake-experiment.js +9 -2
  227. package/template/coding-task-manager/lib/live-defer-announce.js +45 -0
  228. package/template/coding-task-manager/lib/login-tripwire.js +1 -0
  229. package/template/coding-task-manager/lib/machine-pairing.js +238 -0
  230. package/template/coding-task-manager/lib/machine-pool.js +409 -0
  231. package/template/coding-task-manager/lib/machine-registry.js +1494 -0
  232. package/template/coding-task-manager/lib/machine-self.js +66 -0
  233. package/template/coding-task-manager/lib/macos-capabilities.js +32 -15
  234. package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +485 -57
  235. package/template/coding-task-manager/lib/mainloop-observability.js +14 -9
  236. package/template/coding-task-manager/lib/media-draft-owner.js +16 -3
  237. package/template/coding-task-manager/lib/media-journal-control-reader.js +473 -0
  238. package/template/coding-task-manager/lib/media-journal.js +84 -27
  239. package/template/coding-task-manager/lib/media-store-options.js +43 -15
  240. package/template/coding-task-manager/lib/memory-join.js +337 -0
  241. package/template/coding-task-manager/lib/memory-sync-verify.js +393 -0
  242. package/template/coding-task-manager/lib/memory-sync.js +565 -0
  243. package/template/coding-task-manager/lib/migrations/v56-host-samples-and-machine-pool.js +76 -0
  244. package/template/coding-task-manager/lib/migrations/v57-delegate-pref-mirror-opencode.js +68 -0
  245. package/template/coding-task-manager/lib/migrations/v58-subagent-launch-native-subagents.js +42 -0
  246. package/template/coding-task-manager/lib/migrations/v59-coding-session-model-state-dsh.js +73 -0
  247. package/template/coding-task-manager/lib/migrations/v60-delegate-pref-mirror-dsh.js +78 -0
  248. package/template/coding-task-manager/lib/migrations/v61-conversation-item-clock.js +71 -0
  249. package/template/coding-task-manager/lib/mirror-feed-sanitize.js +12 -3
  250. package/template/coding-task-manager/lib/model-availability.js +727 -0
  251. package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +4 -6
  252. package/template/coding-task-manager/lib/model-host-receipt.js +6 -3
  253. package/template/coding-task-manager/lib/model-id-rule.js +19 -0
  254. package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +8 -0
  255. package/template/coding-task-manager/lib/model-proxy/auto-mode-review.js +110 -23
  256. package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +6 -0
  257. package/template/coding-task-manager/lib/model-proxy/generation-probe.js +60 -17
  258. package/template/coding-task-manager/lib/model-proxy/handoff.js +494 -0
  259. package/template/coding-task-manager/lib/model-proxy/historical-tool-declarations.js +37 -0
  260. package/template/coding-task-manager/lib/model-proxy/lead-request-validation.js +1 -0
  261. package/template/coding-task-manager/lib/model-proxy/lead-token-admin.js +130 -0
  262. package/template/coding-task-manager/lib/model-proxy/lead-worker-picks.js +25 -0
  263. package/template/coding-task-manager/lib/model-proxy/native-lead-listener.js +61 -7
  264. package/template/coding-task-manager/lib/model-proxy/proxy-cli.js +200 -0
  265. package/template/coding-task-manager/lib/model-proxy/proxy-instance-record.js +257 -0
  266. package/template/coding-task-manager/lib/model-proxy/refusal-scope.js +151 -0
  267. package/template/coding-task-manager/lib/model-proxy/request-budget-store.js +11 -2
  268. package/template/coding-task-manager/lib/model-proxy/stream-accounting.js +205 -0
  269. package/template/coding-task-manager/lib/model-proxy/tokens.js +147 -5
  270. package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +18 -0
  271. package/template/coding-task-manager/lib/native-agent-model-args.js +25 -22
  272. package/template/coding-task-manager/lib/native-history-control.js +7 -5
  273. package/template/coding-task-manager/lib/native-lead-settings-client.js +46 -5
  274. package/template/coding-task-manager/lib/native-lead-tls.js +18 -4
  275. package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +776 -75
  276. package/template/coding-task-manager/lib/online-backup-worker-client.js +2 -0
  277. package/template/coding-task-manager/lib/opencode-cli.js +480 -0
  278. package/template/coding-task-manager/lib/opencode-launch-model.js +471 -0
  279. package/template/coding-task-manager/lib/opencode-v1-plugin/model-carrier.mjs +35 -0
  280. package/template/coding-task-manager/lib/opencode-v2-plugin/server.js +118 -0
  281. package/template/coding-task-manager/lib/owner-action-manifest-data.json +15 -1
  282. package/template/coding-task-manager/lib/painted-row-recorder.js +9 -1
  283. package/template/coding-task-manager/lib/park-composer-draft.js +54 -0
  284. package/template/coding-task-manager/lib/park-fresh-relaunch.js +41 -10
  285. package/template/coding-task-manager/lib/perf-phase-trace.js +72 -0
  286. package/template/coding-task-manager/lib/perf-summary.js +7 -0
  287. package/template/coding-task-manager/lib/perf-tracker.js +63 -2
  288. package/template/coding-task-manager/lib/project-config.js +7 -0
  289. package/template/coding-task-manager/lib/prompt-purge-v2.js +52 -1
  290. package/template/coding-task-manager/lib/prompt-submission-contract.js +21 -1
  291. package/template/coding-task-manager/lib/provider-login-broker.js +264 -24
  292. package/template/coding-task-manager/lib/provider-login-capture.js +153 -0
  293. package/template/coding-task-manager/lib/provider-login-tab.js +10 -2
  294. package/template/coding-task-manager/lib/queue-draft-status-overlay.js +36 -0
  295. package/template/coding-task-manager/lib/raw-codex-history-window.js +5 -3
  296. package/template/coding-task-manager/lib/read-pool-client.js +94 -4
  297. package/template/coding-task-manager/lib/read-pool-op-registry.js +10 -1
  298. package/template/coding-task-manager/lib/read-pool-worker-handle.js +29 -4
  299. package/template/coding-task-manager/lib/recent-catalog-query.js +41 -0
  300. package/template/coding-task-manager/lib/recent-session-catalog-response.js +76 -10
  301. package/template/coding-task-manager/lib/recovery-evidence.js +26 -11
  302. package/template/coding-task-manager/lib/relay-client.js +57 -3
  303. package/template/coding-task-manager/lib/relink-audit.js +34 -5
  304. package/template/coding-task-manager/lib/remote-command-context.js +12 -0
  305. package/template/coding-task-manager/lib/remote-command-runtime.js +13 -1
  306. package/template/coding-task-manager/lib/remote-machine-catalog.js +1357 -0
  307. package/template/coding-task-manager/lib/remote-machine-create.js +1233 -0
  308. package/template/coding-task-manager/lib/remote-machine-link.js +1426 -0
  309. package/template/coding-task-manager/lib/remote-machine-proxy.js +654 -0
  310. package/template/coding-task-manager/lib/remote-session-forward.js +364 -0
  311. package/template/coding-task-manager/lib/remote-submission-status.js +6 -0
  312. package/template/coding-task-manager/lib/remote-terminal-target.js +9 -2
  313. package/template/coding-task-manager/lib/restart-guard.js +18 -6
  314. package/template/coding-task-manager/lib/restart-outcome-truth.js +20 -3
  315. package/template/coding-task-manager/lib/restart-preflight.js +9 -2
  316. package/template/coding-task-manager/lib/restore-backoff-gate.js +10 -2
  317. package/template/coding-task-manager/lib/restore-prepare-retry.js +12 -5
  318. package/template/coding-task-manager/lib/restore-resume-batch.js +22 -1
  319. package/template/coding-task-manager/lib/restore-seed-modes.js +87 -0
  320. package/template/coding-task-manager/lib/restored-scrollback-hydration-runtime.js +22 -2
  321. package/template/coding-task-manager/lib/resume-admission.js +17 -3
  322. package/template/coding-task-manager/lib/resume-blocked-wire.js +62 -1
  323. package/template/coding-task-manager/lib/resume-cwd.js +13 -0
  324. package/template/coding-task-manager/lib/resume-from-store.js +12 -1
  325. package/template/coding-task-manager/lib/resume-origin-facts.js +38 -1
  326. package/template/coding-task-manager/lib/resume-preflight.js +21 -16
  327. package/template/coding-task-manager/lib/review-repo-admission.js +39 -6
  328. package/template/coding-task-manager/lib/review-repo-registry.js +74 -18
  329. package/template/coding-task-manager/lib/root-delivery-runtime.js +74 -17
  330. package/template/coding-task-manager/lib/root-delivery-selection.js +37 -1
  331. package/template/coding-task-manager/lib/root-prompt-admission.js +33 -2
  332. package/template/coding-task-manager/lib/root-prompt-flow.js +168 -34
  333. package/template/coding-task-manager/lib/runtime-contract.js +3 -1
  334. package/template/coding-task-manager/lib/schema-indexes.js +1 -0
  335. package/template/coding-task-manager/lib/scrollback-archive-store.js +7 -4
  336. package/template/coding-task-manager/lib/session-analysis-memory.js +2 -0
  337. package/template/coding-task-manager/lib/session-context-locator.js +742 -0
  338. package/template/coding-task-manager/lib/session-create/attachment.js +2 -2
  339. package/template/coding-task-manager/lib/session-create/codex-native-provider-gate.js +218 -0
  340. package/template/coding-task-manager/lib/session-create/codex-resume-exit-classify.js +52 -0
  341. package/template/coding-task-manager/lib/session-create/create-phases.js +118 -0
  342. package/template/coding-task-manager/lib/session-create/delegate-worker.js +179 -20
  343. package/template/coding-task-manager/lib/session-create/dsh-session.js +930 -0
  344. package/template/coding-task-manager/lib/session-create/identity.js +20 -1
  345. package/template/coding-task-manager/lib/session-create/lead-route-launch.js +186 -13
  346. package/template/coding-task-manager/lib/session-create/native-lead-lifetime.js +55 -3
  347. package/template/coding-task-manager/lib/session-create/opencode-lead-provider.js +50 -0
  348. package/template/coding-task-manager/lib/session-create/prepared.js +201 -9
  349. package/template/coding-task-manager/lib/session-create/provider-launch-context.js +77 -0
  350. package/template/coding-task-manager/lib/session-create/provider-process.js +193 -64
  351. package/template/coding-task-manager/lib/session-create/response.js +37 -19
  352. package/template/coding-task-manager/lib/session-create/structured-session.js +27 -0
  353. package/template/coding-task-manager/lib/session-create/subagent-pick-table.js +3 -1
  354. package/template/coding-task-manager/lib/session-create/subagent-pick.js +458 -9
  355. package/template/coding-task-manager/lib/session-create/transcript.js +14 -5
  356. package/template/coding-task-manager/lib/session-create/worker-budget-setup.js +21 -2
  357. package/template/coding-task-manager/lib/session-create/worker-continuation.js +50 -2
  358. package/template/coding-task-manager/lib/session-create/worker-launch-sandbox.js +39 -10
  359. package/template/coding-task-manager/lib/session-create/worker-notices.js +94 -5
  360. package/template/coding-task-manager/lib/session-create/worker-observability.js +101 -9
  361. package/template/coding-task-manager/lib/session-create/worker-stop.js +11 -3
  362. package/template/coding-task-manager/lib/session-create/worker-wait-watcher.js +315 -0
  363. package/template/coding-task-manager/lib/session-empty.js +13 -10
  364. package/template/coding-task-manager/lib/session-geometry-authority-handler.js +10 -1
  365. package/template/coding-task-manager/lib/session-host-manager.js +212 -206
  366. package/template/coding-task-manager/lib/session-jobs.js +20 -10
  367. package/template/coding-task-manager/lib/session-lifecycle.js +28 -4
  368. package/template/coding-task-manager/lib/session-model-action-preconditions.js +15 -2
  369. package/template/coding-task-manager/lib/session-model-intent-contract.js +11 -8
  370. package/template/coding-task-manager/lib/session-park.js +738 -0
  371. package/template/coding-task-manager/lib/session-path-grant.js +13 -4
  372. package/template/coding-task-manager/lib/session-resource-sampler.js +19 -9
  373. package/template/coding-task-manager/lib/session-standup.js +67 -4
  374. package/template/coding-task-manager/lib/session-status-ledger.js +147 -6
  375. package/template/coding-task-manager/lib/session-status-runtime.js +45 -1
  376. package/template/coding-task-manager/lib/session-title-mirror.js +25 -57
  377. package/template/coding-task-manager/lib/session-transcript-trash.js +8 -1
  378. package/template/coding-task-manager/lib/session-transport.js +17 -0
  379. package/template/coding-task-manager/lib/session-workspace-projection.js +54 -5
  380. package/template/coding-task-manager/lib/session-workspace-tracking-runtime.js +213 -1
  381. package/template/coding-task-manager/lib/skill-autocomplete-query.js +120 -3
  382. package/template/coding-task-manager/lib/skill-autocomplete.js +15 -1
  383. package/template/coding-task-manager/lib/sqlite-file-set.js +39 -0
  384. package/template/coding-task-manager/lib/standup-search-adapter.js +16 -2
  385. package/template/coding-task-manager/lib/startup-pointer-write.js +57 -0
  386. package/template/coding-task-manager/lib/state-sync/client-ledger.js +12 -0
  387. package/template/coding-task-manager/lib/state-sync/frame-emitter.js +319 -100
  388. package/template/coding-task-manager/lib/state-sync/painted-frame-field.js +11 -0
  389. package/template/coding-task-manager/lib/storage/coding-session-model-store.js +25 -23
  390. package/template/coding-task-manager/lib/storage/delegate-pref-mirror-store.js +32 -9
  391. package/template/coding-task-manager/lib/structured-session-boot-sweep.js +235 -0
  392. package/template/coding-task-manager/lib/submission-ack.js +90 -2
  393. package/template/coding-task-manager/lib/surviving-owner-bootstrap.js +7 -2
  394. package/template/coding-task-manager/lib/surviving-owner-recovery.js +2 -1
  395. package/template/coding-task-manager/lib/systemd-scope.js +115 -0
  396. package/template/coding-task-manager/lib/telemetry-receiver.js +39 -0
  397. package/template/coding-task-manager/lib/terminal-attach-geometry.js +985 -0
  398. package/template/coding-task-manager/lib/terminal-bootstrap.js +30 -0
  399. package/template/coding-task-manager/lib/terminal-draft-http-status.js +25 -0
  400. package/template/coding-task-manager/lib/terminal-draft-operation.js +357 -0
  401. package/template/coding-task-manager/lib/terminal-input-admission.js +17 -1
  402. package/template/coding-task-manager/lib/terminal-input-prepared.js +563 -0
  403. package/template/coding-task-manager/lib/transcript-archiver.js +229 -229
  404. package/template/coding-task-manager/lib/transcript-cache-temps.js +171 -0
  405. package/template/coding-task-manager/lib/transcript-frame-cache.js +20 -5
  406. package/template/coding-task-manager/lib/transcript-guard-job.js +55 -4
  407. package/template/coding-task-manager/lib/transcript-link.js +77 -0
  408. package/template/coding-task-manager/lib/transcript-manifest-store.js +8 -4
  409. package/template/coding-task-manager/lib/transcript-source.js +44 -7
  410. package/template/coding-task-manager/lib/transcript-store.js +49 -0
  411. package/template/coding-task-manager/lib/tunnel-lane-governor.js +6 -3
  412. package/template/coding-task-manager/lib/typing-interaction-trace.js +198 -3
  413. package/template/coding-task-manager/lib/typing-worker-stages.js +60 -0
  414. package/template/coding-task-manager/lib/usage-ledger/backfill.js +40 -5
  415. package/template/coding-task-manager/lib/usage-ledger/client.js +4 -1
  416. package/template/coding-task-manager/lib/usage-ledger/dsh-parse.js +152 -0
  417. package/template/coding-task-manager/lib/usage-ledger/dsh-read.js +73 -0
  418. package/template/coding-task-manager/lib/usage-ledger/ingest.js +34 -6
  419. package/template/coding-task-manager/lib/usage-ledger/live.js +35 -8
  420. package/template/coding-task-manager/lib/usage-ledger/read.js +29 -20
  421. package/template/coding-task-manager/lib/usage-ledger/schema.js +61 -1
  422. package/template/coding-task-manager/lib/usage-ledger/task-coordinator.js +4 -2
  423. package/template/coding-task-manager/lib/visible-revision-watchdog.js +8 -12
  424. package/template/coding-task-manager/lib/wake-skip-reasons.js +47 -0
  425. package/template/coding-task-manager/lib/walle/turn.js +1 -1
  426. package/template/coding-task-manager/lib/walle-history-serve.js +838 -0
  427. package/template/coding-task-manager/lib/walle-kill-authority.js +2 -2
  428. package/template/coding-task-manager/lib/walle-log-rotation.js +164 -1
  429. package/template/coding-task-manager/lib/walle-mcp-auto-config.js +56 -2
  430. package/template/coding-task-manager/lib/walle-row-history.js +495 -0
  431. package/template/coding-task-manager/lib/walle-supervisor.js +130 -27
  432. package/template/coding-task-manager/lib/watch-worker-client.js +203 -0
  433. package/template/coding-task-manager/lib/worker-failure-classify.js +13 -1
  434. package/template/coding-task-manager/lib/worker-terminal-output.js +5 -2
  435. package/template/coding-task-manager/lib/ws/hub-bridge.js +35 -0
  436. package/template/coding-task-manager/lib/ws/lifecycle.js +6 -11
  437. package/template/coding-task-manager/lib/ws/misc.js +1 -1
  438. package/template/coding-task-manager/lib/ws/state-sync.js +125 -6
  439. package/template/coding-task-manager/lib/ws/terminal-attach.js +123 -1
  440. package/template/coding-task-manager/lib/ws-router.js +68 -1
  441. package/template/coding-task-manager/lib/ws-send-admission.js +22 -4
  442. package/template/coding-task-manager/oauth-proxy.js +211 -170
  443. package/template/coding-task-manager/package-lock.json +34 -94
  444. package/template/coding-task-manager/package.json +7 -3
  445. package/template/coding-task-manager/protocol/message-table.json +10 -0
  446. package/template/coding-task-manager/protocol/messages.js +10 -0
  447. package/template/coding-task-manager/protocol/ws-schema.json +20 -0
  448. package/template/coding-task-manager/protocol/ws-schema.md +2 -0
  449. package/template/coding-task-manager/providers/codex-mcp-extract.js +121 -19
  450. package/template/coding-task-manager/providers/codex-mcp.js +14 -5
  451. package/template/coding-task-manager/public/css/app.css +449 -1
  452. package/template/coding-task-manager/public/css/reviews.css +4 -0
  453. package/template/coding-task-manager/public/css/walle-session.css +4 -0
  454. package/template/coding-task-manager/public/index.html +766 -465
  455. package/template/coding-task-manager/public/js/agent-command.js +86 -0
  456. package/template/coding-task-manager/public/js/app/backups-panel.js +111 -5
  457. package/template/coding-task-manager/public/js/app/coding-agent-upgrade.js +103 -4
  458. package/template/coding-task-manager/public/js/app/machines-page.js +2572 -0
  459. package/template/coding-task-manager/public/js/app/models-tab.js +658 -73
  460. package/template/coding-task-manager/public/js/app/restart-banner.js +53 -0
  461. package/template/coding-task-manager/public/js/app/worktrees-panel.js +191 -7
  462. package/template/coding-task-manager/public/js/background-work.js +203 -28
  463. package/template/coding-task-manager/public/js/coding-session-model-presentation.js +181 -13
  464. package/template/coding-task-manager/public/js/core/active-session-groups.js +179 -0
  465. package/template/coding-task-manager/public/js/core/pending-create.js +238 -0
  466. package/template/coding-task-manager/public/js/core/recent-machine-source.js +228 -0
  467. package/template/coding-task-manager/public/js/core/session-commands.js +847 -5
  468. package/template/coding-task-manager/public/js/core/session-selectors.js +5 -1
  469. package/template/coding-task-manager/public/js/dashboard-client-function-order.json +8 -0
  470. package/template/coding-task-manager/public/js/document-review-links.js +9 -1
  471. package/template/coding-task-manager/public/js/file-resolution-client.js +52 -1
  472. package/template/coding-task-manager/public/js/history-app-seam.js +48 -4
  473. package/template/coding-task-manager/public/js/history-painted-rows.js +17 -2
  474. package/template/coding-task-manager/public/js/history-reader-park.js +13 -1
  475. package/template/coding-task-manager/public/js/history-scroller.js +187 -9
  476. package/template/coding-task-manager/public/js/history-transcript-pages.js +5 -5
  477. package/template/coding-task-manager/public/js/machine-pool-shared.js +991 -0
  478. package/template/coding-task-manager/public/js/message-renderer.js +4 -3
  479. package/template/coding-task-manager/public/js/model-picker.js +3 -1
  480. package/template/coding-task-manager/public/js/native-subagent-review.js +15 -2
  481. package/template/coding-task-manager/public/js/new-session-agent-grid.js +346 -0
  482. package/template/coding-task-manager/public/js/pasted-content.js +236 -0
  483. package/template/coding-task-manager/public/js/pe-private-content-lifetime.js +39 -7
  484. package/template/coding-task-manager/public/js/private-model-lifetime.js +6 -2
  485. package/template/coding-task-manager/public/js/private-state-scope.js +31 -3
  486. package/template/coding-task-manager/public/js/prompt-submission-client.js +173 -8
  487. package/template/coding-task-manager/public/js/prompt-submission-tray.js +281 -0
  488. package/template/coding-task-manager/public/js/prompts.js +11 -10
  489. package/template/coding-task-manager/public/js/protocol.js +10 -0
  490. package/template/coding-task-manager/public/js/queue-panel-submission-reconcile.js +174 -1
  491. package/template/coding-task-manager/public/js/restart-banner-policy.js +29 -1
  492. package/template/coding-task-manager/public/js/reviews.js +7 -3
  493. package/template/coding-task-manager/public/js/root-draft-lifetime.js +139 -2
  494. package/template/coding-task-manager/public/js/root-queue-builder-lifetime.js +16 -0
  495. package/template/coding-task-manager/public/js/row-join.js +4 -2
  496. package/template/coding-task-manager/public/js/session-model-picker.js +447 -57
  497. package/template/coding-task-manager/public/js/session-search-utils.js +64 -21
  498. package/template/coding-task-manager/public/js/session-usage-view.js +2 -1
  499. package/template/coding-task-manager/public/js/session-workspace-tracking.js +51 -1
  500. package/template/coding-task-manager/public/js/state-sync-client.js +14 -1
  501. package/template/coding-task-manager/public/js/stream-view.js +6 -5
  502. package/template/coding-task-manager/public/js/terminal/conv-only-session.js +287 -0
  503. package/template/coding-task-manager/public/js/terminal/runtime-02.js +16 -7
  504. package/template/coding-task-manager/public/js/terminal/runtime-03.js +41 -0
  505. package/template/coding-task-manager/public/js/terminal/runtime-04.js +41 -4
  506. package/template/coding-task-manager/public/js/terminal/runtime-09.js +2 -0
  507. package/template/coding-task-manager/public/js/terminal/runtime-10.js +5 -5
  508. package/template/coding-task-manager/public/js/terminal/runtime-12.js +60 -3
  509. package/template/coding-task-manager/public/js/terminal/runtime-16.js +16 -12
  510. package/template/coding-task-manager/public/js/terminal/runtime-18.js +14 -0
  511. package/template/coding-task-manager/public/js/terminal/runtime-19.js +8 -4
  512. package/template/coding-task-manager/public/js/terminal/runtime-20.js +211 -74
  513. package/template/coding-task-manager/public/js/terminal/runtime-21.js +19 -6
  514. package/template/coding-task-manager/public/js/terminal/runtime-22.js +86 -0
  515. package/template/coding-task-manager/public/js/terminal-attachment-draft.js +67 -13
  516. package/template/coding-task-manager/public/js/terminal-history-viewport.js +1 -1
  517. package/template/coding-task-manager/public/js/terminal-image-orchestration.js +52 -6
  518. package/template/coding-task-manager/public/js/terminal-wheel.js +62 -5
  519. package/template/coding-task-manager/public/js/walle/chat-conversation.js +15 -7
  520. package/template/coding-task-manager/public/js/walle-session.js +30 -7
  521. package/template/coding-task-manager/public/js/walle.js +6 -0
  522. package/template/coding-task-manager/public/js/ws/live-dispatch.js +10 -0
  523. package/template/coding-task-manager/public/m/app.css +366 -8
  524. package/template/coding-task-manager/public/m/app.js +1006 -74
  525. package/template/coding-task-manager/public/m/index.html +55 -1
  526. package/template/coding-task-manager/public/m/machines.js +2147 -0
  527. package/template/coding-task-manager/public/m/pool-failover.js +391 -0
  528. package/template/coding-task-manager/public/m/private-api.js +31 -1
  529. package/template/coding-task-manager/public/m/private-queue-actions.js +26 -7
  530. package/template/coding-task-manager/public/m/sw.js +5 -0
  531. package/template/coding-task-manager/public/usage.html +1 -0
  532. package/template/coding-task-manager/queue-engine.js +13 -0
  533. package/template/coding-task-manager/scripts/dev-route-fixture/synthetic-route-upstream.js +104 -0
  534. package/template/coding-task-manager/scripts/dev-route-fixture.js +339 -0
  535. package/template/coding-task-manager/scripts/opencode-lead-route-probe.js +195 -0
  536. package/template/coding-task-manager/scripts/opencode-v2-contract-probe/fake-anthropic.js +168 -0
  537. package/template/coding-task-manager/scripts/opencode-v2-contract-probe/probe-plugin/server.js +95 -0
  538. package/template/coding-task-manager/scripts/opencode-v2-contract-probe.js +673 -0
  539. package/template/coding-task-manager/server/approvals.js +5 -6
  540. package/template/coding-task-manager/server/boot.js +136 -17
  541. package/template/coding-task-manager/server.js +2819 -11885
  542. package/template/coding-task-manager/session-integrity.js +71 -13
  543. package/template/coding-task-manager/workers/db-owner-worker.js +72 -9
  544. package/template/coding-task-manager/workers/online-backup-worker.js +1 -0
  545. package/template/coding-task-manager/workers/read-pool-model-collector.js +51 -3
  546. package/template/coding-task-manager/workers/read-pool-worker.js +93 -12
  547. package/template/coding-task-manager/workers/session-host-pool-process.js +24 -10
  548. package/template/coding-task-manager/workers/session-host-process.js +19 -8
  549. package/template/coding-task-manager/workers/transcript-archive-worker.js +1 -1
  550. package/template/coding-task-manager/workers/watch-worker.js +105 -0
  551. package/template/coding-task-manager/workers/worktree-worker.js +202 -33
  552. package/template/ctm-relay/lib/protocol.js +14 -1
  553. package/template/package-lock.json +2 -2
  554. package/template/package.json +1 -1
  555. package/template/scripts/conversation-storage-v2-migration.js +78 -11
  556. package/template/shared/backup-retention.js +82 -0
  557. package/template/shared/conversation-admission.js +2 -0
  558. package/template/shared/conversation-provenance.js +3 -7
  559. package/template/shared/conversation-storage-v2-contract.js +47 -6
  560. package/template/shared/fixtures/worker-status-payloads.json +392 -0
  561. package/template/shared/git-remote-key.js +83 -0
  562. package/template/shared/host-identity.js +98 -2
  563. package/template/shared/linked-worktree.js +51 -0
  564. package/template/shared/macos-fda-target.js +57 -0
  565. package/template/shared/orphan-parents.js +55 -0
  566. package/template/shared/owner-write-safety.js +135 -0
  567. package/template/shared/public-runtime.js +13 -5
  568. package/template/shared/release-schema.json +3 -2
  569. package/template/shared/report-citations.js +14 -0
  570. package/template/shared/sqlite-write-lock.js +361 -223
  571. package/template/shared/storage/contract.js +38 -3
  572. package/template/wall-e/adapters/imessage.js +12 -0
  573. package/template/wall-e/agent.js +92 -4
  574. package/template/wall-e/api-walle.js +26 -1
  575. package/template/wall-e/bin/brain-purge-legacy-ctm.js +3 -2
  576. package/template/wall-e/bin/train-gemma-e4b-tooluse.js +2 -2
  577. package/template/wall-e/bin/walle-mcp-stdio.js +14 -8
  578. package/template/wall-e/brain/brain-join.js +859 -0
  579. package/template/wall-e/brain/brain-sync-membership.js +20 -0
  580. package/template/wall-e/brain/brain-sync-store.js +131 -77
  581. package/template/wall-e/brain/brain-sync-v2-schema.js +203 -0
  582. package/template/wall-e/brain/brain-sync-v2.js +578 -0
  583. package/template/wall-e/brain/delegate-model-prefs-store.js +13 -4
  584. package/template/wall-e/brain/deterministic-id.js +51 -0
  585. package/template/wall-e/brain/helper-rules-schema.js +129 -0
  586. package/template/wall-e/brain/memories.js +2 -2
  587. package/template/wall-e/brain/migrations.js +91 -28
  588. package/template/wall-e/brain/model-deployment-facts.js +31 -1
  589. package/template/wall-e/brain/model-identity-migration.js +1 -1
  590. package/template/wall-e/brain/owner-call-whitelist.js +39 -7
  591. package/template/wall-e/brain/schema-ensures.js +22 -0
  592. package/template/wall-e/brain/schema.js +45 -85
  593. package/template/wall-e/brain.js +172 -36
  594. package/template/wall-e/chat.js +3 -3
  595. package/template/wall-e/coding/agent-shell-env.js +7 -2
  596. package/template/wall-e/coding/journal-dispatcher.js +51 -0
  597. package/template/wall-e/coding/prompt-bundle.js +66 -21
  598. package/template/wall-e/coding/session-journal.js +28 -40
  599. package/template/wall-e/coding-orchestrator.js +23 -26
  600. package/template/wall-e/config/main-loop-exemptions.json +2 -2
  601. package/template/wall-e/http/admin-api.js +37 -0
  602. package/template/wall-e/http/auth.js +18 -1
  603. package/template/wall-e/http/blog-views-api.js +318 -0
  604. package/template/wall-e/http/gws-api.js +4 -0
  605. package/template/wall-e/http/helper-rules-api.js +327 -0
  606. package/template/wall-e/http/model-admin.js +8 -1
  607. package/template/wall-e/http/model-delegate-pref-admin.js +3 -3
  608. package/template/wall-e/http/model-proxy-providers.js +177 -2
  609. package/template/wall-e/http/model-route-health.js +157 -0
  610. package/template/wall-e/http/sync-api.js +278 -464
  611. package/template/wall-e/http/telemetry-api.js +12 -0
  612. package/template/wall-e/jobs/job-runner.js +28 -1
  613. package/template/wall-e/lib/blog-view-policy.js +88 -0
  614. package/template/wall-e/lib/blog-view-store.js +169 -0
  615. package/template/wall-e/lib/brain-owner-op-priority.js +9 -1
  616. package/template/wall-e/lib/client-config-lock.js +2 -1
  617. package/template/wall-e/lib/coding-journal-writer-child-client.js +67 -18
  618. package/template/wall-e/lib/ctm-data-dir.js +26 -0
  619. package/template/wall-e/lib/derivation-home.js +147 -0
  620. package/template/wall-e/lib/error-kinds.js +10 -1
  621. package/template/wall-e/lib/feature-manifest.js +1 -1
  622. package/template/wall-e/lib/helper-rules/cell-state.js +123 -0
  623. package/template/wall-e/lib/helper-rules/evaluate.js +398 -0
  624. package/template/wall-e/lib/helper-rules/explore-rubric.md +12 -0
  625. package/template/wall-e/lib/helper-rules/grade.js +320 -0
  626. package/template/wall-e/lib/helper-rules/label.js +247 -0
  627. package/template/wall-e/lib/helper-rules/lead-call-hook.js +555 -0
  628. package/template/wall-e/lib/helper-rules/store.js +669 -0
  629. package/template/wall-e/lib/landing-mcp-tools.js +170 -0
  630. package/template/wall-e/lib/mcp-client-config.js +133 -14
  631. package/template/wall-e/lib/mcp-gateway-migrate.js +28 -64
  632. package/template/wall-e/lib/mcp-integration.js +63 -19
  633. package/template/wall-e/lib/parent-death.js +7 -1
  634. package/template/wall-e/lib/runtime-worker-pool.js +1 -0
  635. package/template/wall-e/lib/scheduler-worker-jobs.js +12 -4
  636. package/template/wall-e/lib/telemetry-db-schema.js +37 -0
  637. package/template/wall-e/lib/telemetry-process-client.js +76 -1
  638. package/template/wall-e/llm/default-fallback.js +4 -0
  639. package/template/wall-e/llm/delegate-lead-prefs.js +16 -1
  640. package/template/wall-e/llm/delegate-vendor-default.js +12 -5
  641. package/template/wall-e/llm/model-catalog.js +13 -4
  642. package/template/wall-e/llm/model-roles.js +7 -1
  643. package/template/wall-e/llm/native-delegate-selection.js +56 -8
  644. package/template/wall-e/llm/portkey-http.js +150 -0
  645. package/template/wall-e/llm/portkey-sync.js +15 -145
  646. package/template/wall-e/llm/worker-delegate-args.js +72 -7
  647. package/template/wall-e/llm/worker-mcp-routing.js +117 -7
  648. package/template/wall-e/llm/worker-route.js +43 -1
  649. package/template/wall-e/loops/brain-custom-writes.js +64 -0
  650. package/template/wall-e/loops/ingest.js +17 -1
  651. package/template/wall-e/loops/think.js +19 -4
  652. package/template/wall-e/mcp-contract.js +222 -6
  653. package/template/wall-e/mcp-protocol-contract.js +77 -2
  654. package/template/wall-e/mcp-server.js +141 -31
  655. package/template/wall-e/mcp-worker-schemas.js +25 -7
  656. package/template/wall-e/memory/ctm-context-client.js +110 -5
  657. package/template/wall-e/memory/ctm-session-context.js +9 -3
  658. package/template/wall-e/memory/hub-bridge-client.js +388 -0
  659. package/template/wall-e/memory/replica-origin.js +56 -0
  660. package/template/wall-e/memory/session-pool.js +135 -0
  661. package/template/wall-e/runtime/live-capabilities.js +8 -3
  662. package/template/wall-e/server.js +4 -2
  663. package/template/wall-e/shared/release-schema.json +3 -2
  664. package/template/wall-e/shared/sqlite-file-set.js +39 -0
  665. package/template/wall-e/shared/sqlite-write-lock.js +361 -223
  666. package/template/wall-e/shared/storage/contract.js +38 -3
  667. package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
  668. package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +13 -1
  669. package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +11 -6
  670. package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +13 -8
  671. package/template/wall-e/skills/_templates/fleet-sync/VERSION +1 -0
  672. package/template/wall-e/skills/_templates/fleet-sync/released-sha256.json +16 -0
  673. package/template/wall-e/skills/_templates/fleet-sync/templates/claude/SKILL.md +64 -0
  674. package/template/wall-e/skills/_templates/fleet-sync/templates/codex/SKILL.md +64 -0
  675. package/template/wall-e/tools/chrome-automation.js +6 -0
  676. package/template/wall-e/tools/local-tools.js +6 -4
  677. package/template/wall-e/training/setup-cuda-train-env.sh +2 -2
  678. package/template/wall-e/workers/brain-owner-worker.js +27 -4
  679. package/template/wall-e/workers/coding-journal-writer-child.js +8 -1
  680. package/template/wall-e/workers/mcp-gateway-process.js +5 -5
  681. package/template/wall-e/workers/telemetry-worker.js +8 -0
@@ -0,0 +1,364 @@
1
+ 'use strict';
2
+
3
+ // WP-2 (docs/remote-session-image-upload-forwarding-2026-10-24.html §5 D-1..D-10, §6, §8
4
+ // AC-2a..AC-2f, §9 S-1/S-10) — the hub-side BYTE-FAITHFUL session request forwarder.
5
+ //
6
+ // The hub forwards only `POST /api/sessions/:id/(park|revive|pin|wake)` today
7
+ // (lib/remote-machine-catalog.js's forwardLifecycleRequest). The image-draft family reaches the
8
+ // hub's own handler, and for a MIRROR session that handler can never succeed: the hub does not hold
9
+ // the session in its map, so lib/terminal-draft-owner.js throws a 503
10
+ // CTM_OWNERSHIP_UNAVAILABLE that the browser uploader retries forever (public/js/ctm-uploader.js
11
+ // treats 503 as retryable). This module is the seam that lets that family be answered by the BOX
12
+ // that owns the session — the bytes must land on the PTY host, because the CLI opens the delivered
13
+ // draft path on its own filesystem (§1 "Where the bytes must live").
14
+ //
15
+ // It is deliberately NOT a general reverse proxy. Two dispatch lines use it today: WP-3's image-draft
16
+ // line in api-prompts.js, and WP-2's three terminal-history reads in lib/api/sessions.js (through
17
+ // `serveMirrorOrLocal` below):
18
+ //
19
+ // D-1 ownership is decided ONCE, by `catalog.getMirrorSessionMachine` — local sessions Map
20
+ // first (the 2026-10-23 relay-hijack fix), then the forwarded creates, the live catalog and
21
+ // the sync mirror. A local id, or an id no registered machine claims, MISSES and the caller
22
+ // runs its local handler with the request stream untouched (byte-identical local path).
23
+ // D-2 a mirror id never reaches the hub's draft owner: this module either proxies it or refuses
24
+ // with the same 503 `machine_unreachable` body forwardLifecycleRequest uses.
25
+ // D-3 the forwarded set is a CLOSED list (FORWARDED_SESSION_ROUTES); every member has a
26
+ // matching `peerControl` row on the box (WP-1). A prefix-forward would 403 on every route
27
+ // nobody flagged (lib/auth-rules.js pins the peer allowlist EXACTLY).
28
+ // D-4 outbound headers are the peer credential plus an allowlist. The inbound `cookie` and
29
+ // `authorization` are NEVER forwarded, and the hub's `token` query parameter is stripped:
30
+ // the box's getAuthToken (server.js:11524) prefers `?token=` over the Bearer, so forwarding
31
+ // it verbatim would both leak a hub credential and 401 the request.
32
+ // D-5 bytes stream both ways with NO hub-side cap: `Readable.toWeb(req)` + `duplex:'half'` out,
33
+ // `pipeline(Readable.fromWeb(response.body), res)` back. The box's own 25 MiB limit
34
+ // (api-prompts.js) is the only limit — an intermediate cap reproduces JupyterHub #2831.
35
+ // D-6 honest status: registered but unreachable, no row, no credential, a connect error, or the
36
+ // headers deadline → 503 `machine_unreachable` naming the machine, with `Retry-After: 2`.
37
+ // Any status the box answered (409/413/503 included) goes through VERBATIM.
38
+ // D-7 the headers deadline is 30 s (= public/js/ctm-uploader.js's attemptTimeoutMs), so the hub
39
+ // never outlives the browser's attempt; a client that goes away aborts the upstream fetch.
40
+ // D-8 the hub never retries: a streamed body is single-use and the client uploader already owns
41
+ // retry with an idempotent `request_id`.
42
+ //
43
+ // Dependency note: this module must NOT require lib/hosted-sync-worker.js (dependency-cycle lint —
44
+ // see lib/remote-machine-proxy.js:30-33). The two requires below are leaves on the way in:
45
+ // lib/remote-machine-catalog.js is a dependency SINK and lib/remote-machine-create.js loads its own
46
+ // heavy peers lazily inside `_productionDeps()`.
47
+
48
+ const { Readable } = require('node:stream');
49
+ const { pipeline } = require('node:stream/promises');
50
+
51
+ const catalogDefault = require('./remote-machine-catalog');
52
+ const { buildPeerControlHeaders: buildPeerControlHeadersDefault } = require('./remote-machine-create');
53
+
54
+ // D-7: equal to public/js/ctm-uploader.js's attemptTimeoutMs — hub and browser agree on how long a
55
+ // single upload attempt may live.
56
+ const FORWARD_DEADLINE_MS = 30_000;
57
+
58
+ // D-4: the hub's own device token and the picker's routing param belong to the FIRST hop. Everything
59
+ // else in the query is the box's business (`provider`, `ordinal`, `request_id`, `filename`, `mode`,
60
+ // `v`, the content route's cache buster).
61
+ const STRIPPED_QUERY_PARAMS = Object.freeze(['token', 'machine']);
62
+
63
+ // D-4: request headers copied from the browser — never `cookie`, never the inbound `authorization`.
64
+ const FORWARDED_REQUEST_HEADERS = Object.freeze(['content-type', 'content-length', 'if-match', 'x-ctm-upload-request-id']);
65
+
66
+ // D-5: response headers copied from the box. `retry-after` is here because the box's own 503 must
67
+ // keep its own retry hint; everything else (set-cookie, server, date) stays at the hop that owns it.
68
+ const FORWARDED_RESPONSE_HEADERS = Object.freeze(['content-type', 'content-length', 'etag', 'cache-control', 'retry-after', 'x-content-type-options']);
69
+
70
+ // D-3: the closed forwarded set — EIGHTEEN members. Each entry is [METHOD, RegExp on pathname]. The
71
+ // first ten mirror the image-draft peer-control routes on the box (lib/auth-rules.js:164-179)
72
+ // exactly; WP-1 of docs/composer-image-chip-stuck-submission-recovery-2026-10-30.html §5 R-1 adds the
73
+ // eleventh, `POST /api/sessions/<id>/image-refs` (image-ref recording, session-scoped so it can be
74
+ // forwarded); the next three are WP-2's box-owned terminal-history reads — the SINGULAR
75
+ // `/api/session/<id>/(history-window|scrollback|painted-rows)` GETs
76
+ // (docs/remote-session-history-reads-and-box-status-hooks-2026-10-26.html WP-2 / D-3), whose matching
77
+ // `peerControl` row is lib/auth-rules.js's single anchor regex; the fourteenth is WP-13's canonical
78
+ // conversation read for a BOX-OWNED session — the SINGULAR `/api/session/messages` GET, whose session
79
+ // id rides the `?id=` query (see the member's own comment below); the last three are WP-1's box-owned
80
+ // child-transcript routes — the native/worker review GETs and the native clear cutoff
81
+ // (docs/remote-session-child-transcript-model-truth-and-restart-2026-10-27.html §5 D-2/D-3), whose
82
+ // `peerControl` rows are lib/auth-rules.js:181/187/485. The
83
+ // pairing meta-test is tests/peer-control-auth.test.js → `forwarded-route pairing: every
84
+ // FORWARDED_SESSION_ROUTES member resolves to a peerControl HTTP rule with the same method`: it
85
+ // iterates this set and fails when a member here has no flagged row on the box. A member added here
86
+ // without that flag turns the hub's honest 503 into the box's 403 insufficient_scope (the
87
+ // incident-2/incident-3 class).
88
+ const FORWARDED_SESSION_ROUTES = Object.freeze([
89
+ ['GET', /^\/api\/sessions\/[^/]+\/image-drafts$/],
90
+ ['GET', /^\/api\/sessions\/[^/]+\/image-drafts\/[^/]+\/content$/],
91
+ ['POST', /^\/api\/sessions\/[^/]+\/image-drafts$/],
92
+ ['PUT', /^\/api\/sessions\/[^/]+\/image-drafts\/[^/]+$/],
93
+ ['DELETE', /^\/api\/sessions\/[^/]+\/image-drafts$/],
94
+ ['DELETE', /^\/api\/sessions\/[^/]+\/image-drafts\/[^/]+$/],
95
+ ['POST', /^\/api\/sessions\/[^/]+\/image-drafts\/[^/]+\/delivery$/],
96
+ ['POST', /^\/api\/sessions\/[^/]+\/image-drafts\/[^/]+\/freeze$/],
97
+ ['POST', /^\/api\/sessions\/[^/]+\/image-drafts\/[^/]+\/submit$/],
98
+ ['POST', /^\/api\/sessions\/[^/]+\/image-drafts\/[^/]+\/retry$/],
99
+ // WP-1 (§5 R-1, §6, §8 WP-1): image-ref RECORDING is session-scoped so it can be forwarded too —
100
+ // the draft it resolves lives on the box that owns a MIRROR session, and the hub's local resolver
101
+ // cannot see it (it answered CTM_SESSION_IMAGE_REF_UNRESOLVED until this row existed). The singular
102
+ // `/api/session/image-refs` path is REMOVED, not aliased, and lib/auth-rules.js carries the paired
103
+ // peerControl row.
104
+ ['POST', /^\/api\/sessions\/[^/]+\/image-refs$/],
105
+ // WP-2/D-3: the box's terminal-history reads — SINGULAR `/api/session/`, not `/api/sessions/`.
106
+ ['GET', /^\/api\/session\/[^/]+\/history-window$/],
107
+ ['GET', /^\/api\/session\/[^/]+\/scrollback$/],
108
+ ['GET', /^\/api\/session\/[^/]+\/painted-rows$/],
109
+ // WP-13 (docs/deepseek-harness-acp-agent-2026-10-28.html §5 D-25, §8 WP-13, §9 R-1, §10 T-23): the
110
+ // CANONICAL conversation read — the one the Conv view polls. It was local-only, so a box-owned
111
+ // session's Conv showed nothing on the hub for EVERY agent (Claude and Codex included, not just
112
+ // dsh): the hub holds no session row for a mirror id, so its own reader answered empty. There is
113
+ // ONE generic forward — no dsh-only route and no hub mirror file. The session id is the `?id=`
114
+ // QUERY parameter here (server.js's apiSessionMessages reads `url.searchParams.get('id')`), so the
115
+ // dispatch line in lib/api/sessions.js passes that value as serveMirrorOrLocal's encodedSessionId.
116
+ // The pathname is fixed, which is all this predicate needs (D-3 is purely lexical).
117
+ ['GET', /^\/api\/session\/messages$/],
118
+ // WP-1 (docs/remote-session-child-transcript-model-truth-and-restart-2026-10-27.html §5 D-2):
119
+ // child-transcript reads and the clear cutoff are box-owned — the transcript and the native
120
+ // runtime live on the box; the hub has no row for a mirror id.
121
+ ['GET', /^\/api\/sessions\/[^/]+\/native-subagents\/[^/]+\/messages$/],
122
+ ['GET', /^\/api\/sessions\/[^/]+\/worker-transcript\/messages$/],
123
+ ['POST', /^\/api\/sessions\/[^/]+\/native-subagents\/clear$/],
124
+ ]);
125
+
126
+ function _string(value, max = 200) {
127
+ return String(value == null ? '' : value).trim().slice(0, max);
128
+ }
129
+
130
+ /** D-3 as a predicate: is (method, pathname) one of the forwarded routes? Purely lexical. */
131
+ function isForwardedSessionRoute(method, pathname) {
132
+ const verb = _string(method, 12).toUpperCase();
133
+ const target = String(pathname == null ? '' : pathname);
134
+ if (!verb || !target) return false;
135
+ return FORWARDED_SESSION_ROUTES.some(([routeMethod, pattern]) => routeMethod === verb && pattern.test(target));
136
+ }
137
+
138
+ /**
139
+ * D-1 as a SYNCHRONOUS predicate for the dispatch line: is this a forwarded route for a MIRROR id?
140
+ * The caller uses it to keep the local path byte-identical — a local id calls its handler in the same
141
+ * tick, so the handler's body listeners attach before any `aborted`/`data` event can be missed.
142
+ */
143
+ function isMirrorSessionRequest(req, url, sessionId, deps = {}) {
144
+ if (!isForwardedSessionRoute(req && req.method, url && url.pathname)) return false;
145
+ const catalog = (deps && deps.catalog) || catalogDefault;
146
+ if (typeof catalog.getMirrorSessionMachine !== 'function') return false;
147
+ const mirror = catalog.getMirrorSessionMachine(sessionId, deps || {});
148
+ return !!(mirror && mirror.machineInstanceId);
149
+ }
150
+
151
+ /** An allowlist copy of `headers` (values verbatim; a repeated header is comma-joined). */
152
+ function _pickHeaders(headers, names) {
153
+ const out = {};
154
+ if (!headers) return out;
155
+ for (const name of names) {
156
+ const value = headers[name];
157
+ if (value === undefined || value === null) continue;
158
+ out[name] = Array.isArray(value) ? value.join(', ') : String(value);
159
+ }
160
+ return out;
161
+ }
162
+
163
+ /** The same allowlist over a fetch `Headers` object (or a plain object, for an injected fetch). */
164
+ function _pickResponseHeaders(headers) {
165
+ const out = {};
166
+ if (!headers) return out;
167
+ for (const name of FORWARDED_RESPONSE_HEADERS) {
168
+ const value = typeof headers.get === 'function' ? headers.get(name) : headers[name];
169
+ if (value === undefined || value === null || value === '') continue;
170
+ out[name] = String(value);
171
+ }
172
+ return out;
173
+ }
174
+
175
+ /**
176
+ * D-6: the one refusal shape — the same body forwardLifecycleRequest writes, so the client renders
177
+ * one message for both forwarders, plus `Retry-After: 2` (the reader may retry; the box is down, not
178
+ * the request) and an optional machine-readable `detail`.
179
+ *
180
+ * @returns {true} always — the request was answered here (never falls through to a local handler).
181
+ */
182
+ function _refuse(res, mirror, machineName, detail) {
183
+ const label = _string(machineName, 200) || _string(mirror && mirror.machineInstanceId, 160) || 'machine';
184
+ const payload = {
185
+ ok: false,
186
+ code: 'machine_unreachable',
187
+ error: `Machine ${label} is unreachable`,
188
+ machine: _string(mirror && mirror.machineInstanceId, 160),
189
+ machineName: _string(machineName, 200),
190
+ ...(detail ? { detail } : {}),
191
+ };
192
+ const body = JSON.stringify(payload);
193
+ // A client that already hung up (the abort path) has a destroyed res: writing to it would only
194
+ // raise a second, uninteresting error on the way out.
195
+ if (!res.headersSent && !res.writableEnded && !res.destroyed) {
196
+ res.writeHead(503, {
197
+ 'Content-Type': 'application/json',
198
+ 'Content-Length': Buffer.byteLength(body),
199
+ 'Retry-After': '2',
200
+ });
201
+ res.end(body);
202
+ }
203
+ return true;
204
+ }
205
+
206
+ /**
207
+ * D-1/D-2 entry point. Returns `false` (the caller runs its local handler with the request stream
208
+ * untouched) unless `sessionId` is a MIRROR id AND `(req.method, url.pathname)` is in
209
+ * FORWARDED_SESSION_ROUTES. Otherwise it fully answers `res` and resolves `true`.
210
+ *
211
+ * Never throws, and never reads `req` before it has decided (a non-forwarded route leaves
212
+ * `req.readableFlowing === null`).
213
+ *
214
+ * @param {import('http').IncomingMessage} req
215
+ * @param {import('http').ServerResponse} res
216
+ * @param {URL} url
217
+ * @param {string} sessionId already decoded
218
+ * @param {{catalog?, buildPeerControlHeaders?, fetchImpl?, env?, deadlineMs?, setTimeoutFn?,
219
+ * clearTimeoutFn?}} [deps]
220
+ * @returns {Promise<boolean>}
221
+ */
222
+ async function maybeForwardSessionRequest(req, res, url, sessionId, deps = {}) {
223
+ const d = deps || {};
224
+ // 1. A route this module does not own is never even looked up — the request stream stays virgin.
225
+ if (!isForwardedSessionRoute(req && req.method, url && url.pathname)) return false;
226
+
227
+ // 2. D-1: the ONE ownership decision (local Map first). A local or unclaimed id falls through.
228
+ const catalog = d.catalog || catalogDefault;
229
+ const mirror = typeof catalog.getMirrorSessionMachine === 'function'
230
+ ? catalog.getMirrorSessionMachine(sessionId, d)
231
+ : null;
232
+ if (!mirror || !mirror.machineInstanceId) return false;
233
+
234
+ // 3. D-6: a registered machine with no usable row, or one known to be down, is refused here —
235
+ // never acted on locally.
236
+ const machine = typeof catalog.machineRowForMirror === 'function' ? catalog.machineRowForMirror(mirror, d) : null;
237
+ const machineName = _string(machine ? machine.displayName : mirror.machineName, 200);
238
+ if (!machine) return _refuse(res, mirror, machineName, 'machine_row_unavailable');
239
+ if (_string(machine.health, 40) === 'unreachable') return _refuse(res, mirror, machineName, 'machine_unreachable');
240
+
241
+ // 4. D-4: the peer credential is the ONLY authorization on the wire. No credential configured
242
+ // means this hub cannot be a peer of that box — refuse rather than send an unauthenticated
243
+ // request that would come back as an opaque 401.
244
+ const buildHeaders = typeof d.buildPeerControlHeaders === 'function'
245
+ ? d.buildPeerControlHeaders
246
+ : buildPeerControlHeadersDefault;
247
+ const peerHeaders = buildHeaders(d.env || process.env);
248
+ if (!peerHeaders) return _refuse(res, mirror, machineName, 'peer_credential_missing');
249
+
250
+ const fetchImpl = typeof d.fetchImpl === 'function'
251
+ ? d.fetchImpl
252
+ : (typeof d.fetch === 'function' ? d.fetch : globalThis.fetch);
253
+ if (typeof fetchImpl !== 'function') return _refuse(res, mirror, machineName, 'fetch_unavailable');
254
+
255
+ // 5. D-4: the same path and query, minus what belongs to the first hop.
256
+ let target;
257
+ try {
258
+ target = new URL(`${(url && url.pathname) || ''}${(url && url.search) || ''}`, _string(machine.url, 1000));
259
+ for (const key of STRIPPED_QUERY_PARAMS) target.searchParams.delete(key);
260
+ } catch {
261
+ return _refuse(res, mirror, machineName, 'machine_url_invalid'); // expected: a malformed registry url is a refusal, not a throw
262
+ }
263
+
264
+ // 6/7. D-7: the abort path. Two independent signals, because Node emits the REQUEST's `close` on
265
+ // natural completion too (a fully received POST body closes long before the box answers) — so the
266
+ // request's own close only counts while the message is INCOMPLETE, and the response's close only
267
+ // counts while nothing has been written yet. Between them, exactly one shape aborts: the client
268
+ // went away with the answer still owed to it.
269
+ const controller = new AbortController();
270
+ let headersArrived = false;
271
+ const abortIfClientGone = () => {
272
+ if (!headersArrived && !res.writableEnded) controller.abort();
273
+ };
274
+ res.once('close', abortIfClientGone);
275
+ req.once('close', () => { if (!req.complete) abortIfClientGone(); });
276
+
277
+ const timeoutFn = typeof d.setTimeoutFn === 'function' ? d.setTimeoutFn : setTimeout;
278
+ const clearFn = typeof d.clearTimeoutFn === 'function' ? d.clearTimeoutFn : clearTimeout;
279
+ const deadlineMs = Number(d.deadlineMs) > 0 ? Number(d.deadlineMs) : FORWARD_DEADLINE_MS;
280
+ let timedOut = false;
281
+ const timer = timeoutFn(() => {
282
+ timedOut = true;
283
+ controller.abort();
284
+ }, deadlineMs);
285
+ if (timer && typeof timer.unref === 'function') timer.unref();
286
+
287
+ const method = _string(req.method, 12).toUpperCase();
288
+ const hasBody = method !== 'GET' && method !== 'HEAD';
289
+ let response;
290
+ try {
291
+ response = await fetchImpl(target, {
292
+ method,
293
+ headers: { ...peerHeaders, ..._pickHeaders(req.headers, FORWARDED_REQUEST_HEADERS) },
294
+ redirect: 'manual',
295
+ signal: controller.signal,
296
+ // D-5: the body streams through — no buffering, no hub-side cap, single use (D-8: never retry).
297
+ ...(hasBody ? { body: Readable.toWeb(req), duplex: 'half' } : {}),
298
+ });
299
+ } catch (error) {
300
+ clearFn(timer);
301
+ // D-6: the response never started, so the honest answer is the machine_unreachable refusal. When
302
+ // the client itself is gone this write is skipped (the socket is dead) — `_refuse` owns that.
303
+ const detail = timedOut ? 'timeout' : (_string((error && (error.code || error.name)) || error, 80) || 'fetch_failed');
304
+ return _refuse(res, mirror, machineName, detail);
305
+ }
306
+ clearFn(timer);
307
+ headersArrived = true;
308
+
309
+ if (!response) return _refuse(res, mirror, machineName, 'empty_response');
310
+
311
+ // 8. Status and the response allowlist go through verbatim (D-5/D-6) — the box's own 4xx/5xx
312
+ // included: the client parses the box's answer exactly as it parses a local one.
313
+ const status = Number(response.status) || 502;
314
+ try {
315
+ res.writeHead(status, _pickResponseHeaders(response.headers));
316
+ } catch {
317
+ // A header value the runtime refuses to write (a box bug, not a hub one) must still leave the
318
+ // hook's "never throws" contract intact for its caller: refuse honestly instead of rejecting.
319
+ return _refuse(res, mirror, machineName, 'invalid_response_headers'); // expected: an unwritable header from the box
320
+ }
321
+
322
+ // 9. Stream the body back.
323
+ if (!response.body) {
324
+ res.end();
325
+ return true;
326
+ }
327
+ try {
328
+ await pipeline(Readable.fromWeb(response.body), res, { signal: controller.signal });
329
+ } catch (error) {
330
+ // The headers are already on the wire, so there is no honest status left to send: destroy the
331
+ // response (the client sees a truncated body and a network error) and let its uploader retry
332
+ // with the same idempotent request_id (D-8).
333
+ try { res.destroy(error); } catch { /* expected: a response that is already destroyed */ }
334
+ }
335
+ return true;
336
+ }
337
+
338
+ /**
339
+ * D-1/D-4: serve `localHandler` for a local or unclaimed id (same tick, request untouched), or forward a mirror id.
340
+ * @param {import('http').IncomingMessage} req
341
+ * @param {import('http').ServerResponse} res
342
+ * @param {URL} url
343
+ * @param {string} encodedSessionId the raw path segment (route param '1')
344
+ * @param {(req, res, url, encodedSessionId) => any} localHandler
345
+ * @param {object} [deps] passed through to isMirrorSessionRequest / maybeForwardSessionRequest
346
+ */
347
+ function serveMirrorOrLocal(req, res, url, encodedSessionId, localHandler, deps = {}) {
348
+ let sessionId = '';
349
+ try { sessionId = decodeURIComponent(String(encodedSessionId || '')); }
350
+ catch { return localHandler(req, res, url, encodedSessionId); } // expected: a malformed id is the local handler's 4xx to give
351
+ if (!isMirrorSessionRequest(req, url, sessionId, deps)) return localHandler(req, res, url, encodedSessionId);
352
+ return maybeForwardSessionRequest(req, res, url, sessionId, deps)
353
+ .then((forwarded) => (forwarded ? undefined : localHandler(req, res, url, encodedSessionId)));
354
+ }
355
+
356
+ module.exports = {
357
+ FORWARDED_SESSION_ROUTES,
358
+ FORWARD_DEADLINE_MS,
359
+ STRIPPED_QUERY_PARAMS,
360
+ maybeForwardSessionRequest,
361
+ isForwardedSessionRoute,
362
+ isMirrorSessionRequest,
363
+ serveMirrorOrLocal,
364
+ };
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ const { normalizeRecoveryAction } = require('./prompt-submission-contract');
4
+
3
5
  function createRemoteSubmissionStatusWriter(deps = {}) {
4
6
  const required = ['getDb', 'getDbPath', 'getInstanceId', 'getSession', 'updateRemoteSubmission',
5
7
  'publicSubmission', 'remoteSubmissionIdentity', 'broadcastSubmissionStatus',
@@ -67,6 +69,10 @@ function createRemoteSubmissionStatusWriter(deps = {}) {
67
69
  reason: details.reason || '',
68
70
  message: details.message || '',
69
71
  retryable: details.retryable === true,
72
+ // WP-0: persisted next to `retryable` so a reloaded row (or any later
73
+ // frame built from `row.result`) carries the same recovery verdict the
74
+ // direct reply carried. Same normalization as publicSubmissionStatus.
75
+ recoveryAction: normalizeRecoveryAction(details.recoveryAction, details.retryable === true),
70
76
  source: details.source || '',
71
77
  evidence_source: details.evidenceSource || details.evidence_source || '',
72
78
  observed_at: Date.now(),
@@ -2,10 +2,17 @@
2
2
 
3
3
  const attemptOwners = new WeakMap();
4
4
 
5
+ // The delivery target's process identity: a PTY session's ptyProcess, or an ACP (DeepSeek Harness)
6
+ // session's `_acpProcess` token — set once per child by lib/session-create/dsh-session.js and cleared when
7
+ // the child exits — so a replaced or dead ACP child retires the target exactly like a replaced PTY.
8
+ function targetProcessOf(session) {
9
+ return session?.ptyProcess || session?._acpProcess || null;
10
+ }
11
+
5
12
  function captureRemoteTerminalTarget(sessionId, session, sessionSource, getProcessGeneration) {
6
13
  const getSession = typeof sessionSource === 'function' ? sessionSource : id => sessionSource?.get(id);
7
14
  const originalSession = session && typeof session === 'object' ? session : null;
8
- const originalPtyProcess = originalSession?.ptyProcess || null;
15
+ const originalPtyProcess = targetProcessOf(originalSession);
9
16
  const originalGeneration = originalSession && typeof getProcessGeneration === 'function'
10
17
  ? getProcessGeneration(originalSession)
11
18
  : null;
@@ -19,7 +26,7 @@ function captureRemoteTerminalTarget(sessionId, session, sessionSource, getProce
19
26
  }
20
27
  const current = getSession(sessionId);
21
28
  const matches = current === originalSession
22
- && current.ptyProcess === originalPtyProcess
29
+ && targetProcessOf(current) === originalPtyProcess
23
30
  && typeof getProcessGeneration === 'function'
24
31
  && getProcessGeneration(current) === originalGeneration;
25
32
  if (!matches) targetRetired = true;
@@ -81,13 +81,17 @@ function summarizeRestartGuard(sessions = [], options = {}) {
81
81
  ? normalizeWaitingReason(options.waitingReasonForSession(session))
82
82
  : defaultWaitingReasonForSession(session);
83
83
  const summary = restartSessionSummary(session, rawStatus, waitingForInput, waitingReason);
84
- // WP-4 (pty-survival design doc, S-16): a restart no longer kills a HOSTED
85
- // session's live process (WP-1/2 linger + WP-3 boot adoption) -- a
86
- // running/busy hosted session survives the restart itself, so it must stop
87
- // counting as "would be interrupted". Approval/choice waits still block:
88
- // those are a human decision left hanging mid-turn, not process survival.
84
+ // WP-4 (pty-survival design doc, S-16) + WP-2 (session-host-cgroup-survival design doc, D-5): a HOSTED
85
+ // session's live process survives a restart ONLY IF its host actually survives CTM's exit -- true under
86
+ // launchd (proven), and under systemd only when the host was moved out of ctm.service's cgroup
87
+ // (KillMode=control-group reaps everything else). `options.hostSurvivesRestart(session)` answers that at
88
+ // snapshot time; when absent it defaults to true (callers/tests that never knew about cgroups). A running or
89
+ // busy session whose host would NOT survive blocks like a non-hosted one. Approval/choice waits still
90
+ // block: those are a human decision left hanging mid-turn, not process survival.
89
91
  const isHosted = typeof options.isHostedSession === 'function' ? !!options.isHostedSession(session) : false;
90
- const runningBlocked = BLOCKING_STATUSES.has(summary.status) && !isHosted;
92
+ const survives = isHosted && (typeof options.hostSurvivesRestart === 'function' ? !!options.hostSurvivesRestart(session) : true);
93
+ summary.hostSurvives = isHosted ? survives : null;
94
+ const runningBlocked = BLOCKING_STATUSES.has(summary.status) && !survives;
91
95
  const waitingBlocked = summary.status === 'waiting_input' &&
92
96
  isBlockingWaitingSession(session, summary, waitingForInput, waitingReason, options);
93
97
  if (runningBlocked || waitingBlocked) blockers.push(summary);
@@ -107,6 +111,14 @@ function summarizeRestartGuard(sessions = [], options = {}) {
107
111
  blockers.push(summary);
108
112
  }
109
113
 
114
+ // WP-3 (docs/session-create-box-restart-and-git-lane-starvation-2026-10-30.html §6.3/§8):
115
+ // an in-flight CREATE has no session row yet, so the loop above cannot see it — but a restart
116
+ // would still abort it. Each entry is appended VERBATIM (the caller owns the shape:
117
+ // `{ id, kind: 'create_in_progress', ... }`), and counts as a blocker. Absent/empty => unchanged.
118
+ for (const entry of options.pendingCreates || []) {
119
+ if (entry) blockers.push(entry);
120
+ }
121
+
110
122
  return {
111
123
  preflight,
112
124
  totalCount: items.length,
@@ -63,16 +63,33 @@ function recordLingerEntered({ sessions, isHosted, hostIdForSession, recordSessi
63
63
  }
64
64
  }
65
65
 
66
+ // §5 D-10 / §9 S-12: the model proxy's own restart outcome, as `adoption.proxy`. The default is the
67
+ // real supervisor, required LAZILY (this module loads during boot, before any proxy exists), and a
68
+ // failure is reported and answered as null — a diagnostics row must never break the boot it describes.
69
+ function _proxyOutcomeFor(proxyOutcome, errorSink) {
70
+ try {
71
+ const outcome = (proxyOutcome || (() => require('./oauth-proxy-supervisor').lastRestartOutcome()))();
72
+ return outcome && typeof outcome === 'object' ? outcome : null;
73
+ } catch (e) {
74
+ if (errorSink && typeof errorSink.report === 'function') errorSink.report('restore:proxy-outcome', e);
75
+ return null;
76
+ }
77
+ }
78
+
66
79
  // Ledgering must never break boot: any failure is reported, not thrown.
67
- function appendRestoreCompleteLedger({ build, summary, errorSink, ledger = require('./restart-ledger') }) {
80
+ function appendRestoreCompleteLedger({ build, summary, errorSink, proxyOutcome, ledger = require('./restart-ledger') }) {
81
+ // `proxy` is nested FIRST on purpose: lib/restart-ledger.js:52-63 keeps an object's first 10 keys, and
82
+ // the adoption summary already carries more than that, so a trailing key would be silently dropped from
83
+ // the very row the design is judged on.
84
+ const adoption = () => ({ proxy: _proxyOutcomeFor(proxyOutcome, errorSink), ...summary() });
68
85
  try {
69
86
  const bootRestartId = ledger.getBootRestartId();
70
87
  if (bootRestartId) {
71
- ledger.appendRestartReceiptStage(bootRestartId, 'restore_complete', { newPid: process.pid, build, adoption: summary() });
88
+ ledger.appendRestartReceiptStage(bootRestartId, 'restore_complete', { newPid: process.pid, build, adoption: adoption() });
72
89
  } else {
73
90
  ledger.appendRestartLedgerEntry({
74
91
  method: 'launchd-respawn', requester: { source: 'launchd' }, reason: 'restore complete (no restart id)',
75
- force: false, guardVerdict: { blocked: false, blockers: [] }, build, stage: 'restore_complete', adoption: summary(),
92
+ force: false, guardVerdict: { blocked: false, blockers: [] }, build, stage: 'restore_complete', adoption: adoption(),
76
93
  });
77
94
  }
78
95
  } catch (e) { errorSink.report('restore:ledger', e); }
@@ -11,7 +11,14 @@ function aliveFn(isProcessAlive) {
11
11
 
12
12
  // `hostCodeDiffers(hostId, record)`: true when the live host's LOADED code differs from the files on
13
13
  // disk now -- the next boot will adopt it as upgrade-pending and hand it off, so predict a handoff.
14
- function computeRestartPreflight({ sessions, sessionHostManager, hostRecords, isProcessAlive, isRunning, isHosted, isExited, hostCodeDiffers } = {}) {
14
+ //
15
+ // `proxy` (§5 D-10, WP-3): what the next boot will do with the model proxy, already computed by
16
+ // `lib/oauth-proxy-supervisor.js:proxyPreflight()`. It is passed THROUGH, never recomputed here: this
17
+ // module reads session/host state, and the proxy is a different process with a different truth. A caller
18
+ // with no proxy answer gets the honest default -- 'none', with the three measurements null rather than
19
+ // guessed -- so the surface has one shape and the three session arrays below stay byte-for-byte what they
20
+ // have always been.
21
+ function computeRestartPreflight({ sessions, sessionHostManager, hostRecords, isProcessAlive, isRunning, isHosted, isExited, hostCodeDiffers, proxy = null } = {}) {
15
22
  const alive = aliveFn(isProcessAlive);
16
23
  const differsFn = typeof hostCodeDiffers === 'function' ? hostCodeDiffers : () => false;
17
24
  const differsByHost = new Map(); // one disk hash per host per preflight, not per session
@@ -52,7 +59,7 @@ function computeRestartPreflight({ sessions, sessionHostManager, hostRecords, is
52
59
  if (compat?.reason === 'upgrade-pending' || codeDiffers(String(hostId), record)) willHandoff.push(sessionId);
53
60
  else willAdopt.push(sessionId);
54
61
  }
55
- return { willAdopt, willHandoff, willRevive };
62
+ return { willAdopt, willHandoff, willRevive, proxy: proxy ?? { action: 'none', pid: null, openStreams: null, closureDiffers: null } };
56
63
  }
57
64
 
58
65
  module.exports = { computeRestartPreflight };
@@ -14,6 +14,10 @@
14
14
  // activation): allowed past the auto ceiling, but a cooldown is waited out (bounded by
15
15
  // maxCooldownMs) unless this is an unclaimed prewarm;
16
16
  // - after a wait the session must still be the live, deferred, non-closing one.
17
+ //
18
+ // WP-3 (§9 S-10/S-11): the two silent bails below are pure skips of THIS attempt -- they change no
19
+ // return value, they only report through the injected `onSkip(reason, id, session)` dep (default
20
+ // no-op, so this module stays server-free and its unit tests need no lifecycle singleton).
17
21
 
18
22
  function createAwaitRestoreBackoffOutsideGate({
19
23
  enabled,
@@ -23,11 +27,12 @@ function createAwaitRestoreBackoffOutsideGate({
23
27
  maxCooldownMs,
24
28
  now = Date.now,
25
29
  setTimer = setTimeout,
30
+ onSkip = () => {},
26
31
  }) {
27
32
  return async function awaitRestoreBackoffOutsideGate(session, opts = {}) {
28
33
  if (!enabled) return true;
29
34
  const task = session?._restoreTask || {};
30
- if (!task.session_id) return false;
35
+ if (!task.session_id) { onSkip('BackoffTaskMissingSessionId', task.session_id, session); return false; }
31
36
  const source = String(opts.source || '');
32
37
  const background = /auto-resume/.test(source);
33
38
  const decision = restoreBackoff.shouldAttempt(task.session_id, now(), { userInitiated: !background });
@@ -47,7 +52,10 @@ function createAwaitRestoreBackoffOutsideGate({
47
52
  timer?.unref?.();
48
53
  });
49
54
  const latest = getSession(task.session_id);
50
- if (latest !== session || !session._restoreDeferred || session._closing || session._exited) return false;
55
+ if (latest !== session || !session._restoreDeferred || session._closing || session._exited) {
56
+ onSkip('BackoffSessionReplaced', task.session_id, session);
57
+ return false;
58
+ }
51
59
  }
52
60
  return true;
53
61
  };
@@ -22,9 +22,13 @@ function prepareRetryJitterMs(sessionId) {
22
22
  // The coalescing "start a deferred restore on the next tick" scheduler, extracted verbatim from
23
23
  // server.js (`_scheduleDeferredRestoreStart`) so server.js stays under its file-size ratchet;
24
24
  // the retry timer below is one more caller of it (with source:'prepare-retry').
25
- function createScheduleDeferredRestoreStart({ getSession, startDeferredRestoreSession, log = console.error }) {
25
+ //
26
+ // WP-3 (§9 S-16): the bails report through the injected `onSkip(reason, id, session)` dep (default
27
+ // no-op) and change no return value -- `RetryAlreadyStarting` in particular still returns TRUE: an
28
+ // attempt is already in flight, which is a success-shaped bail, not a skip of the session.
29
+ function createScheduleDeferredRestoreStart({ getSession, startDeferredRestoreSession, log = console.error, onSkip = () => {} }) {
26
30
  return function scheduleDeferredRestoreStart(session, opts = {}) {
27
- if (!session?._restoreDeferred) return false;
31
+ if (!session?._restoreDeferred) { onSkip('RetryNotDeferred', session?.id, session); return false; }
28
32
  if (!session._deferredInputGeneration) {
29
33
  session._deferredInputGeneration = Math.max(1, Number(session._terminalLifecycleCounter || 0) + 1);
30
34
  }
@@ -32,7 +36,7 @@ function createScheduleDeferredRestoreStart({ getSession, startDeferredRestoreSe
32
36
  ...(session._restoreStartOpts || {}),
33
37
  ...(opts || {}),
34
38
  };
35
- if (session._restoreStarting || session._restoreStartTimer) return true;
39
+ if (session._restoreStarting || session._restoreStartTimer) { onSkip('RetryAlreadyStarting', session.id, session); return true; }
36
40
  session._restoreStartTimer = setTimeout(() => {
37
41
  session._restoreStartTimer = null;
38
42
  const latest = getSession(session.id);
@@ -53,19 +57,22 @@ function scheduleDeferredRestoreRetry(session, params, deps) {
53
57
  const {
54
58
  getSession, recordSessionDiagnostic, scheduleStart,
55
59
  setTimer = setTimeout, clearTimer = clearTimeout, jitterMs = prepareRetryJitterMs,
60
+ onSkip = () => {},
56
61
  } = deps;
57
- if (!session?._restoreDeferred || session._closing || session._exited) return false;
62
+ if (!session?._restoreDeferred || session._closing || session._exited) { onSkip('RetryNotDeferred', session?.id, session); return false; }
58
63
  const source = String(opts.source || '');
59
64
  const openClients = (session.clients || []).filter((client) => client?.readyState === 1).length;
60
65
  // No open client and a background origin: nothing is waiting to see the retry, and a
61
66
  // background drain will pick this session up again on its own cadence -- don't arm a timer
62
67
  // that will just fire into an empty room. An 'attach'-sourced failure (or any other
63
68
  // user-initiated source) still schedules: the client may reconnect before the timer fires.
64
- if (openClients === 0 && /auto-resume|prewarm/.test(source)) return false;
69
+ if (openClients === 0 && /auto-resume|prewarm/.test(source)) { onSkip('RetryNoClients', session.id, session); return false; }
65
70
  const delayMs = Math.max(1500, Number(retryAfterMs) || 0) + jitterMs(session.id);
66
71
  if (session._prepareRetryTimer) clearTimer(session._prepareRetryTimer);
67
72
  session._prepareRetryTimer = setTimer(() => {
68
73
  session._prepareRetryTimer = null;
74
+ // WP-3 (§9 S-16): the fire-time guard records NOTHING -- it is an idempotent re-arm guard
75
+ // (something else already started / this session is gone), not a skip predicate.
69
76
  const latest = getSession(session.id);
70
77
  if (!latest?._restoreDeferred || latest._restoreStarting || latest._closing || latest._exited) return;
71
78
  scheduleStart(latest, { ...opts, source: 'prepare-retry' });