create-walle 0.10.2 → 0.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (488) hide show
  1. package/README.md +3 -1
  2. package/lib/release-schema.json +2 -2
  3. package/lib/runtime-closure-policy.json +8 -7
  4. package/package.json +1 -1
  5. package/template/coding-task-manager/api-prompts.js +45 -7
  6. package/template/coding-task-manager/bin/claude-hook.js +55 -1
  7. package/template/coding-task-manager/bin/ctm-relay-client.js +35 -12
  8. package/template/coding-task-manager/bin/land.js +2069 -0
  9. package/template/coding-task-manager/bin/memory-census.js +4 -2
  10. package/template/coding-task-manager/bin/memory-sync-verify.js +151 -0
  11. package/template/coding-task-manager/bin/probe-refusal-scope.js +530 -0
  12. package/template/coding-task-manager/db.js +156 -32
  13. package/template/coding-task-manager/lib/acp/acp-client.js +383 -0
  14. package/template/coding-task-manager/lib/acp/dsh-context-truth.js +176 -0
  15. package/template/coding-task-manager/lib/acp/dsh-launch-model.js +302 -0
  16. package/template/coding-task-manager/lib/acp/dsh-mcp-servers.js +194 -0
  17. package/template/coding-task-manager/lib/acp/dsh-prompt-lane.js +616 -0
  18. package/template/coding-task-manager/lib/acp/dsh-route-patch.js +308 -0
  19. package/template/coding-task-manager/lib/acp/dsh-session-runtime.js +522 -0
  20. package/template/coding-task-manager/lib/acp/dsh-transcript.js +395 -0
  21. package/template/coding-task-manager/lib/acp/dsh-usage-log.js +162 -0
  22. package/template/coding-task-manager/lib/acp/ndjson-stdio-transport.js +225 -0
  23. package/template/coding-task-manager/lib/adopted-host-redial.js +47 -11
  24. package/template/coding-task-manager/lib/adopted-launch-environment.js +123 -0
  25. package/template/coding-task-manager/lib/agent-auto-update-runtime.js +0 -3
  26. package/template/coding-task-manager/lib/agent-auto-update.js +26 -10
  27. package/template/coding-task-manager/lib/agent-bundle/build.js +657 -0
  28. package/template/coding-task-manager/lib/agent-bundle/codex-install.js +558 -0
  29. package/template/coding-task-manager/lib/agent-bundle/drift.js +120 -0
  30. package/template/coding-task-manager/lib/agent-bundle/gc.js +522 -0
  31. package/template/coding-task-manager/lib/agent-bundle/inventory.js +346 -0
  32. package/template/coding-task-manager/lib/agent-bundle/push.js +717 -0
  33. package/template/coding-task-manager/lib/agent-bundle/skill-transfer.js +724 -0
  34. package/template/coding-task-manager/lib/agent-bundle/spawn.js +119 -0
  35. package/template/coding-task-manager/lib/agent-bundle/store.js +568 -0
  36. package/template/coding-task-manager/lib/agent-capabilities.js +142 -12
  37. package/template/coding-task-manager/lib/agent-cli-cache.js +30 -5
  38. package/template/coding-task-manager/lib/agent-definitions.js +19 -0
  39. package/template/coding-task-manager/lib/agent-hooks-codex-toml.js +28 -16
  40. package/template/coding-task-manager/lib/agent-hooks-codex-workspace.js +9 -1
  41. package/template/coding-task-manager/lib/agent-hooks-installer.js +23 -8
  42. package/template/coding-task-manager/lib/agent-hooks-prune.js +37 -11
  43. package/template/coding-task-manager/lib/agent-hooks-shim.js +105 -0
  44. package/template/coding-task-manager/lib/agent-presets.js +84 -1
  45. package/template/coding-task-manager/lib/agent-upgrade-jobs.js +12 -1
  46. package/template/coding-task-manager/lib/agent-version-service.js +74 -11
  47. package/template/coding-task-manager/lib/all-sessions-query.js +6 -2
  48. package/template/coding-task-manager/lib/api/agent-bundles.js +436 -0
  49. package/template/coding-task-manager/lib/api/backup-retention.js +83 -0
  50. package/template/coding-task-manager/lib/api/conversation-sync-routes.js +124 -0
  51. package/template/coding-task-manager/lib/api/diagnostics.js +549 -69
  52. package/template/coding-task-manager/lib/api/fleet.js +118 -0
  53. package/template/coding-task-manager/lib/api/hub-bridge.js +243 -0
  54. package/template/coding-task-manager/lib/api/ingress.js +9 -1
  55. package/template/coding-task-manager/lib/api/landing.js +403 -0
  56. package/template/coding-task-manager/lib/api/machines.js +691 -2
  57. package/template/coding-task-manager/lib/api/memory-sync-routes.js +335 -0
  58. package/template/coding-task-manager/lib/api/misc-ops.js +8 -3
  59. package/template/coding-task-manager/lib/api/remote-sessions.js +1326 -0
  60. package/template/coding-task-manager/lib/api/session-attach.js +623 -0
  61. package/template/coding-task-manager/lib/api/session-messages.js +1384 -0
  62. package/template/coding-task-manager/lib/api/sessions.js +77 -51
  63. package/template/coding-task-manager/lib/api/setup-network.js +544 -16
  64. package/template/coding-task-manager/lib/api/setup-wizard-handlers.js +884 -0
  65. package/template/coding-task-manager/lib/api/setup.js +829 -10
  66. package/template/coding-task-manager/lib/api/walle-bridge.js +9 -1
  67. package/template/coding-task-manager/lib/attachment-reconciler-wiring.js +5 -2
  68. package/template/coding-task-manager/lib/auth-rate-limit.js +23 -0
  69. package/template/coding-task-manager/lib/auth-rules.js +292 -21
  70. package/template/coding-task-manager/lib/background-stop.js +369 -0
  71. package/template/coding-task-manager/lib/best-of-attempts.js +4 -1
  72. package/template/coding-task-manager/lib/best-of-launch-plan.js +52 -0
  73. package/template/coding-task-manager/lib/box-keep-awake.js +89 -0
  74. package/template/coding-task-manager/lib/broadcast-reason-stats.js +152 -0
  75. package/template/coding-task-manager/lib/broadcast-serialize.js +5 -0
  76. package/template/coding-task-manager/lib/build-info.js +4 -2
  77. package/template/coding-task-manager/lib/claude-model-truth.js +13 -2
  78. package/template/coding-task-manager/lib/claude-transcript-terminal-renderer.js +17 -13
  79. package/template/coding-task-manager/lib/client-diag-handler.js +64 -2
  80. package/template/coding-task-manager/lib/codex-app-server-client.js +14 -16
  81. package/template/coding-task-manager/lib/codex-configuration-history.js +55 -0
  82. package/template/coding-task-manager/lib/codex-harness-qualification.js +43 -20
  83. package/template/coding-task-manager/lib/codex-rollout-history.js +743 -0
  84. package/template/coding-task-manager/lib/coding-agent-models.js +27 -12
  85. package/template/coding-task-manager/lib/coding-cli-skill-installer.js +44 -14
  86. package/template/coding-task-manager/lib/coding-session-model-adapters.js +43 -2
  87. package/template/coding-task-manager/lib/coding-session-model-owner.js +1 -1
  88. package/template/coding-task-manager/lib/coding-session-model-public.js +7 -1
  89. package/template/coding-task-manager/lib/coding-session-model-runtime.js +23 -4
  90. package/template/coding-task-manager/lib/coding-session-model-scan.js +31 -0
  91. package/template/coding-task-manager/lib/coding-session-model-state.js +7 -0
  92. package/template/coding-task-manager/lib/conversation-freshness-diagnostics.js +280 -0
  93. package/template/coding-task-manager/lib/conversation-item-clock.js +261 -0
  94. package/template/coding-task-manager/lib/conversation-source-registry.js +5 -0
  95. package/template/coding-task-manager/lib/conversation-store-v2.js +44 -0
  96. package/template/coding-task-manager/lib/conversation-sync.js +355 -0
  97. package/template/coding-task-manager/lib/create/resolve-launch-params.js +96 -12
  98. package/template/coding-task-manager/lib/create/worker-role-profile.js +4 -4
  99. package/template/coding-task-manager/lib/create-intent-lease.js +51 -0
  100. package/template/coding-task-manager/lib/ctm-session-context-api.js +97 -6
  101. package/template/coding-task-manager/lib/db-domain-tables.js +1 -0
  102. package/template/coding-task-manager/lib/db-domains.js +1 -0
  103. package/template/coding-task-manager/lib/db-owner-dispatch-probe.js +32 -0
  104. package/template/coding-task-manager/lib/db-owner-request-counts.js +178 -0
  105. package/template/coding-task-manager/lib/db-owner-worker-client.js +68 -14
  106. package/template/coding-task-manager/lib/db-schema-source-files.js +5 -0
  107. package/template/coding-task-manager/lib/deferred-restore-attempt.js +6 -2
  108. package/template/coding-task-manager/lib/feature-manifest.js +4 -0
  109. package/template/coding-task-manager/lib/fleet-conversation-route.js +97 -0
  110. package/template/coding-task-manager/lib/fleet-fanout.js +78 -0
  111. package/template/coding-task-manager/lib/fleet-hub.js +762 -0
  112. package/template/coding-task-manager/lib/fleet-origin-follower.js +252 -0
  113. package/template/coding-task-manager/lib/fleet-resolver-effects.js +147 -0
  114. package/template/coding-task-manager/lib/fleet-resolver-tick.js +148 -0
  115. package/template/coding-task-manager/lib/fleet-resolver.js +454 -0
  116. package/template/coding-task-manager/lib/fleet-session-list-routes.js +114 -0
  117. package/template/coding-task-manager/lib/fleet-session-lists.js +672 -0
  118. package/template/coding-task-manager/lib/fleet-update.js +798 -0
  119. package/template/coding-task-manager/lib/fs-watcher-root-watch.js +141 -0
  120. package/template/coding-task-manager/lib/fs-watcher.js +58 -42
  121. package/template/coding-task-manager/lib/harness-history-transition.js +50 -9
  122. package/template/coding-task-manager/lib/headless-term-service.js +84 -8
  123. package/template/coding-task-manager/lib/hermetic-agent-launch-guard.js +10 -0
  124. package/template/coding-task-manager/lib/history-transition-read-op.js +175 -8
  125. package/template/coding-task-manager/lib/host-cpu-categories.js +310 -0
  126. package/template/coding-task-manager/lib/host-fseventsd-sampler.js +399 -0
  127. package/template/coding-task-manager/lib/host-handoff.js +16 -19
  128. package/template/coding-task-manager/lib/host-stats.js +150 -3
  129. package/template/coding-task-manager/lib/hosted-sync-worker.js +43 -320
  130. package/template/coding-task-manager/lib/hub-bridge-access.js +798 -0
  131. package/template/coding-task-manager/lib/hub-bridge-box.js +409 -0
  132. package/template/coding-task-manager/lib/hub-bridge-mcp.js +380 -0
  133. package/template/coding-task-manager/lib/hub-bridge-mesh.js +313 -0
  134. package/template/coding-task-manager/lib/hub-bridge-ops.js +721 -0
  135. package/template/coding-task-manager/lib/hub-bridge.js +398 -0
  136. package/template/coding-task-manager/lib/idle-notify.js +491 -0
  137. package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +8 -0
  138. package/template/coding-task-manager/lib/instance-manifest.js +5 -1
  139. package/template/coding-task-manager/lib/instance-sync-status.js +18 -8
  140. package/template/coding-task-manager/lib/landing/agent-rule.txt +1 -0
  141. package/template/coding-task-manager/lib/landing/batch-runner.js +366 -0
  142. package/template/coding-task-manager/lib/landing/config.js +536 -0
  143. package/template/coding-task-manager/lib/landing/ctm-view.js +256 -0
  144. package/template/coding-task-manager/lib/landing/gate.js +360 -0
  145. package/template/coding-task-manager/lib/landing/git.js +344 -0
  146. package/template/coding-task-manager/lib/landing/lease.js +247 -0
  147. package/template/coding-task-manager/lib/landing/merge-delta.js +380 -0
  148. package/template/coding-task-manager/lib/landing/proof.js +223 -0
  149. package/template/coding-task-manager/lib/landing/queue.js +998 -0
  150. package/template/coding-task-manager/lib/landing/radar.js +489 -0
  151. package/template/coding-task-manager/lib/landing/resolve-cli.js +424 -0
  152. package/template/coding-task-manager/lib/landing/state.js +263 -0
  153. package/template/coding-task-manager/lib/landing/stop.js +49 -0
  154. package/template/coding-task-manager/lib/landing/sync-cli.js +475 -0
  155. package/template/coding-task-manager/lib/landing/sync.js +456 -0
  156. package/template/coding-task-manager/lib/landing/train.js +885 -0
  157. package/template/coding-task-manager/lib/landing/window.js +57 -0
  158. package/template/coding-task-manager/lib/launch-environment.js +121 -0
  159. package/template/coding-task-manager/lib/launch-model-override.js +36 -10
  160. package/template/coding-task-manager/lib/launch-plan-pool.js +2 -1
  161. package/template/coding-task-manager/lib/launch-plan-warm-cache.js +6 -0
  162. package/template/coding-task-manager/lib/lead-model-observer.js +57 -1
  163. package/template/coding-task-manager/lib/lead-model-options.js +160 -3
  164. package/template/coding-task-manager/lib/lead-model-restore-reconciliation.js +106 -24
  165. package/template/coding-task-manager/lib/lead-model-switch-runtime.js +352 -68
  166. package/template/coding-task-manager/lib/lead-model-switch.js +114 -10
  167. package/template/coding-task-manager/lib/lead-model-transition-runtime.js +14 -2
  168. package/template/coding-task-manager/lib/lead-model-transition-store.js +24 -6
  169. package/template/coding-task-manager/lib/lead-route-preflight.js +179 -0
  170. package/template/coding-task-manager/lib/lead-switch-history-mode.js +110 -0
  171. package/template/coding-task-manager/lib/lead-wire-agent.js +7 -0
  172. package/template/coding-task-manager/lib/lifecycle-wake-experiment.js +9 -2
  173. package/template/coding-task-manager/lib/live-defer-announce.js +45 -0
  174. package/template/coding-task-manager/lib/machine-registry.js +750 -5
  175. package/template/coding-task-manager/lib/macos-capabilities.js +32 -15
  176. package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +433 -53
  177. package/template/coding-task-manager/lib/mainloop-observability.js +14 -9
  178. package/template/coding-task-manager/lib/media-draft-owner.js +16 -3
  179. package/template/coding-task-manager/lib/memory-join.js +337 -0
  180. package/template/coding-task-manager/lib/memory-sync-verify.js +393 -0
  181. package/template/coding-task-manager/lib/memory-sync.js +565 -0
  182. package/template/coding-task-manager/lib/migrations/v57-delegate-pref-mirror-opencode.js +68 -0
  183. package/template/coding-task-manager/lib/migrations/v58-subagent-launch-native-subagents.js +42 -0
  184. package/template/coding-task-manager/lib/migrations/v59-coding-session-model-state-dsh.js +73 -0
  185. package/template/coding-task-manager/lib/migrations/v60-delegate-pref-mirror-dsh.js +78 -0
  186. package/template/coding-task-manager/lib/migrations/v61-conversation-item-clock.js +71 -0
  187. package/template/coding-task-manager/lib/model-availability.js +727 -0
  188. package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +4 -6
  189. package/template/coding-task-manager/lib/model-host-receipt.js +6 -3
  190. package/template/coding-task-manager/lib/model-id-rule.js +19 -0
  191. package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
  192. package/template/coding-task-manager/lib/model-proxy/auto-mode-review.js +110 -23
  193. package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
  194. package/template/coding-task-manager/lib/model-proxy/generation-probe.js +60 -17
  195. package/template/coding-task-manager/lib/model-proxy/historical-tool-declarations.js +37 -0
  196. package/template/coding-task-manager/lib/model-proxy/lead-request-validation.js +1 -0
  197. package/template/coding-task-manager/lib/model-proxy/lead-token-admin.js +130 -0
  198. package/template/coding-task-manager/lib/model-proxy/refusal-scope.js +151 -0
  199. package/template/coding-task-manager/lib/model-proxy/request-budget-store.js +11 -2
  200. package/template/coding-task-manager/lib/model-proxy/tokens.js +69 -5
  201. package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
  202. package/template/coding-task-manager/lib/native-agent-model-args.js +25 -22
  203. package/template/coding-task-manager/lib/native-history-control.js +6 -4
  204. package/template/coding-task-manager/lib/native-lead-settings-client.js +44 -4
  205. package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +173 -36
  206. package/template/coding-task-manager/lib/online-backup-worker-client.js +2 -0
  207. package/template/coding-task-manager/lib/opencode-cli.js +480 -0
  208. package/template/coding-task-manager/lib/opencode-launch-model.js +471 -0
  209. package/template/coding-task-manager/lib/opencode-v1-plugin/model-carrier.mjs +35 -0
  210. package/template/coding-task-manager/lib/opencode-v2-plugin/server.js +118 -0
  211. package/template/coding-task-manager/lib/owner-action-manifest-data.json +1 -1
  212. package/template/coding-task-manager/lib/park-composer-draft.js +54 -0
  213. package/template/coding-task-manager/lib/park-fresh-relaunch.js +41 -10
  214. package/template/coding-task-manager/lib/perf-phase-trace.js +72 -0
  215. package/template/coding-task-manager/lib/perf-summary.js +7 -0
  216. package/template/coding-task-manager/lib/perf-tracker.js +63 -2
  217. package/template/coding-task-manager/lib/project-config.js +7 -0
  218. package/template/coding-task-manager/lib/prompt-purge-v2.js +52 -1
  219. package/template/coding-task-manager/lib/provider-login-broker.js +72 -15
  220. package/template/coding-task-manager/lib/provider-login-tab.js +10 -2
  221. package/template/coding-task-manager/lib/read-pool-client.js +89 -2
  222. package/template/coding-task-manager/lib/read-pool-worker-handle.js +29 -4
  223. package/template/coding-task-manager/lib/recent-catalog-query.js +15 -0
  224. package/template/coding-task-manager/lib/recent-session-catalog-response.js +67 -10
  225. package/template/coding-task-manager/lib/recovery-evidence.js +26 -11
  226. package/template/coding-task-manager/lib/relay-client.js +57 -3
  227. package/template/coding-task-manager/lib/relink-audit.js +34 -5
  228. package/template/coding-task-manager/lib/remote-machine-catalog.js +321 -26
  229. package/template/coding-task-manager/lib/remote-machine-create.js +576 -36
  230. package/template/coding-task-manager/lib/remote-machine-link.js +546 -59
  231. package/template/coding-task-manager/lib/remote-machine-proxy.js +143 -9
  232. package/template/coding-task-manager/lib/remote-session-forward.js +65 -7
  233. package/template/coding-task-manager/lib/remote-terminal-target.js +9 -2
  234. package/template/coding-task-manager/lib/restart-guard.js +18 -6
  235. package/template/coding-task-manager/lib/restore-seed-modes.js +87 -0
  236. package/template/coding-task-manager/lib/restored-scrollback-hydration-runtime.js +22 -2
  237. package/template/coding-task-manager/lib/resume-admission.js +17 -3
  238. package/template/coding-task-manager/lib/review-repo-registry.js +58 -19
  239. package/template/coding-task-manager/lib/root-delivery-runtime.js +2 -2
  240. package/template/coding-task-manager/lib/root-prompt-flow.js +1 -1
  241. package/template/coding-task-manager/lib/runtime-contract.js +3 -1
  242. package/template/coding-task-manager/lib/schema-indexes.js +1 -0
  243. package/template/coding-task-manager/lib/session-context-locator.js +742 -0
  244. package/template/coding-task-manager/lib/session-create/attachment.js +2 -2
  245. package/template/coding-task-manager/lib/session-create/create-phases.js +118 -0
  246. package/template/coding-task-manager/lib/session-create/delegate-worker.js +86 -16
  247. package/template/coding-task-manager/lib/session-create/dsh-session.js +930 -0
  248. package/template/coding-task-manager/lib/session-create/lead-route-launch.js +186 -13
  249. package/template/coding-task-manager/lib/session-create/native-lead-lifetime.js +55 -3
  250. package/template/coding-task-manager/lib/session-create/opencode-lead-provider.js +50 -0
  251. package/template/coding-task-manager/lib/session-create/prepared.js +162 -38
  252. package/template/coding-task-manager/lib/session-create/provider-process.js +160 -28
  253. package/template/coding-task-manager/lib/session-create/response.js +7 -7
  254. package/template/coding-task-manager/lib/session-create/structured-session.js +27 -0
  255. package/template/coding-task-manager/lib/session-create/subagent-pick-table.js +3 -1
  256. package/template/coding-task-manager/lib/session-create/subagent-pick.js +458 -9
  257. package/template/coding-task-manager/lib/session-create/transcript.js +1 -1
  258. package/template/coding-task-manager/lib/session-create/worker-budget-setup.js +21 -2
  259. package/template/coding-task-manager/lib/session-create/worker-continuation.js +7 -1
  260. package/template/coding-task-manager/lib/session-create/worker-launch-sandbox.js +39 -10
  261. package/template/coding-task-manager/lib/session-create/worker-observability.js +2 -2
  262. package/template/coding-task-manager/lib/session-empty.js +13 -10
  263. package/template/coding-task-manager/lib/session-host-manager.js +60 -0
  264. package/template/coding-task-manager/lib/session-jobs.js +3 -1
  265. package/template/coding-task-manager/lib/session-lifecycle.js +10 -4
  266. package/template/coding-task-manager/lib/session-model-action-preconditions.js +6 -2
  267. package/template/coding-task-manager/lib/session-model-intent-contract.js +11 -8
  268. package/template/coding-task-manager/lib/session-park.js +738 -0
  269. package/template/coding-task-manager/lib/session-path-grant.js +13 -4
  270. package/template/coding-task-manager/lib/session-status-ledger.js +106 -4
  271. package/template/coding-task-manager/lib/session-transport.js +17 -0
  272. package/template/coding-task-manager/lib/session-workspace-projection.js +54 -5
  273. package/template/coding-task-manager/lib/session-workspace-tracking-runtime.js +213 -1
  274. package/template/coding-task-manager/lib/skill-autocomplete-query.js +120 -3
  275. package/template/coding-task-manager/lib/skill-autocomplete.js +15 -1
  276. package/template/coding-task-manager/lib/sqlite-file-set.js +39 -0
  277. package/template/coding-task-manager/lib/standup-search-adapter.js +16 -2
  278. package/template/coding-task-manager/lib/state-sync/client-ledger.js +12 -0
  279. package/template/coding-task-manager/lib/state-sync/frame-emitter.js +319 -100
  280. package/template/coding-task-manager/lib/storage/coding-session-model-store.js +4 -1
  281. package/template/coding-task-manager/lib/storage/delegate-pref-mirror-store.js +32 -9
  282. package/template/coding-task-manager/lib/structured-session-boot-sweep.js +235 -0
  283. package/template/coding-task-manager/lib/submission-ack.js +90 -2
  284. package/template/coding-task-manager/lib/systemd-scope.js +115 -0
  285. package/template/coding-task-manager/lib/telemetry-receiver.js +39 -0
  286. package/template/coding-task-manager/lib/terminal-attach-geometry.js +985 -0
  287. package/template/coding-task-manager/lib/terminal-bootstrap.js +30 -0
  288. package/template/coding-task-manager/lib/terminal-draft-operation.js +357 -0
  289. package/template/coding-task-manager/lib/terminal-input-admission.js +17 -1
  290. package/template/coding-task-manager/lib/terminal-input-prepared.js +563 -0
  291. package/template/coding-task-manager/lib/transcript-cache-temps.js +171 -0
  292. package/template/coding-task-manager/lib/transcript-frame-cache.js +8 -3
  293. package/template/coding-task-manager/lib/transcript-source.js +36 -4
  294. package/template/coding-task-manager/lib/transcript-store.js +9 -0
  295. package/template/coding-task-manager/lib/typing-interaction-trace.js +106 -3
  296. package/template/coding-task-manager/lib/usage-ledger/backfill.js +40 -5
  297. package/template/coding-task-manager/lib/usage-ledger/client.js +4 -1
  298. package/template/coding-task-manager/lib/usage-ledger/dsh-parse.js +152 -0
  299. package/template/coding-task-manager/lib/usage-ledger/dsh-read.js +73 -0
  300. package/template/coding-task-manager/lib/usage-ledger/ingest.js +34 -6
  301. package/template/coding-task-manager/lib/usage-ledger/live.js +35 -8
  302. package/template/coding-task-manager/lib/usage-ledger/read.js +29 -20
  303. package/template/coding-task-manager/lib/usage-ledger/schema.js +61 -1
  304. package/template/coding-task-manager/lib/usage-ledger/task-coordinator.js +4 -2
  305. package/template/coding-task-manager/lib/wake-skip-reasons.js +1 -0
  306. package/template/coding-task-manager/lib/walle/turn.js +1 -1
  307. package/template/coding-task-manager/lib/walle-history-serve.js +838 -0
  308. package/template/coding-task-manager/lib/walle-kill-authority.js +2 -2
  309. package/template/coding-task-manager/lib/walle-log-rotation.js +164 -1
  310. package/template/coding-task-manager/lib/walle-mcp-auto-config.js +56 -2
  311. package/template/coding-task-manager/lib/walle-row-history.js +495 -0
  312. package/template/coding-task-manager/lib/walle-supervisor.js +33 -14
  313. package/template/coding-task-manager/lib/watch-worker-client.js +203 -0
  314. package/template/coding-task-manager/lib/worker-terminal-output.js +5 -2
  315. package/template/coding-task-manager/lib/ws/hub-bridge.js +35 -0
  316. package/template/coding-task-manager/lib/ws/lifecycle.js +6 -11
  317. package/template/coding-task-manager/lib/ws/misc.js +1 -1
  318. package/template/coding-task-manager/lib/ws/state-sync.js +106 -4
  319. package/template/coding-task-manager/lib/ws/terminal-attach.js +91 -0
  320. package/template/coding-task-manager/oauth-proxy.js +112 -115
  321. package/template/coding-task-manager/package-lock.json +10 -94
  322. package/template/coding-task-manager/package.json +4 -3
  323. package/template/coding-task-manager/protocol/message-table.json +10 -0
  324. package/template/coding-task-manager/protocol/messages.js +10 -0
  325. package/template/coding-task-manager/protocol/ws-schema.json +20 -0
  326. package/template/coding-task-manager/protocol/ws-schema.md +2 -0
  327. package/template/coding-task-manager/public/css/app.css +170 -0
  328. package/template/coding-task-manager/public/css/walle-session.css +4 -0
  329. package/template/coding-task-manager/public/index.html +473 -243
  330. package/template/coding-task-manager/public/js/agent-command.js +86 -0
  331. package/template/coding-task-manager/public/js/app/backups-panel.js +111 -5
  332. package/template/coding-task-manager/public/js/app/coding-agent-upgrade.js +103 -4
  333. package/template/coding-task-manager/public/js/app/machines-page.js +1328 -8
  334. package/template/coding-task-manager/public/js/app/models-tab.js +113 -38
  335. package/template/coding-task-manager/public/js/app/restart-banner.js +53 -0
  336. package/template/coding-task-manager/public/js/app/worktrees-panel.js +184 -2
  337. package/template/coding-task-manager/public/js/background-work.js +196 -27
  338. package/template/coding-task-manager/public/js/coding-session-model-presentation.js +138 -10
  339. package/template/coding-task-manager/public/js/core/active-session-groups.js +179 -0
  340. package/template/coding-task-manager/public/js/core/pending-create.js +238 -0
  341. package/template/coding-task-manager/public/js/core/recent-machine-source.js +228 -0
  342. package/template/coding-task-manager/public/js/core/session-commands.js +180 -14
  343. package/template/coding-task-manager/public/js/dashboard-client-function-order.json +8 -0
  344. package/template/coding-task-manager/public/js/document-review-links.js +9 -1
  345. package/template/coding-task-manager/public/js/file-resolution-client.js +52 -1
  346. package/template/coding-task-manager/public/js/history-app-seam.js +22 -2
  347. package/template/coding-task-manager/public/js/machine-pool-shared.js +558 -3
  348. package/template/coding-task-manager/public/js/message-renderer.js +4 -3
  349. package/template/coding-task-manager/public/js/model-picker.js +3 -1
  350. package/template/coding-task-manager/public/js/native-subagent-review.js +15 -2
  351. package/template/coding-task-manager/public/js/new-session-agent-grid.js +346 -0
  352. package/template/coding-task-manager/public/js/pasted-content.js +236 -0
  353. package/template/coding-task-manager/public/js/pe-private-content-lifetime.js +39 -7
  354. package/template/coding-task-manager/public/js/private-model-lifetime.js +6 -2
  355. package/template/coding-task-manager/public/js/prompts.js +11 -10
  356. package/template/coding-task-manager/public/js/protocol.js +10 -0
  357. package/template/coding-task-manager/public/js/restart-banner-policy.js +29 -1
  358. package/template/coding-task-manager/public/js/session-model-picker.js +447 -57
  359. package/template/coding-task-manager/public/js/session-search-utils.js +18 -2
  360. package/template/coding-task-manager/public/js/session-usage-view.js +2 -1
  361. package/template/coding-task-manager/public/js/session-workspace-tracking.js +51 -1
  362. package/template/coding-task-manager/public/js/state-sync-client.js +10 -1
  363. package/template/coding-task-manager/public/js/stream-view.js +6 -5
  364. package/template/coding-task-manager/public/js/terminal/conv-only-session.js +287 -0
  365. package/template/coding-task-manager/public/js/terminal/runtime-09.js +2 -0
  366. package/template/coding-task-manager/public/js/terminal/runtime-10.js +5 -5
  367. package/template/coding-task-manager/public/js/terminal/runtime-12.js +8 -1
  368. package/template/coding-task-manager/public/js/terminal/runtime-16.js +4 -0
  369. package/template/coding-task-manager/public/js/terminal/runtime-20.js +1 -1
  370. package/template/coding-task-manager/public/js/terminal-attachment-draft.js +67 -13
  371. package/template/coding-task-manager/public/js/terminal-image-orchestration.js +52 -6
  372. package/template/coding-task-manager/public/js/terminal-wheel.js +23 -3
  373. package/template/coding-task-manager/public/js/walle/chat-conversation.js +4 -4
  374. package/template/coding-task-manager/public/js/walle.js +6 -0
  375. package/template/coding-task-manager/public/js/ws/live-dispatch.js +10 -0
  376. package/template/coding-task-manager/public/m/app.css +140 -0
  377. package/template/coding-task-manager/public/m/app.js +507 -68
  378. package/template/coding-task-manager/public/m/index.html +17 -0
  379. package/template/coding-task-manager/public/m/machines.js +838 -4
  380. package/template/coding-task-manager/public/m/private-api.js +31 -1
  381. package/template/coding-task-manager/public/usage.html +1 -0
  382. package/template/coding-task-manager/scripts/dev-route-fixture/synthetic-route-upstream.js +104 -0
  383. package/template/coding-task-manager/scripts/dev-route-fixture.js +339 -0
  384. package/template/coding-task-manager/scripts/opencode-lead-route-probe.js +195 -0
  385. package/template/coding-task-manager/scripts/opencode-v2-contract-probe/fake-anthropic.js +168 -0
  386. package/template/coding-task-manager/scripts/opencode-v2-contract-probe/probe-plugin/server.js +95 -0
  387. package/template/coding-task-manager/scripts/opencode-v2-contract-probe.js +673 -0
  388. package/template/coding-task-manager/server.js +1950 -11679
  389. package/template/coding-task-manager/session-integrity.js +64 -4
  390. package/template/coding-task-manager/workers/db-owner-worker.js +19 -2
  391. package/template/coding-task-manager/workers/online-backup-worker.js +1 -0
  392. package/template/coding-task-manager/workers/read-pool-model-collector.js +51 -3
  393. package/template/coding-task-manager/workers/read-pool-worker.js +76 -6
  394. package/template/coding-task-manager/workers/session-host-pool-process.js +6 -6
  395. package/template/coding-task-manager/workers/session-host-process.js +5 -5
  396. package/template/coding-task-manager/workers/watch-worker.js +105 -0
  397. package/template/coding-task-manager/workers/worktree-worker.js +168 -33
  398. package/template/ctm-relay/lib/protocol.js +14 -1
  399. package/template/package-lock.json +2 -2
  400. package/template/package.json +1 -1
  401. package/template/shared/backup-retention.js +82 -0
  402. package/template/shared/conversation-admission.js +2 -0
  403. package/template/shared/conversation-provenance.js +3 -7
  404. package/template/shared/conversation-storage-v2-contract.js +5 -0
  405. package/template/shared/linked-worktree.js +51 -0
  406. package/template/shared/macos-fda-target.js +57 -0
  407. package/template/shared/orphan-parents.js +55 -0
  408. package/template/shared/release-schema.json +2 -2
  409. package/template/shared/storage/contract.js +3 -0
  410. package/template/wall-e/adapters/imessage.js +12 -0
  411. package/template/wall-e/agent.js +71 -4
  412. package/template/wall-e/api-walle.js +21 -1
  413. package/template/wall-e/bin/train-gemma-e4b-tooluse.js +2 -2
  414. package/template/wall-e/bin/walle-mcp-stdio.js +5 -5
  415. package/template/wall-e/brain/brain-join.js +859 -0
  416. package/template/wall-e/brain/brain-sync-membership.js +20 -0
  417. package/template/wall-e/brain/brain-sync-store.js +131 -77
  418. package/template/wall-e/brain/brain-sync-v2-schema.js +203 -0
  419. package/template/wall-e/brain/brain-sync-v2.js +578 -0
  420. package/template/wall-e/brain/delegate-model-prefs-store.js +13 -4
  421. package/template/wall-e/brain/deterministic-id.js +51 -0
  422. package/template/wall-e/brain/memories.js +2 -2
  423. package/template/wall-e/brain/migrations.js +40 -6
  424. package/template/wall-e/brain/model-identity-migration.js +1 -1
  425. package/template/wall-e/brain/owner-call-whitelist.js +23 -7
  426. package/template/wall-e/brain/schema.js +45 -85
  427. package/template/wall-e/brain.js +171 -35
  428. package/template/wall-e/chat.js +3 -3
  429. package/template/wall-e/coding/agent-shell-env.js +7 -2
  430. package/template/wall-e/coding/prompt-bundle.js +66 -21
  431. package/template/wall-e/config/main-loop-exemptions.json +2 -2
  432. package/template/wall-e/http/admin-api.js +37 -0
  433. package/template/wall-e/http/gws-api.js +4 -0
  434. package/template/wall-e/http/helper-rules-api.js +7 -1
  435. package/template/wall-e/http/model-admin.js +8 -1
  436. package/template/wall-e/http/model-delegate-pref-admin.js +3 -3
  437. package/template/wall-e/http/model-proxy-providers.js +174 -1
  438. package/template/wall-e/http/model-route-health.js +157 -0
  439. package/template/wall-e/http/sync-api.js +278 -464
  440. package/template/wall-e/jobs/job-runner.js +28 -1
  441. package/template/wall-e/lib/brain-owner-op-priority.js +9 -1
  442. package/template/wall-e/lib/ctm-data-dir.js +26 -0
  443. package/template/wall-e/lib/derivation-home.js +147 -0
  444. package/template/wall-e/lib/helper-rules/evaluate.js +50 -9
  445. package/template/wall-e/lib/helper-rules/grade.js +51 -8
  446. package/template/wall-e/lib/helper-rules/lead-call-hook.js +38 -5
  447. package/template/wall-e/lib/helper-rules/store.js +4 -2
  448. package/template/wall-e/lib/landing-mcp-tools.js +170 -0
  449. package/template/wall-e/lib/mcp-client-config.js +133 -14
  450. package/template/wall-e/lib/mcp-gateway-migrate.js +28 -64
  451. package/template/wall-e/lib/mcp-integration.js +58 -13
  452. package/template/wall-e/lib/parent-death.js +7 -1
  453. package/template/wall-e/lib/scheduler-worker-jobs.js +6 -4
  454. package/template/wall-e/llm/delegate-lead-prefs.js +16 -1
  455. package/template/wall-e/llm/delegate-vendor-default.js +12 -5
  456. package/template/wall-e/llm/model-roles.js +1 -1
  457. package/template/wall-e/llm/native-delegate-selection.js +56 -8
  458. package/template/wall-e/llm/worker-delegate-args.js +72 -7
  459. package/template/wall-e/llm/worker-mcp-routing.js +66 -17
  460. package/template/wall-e/loops/brain-custom-writes.js +19 -0
  461. package/template/wall-e/loops/ingest.js +17 -1
  462. package/template/wall-e/loops/think.js +19 -4
  463. package/template/wall-e/mcp-contract.js +222 -6
  464. package/template/wall-e/mcp-protocol-contract.js +40 -5
  465. package/template/wall-e/mcp-server.js +128 -29
  466. package/template/wall-e/mcp-worker-schemas.js +5 -5
  467. package/template/wall-e/memory/ctm-context-client.js +85 -0
  468. package/template/wall-e/memory/ctm-session-context.js +9 -3
  469. package/template/wall-e/memory/hub-bridge-client.js +388 -0
  470. package/template/wall-e/memory/replica-origin.js +56 -0
  471. package/template/wall-e/memory/session-pool.js +135 -0
  472. package/template/wall-e/runtime/live-capabilities.js +8 -3
  473. package/template/wall-e/server.js +4 -2
  474. package/template/wall-e/shared/release-schema.json +2 -2
  475. package/template/wall-e/shared/sqlite-file-set.js +39 -0
  476. package/template/wall-e/shared/storage/contract.js +3 -0
  477. package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
  478. package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +7 -1
  479. package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +4 -4
  480. package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +6 -6
  481. package/template/wall-e/skills/_templates/fleet-sync/VERSION +1 -0
  482. package/template/wall-e/skills/_templates/fleet-sync/released-sha256.json +16 -0
  483. package/template/wall-e/skills/_templates/fleet-sync/templates/claude/SKILL.md +64 -0
  484. package/template/wall-e/skills/_templates/fleet-sync/templates/codex/SKILL.md +64 -0
  485. package/template/wall-e/tools/chrome-automation.js +6 -0
  486. package/template/wall-e/training/setup-cuda-train-env.sh +2 -2
  487. package/template/wall-e/workers/brain-owner-worker.js +18 -4
  488. package/template/wall-e/workers/mcp-gateway-process.js +5 -5
