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,399 @@
1
+ 'use strict';
2
+
3
+ // WP-2 (design doc coding-task-manager/docs/fsevents-churn-followups-r2-2026-10-26.html
4
+ // §5 D-4..D-6, §6, §8 WP-2, §9 S-11): the host fseventsd sampler.
5
+ //
6
+ // Why it exists: fseventsd reached 2262 MB RSS on 2026-10-26 (§1.1) and nothing in this repo
7
+ // recorded it. The parent AC-8d ("< 100 MB on 10-28") was unmeasurable and is superseded by
8
+ // D-5: prove the sampler is alive (>= 1 row/hour of primary uptime), parse every JetsamEvent,
9
+ // and attach a producer attribution to every growth event so "our trees are not the producer"
10
+ // is a number instead of a feeling.
11
+ //
12
+ // Rules it obeys (§5 D-6, §11 anti-goals):
13
+ // * read-only instrumentation: it never starts, signals or heals fseventsd, never calls
14
+ // sudo/vmmap/sample/footprint, and never deletes anything;
15
+ // * every child process is ASYNC (execFile with a timeout, never execFileSync);
16
+ // * a metric is `top -l 1 -pid <pid> -stats pid,mem,cmprs` (no sudo; ~2.5 s wall) — chosen
17
+ // over vmmap (it suspends the target) and ps RSS (it excludes compressed pages);
18
+ // * every failure becomes an `error` row in the log; tick() never throws into the server.
19
+ //
20
+ // It runs inside the primary CTM process (launchd com.walle.server, survives reboot) — see
21
+ // server.js's registration block, gated by shouldRunSampler().
22
+
23
+ const fs = require('node:fs');
24
+ const path = require('node:path');
25
+ const os = require('node:os');
26
+ const { execFile: defaultExecFile } = require('node:child_process');
27
+
28
+ const SAMPLE_INTERVAL_MS = 30 * 60_000;
29
+ const GROWTH_ATTRIBUTION_BYTES = 256 * 1024 * 1024;
30
+ const ATTRIBUTION_MIN_GAP_MS = 6 * 60 * 60_000;
31
+ // D-6: one `top` per sample, async, bounded.
32
+ const TOP_TIMEOUT_MS = 10000;
33
+ // §6: the attribution child runs `fs-event-census.js --seconds 30`, bounded at 60 s.
34
+ const ATTRIBUTION_TIMEOUT_MS = 60000;
35
+ const ATTRIBUTION_SECONDS = 30;
36
+ const ATTRIBUTION_MAX_BUFFER = 8 * 1024 * 1024;
37
+ const JETSAM_DIR = '/Library/Logs/DiagnosticReports';
38
+ // §6: `memoryStatus.pageSize` (16384 on Apple silicon); 16384 is the documented fallback.
39
+ const FALLBACK_PAGE_SIZE = 16384;
40
+ const DEFAULT_LOG_PATH = path.join(os.homedir(), '.walle', 'logs', 'host-fseventsd.jsonl');
41
+ const STATE_FILE_NAME = 'host-fseventsd.state.json';
42
+
43
+ // ---------------------------------------------------------------------------
44
+ // Gating (D-4). server.js inlines this condition (the doc's §6 snippet); the predicate is
45
+ // exported so the gating itself is unit-testable without booting a server.
46
+ // ---------------------------------------------------------------------------
47
+ function shouldRunSampler({ platform = process.platform, devPort = '', flag = '1' } = {}) {
48
+ return platform === 'darwin' && !devPort && String(flag) !== '0';
49
+ }
50
+
51
+ // ---------------------------------------------------------------------------
52
+ // parseTopLine (pure): the last line of
53
+ // top -l 1 -pid <pid> -stats pid,mem,cmprs
54
+ // looks like `29548 2262M 637M`. Units may be B/K/M/G and may carry a +/- delta marker
55
+ // (either side; the magnitude is what the row is about). Returns
56
+ // { pid, memBytes, cmprsBytes } or null (e.g. for the `PID MEM CMPrS` header).
57
+ // ---------------------------------------------------------------------------
58
+ const TOP_ROW_RE = /^(\d+)\s+([+-]?[\d.]+)\s*([BKMG])?([+-])?\s+([+-]?[\d.]+)\s*([BKMG])?([+-])?$/;
59
+ const UNIT_MULTIPLIERS = { B: 1, K: 1024, M: 1024 ** 2, G: 1024 ** 3 };
60
+
61
+ function unitToBytes(value, unit) {
62
+ const n = Math.abs(Number(value));
63
+ if (!Number.isFinite(n)) return null;
64
+ const multiplier = UNIT_MULTIPLIERS[String(unit || '').toUpperCase()] || 1;
65
+ return Math.round(n * multiplier);
66
+ }
67
+
68
+ function parseTopLine(line) {
69
+ const s = String(line === null || line === undefined ? '' : line).trim();
70
+ if (s === '') return null;
71
+ const m = s.match(TOP_ROW_RE);
72
+ if (!m) return null;
73
+ const memBytes = unitToBytes(m[2], m[3]);
74
+ const cmprsBytes = unitToBytes(m[5], m[6]);
75
+ if (memBytes === null || cmprsBytes === null) return null;
76
+ return { pid: Number(m[1]), memBytes, cmprsBytes };
77
+ }
78
+
79
+ function lastNonEmptyLine(text) {
80
+ const lines = String(text === null || text === undefined ? '' : text).split('\n');
81
+ for (let i = lines.length - 1; i >= 0; i -= 1) {
82
+ if (lines[i].trim() !== '') return lines[i];
83
+ }
84
+ return '';
85
+ }
86
+
87
+ // ---------------------------------------------------------------------------
88
+ // sampleOnce: pgrep the pid, then one bounded async `top`.
89
+ // Returns { at, pid, memBytes, cmprsBytes, raw } or { at, error } — never throws.
90
+ // ---------------------------------------------------------------------------
91
+ function runChild(execFile, file, args, options) {
92
+ return new Promise((resolve, reject) => {
93
+ let settled = false;
94
+ const settle = (fn, value) => {
95
+ if (settled) return;
96
+ settled = true;
97
+ fn(value);
98
+ };
99
+ const callback = (err, stdout, stderr) => {
100
+ if (err) settle(reject, err);
101
+ else settle(resolve, { stdout: String(stdout === null || stdout === undefined ? '' : stdout), stderr: String(stderr === null || stderr === undefined ? '' : stderr) });
102
+ };
103
+ let returned;
104
+ try {
105
+ returned = execFile(file, args, options, callback);
106
+ } catch (err) {
107
+ settle(reject, err);
108
+ return;
109
+ }
110
+ // HANDLE: an injected promise-style stand-in (a test fake) resolves instead of calling
111
+ // back; accept either shape so the fake needs no callback plumbing.
112
+ if (returned && typeof returned.then === 'function') {
113
+ returned.then(
114
+ (value) => settle(resolve, {
115
+ stdout: String(value && value.stdout !== undefined ? value.stdout : (value === undefined ? '' : value)),
116
+ stderr: String(value && value.stderr !== undefined ? value.stderr : ''),
117
+ }),
118
+ (err) => settle(reject, err),
119
+ );
120
+ }
121
+ });
122
+ }
123
+
124
+ async function sampleOnce({ execFile = defaultExecFile, now = Date.now } = {}) {
125
+ const at = now();
126
+ try {
127
+ const pidOut = await runChild(execFile, 'pgrep', ['-x', 'fseventsd'], { timeout: TOP_TIMEOUT_MS });
128
+ const pid = Number(String(pidOut.stdout).trim().split('\n')[0]);
129
+ if (!Number.isFinite(pid) || pid <= 0) return { at, error: 'pgrep -x fseventsd returned no pid' };
130
+ const topOut = await runChild(
131
+ execFile,
132
+ 'top',
133
+ ['-l', '1', '-pid', String(pid), '-stats', 'pid,mem,cmprs'],
134
+ { timeout: TOP_TIMEOUT_MS },
135
+ );
136
+ const raw = lastNonEmptyLine(topOut.stdout);
137
+ const parsed = parseTopLine(raw);
138
+ if (!parsed) return { at, error: `unparsable top row ${JSON.stringify(raw)}` };
139
+ return { at, pid, memBytes: parsed.memBytes, cmprsBytes: parsed.cmprsBytes, raw };
140
+ } catch (err) {
141
+ return { at, error: String((err && err.message) || err) };
142
+ }
143
+ }
144
+
145
+ // ---------------------------------------------------------------------------
146
+ // readNewJetsam: every JetsamEvent-*.ips newer than `lastSeen`, oldest first.
147
+ // Format (§6): line 1 is a JSON header, the rest is one JSON body carrying
148
+ // memoryStatus.pageSize, largestProcess, date and processes[] entries with name/rpages.
149
+ // Returns [{ file, date, largestProcess, fseventsdBytes, pageSize }] — plus `error` when a
150
+ // single file could not be read or parsed (the caller turns that into an `error` row).
151
+ // ---------------------------------------------------------------------------
152
+ async function readNewJetsam({ dir = JETSAM_DIR, lastSeen = '', fsImpl = fs } = {}) {
153
+ const io = fsImpl && fsImpl.promises ? fsImpl.promises : fsImpl;
154
+ let names;
155
+ try {
156
+ names = await io.readdir(dir);
157
+ } catch (err) {
158
+ // HANDLE: a host with no JetsamEvent directory (or no read permission) simply has no
159
+ // reports to ingest; that is not a sampler failure.
160
+ if (err && (err.code === 'ENOENT' || err.code === 'EACCES' || err.code === 'EPERM' || err.code === 'ENOTDIR')) return [];
161
+ throw err; // RETHROW: EMFILE/EIO are real problems worth an error row.
162
+ }
163
+ const since = String(lastSeen || '');
164
+ const files = names
165
+ .filter((name) => /^JetsamEvent-.*\.ips$/.test(name) && name > since)
166
+ .sort();
167
+ const rows = [];
168
+ for (const file of files) {
169
+ rows.push(await readJetsamFile(dir, file, io));
170
+ }
171
+ return rows;
172
+ }
173
+
174
+ async function readJetsamFile(dir, file, io) {
175
+ const pageSizeFallback = { file, date: null, largestProcess: null, fseventsdBytes: null, pageSize: FALLBACK_PAGE_SIZE };
176
+ let text;
177
+ try {
178
+ text = String(await io.readFile(path.join(dir, file), 'utf8'));
179
+ } catch (err) {
180
+ return { ...pageSizeFallback, error: `read failed: ${(err && err.message) || err}` };
181
+ }
182
+ const newline = text.indexOf('\n');
183
+ const headerText = newline === -1 ? text : text.slice(0, newline);
184
+ const bodyText = newline === -1 ? '' : text.slice(newline + 1);
185
+ let header = null;
186
+ let body = null;
187
+ try {
188
+ header = JSON.parse(headerText);
189
+ } catch {
190
+ /* expected: a truncated/foreign .ips header must not abort the remaining reports */
191
+ }
192
+ try {
193
+ body = JSON.parse(bodyText);
194
+ } catch {
195
+ /* expected: a truncated/foreign .ips body is reported as a per-file error below */
196
+ }
197
+ if (!body || typeof body !== 'object') {
198
+ return { ...pageSizeFallback, date: (header && header.timestamp) || null, error: 'body is not JSON' };
199
+ }
200
+ const pageSize = Number(body.memoryStatus && body.memoryStatus.pageSize) || FALLBACK_PAGE_SIZE;
201
+ const processes = Array.isArray(body.processes) ? body.processes : [];
202
+ const entry = processes.find((row) => row && row.name === 'fseventsd');
203
+ const rpages = entry && Number(entry.rpages);
204
+ return {
205
+ file,
206
+ date: body.date || (header && header.timestamp) || null,
207
+ largestProcess: body.largestProcess === undefined ? null : body.largestProcess,
208
+ fseventsdBytes: Number.isFinite(rpages) ? rpages * pageSize : null,
209
+ pageSize,
210
+ lifetimeMax: entry && entry.lifetimeMax !== undefined ? entry.lifetimeMax : null,
211
+ };
212
+ }
213
+
214
+ // ---------------------------------------------------------------------------
215
+ // createSampler: append-only JSONL rows + a sibling state file so a restart keeps the growth
216
+ // baseline (and does not re-ingest every JetsamEvent again).
217
+ // { kind: 'sample', at, pid, memBytes, cmprsBytes }
218
+ // { kind: 'jetsam', at, file, date, largestProcess, fseventsdBytes }
219
+ // { kind: 'attribution', at, memBytes, deltaBytes, census: { total, perSecond, categories, families } }
220
+ // { kind: 'error', at, stage, message }
221
+ // ---------------------------------------------------------------------------
222
+ function defaultState() {
223
+ return { version: 1, lastJetsam: '', lastSample: null, lastAttributionAt: null, updatedAt: null };
224
+ }
225
+
226
+ function createSampler({
227
+ logPath = DEFAULT_LOG_PATH,
228
+ repoRoot,
229
+ now = Date.now,
230
+ execFile = defaultExecFile,
231
+ homeDir = os.homedir(),
232
+ tmpDir = os.tmpdir(),
233
+ jetsamDir = JETSAM_DIR,
234
+ } = {}) {
235
+ const resolvedLogPath = logPath;
236
+ const statePath = path.join(path.dirname(resolvedLogPath), STATE_FILE_NAME);
237
+ const root = repoRoot || path.resolve(__dirname, '..', '..');
238
+ let state = null;
239
+
240
+ async function appendRow(row) {
241
+ await fs.promises.mkdir(path.dirname(resolvedLogPath), { recursive: true });
242
+ await fs.promises.appendFile(resolvedLogPath, `${JSON.stringify(row)}\n`, { mode: 0o600 });
243
+ }
244
+
245
+ // REPORT: an unwritable log must not stop the sampler from trying again next tick, so the
246
+ // caller sees the failure through console.warn in the server's timer callback.
247
+ async function appendRowSafe(row) {
248
+ try {
249
+ await appendRow(row);
250
+ } catch (err) {
251
+ process.stderr.write(`[fseventsd-sampler] log write failed: ${(err && err.message) || err}\n`);
252
+ }
253
+ }
254
+
255
+ async function loadState() {
256
+ if (state) return state;
257
+ try {
258
+ const parsed = JSON.parse(String(await fs.promises.readFile(statePath, 'utf8')));
259
+ state = { ...defaultState(), ...parsed };
260
+ return state;
261
+ } catch (err) {
262
+ if (err && err.code !== 'ENOENT') {
263
+ await appendRowSafe({ kind: 'error', at: now(), stage: 'state-read', message: String((err && err.message) || err) });
264
+ }
265
+ state = defaultState();
266
+ return state;
267
+ }
268
+ }
269
+
270
+ async function saveState() {
271
+ const tmp = `${statePath}.${process.pid}.tmp`;
272
+ state.updatedAt = new Date(now()).toISOString();
273
+ await fs.promises.writeFile(tmp, `${JSON.stringify(state)}\n`, { mode: 0o600 });
274
+ await fs.promises.rename(tmp, statePath);
275
+ }
276
+
277
+ // The attribution snapshot: one census run over the three producers we own (§6, §1.2).
278
+ async function runAttributionCensus() {
279
+ const args = [
280
+ path.join(root, 'bin', 'fs-event-census.js'),
281
+ '--seconds', String(ATTRIBUTION_SECONDS),
282
+ '--json',
283
+ '--families',
284
+ '--root', tmpDir,
285
+ '--root', path.join(homeDir, '.walle'),
286
+ '--root', path.join(homeDir, 'ws'),
287
+ ];
288
+ const { stdout } = await runChild(execFile, process.execPath, args, {
289
+ timeout: ATTRIBUTION_TIMEOUT_MS,
290
+ maxBuffer: ATTRIBUTION_MAX_BUFFER,
291
+ });
292
+ const parsed = JSON.parse(stdout);
293
+ return {
294
+ total: parsed.total,
295
+ perSecond: parsed.perSecond,
296
+ categories: (Array.isArray(parsed.categories) ? parsed.categories : []).map((row) => ({
297
+ name: row.name, count: row.count, share: row.share, newUnique: row.newUnique,
298
+ })),
299
+ families: Array.isArray(parsed.families)
300
+ ? parsed.families.map((row) => ({ name: row.name, count: row.count, newUnique: row.newUnique }))
301
+ : [],
302
+ };
303
+ }
304
+
305
+ async function ingestJetsam(current) {
306
+ let rows;
307
+ try {
308
+ rows = await readNewJetsam({ dir: jetsamDir, lastSeen: current.lastJetsam });
309
+ } catch (err) {
310
+ await appendRowSafe({ kind: 'error', at: now(), stage: 'jetsam', message: String((err && err.message) || err) });
311
+ return;
312
+ }
313
+ for (const row of rows) {
314
+ if (row.error) {
315
+ await appendRowSafe({ kind: 'error', at: now(), stage: 'jetsam-parse', message: `${row.file}: ${row.error}` });
316
+ } else {
317
+ await appendRowSafe({
318
+ kind: 'jetsam',
319
+ at: now(),
320
+ file: row.file,
321
+ date: row.date,
322
+ largestProcess: row.largestProcess,
323
+ fseventsdBytes: row.fseventsdBytes,
324
+ });
325
+ }
326
+ // HANDLE: the name advances even for an unparsable report — .ips files are immutable,
327
+ // so re-reading one every 30 min would only repeat the same error row forever.
328
+ current.lastJetsam = row.file;
329
+ }
330
+ }
331
+
332
+ async function maybeAttribute(current, sample) {
333
+ const prev = current.lastSample;
334
+ if (!prev || !Number.isFinite(prev.memBytes) || !Number.isFinite(sample.memBytes)) return;
335
+ const deltaBytes = sample.memBytes - prev.memBytes;
336
+ if (deltaBytes <= GROWTH_ATTRIBUTION_BYTES) return;
337
+ if (current.lastAttributionAt !== null && sample.at - current.lastAttributionAt < ATTRIBUTION_MIN_GAP_MS) return;
338
+ try {
339
+ const census = await runAttributionCensus();
340
+ await appendRowSafe({ kind: 'attribution', at: sample.at, memBytes: sample.memBytes, deltaBytes, census });
341
+ current.lastAttributionAt = sample.at;
342
+ } catch (err) {
343
+ // REPORT: no attribution time is recorded, so the next sample retries (the 6 h gap only
344
+ // bounds successes, §6). The absence is visible as an `error` row beside the growth.
345
+ await appendRowSafe({ kind: 'error', at: sample.at, stage: 'attribution', message: String((err && err.message) || err) });
346
+ }
347
+ }
348
+
349
+ async function tick() {
350
+ let current;
351
+ let sample;
352
+ try {
353
+ current = await loadState();
354
+ sample = await sampleOnce({ execFile, now });
355
+ if (sample.error) {
356
+ await appendRowSafe({ kind: 'error', at: sample.at, stage: 'sample', message: sample.error });
357
+ return;
358
+ }
359
+ await appendRowSafe({ kind: 'sample', at: sample.at, pid: sample.pid, memBytes: sample.memBytes, cmprsBytes: sample.cmprsBytes });
360
+ await ingestJetsam(current);
361
+ await maybeAttribute(current, sample);
362
+ current.lastSample = { at: sample.at, memBytes: sample.memBytes };
363
+ await saveState();
364
+ } catch (err) {
365
+ // REPORT: tick() is called from a named interval and from a boot timer; a rejection
366
+ // there would only be logged by the caller, so it is recorded here as an error row.
367
+ await appendRowSafe({
368
+ kind: 'error',
369
+ at: now(),
370
+ stage: 'tick',
371
+ message: String((err && err.message) || err),
372
+ });
373
+ }
374
+ }
375
+
376
+ return {
377
+ tick,
378
+ // Test/ops surface (read-only): where rows and state live.
379
+ logPath: resolvedLogPath,
380
+ statePath,
381
+ loadState,
382
+ };
383
+ }
384
+
385
+ module.exports = {
386
+ SAMPLE_INTERVAL_MS,
387
+ GROWTH_ATTRIBUTION_BYTES,
388
+ ATTRIBUTION_MIN_GAP_MS,
389
+ ATTRIBUTION_SECONDS,
390
+ DEFAULT_LOG_PATH,
391
+ JETSAM_DIR,
392
+ STATE_FILE_NAME,
393
+ FALLBACK_PAGE_SIZE,
394
+ createSampler,
395
+ parseTopLine,
396
+ readNewJetsam,
397
+ sampleOnce,
398
+ shouldRunSampler,
399
+ };
@@ -173,10 +173,17 @@ async function probeSuccessor(ch, spawned, hostId, deadlineAt) {
173
173
  }