@@ -6,6 +6,11 @@ const { MAX_BATCH_BYTES, jsonByteLength, batchEntriesByBytes } = require('./sync
6
6
  // WP-0 (remote-machine-hub-sessions-2026-10-22.html D-4): the machine registry's liveness probe
7
7
  // rides THIS tick rather than owning a timer, so the hub keeps exactly one outbound cadence.
8
8
  const machineRegistry = require('./machine-registry');
9
+ // WP-3 (docs/shared-memory-every-machine-2026-10-31.html D-1/D-2, §6.6): the v2 brain replica rides
10
+ // the SAME tick for the SAME members — membership is pairing (the registry), so `CTM_SYNC_PEERS`
11
+ // plays no part in the memory domains. The round is a leaf here (machine-registry only), so this
12
+ // edge adds no lib/** cycle.
13
+ const memorySync = require('./memory-sync');
9
14
 
10
15
  const DEFAULT_INTERVAL_MS = 15000;
11
16
  const DEFAULT_GAP_BACKOFF_MS = 5 * 60 * 1000;
@@ -445,269 +450,6 @@ async function pushSyncPeerOnce(options = {}) {
445
450
  };
446
451
  }
447
452
 
448
- // ---------------------------------------------------------------------------
449
- // WP-5 (multi-machine login/resume sync §6.6, R-10/R-11, S-15..S-18): brain
450
- // replication rides the SAME tick as the CTM legs but never the same failure
451
- // domain — a brain leg that fails (peer carries no walle url, Wall-E is down,
452
- // the peer 401s) must leave the CTM verdict of that tick alone and is reported
453
- // per peer in status().brain.
454
- //
455
- // pull: peer /api/walle/sync/outbox -> LOCAL Wall-E /api/walle/sync/apply
456
- // push: local /api/walle/sync/outbox -> peer /api/walle/sync/apply
457
- //
458
- // The cursors are the settings rows `sync.brain_pull.<peer>` / `sync.brain_push.<peer>`.
459
- // A brain cursor is deliberately NOT recorded through `markSyncOutboxDeliveredThrough`:
460
- // that mutation also stamps the GLOBAL `sync_outbox.delivered_at`, which would hide CTM
461
- // rows from the other peers (F4).
462
- // ---------------------------------------------------------------------------
463
-
464
- const DEFAULT_BRAIN_BATCH_LIMIT = 200;
465
-
466
- // peer.walleUrl is the explicit form (the JSON form of CTM_SYNC_PEERS can carry it);
467
- // otherwise Wall-E is CTM's port + 1 — 3456/3457 on the laptop, 3556/3557 through the
468
- // SSH forwards.
469
- function _wallePeerUrl(peer = {}, walle = {}) {
470
- const explicit = _string(walle.peerUrl || peer.walleUrl || peer.walle_url, 1000).replace(/\/+$/, '');
471
- if (explicit) return explicit;
472
- const baseUrl = _string(peer.url, 1000).replace(/\/+$/, '');
473
- if (!baseUrl) return '';
474
- try {
475
- const parsed = new URL(baseUrl);
476
- const port = Number(parsed.port || (parsed.protocol === 'https:' ? 443 : 80));
477
- if (!Number.isFinite(port) || port <= 0) return '';
478
- parsed.port = String(port + 1);
479
- return parsed.toString().replace(/\/+$/, '');
480
- } catch {
481
- return '';
482
- }
483
- }
484
-
485
- // WALL_E_PORT is the knob the rest of CTM resolves the local Wall-E with; an explicit
486
- // '0' means "this host has no local Wall-E" and disables the local half of the brain pair.
487
- function _localWalleUrl(env = {}, walle = {}) {
488
- const explicit = _string(walle.localUrl, 1000).replace(/\/+$/, '');
489
- if (explicit) return explicit;
490
- const raw = env.WALL_E_PORT;
491
- if (raw !== undefined && String(raw).trim() === '0') return '';
492
- return `http://127.0.0.1:${Number(raw || 0) || 3457}`;
493
- }
494
-
495
- function _brainHeaders(env) {
496
- return { ..._authHeaders(env), Accept: 'application/json', 'Content-Type': 'application/json' };
497
- }
498
-
499
- function _brainCursorKey(direction, peerKey) {
500
- return `sync.brain_${direction === 'push' ? 'push' : 'pull'}.${_string(peerKey, 160)}`;
501
- }
502
-
503
- function _readBrainCursor(db, key) {
504
- if (!db || typeof db.getSetting !== 'function') return 0;
505
- try {
506
- return Math.max(0, Number(db.getSetting(key, 0)) || 0);
507
- } catch {
508
- return 0;
509
- }
510
- }
511
-
512
- // Best-effort: a cursor that fails to persist costs a re-send next tick, and the
513
- // operation_id keyed by the receiver makes the re-send idempotent.
514
- async function _writeBrainCursor(db, key, seq) {
515
- if (!db || typeof db.setSetting !== 'function') return false;
516
- try {
517
- await dispatchOwnerMutation(db, 'setSetting', [key, String(seq)], 'hosted sync brain cursor');
518
- return true;
519
- } catch {
520
- return false;
521
- }
522
- }
523
-
524
- function _brainBatchLimit(env = {}, options = {}, walle = {}) {
525
- // No new flag: the brain legs page with the same CTM_SYNC_BATCH_LIMIT knob the
526
- // CTM legs already use (default 200 rows for brain, see DEFAULT_BRAIN_BATCH_LIMIT).
527
- const raw = env.CTM_SYNC_BATCH_LIMIT || walle.limit || options.brainLimit || DEFAULT_BRAIN_BATCH_LIMIT;
528
- return Math.max(1, Math.min(1000, Number(raw) || DEFAULT_BRAIN_BATCH_LIMIT));
529
- }
530
-
531
- function _brainMaxBatches(env = {}, options = {}) {
532
- return Math.max(1, Math.min(100, Number(env.CTM_SYNC_MAX_BATCHES || options.maxBatches || 20) || 20));
533
- }
534
-
535
- // The copy loop both directions share: page from `fromUrl`, hand the page to `toUrl`,
536
- // advance the cursor only as far as the receiver accepted.
537
- async function _copyBrainEntries({ fromUrl, toUrl, sourceInstanceId, headers, fetchImpl, db, cursorKey, limit, maxBatches }) {
538
- let afterSeq = _readBrainCursor(db, cursorKey);
539
- let moved = 0;
540
- let batches = 0;
541
- let parked = false;
542
- // Follow-up #16: the source's history-backfill progress and live backlog, as of the last page read.
543
- let backfill = null;
544
- let pending = null;
545
- while (batches < maxBatches) {
546
- const page = await _jsonFetch(fetchImpl, `${fromUrl}/api/walle/sync/outbox?after_seq=${afterSeq}&limit=${limit}`, { headers });
547
- if (page.backfill && typeof page.backfill === 'object') backfill = page.backfill;
548
- if (Number.isFinite(Number(page.pending))) pending = Number(page.pending);
549
- const entries = Array.isArray(page.entries) ? page.entries : [];
550
- if (!entries.length) break;
551
- batches += 1;
552
- const tailSeq = entries.reduce((max, entry) => Math.max(max, Number(entry.seq) || 0), 0);
553
- const applied = await _jsonFetch(fetchImpl, `${toUrl}/api/walle/sync/apply`, {
554
- method: 'POST',
555
- headers,
556
- body: JSON.stringify({ sourceInstanceId, entries }),
557
- });
558
- const next = Math.max(afterSeq, Number(applied.lastSeq ?? page.lastSeq ?? 0) || 0);
559
- // The receiver reports how far it got (its lastSeq). A receiver that stops short of
560
- // the batch tail is defensive only — the Wall-E apply route settles every row it is
561
- // given — so the cursor never steps past what the receiver acknowledged.
562
- if (next <= afterSeq) {
563
- parked = true;
564
- break;
565
- }
566
- await _writeBrainCursor(db, cursorKey, next);
567
- moved += entries.filter((entry) => Number(entry.seq) <= next).length;
568
- afterSeq = next;
569
- if (next < tailSeq) {
570
- parked = true;
571
- break;
572
- }
573
- if (entries.length < limit) break;
574
- }
575
- return { moved, batches, lastSeq: afterSeq, parked, backfill, pending };
576
- }
577
-
578
- async function pullBrainOnce(options = {}) {
579
- const env = options.env || process.env;
580
- const peer = options.peer || {};
581
- const walle = options.walle || {};
582
- const db = options.db;
583
- const fetchImpl = options.fetch || global.fetch;
584
- if (!db) throw new Error('db required');
585
- if (typeof fetchImpl !== 'function') throw new Error('fetch required');
586
- const peerUrl = _wallePeerUrl(peer, walle);
587
- if (!peerUrl) throw new Error('peer_walle_url_required');
588
- const localUrl = _localWalleUrl(env, walle);
589
- if (!localUrl) throw new Error('local_walle_url_required');
590
- const peerKey = _peerIdentity(peer) || _string(peer.url, 1000);
591
- // The source identity the LOCAL Wall-E files this peer under is the peer's own id,
592
- // so the local brain_sync_hwm row names the peer that produced the rows.
593
- const copy = await _copyBrainEntries({
594
- fromUrl: peerUrl,
595
- toUrl: localUrl,
596
- sourceInstanceId: peerKey,
597
- headers: _brainHeaders(env),
598
- fetchImpl,
599
- db,
600
- cursorKey: _brainCursorKey('pull', peerKey),
601
- limit: _brainBatchLimit(env, options, walle),
602
- maxBatches: _brainMaxBatches(env, options),
603
- });
604
- return {
605
- ok: true,
606
- peer: peerKey,
607
- direction: 'pull',
608
- walleUrl: peerUrl,
609
- fetched: copy.moved,
610
- batches: copy.batches,
611
- lastSeq: copy.lastSeq,
612
- parked: copy.parked,
613
- backfill: copy.backfill,
614
- pending: copy.pending,
615
- };
616
- }
617
-
618
- async function pushBrainOnce(options = {}) {
619
- const env = options.env || process.env;
620
- const peer = options.peer || {};
621
- const walle = options.walle || {};
622
- const db = options.db;
623
- const fetchImpl = options.fetch || global.fetch;
624
- if (!db) throw new Error('db required');
625
- if (typeof fetchImpl !== 'function') throw new Error('fetch required');
626
- const peerUrl = _wallePeerUrl(peer, walle);
627
- if (!peerUrl) throw new Error('peer_walle_url_required');
628
- const localUrl = _localWalleUrl(env, walle);
629
- if (!localUrl) throw new Error('local_walle_url_required');
630
- const localInstanceId = _localInstanceId(db, env);
631
- if (!localInstanceId) throw new Error('sync_local_instance_required');
632
- const peerKey = _peerIdentity(peer) || _string(peer.url, 1000);
633
- const copy = await _copyBrainEntries({
634
- fromUrl: localUrl,
635
- toUrl: peerUrl,
636
- sourceInstanceId: localInstanceId,
637
- headers: _brainHeaders(env),
638
- fetchImpl,
639
- db,
640
- cursorKey: _brainCursorKey('push', peerKey),
641
- limit: _brainBatchLimit(env, options, walle),
642
- maxBatches: _brainMaxBatches(env, options),
643
- });
644
- return {
645
- ok: true,
646
- peer: peerKey,
647
- direction: 'push',
648
- walleUrl: peerUrl,
649
- pushed: copy.moved,
650
- batches: copy.batches,
651
- lastSeq: copy.lastSeq,
652
- parked: copy.parked,
653
- backfill: copy.backfill,
654
- pending: copy.pending,
655
- };
656
- }
657
-
658
- // Runs both directions for one peer, isolating each from the other and from the CTM
659
- // legs: the return value is always a report, never a throw.
660
- async function syncPeerBrainOnce(options = {}) {
661
- const peer = options.peer || {};
662
- const peerKey = _peerIdentity(peer) || _string(peer.url, 1000);
663
- const report = { peer: peerKey, ok: true, pull: null, push: null };
664
- for (const [direction, fn] of [['pull', pullBrainOnce], ['push', pushBrainOnce]]) {
665
- try {
666
- report[direction] = await fn(options);
667
- } catch (err) {
668
- report[direction] = {
669
- ok: false,
670
- peer: peerKey,
671
- direction,
672
- error: err.message || String(err),
673
- status: Number(err.status || 0) || null,
674
- };
675
- report.ok = false;
676
- }
677
- }
678
- return report;
679
- }
680
-
681
- // Follow-up #17: local outbox retention. Called only after a tick in which EVERY configured peer's
682
- // brain push leg ended ok; `pushReports` are those legs' reports. The push leg is what delivers
683
- // every local outbox row to each peer, so the prune point is the minimum persisted push cursor
684
- // (`sync.brain_push.<peer>`) — a peer's pull of our outbox is redundant delivery and does not
685
- // count. One bounded call per tick (the Wall-E side deletes at most 5,000 rows and says `more`).
686
- async function pruneLocalBrainOutbox(options = {}) {
687
- const env = options.env || process.env;
688
- const walle = options.walle || {};
689
- const db = options.db;
690
- const fetchImpl = options.fetch || global.fetch;
691
- const pushReports = Array.isArray(options.pushReports) ? options.pushReports : [];
692
- if (!pushReports.length) return { ok: true, skipped: 'no_peers', throughSeq: 0, pruned: 0 };
693
- const localUrl = _localWalleUrl(env, walle);
694
- if (!localUrl) return { ok: true, skipped: 'no_local_walle', throughSeq: 0, pruned: 0 };
695
- const throughSeq = Math.min(...pushReports.map((push) => _readBrainCursor(db, _brainCursorKey('push', push.peer))));
696
- if (!(throughSeq > 0)) return { ok: true, skipped: 'nothing_delivered', throughSeq: 0, pruned: 0 };
697
- const res = await _jsonFetch(fetchImpl, `${localUrl}/api/walle/sync/prune`, {
698
- method: 'POST',
699
- headers: _brainHeaders(env),
700
- body: JSON.stringify({ throughSeq }),
701
- });
702
- return {
703
- ok: true,
704
- throughSeq,
705
- pruned: Number(res.pruned || 0) || 0,
706
- more: res.more === true,
707
- appliedPruned: Number(res.appliedPruned || 0) || 0,
708
- };
709
- }
710
-
711
453
  function _failureDelayMs(env, options, intervalMs, attempt) {
712
454
  const base = Math.max(1000, Number(env.CTM_SYNC_FAILURE_BACKOFF_MS || options.failureBackoffMs || intervalMs) || intervalMs);
713
455
  const max = Math.max(base, Number(env.CTM_SYNC_FAILURE_BACKOFF_MAX_MS || options.failureBackoffMaxMs || 60 * 1000) || 60 * 1000);
@@ -719,7 +461,7 @@ function _failureDelayMs(env, options, intervalMs, attempt) {
719
461
  // WP-0 (remote-machine-hub-sessions-2026-10-22.html §8): the machine-registry sweep, plus the WP-6
720
462
  // live-catalog refresh riding it. Shared by the sync tick and the machines-only loop below; a
721
463
  // probe failure is reported, never thrown, and never folded into a sync verdict.
722
- async function _sweepMachines({ db, fetchImpl, env, peerHeadersFor, selfInstanceId }) {
464
+ async function _sweepMachines({ db, fetchImpl, env, peerHeadersFor, selfInstanceId, walleClient }) {
723
465
  try {
724
466
  const machineProbe = await machineRegistry.probeMachinesOnce({ fetchImpl }, {
725
467
  db,
@@ -737,7 +479,37 @@ async function _sweepMachines({ db, fetchImpl, env, peerHeadersFor, selfInstance
737
479
  try {
738
480
  require('./remote-machine-catalog').refreshAll({ db }).catch(() => { /* expected: refreshAll resolves its own per-machine failures */ });
739
481
  } catch { /* expected: a catalog fault must never fail a machine probe sweep */ }
740
- return machineProbe;
482
+ // WP-2 (docs/fleet-auto-update-pooled-machines-2026-10-26.html §8 WP-2, §9 S-8): the fleet
483
+ // reconciler rides the same sweep — deliberately NOT awaited, because its bundle POST may take up
484
+ // to FLEET_SEND_TIMEOUT_MS and the tick's cadence must not be held hostage by one box. Only when
485
+ // the server injected a real per-target credential: the fixed env-token fallback cannot update a
486
+ // box (a pool member authenticates with the pool secret), so firing it would only produce refusals.
487
+ if (typeof peerHeadersFor === 'function') {
488
+ try {
489
+ require('./fleet-hub').reconcileFleetOnce({ db, fetchImpl, peerHeadersFor, dataDir: require('./data-dir').getDataDir() })
490
+ .catch((err) => console.warn(`[fleet] reconcile failed: ${err.message || err}`)); // REPORT: the next sweep retries
491
+ } catch (err) {
492
+ console.warn(`[fleet] reconcile not started: ${err.message || err}`); // REPORT: a wiring fault must never fail a probe sweep
493
+ }
494
+ }
495
+ // WP-3 (D-1/D-2, §6.6): the v2 brain replica rides the SAME sweep, for the SAME registry members
496
+ // and on the SAME per-target credential — `CTM_SYNC_PEERS` is irrelevant to the memory domains,
497
+ // so this runs in BOTH the peers loop and the machines-only loop. AWAITED (the probe read is
498
+ // already done by now, and the tick owns the cadence) but its failure is REPORTED into the sweep
499
+ // result as `brainSync`, never folded into the probe verdict.
500
+ let brainSync = null;
501
+ try {
502
+ brainSync = await memorySync.runBrainMemberRound({
503
+ db, fetchImpl, env, peerHeadersFor, selfInstanceId,
504
+ // Tests inject a stub; production omits it and lib/memory-sync.js takes the co-located
505
+ // lib/walle-client (the hub's own loopback Wall-E).
506
+ ...(walleClient ? { walle: walleClient } : {}),
507
+ });
508
+ } catch (brainErr) {
509
+ // REPORT: surfaced as status().machines.brainSync; the next tick retries with backoff.
510
+ brainSync = { ok: false, error: brainErr.message || String(brainErr) };
511
+ }
512
+ return { ...machineProbe, brainSync };
741
513
  } catch (probeErr) {
742
514
  // REPORT: surfaced as status().machines / lastResult.machineProbe; the next tick retries.
743
515
  return { ok: false, error: probeErr.message || String(probeErr) };
@@ -749,7 +521,7 @@ async function _sweepMachines({ db, fetchImpl, env, peerHeadersFor, selfInstance
749
521
  // surfaces read that as "sync off"), but the registered machines are still probed on the same
750
522
  // cadence — otherwise a machine's health would freeze at whatever registration recorded and a
751
523
  // stopped box would read "reachable" forever. Zero registered machines => zero fetches (AC-0d).
752
- function _startMachinesOnlyLoop({ db, fetchImpl, intervalMs, env, peerHeadersFor, selfInstanceId }) {
524
+ function _startMachinesOnlyLoop({ db, fetchImpl, intervalMs, env, peerHeadersFor, selfInstanceId, walleClient }) {
753
525
  let running = false;
754
526
  let stopped = false;
755
527
  let machineProbe = null;
@@ -757,7 +529,7 @@ function _startMachinesOnlyLoop({ db, fetchImpl, intervalMs, env, peerHeadersFor
757
529
  if (running || stopped) return;
758
530
  running = true;
759
531
  try {
760
- machineProbe = await _sweepMachines({ db, fetchImpl, env, peerHeadersFor, selfInstanceId });
532
+ machineProbe = await _sweepMachines({ db, fetchImpl, env, peerHeadersFor, selfInstanceId, walleClient });
761
533
  } finally {
762
534
  running = false;
763
535
  }
@@ -786,9 +558,9 @@ function startHostedSyncWorker(options = {}) {
786
558
  const fetchImpl = options.fetch || global.fetch;
787
559
  const intervalMs = Math.max(1000, Number(env.CTM_SYNC_POLL_INTERVAL_MS || options.intervalMs || DEFAULT_INTERVAL_MS) || DEFAULT_INTERVAL_MS);
788
560
  // R-12: "peers configured" is the gate (there is no separate enable flag any more).
789
- if (!syncEnabledByConfig(env)) return _startMachinesOnlyLoop({ db, fetchImpl, intervalMs, env, peerHeadersFor: options.peerHeadersFor, selfInstanceId: options.selfInstanceId });
561
+ if (!syncEnabledByConfig(env)) return _startMachinesOnlyLoop({ db, fetchImpl, intervalMs, env, peerHeadersFor: options.peerHeadersFor, selfInstanceId: options.selfInstanceId, walleClient: options.walleClient });
790
562
  const peers = options.peers || parseSyncPeers(env);
791
- if (!peers.length) return _startMachinesOnlyLoop({ db, fetchImpl, intervalMs, env, peerHeadersFor: options.peerHeadersFor, selfInstanceId: options.selfInstanceId });
563
+ if (!peers.length) return _startMachinesOnlyLoop({ db, fetchImpl, intervalMs, env, peerHeadersFor: options.peerHeadersFor, selfInstanceId: options.selfInstanceId, walleClient: options.walleClient });
792
564
  // WP-0 (§8 "seed-from-CTM_SYNC_PEERS"): this worker starts exactly once per boot, which makes
793
565
  // it the hub's seeding hook. Every configured peer that is not yet in the registry becomes a
794
566
  // DISABLED machines row — env is a seed, never an authority, so nothing is auto-enabled or
@@ -813,15 +585,6 @@ function startHostedSyncWorker(options = {}) {
813
585
  const prev = pushState.get(peerKey) || { peer: peerKey, lastAttemptAt: null, lastOkAt: null, lastDeliveredSeq: 0, lastError: null };
814
586
  pushState.set(peerKey, { ...prev, ...patch });
815
587
  };
816
- // WP-5: the brain pair (memories/knowledge/entities/people) keeps its own state so a
817
- // failure there is visible in status().brain without ever marking the CTM legs failed.
818
- const brainState = new Map();
819
- const _recordBrain = (peerKey, patch) => {
820
- const prev = brainState.get(peerKey) || { peer: peerKey, lastAttemptAt: null, lastOkAt: null, lastSeq: 0, lastError: null, pull: null, push: null, backfill: null };
821
- brainState.set(peerKey, { ...prev, ...patch });
822
- };
823
- // Follow-up #17: the last local outbox prune (null until one is attempted).
824
- let brainPrune = null;
825
588
  // WP-0: the last machine-registry sweep (null until one is attempted). Reported, never folded
826
589
  // into the sync verdict.
827
590
  let machineProbe = null;
@@ -872,26 +635,6 @@ function startHostedSyncWorker(options = {}) {
872
635
  lastError: pushErr.message || String(pushErr),
873
636
  });
874
637
  }
875
- // WP-5: the brain legs run in the same tick and are independent of the CTM push
876
- // outcome above — `result.ok` is only ever set false by the CTM legs, so a failed
877
- // brain leg is reported (status().brain) without failing the CTM leg's verdict.
878
- const brain = await syncPeerBrainOnce({ peer, db, env, fetch: fetchImpl, ...(options.brain || {}) });
879
- result.brain = brain;
880
- const attemptAt = new Date().toISOString();
881
- _recordBrain(peerKey, {
882
- lastAttemptAt: attemptAt,
883
- lastOkAt: brain.ok ? attemptAt : (brainState.get(peerKey)?.lastOkAt || null),
884
- lastSeq: Math.max(Number(brain.pull?.lastSeq || 0) || 0, Number(brain.push?.lastSeq || 0) || 0),
885
- lastError: brain.ok ? null : (brain.pull?.error || brain.push?.error || 'brain_sync_failed'),
886
- pull: brain.pull,
887
- push: brain.push,
888
- // Follow-up #16: history-backfill progress per side — `local` is this host's brain (read
889
- // by the push leg), `peer` the peer's brain (read by the pull leg).
890
- backfill: {
891
- local: brain.push?.backfill || brainState.get(peerKey)?.backfill?.local || null,
892
- peer: brain.pull?.backfill || brainState.get(peerKey)?.backfill?.peer || null,
893
- },
894
- });
895
638
  }
896
639
  results.push(result);
897
640
  if (result.ok === false) {
@@ -904,27 +647,13 @@ function startHostedSyncWorker(options = {}) {
904
647
  nextPollAt.delete(peerKey);
905
648
  }
906
649
  }
907
- // Follow-up #17: prune the local outbox only when every configured peer's brain push leg ran
908
- // and ended ok in THIS tick (a skipped/backed-off peer has no push leg, so it blocks the
909
- // prune). A prune failure is reported and never fails the tick.
910
- const pushReports = results.map((r) => r?.brain?.push);
911
- let pruneReport = null;
912
- if (peers.length && pushReports.length === peers.length && pushReports.every((push) => push && push.ok === true)) {
913
- try {
914
- pruneReport = await pruneLocalBrainOutbox({ db, env, fetch: fetchImpl, pushReports, ...(options.brain || {}) });
915
- } catch (pruneErr) {
916
- // REPORT: surfaced as status().brainPrune / lastResult.brainPrune; the rows stay and the next tick retries.
917
- pruneReport = { ok: false, error: pruneErr.message || String(pruneErr), status: Number(pruneErr.status || 0) || null };
918
- }
919
- brainPrune = { ...pruneReport, lastAttemptAt: new Date().toISOString() };
920
- }
921
650
  // WP-0 (remote-machine-hub-sessions-2026-10-22.html §8): the machine-registry sweep rides
922
651
  // this tick, AFTER the peer legs and independent of them — it shares the cadence (D-4) but
923
652
  // not the verdict, so a probe failure never marks a sync leg failed. Zero registered
924
653
  // machines ⇒ zero fetches (AC-0d), so an instance with no machines performs no extra
925
654
  // network work per tick.
926
- machineProbe = await _sweepMachines({ db, fetchImpl, env, peerHeadersFor: options.peerHeadersFor, selfInstanceId: options.selfInstanceId });
927
- lastResult = { ok: results.every((r) => r.ok !== false), checkedAt: new Date().toISOString(), results, brainPrune: pruneReport, machineProbe };
655
+ machineProbe = await _sweepMachines({ db, fetchImpl, env, peerHeadersFor: options.peerHeadersFor, selfInstanceId: options.selfInstanceId, walleClient: options.walleClient });
656
+ lastResult = { ok: results.every((r) => r.ok !== false), checkedAt: new Date().toISOString(), results, machineProbe };
928
657
  } catch (err) {
929
658
  lastResult = { ok: false, checkedAt: new Date().toISOString(), error: err.message || String(err) };
930
659
  } finally {
@@ -950,8 +679,6 @@ function startHostedSyncWorker(options = {}) {
950
679
  running,
951
680
  lastResult,
952
681
  push: [...pushState.values()],
953
- brain: [...brainState.values()],
954
- brainPrune,
955
682
  machines: machineProbe,
956
683
  machineSeed,
957
684
  };
@@ -964,9 +691,5 @@ module.exports = {
964
691
  syncEnabledByConfig,
965
692
  pollSyncPeerOnce,
966
693
  pushSyncPeerOnce,
967
- pullBrainOnce,
968
- pushBrainOnce,
969
- syncPeerBrainOnce,
970
- pruneLocalBrainOutbox,
971
694
  startHostedSyncWorker,
972
695
  };