174
174
 
175
175
  // One handoff attempt. Resolves { ok:true, ... } or { ok:false, reason, attempted }; never rejects.
176
+ //
177
+ // WP-3 (D-3/S-3): opts.reason is 'upgrade' (default) or 'evacuate-threadpool'.
178
+ // An evacuation is not an upgrade -- the host is being replaced because its
179
+ // libuv pool is dead, so it does not need an 'upgrade-pending' compat entry to
180
+ // be eligible (any entry, or none, passes). The recovery-protected check stays
181
+ // first for both reasons, and 'upgrade' keeps today's check byte-for-byte.
176
182
  async function handoffHost(manager, hostId, opts = {}) {
183
+ const reason = opts.reason === 'evacuate-threadpool' ? 'evacuate-threadpool' : 'upgrade';
177
184
  if (manager.isRecoveryProtectedHost?.(hostId)) return { ok: false, attempted: false, reason: 'owner-recovery-pending' };
178
185
  const compat = manager.hostCompatibility.get(hostId);
179
- if (!compat || compat.reason !== 'upgrade-pending') return { ok: false, attempted: false, reason: 'not-upgrade-pending' };
186
+ if (reason === 'upgrade' && (!compat || compat.reason !== 'upgrade-pending')) return { ok: false, attempted: false, reason: 'not-upgrade-pending' };
180
187
  const adapters = liveAdapters(manager, hostId);
181
188
  const first = adapters.values().next().value;
182
189
  const conn = first && first._socketConn && !first._socketConn.destroyed ? first._socketConn : null;
@@ -331,11 +338,18 @@ async function handoffHostWithRetry(manager, hostId, opts = {}) {
331
338
  }
332
339
 
333
340
  // Restore-loop tail (server.js): upgrade every upgrade-pending host, serially. Never throws.
334
- async function runUpgradePendingHandoffs({ manager, log = console.log, ...opts } = {}) {
341
+ // WP-3 (S-4): skipHostIds names hosts the boot-time stall escalation (D-4) has
342
+ // ALREADY decided to evacuate -- they are logged and left alone here, so no
343
+ // rollup/stale flag/10-minute retry can be armed against a stalled host.
344
+ async function runUpgradePendingHandoffs({ manager, skipHostIds = new Set(), log = console.log, ...opts } = {}) {
335
345
  const results = [];
336
346
  try {
337
347
  const hostIds = [...manager.hostCompatibility].filter(([, c]) => c && c.reason === 'upgrade-pending').map(([id]) => id);
338
348
  for (const hostId of hostIds) {
349
+ if (skipHostIds.has(hostId)) {
350
+ log(`[host-handoff] ${hostId} skipped: evacuating`);
351
+ continue;
352
+ }
339
353
  const result = await handoffHostWithRetry(manager, hostId, { ...opts, log });
340
354
  results.push(result);
341
355
  if (!result.attempted) {
@@ -33,6 +33,14 @@ function modelProcessGenerationMetadata(value) {
33
33
  return validModelProcessGeneration(value) ? { modelProcessGeneration: value } : {};
34
34
  }
35
35
  const MODEL_STORAGE_ROOT_KEYS = Object.freeze(['HOME', 'CODEX_HOME', 'CTM_CODEX_SESSIONS_DIR', 'CLAUDE_CONFIG_DIR', 'GEMINI_CLI_HOME', 'OPENCODE_DATA_DIR', 'XDG_DATA_HOME']);
36
+ // WP-0: the projected keys and the strip moved to lib/launch-environment.js (§5 D-1); re-exported from here so
37
+ // the existing importers are unchanged. The keys a lead-model switch re-projects into the launch context
38
+ // (lib/lead-model-restore-reconciliation.js projectDeferredRestoreLaunch: HOME / CODEX_HOME from the launch
39
+ // context, TMPDIR alongside them) are PROJECTED launch context, not per-session private overrides: a spawn
40
+ // still receives them, but their presence must never turn an otherwise empty override set into a private
41
+ // environment that only a surviving owner can reproduce. Anything else in the env is private and is captured
42
+ // by value.
43
+ const { PROJECTED_LAUNCH_CONTEXT_KEYS, privateOverridesFromEnv, launchEnvironmentMetadata } = require('./launch-environment');
36
44
  function modelStorageRootsFromEnv(env) {
37
45
  const roots = {};
38
46
  for (const key of MODEL_STORAGE_ROOT_KEYS) {
@@ -51,8 +59,8 @@ function writeHandoffManifest(dir, oldHostId, entries, { manifestPath } = {}) {
51
59
  const target = manifestPath || path.join(dir, `handoff-${oldHostId}-${++manifestCounter}.json`);
52
60
  const tmp = `${target}.tmp-${process.pid}`;
53
61
  entries = entries.map((entry) => {
54
- const { modelProcessGeneration, modelStorageRoots, modelExecutionRecipe, ...base } = entry;
55
- return { ...base, ...modelProcessGenerationMetadata(modelProcessGeneration), ...modelStorageRootsMetadata(modelStorageRoots), ...modelExecutionRecipeMetadata(modelExecutionRecipe, { sessionId: entry.sessionId, processGeneration: modelProcessGeneration }) };
62
+ const { modelProcessGeneration, modelStorageRoots, modelExecutionRecipe, launchEnvironment, ...base } = entry;
63
+ return { ...base, ...modelProcessGenerationMetadata(modelProcessGeneration), ...modelStorageRootsMetadata(modelStorageRoots), ...modelExecutionRecipeMetadata(modelExecutionRecipe, { sessionId: entry.sessionId, processGeneration: modelProcessGeneration }), ...launchEnvironmentMetadata(launchEnvironment, { manifest: true }) };
56
64
  });
57
65
  fs.writeFileSync(tmp, JSON.stringify({ version: 1, oldHostId, entries }), { mode: 0o600 });
58
66
  fs.renameSync(tmp, target);
@@ -84,6 +92,10 @@ function readHandoffManifest(manifestPath) {
84
92
  const recipe = modelExecutionRecipeMetadata(entry.modelExecutionRecipe, { sessionId: entry.sessionId, processGeneration: entry.modelProcessGeneration });
85
93
  if (recipe.modelExecutionRecipe) entry.modelExecutionRecipe = recipe.modelExecutionRecipe;
86
94
  else delete entry.modelExecutionRecipe;
95
+ // WP-1 (S-11): a manifest written by an older host has no field at all -- absent stays absent.
96
+ const launchEnv = launchEnvironmentMetadata(entry.launchEnvironment, { manifest: true });
97
+ if (launchEnv.launchEnvironment) entry.launchEnvironment = launchEnv.launchEnvironment;
98
+ else delete entry.launchEnvironment;
87
99
  });
88
100
  fs.unlinkSync(manifestPath);
89
101
  return { entries: parsed.entries };
@@ -111,6 +123,10 @@ function isAlive(pid) {
111
123
  // listSessions() -> [{ sessionId, ptyProcess, ptyClosed, cols, rows, seq, cmd, cwd, name, outputEpoch,
112
124
  // workerDisplayContext, suppressPtyHeadlessUntilInput, mirrorFeed }]; serialize(sessionId) -> {data,cols,rows}|null.
113
125
  const REPAINT_NUDGE_MS = 80;
126
+ // D-1: the old host's painted-seal await is bounded. A seal runs on its session's own op chain; a wedged chain
127
+ // (a dead libuv pool) never comes back, and no deadline is long enough to wait it out. Losing the race costs a
128
+ // restart break in that session's painted rows (an unsealed stretch cannot be joined), never the whole handoff.
129
+ const HANDOFF_SEAL_TIMEOUT_MS = 1000;
114
130
 
115
131
  function createHandoff({ hostId, workerPath, controlSocketPath, listSessions, serialize, mirrorStatus, headless, send, log = () => {}, setTimer = setTimeout, spawnSuccessor = spawnSuccessorHost }) {
116
132
  let active = null;
@@ -140,6 +156,26 @@ function createHandoff({ hostId, workerPath, controlSocketPath, listSessions, se
140
156
  (reply || send)({ type: 'handoff-aborted', handoffId: cur.handoffId, reason });
141
157
  }
142
158
 
159
+ // One session's painted-seal, raced against HANDOFF_SEAL_TIMEOUT_MS: resolves when the seal completes (its
160
+ // timer then cleared) or when the bound expires, in which case the handoff proceeds and the loss is reported.
161
+ // A rejecting seal still rejects (the begin() catch aborts the handoff, unchanged).
162
+ function raceSeal(sessionId) {
163
+ return new Promise((resolve, reject) => {
164
+ let settled = false;
165
+ const timer = setTimer(() => {
166
+ if (settled) return;
167
+ settled = true;
168
+ diagnostic(sessionId, 'host-handoff-seal-timeout', { timeoutMs: HANDOFF_SEAL_TIMEOUT_MS, oldHostId: hostId });
169
+ resolve();
170
+ }, HANDOFF_SEAL_TIMEOUT_MS);
171
+ timer?.unref?.();
172
+ Promise.resolve(headless.handleMessage({ type: 'painted-seal', sessionId })).then(
173
+ () => { if (settled) return; settled = true; clearTimeout(timer); resolve(); },
174
+ (err) => { if (settled) return; settled = true; clearTimeout(timer); reject(err); },
175
+ );
176
+ });
177
+ }
178
+
143
179
  async function begin(msg, reply) {
144
180
  const handoffId = String(msg.handoffId || '');
145
181
  if (active) { reply({ type: 'handoff-aborted', handoffId, reason: 'already-in-progress' }); return; }
@@ -153,11 +189,11 @@ function createHandoff({ hostId, workerPath, controlSocketPath, listSessions, se
153
189
  s.ptyProcess.pause();
154
190
  cur.paused.push(s);
155
191
  }
156
- const seeds = new Map();
157
- for (const s of cur.paused) {
192
+ // D-1: every seed is issued concurrently -- each `serialize` keeps its own 2 000 ms cap, so N sessions cost
193
+ // one cap, not N. The mirrorFeed flush still lands immediately before its own session's serialize.
194
+ const seeds = new Map(await Promise.all(cur.paused.map(async (s) => {
158
195
  s.mirrorFeed?.flush?.({ force: true });
159
196
  const snap = await serialize(s.sessionId);
160
- seeds.set(s.sessionId, snap);
161
197
  // Probe (observe only): what the seed carries vs what the mirror believed at the same instant.
162
198
  const seedData = String((snap && snap.data) || '');
163
199
  diagnostic(s.sessionId, 'host-handoff-mirror-seed', {
@@ -168,18 +204,16 @@ function createHandoff({ hostId, workerPath, controlSocketPath, listSessions, se
168
204
  seedBytes: Buffer.byteLength(seedData),
169
205
  oldHostId: hostId,
170
206
  });
171
- }
207
+ return [s.sessionId, snap];
208
+ })));
172
209
  if (active !== cur) return; // aborted (deadline) while serializing
173
210
  // This host exits without its headless close(): seal each painted-row stretch (with its last screen) and flush the
174
211
  // log now, before the successor exists to load it -- an unsealed stretch cannot be joined (a restart break).
175
- // Each id is listed BEFORE its seal is queued, so an abort that lands mid-seal still reopens it (the per-session op
176
- // queue runs that reopen after the seal).
177
- cur.sealed = [];
178
- for (const s of cur.paused) {
179
- if (active !== cur) return; // aborted (deadline) while sealing
180
- cur.sealed.push(s.sessionId);
181
- await headless.handleMessage({ type: 'painted-seal', sessionId: s.sessionId });
182
- }
212
+ // D-1: every id is listed BEFORE any seal is queued (so an abort that lands mid-seal still reopens all of them,
213
+ // the per-session op queue running each reopen after its seal), and every seal is raced against
214
+ // HANDOFF_SEAL_TIMEOUT_MS, so one wedged op chain cannot hold the handoff past its bound.
215
+ cur.sealed = cur.paused.map((s) => s.sessionId);
216
+ await Promise.all(cur.paused.map((s) => raceSeal(s.sessionId)));
183
217
  if (active !== cur) return; // aborted (deadline) while sealing
184
218
  const running = cur.paused.filter((s) => !s.ptyClosed);
185
219
  const entries = running.map((s, i) => {
@@ -190,6 +224,7 @@ function createHandoff({ hostId, workerPath, controlSocketPath, listSessions, se
190
224
  ...modelProcessGenerationMetadata(s.modelProcessGeneration),
191
225
  ...modelStorageRootsMetadata(s.modelStorageRoots),
192
226
  ...modelExecutionRecipeMetadata(s.modelExecutionRecipe),
227
+ ...launchEnvironmentMetadata(s.launchEnvironment, { manifest: true }),
193
228
  // Identity only: the context also carries the runtime render cache (Sets/Maps JSON turns into {}).
194
229
  workerDisplayContext: s.workerDisplayContext ? { agentRole: s.workerDisplayContext.agentRole, _workerAgent: s.workerDisplayContext._workerAgent, cwd: s.workerDisplayContext.cwd } : null,
195
230
  suppressPtyHeadlessUntilInput: !!s.suppressPtyHeadlessUntilInput,
@@ -306,4 +341,4 @@ function createHandoff({ hostId, workerPath, controlSocketPath, listSessions, se
306
341
  return { intercept, restore, resumeRestored, isActive: () => !!active };
307
342
  }
308
343
 
309
- module.exports = { handoffManifestFromArgv, writeHandoffManifest, readHandoffManifest, spawnSuccessorHost, createHandoff, validModelProcessGeneration, modelProcessGenerationFromEnv, modelProcessGenerationMetadata, modelStorageRootsFromEnv, modelStorageRootsMetadata };
344
+ module.exports = { HANDOFF_SEAL_TIMEOUT_MS, handoffManifestFromArgv, writeHandoffManifest, readHandoffManifest, spawnSuccessorHost, createHandoff, validModelProcessGeneration, modelProcessGenerationFromEnv, modelProcessGenerationMetadata, modelStorageRootsFromEnv, modelStorageRootsMetadata, PROJECTED_LAUNCH_CONTEXT_KEYS, privateOverridesFromEnv, launchEnvironmentMetadata };