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
@@ -15,6 +15,8 @@ const { codexProxyProviderArgs } = require('../codex-launch-health');
15
15
  const { prepareHarnessModelProfile, ADAPTER_VERSION } = require('../harness-model-profile');
16
16
  const { WORKER_MODEL_ALIAS } = require('../model-proxy/lead-worker-picks');
17
17
  const { modelExecutionRecipeMetadata } = require('../model-execution-recipe-metadata');
18
+ const { leadWireAgent } = require('../lead-wire-agent');
19
+ const { opencodeLeadProvider, OPENCODE_LEAD_PROVIDER_ID, OPENCODE_LEAD_MODEL_REF } = require('./opencode-lead-provider');
18
20
  const nativeLeadLifetime = require('./native-lead-lifetime');
19
21
 
20
22
  const READINESS_BUDGET_MS = 12000;
@@ -110,6 +112,105 @@ function _nativePrepareReason(prepared) {
110
112
  return 'native_settings_prepare_failed';
111
113
  }
112
114
 
115
+ // §5 D-5/D-6 (WP-2, S7): the FINITE failure vocabulary for a native adoption. At base both channels
116
+ // collapsed into one generic reason, so a refused PROXY replay read as a settings failure. Every field is
117
+ // a fixed literal or an EXACT member of a code table this build exports, so an exception message, token,
118
+ // PEM or settings path can only ever map to `unknown`.
119
+ const NATIVE_ADOPTION_STAGE_SETTINGS = 'settings';
120
+ const NATIVE_ADOPTION_STAGE_PROXY = 'proxy';
121
+ const NATIVE_ADOPTION_UNKNOWN = 'unknown';
122
+ // The one generic reason a failed mTLS verification still returns to its caller (unchanged from base, so
123
+ // the claim contract is compatible). It is a NAMED constant because the claim-failure branch below uses it
124
+ // to recognise "the finite diagnostic for this failure was already emitted" — one shared verification, one
125
+ // diagnostic — and a bare literal in two places would drift.
126
+ const NATIVE_ADOPTION_GENERIC_REASON = 'native_settings_adopt_failed';
127
+ // The reasons `oauth-proxy-supervisor.adoptLeadToken` can refuse with (`_normalizeLeadRegistration`,
128
+ // `_registerLeadTokenIntoChild`) — plus `unknown` for anything else.
129
+ const NATIVE_ADOPTION_PROXY_REASONS = new Set([
130
+ 'proxy_unavailable', 'admin_rejected', 'revoked', 'invalid_token',
131
+ 'invalid_binding', 'missing_exact_binding', 'conflicting_binding',
132
+ ]);
133
+ // The two underlying codes worth naming as a CAUSE: a handoff that closed the listener this attempt was
134
+ // talking to, and a token the registry already tombstoned. Exact matching only.
135
+ const NATIVE_ADOPTION_CAUSES = new Set(['native_lead_listener_closed', 'lead_token_revoked']);
136
+
137
+ // The settings allowlist is built from the EXPORTED code tables of the settings/client modules, with one
138
+ // LITERAL specifier per table (never computed). Those modules are invariants of this build: a missing table
139
+ // throws here rather than silently shrinking the allowlist.
140
+ let _nativeAdoptionSettingsReasons = null;
141
+ function _nativeSettingsReasons() {
142
+ if (!_nativeAdoptionSettingsReasons) {
143
+ _nativeAdoptionSettingsReasons = new Set([
144
+ ...Object.values(require('../native-lead-settings').NATIVE_LEAD_SETTINGS_CODES),
145
+ ...Object.values(require('../native-lead-tls').NATIVE_LEAD_TLS_CODES),
146
+ ...Object.values(require('../native-lead-settings-client').NATIVE_LEAD_SETTINGS_CLIENT_CODES),
147
+ ]);
148
+ }
149
+ return _nativeAdoptionSettingsReasons;
150
+ }
151
+
152
+ // §5 D-6: the CAUSE is the underlying condition, and it is read from every bounded carrier the two channels
153
+ // actually use: a thrown error's `code`/`cause`, and the supervisor's `error` field (the refusal object
154
+ // carries the listener/tombstone code there: `{ok:false, reason:'admin_rejected', error:'native_lead_listener_closed'}`).
155
+ // Each candidate is EXACT-matched against the two-member allowlist, so a free-form exception message or any
156
+ // other caller text can only ever map to `unknown` — nothing is echoed.
157
+ function _adoptionCause(...values) {
158
+ for (const value of values) {
159
+ if (typeof value === 'string' && NATIVE_ADOPTION_CAUSES.has(value)) return value;
160
+ }
161
+ return NATIVE_ADOPTION_UNKNOWN;
162
+ }
163
+
164
+ function _adoptionSettingsReason(...values) {
165
+ const allowlist = _nativeSettingsReasons();
166
+ for (const value of values) {
167
+ if (typeof value === 'string' && allowlist.has(value)) return value;
168
+ }
169
+ return NATIVE_ADOPTION_UNKNOWN;
170
+ }
171
+
172
+ function _adoptionProxyReason(...values) {
173
+ for (const value of values) {
174
+ if (typeof value === 'string' && NATIVE_ADOPTION_PROXY_REASONS.has(value)) return value;
175
+ }
176
+ return NATIVE_ADOPTION_UNKNOWN;
177
+ }
178
+
179
+ /**
180
+ * §5 D-6 (WP-2, S7): the ONE bounded diagnostic per failed native adoption. `stage` says which channel
181
+ * refused, `reason` is an allowlisted code for that stage, and `cause` names the underlying condition when
182
+ * it is exactly one of the two known ones. Nothing here is interpolated from an exception, a token, a PEM
183
+ * or a settings reference; the session id is truncated like every other launcher line.
184
+ */
185
+ function _emitNativeAdoptionFailure(sessionId, failure) {
186
+ const line = `[lead-route] native adoption failed session=${String(sessionId ?? '').slice(0, 64)}`
187
+ + ` stage=${failure.stage} reason=${failure.reason} cause=${failure.cause}\n`;
188
+ process.stderr.write(line);
189
+ return failure;
190
+ }
191
+
192
+ // The two channels, each with its own allowlist. A settings verification reports one bounded code and the
193
+ // two vocabularies are disjoint, so it is offered to both.
194
+ function _emitNativeSettingsFailure(sessionId, code) {
195
+ return _emitNativeAdoptionFailure(sessionId, {
196
+ stage: NATIVE_ADOPTION_STAGE_SETTINGS,
197
+ reason: _adoptionSettingsReason(code),
198
+ cause: _adoptionCause(code),
199
+ });
200
+ }
201
+
202
+ // `{ reason: [...], cause: [...] }` — the refusal's own code(s) vs the underlying condition code(s). The
203
+ // lists are DELIBERATELY separate: only a refusal's own reason may name a reason, while `error` is eligible
204
+ // as a cause ONLY — so free-form text can never be promoted into a semantic reason, and a reason word
205
+ // arriving in `error` (e.g. `'revoked'`) stays `unknown`.
206
+ function _emitNativeProxyFailure(sessionId, { reason = [], cause = [] } = {}) {
207
+ return _emitNativeAdoptionFailure(sessionId, {
208
+ stage: NATIVE_ADOPTION_STAGE_PROXY,
209
+ reason: _adoptionProxyReason(...reason),
210
+ cause: _adoptionCause(...cause),
211
+ });
212
+ }
213
+
113
214
  // §6.3/§6.4 item 2: the fence every awaited boundary re-checks. It is the coordinator's PURE
114
215
  // current-generation accessor when the caller supplies one (the server's provider deps do); without
115
216
  // one this is a no-op fence, exactly as before, so existing callers keep their current semantics.
@@ -258,10 +359,15 @@ async function prepareLeadRoute(target = {}, deps = {}) {
258
359
  const { sessionId, agent, routeId, model, plannedGeneration, transitionId } = target;
259
360
  if (!Number.isSafeInteger(plannedGeneration) || plannedGeneration < 1) return { ok: false, reason: 'lead_generation_unavailable' };
260
361
 
362
+ // §5 R-1 / §6.1: an OpenCode lead speaks the claude wire (anthropic face), so route servability
363
+ // and the per-agent execution profile are asked of 'claude' -- never of 'opencode'. This is the
364
+ // ONE mapping (lib/lead-wire-agent.js); Claude and Codex map to themselves unchanged.
365
+ const wireAgent = leadWireAgent(agent);
366
+
261
367
  let r = target.resolvedRoute || null;
262
368
  if (!r) {
263
369
  try {
264
- r = await readiness.resolveRoute({ route: routeId, model, agent, signal: target.signal });
370
+ r = await readiness.resolveRoute({ route: routeId, model, agent: wireAgent, signal: target.signal });
265
371
  } catch (err) {
266
372
  if (err instanceof DelegateError) {
267
373
  const map = {
@@ -289,7 +395,7 @@ async function prepareLeadRoute(target = {}, deps = {}) {
289
395
  routeId: r.deployment.routeId,
290
396
  providerId: r.deployment.providerId,
291
397
  wireModelId: r.deployment.wireModelId,
292
- harness: agent === 'codex' ? 'codex-cli' : 'claude-code',
398
+ harness: wireAgent === 'codex' ? 'codex-cli' : 'claude-code',
293
399
  cliVersion: target.cliVersion,
294
400
  binaryPath: target.binaryPath,
295
401
  adapterVersion: target.adapterVersion || ADAPTER_VERSION,
@@ -361,11 +467,16 @@ async function prepareLeadRoute(target = {}, deps = {}) {
361
467
 
362
468
  // D-13: persist the token so a CTM restart that adopts this session can re-register it. A store
363
469
  // throw must never fail the launch -- the token is already live in the supervisor.
470
+ //
471
+ // §5 R-1 (WP-2): the row's `agent` column is the CLI WIRE the token serves, and the store's own
472
+ // contract admits exactly {'claude','codex'} (session-lead-route-store.js LEAD_AGENTS). An OpenCode
473
+ // lead speaks the claude wire, so it persists `agent: wireAgent` ('claude') -- never 'opencode',
474
+ // which the store refuses. Claude/Codex map to themselves, so their rows are byte-identical.
364
475
  try {
365
476
  const bindings = [{ alias: r.alias, wireModelId: r.deployment.wireModelId, harness, metadataRevision: r.deployment.factsRevision }];
366
477
  if (transitionId) {
367
478
  const staged = await store.stageSessionLeadToken({
368
- ctmSessionId: sessionId, agent, routeId, alias: r.alias, model, token, bindings,
479
+ ctmSessionId: sessionId, agent: wireAgent, routeId, alias: r.alias, model, token, bindings,
369
480
  generation: plannedGeneration, transitionId, expectedRevision: target.expectedRevision,
370
481
  sourceGeneration: target.sourceGeneration, profileFingerprint: profile.fingerprint,
371
482
  factsRevision: r.deployment.factsRevision,
@@ -376,7 +487,7 @@ async function prepareLeadRoute(target = {}, deps = {}) {
376
487
  return { ok: false, reason: 'transition_superseded' };
377
488
  }
378
489
  } else if (typeof deps.recordLeadRouteLaunchOwnership === 'function') {
379
- const recorded = await deps.recordLeadRouteLaunchOwnership({ ctmSessionId: sessionId, agent, routeId,
490
+ const recorded = await deps.recordLeadRouteLaunchOwnership({ ctmSessionId: sessionId, agent: wireAgent, routeId,
380
491
  alias: r.alias, model, token, bindings, profileFingerprint: profile.fingerprint,
381
492
  factsRevision: r.deployment.factsRevision, processGeneration: plannedGeneration,
382
493
  providerThreadId: target.providerThreadId || null, display: target.display || model,
@@ -387,7 +498,7 @@ async function prepareLeadRoute(target = {}, deps = {}) {
387
498
  }
388
499
  } else {
389
500
  await store.setSessionLeadToken({
390
- ctmSessionId: sessionId, agent, routeId, alias: r.alias, model, token, bindings,
501
+ ctmSessionId: sessionId, agent: wireAgent, routeId, alias: r.alias, model, token, bindings,
391
502
  profileFingerprint: profile.fingerprint, factsRevision: r.deployment.factsRevision,
392
503
  processGeneration: plannedGeneration, transitionId: null,
393
504
  providerThreadId: target.providerThreadId || null,
@@ -413,6 +524,37 @@ async function prepareLeadRoute(target = {}, deps = {}) {
413
524
  return { ok: true, token, env, argsTransform, alias: r.alias, model, profile, ownership };
414
525
  }
415
526
 
527
+ // §5 R-3/R-4/R-6, §6.2 (WP-2): the OpenCode last step. Codex gets a `-c model_providers.ctm-lead`
528
+ // block and Claude gets ANTHROPIC_BASE_URL env; OpenCode gets a `ctm-lead` provider entry that the
529
+ // spawn path merges into the SAME OPENCODE_CONFIG_CONTENT blob its subagent pick and Wall-E MCP
530
+ // server ride (subagent-pick.opencodeLeadRouteProjection). The token rides env only; the model ref
531
+ // is the FIXED `ctm-lead/lead` so a prompted 1.x tab's resumed conversation keeps its ref (R-4).
532
+ if (agent === 'opencode') {
533
+ const env = { CTM_LEAD_TOKEN: token };
534
+ const configPatch = {
535
+ provider: {
536
+ [OPENCODE_LEAD_PROVIDER_ID]: opencodeLeadProvider({
537
+ proxyPort: port,
538
+ alias: r.alias,
539
+ wireModelId: r.deployment.wireModelId,
540
+ display: target.display || model,
541
+ contextTokens: r.deployment.contextTokens || null,
542
+ maxOutputTokens: r.deployment.maxOutputTokens || null,
543
+ }),
544
+ },
545
+ model: OPENCODE_LEAD_MODEL_REF,
546
+ };
547
+ const argsTransform = (args) => {
548
+ const stripped = stripModelFlags(args);
549
+ // §5 R-4 / probe P-R4: OpenCode 2.x's TUI rejects `--model`, so the ref is injected only on the
550
+ // v1 line. An unknown line (peekOpencodeLine -> null) records nothing else and appends no flag.
551
+ const peekLine = typeof deps.peekOpencodeLine === 'function' ? deps.peekOpencodeLine : require('../opencode-cli').peekOpencodeLine; // test seam
552
+ let line = null; try { line = peekLine(); } catch { line = null; }
553
+ return line === 'v1' ? [...stripped, '--model', OPENCODE_LEAD_MODEL_REF] : stripped;
554
+ };
555
+ return { ok: true, token, env, configPatch, argsTransform, alias: r.alias, model, profile, ownership };
556
+ }
557
+
416
558
  const env = { ..._claudeEnv(base, token, model), ...(profile.contextEnv || {}) };
417
559
  const argsTransform = (args) => [...stripModelFlags(args), '--model', model];
418
560
  return { ok: true, token, env, argsTransform, alias: r.alias, model, profile, ownership };
@@ -914,12 +1056,16 @@ async function adoptLeadRouteForSession(sessionId, deps = {}, actual = {}) {
914
1056
  settingsRef: nativeFields.settingsRef,
915
1057
  });
916
1058
  if (!adoptedSettings || adoptedSettings.ok !== true || !adoptedSettings.lease) {
917
- return { ok: false, reason: 'native_settings_adopt_failed' };
1059
+ // §5 D-6 (WP-2, S7): the client's OWN exported code is the reason; anything else is `unknown`.
1060
+ _emitNativeSettingsFailure(sessionId, adoptedSettings && adoptedSettings.code);
1061
+ return { ok: false, reason: NATIVE_ADOPTION_GENERIC_REASON };
918
1062
  }
919
1063
  lease = adoptedSettings.lease;
920
1064
  } catch (error) {
921
- process.stderr.write(`[lead-route] native settings adopt failed session=${sessionId}: ${String((error && error.message) || error).slice(0, 200)}\n`);
922
- return { ok: false, reason: 'native_settings_adopt_failed' };
1065
+ // §5 D-6 (WP-2, S7): a throwing verification reports its bounded CODE — never `error.message`,
1066
+ // which is exactly how a settings path or a caller string used to reach the log.
1067
+ _emitNativeSettingsFailure(sessionId, error && error.code);
1068
+ return { ok: false, reason: NATIVE_ADOPTION_GENERIC_REASON };
923
1069
  }
924
1070
  let adoptedNative;
925
1071
  try {
@@ -933,15 +1079,32 @@ async function adoptLeadRouteForSession(sessionId, deps = {}, actual = {}) {
933
1079
  nativeSettingsRef: nativeFields.settingsRef,
934
1080
  });
935
1081
  } catch (error) {
936
- process.stderr.write(`[lead-route] native auth adopt failed session=${sessionId}: ${String((error && error.message) || error).slice(0, 200)}\n`);
1082
+ // §5 D-6/DEFENSIVE: production `adoptLeadToken` RETURNS a bounded refusal for an admin failure,
1083
+ // so a thrown replay is an unexpected transport/registration throw, not the live handoff path
1084
+ // (that one is the `!ok` refusal below). A thrown error's `code` is a bounded control code, so
1085
+ // it may name the reason or the cause; its `cause`/`message` are only ever cause CANDIDATES, and
1086
+ // the EXACT allowlist match means no free-form text can reach the line.
1087
+ _emitNativeProxyFailure(sessionId, {
1088
+ reason: [error && error.code],
1089
+ cause: [error && error.code, error && error.cause, error && error.message],
1090
+ });
937
1091
  // §7.3 (gen-7 item 3): the mTLS settings client already granted this attempt a committed
938
1092
  // adopted lease. A refused/THROWN proxy replay must carry that partial resource through the
939
1093
  // SHARED verification failure result so the lifetime's last-claim path can release its client
940
1094
  // tracking exactly once — dropping it here was the reproduced leak.
941
- return { ok: false, reason: 'native_settings_adopt_failed', lease, partialLease: lease };
1095
+ return { ok: false, reason: NATIVE_ADOPTION_GENERIC_REASON, lease, partialLease: lease };
942
1096
  }
943
1097
  if (!adoptedNative?.ok) {
944
- return { ok: false, reason: 'native_settings_adopt_failed', lease, partialLease: lease };
1098
+ // §5 D-6: the supervisor's own refusal reason (`admin_rejected`, `revoked`, …) is kept VERBATIM
1099
+ // when it is in vocabulary, and its `error` field is read for the CAUSE ONLY: the real
1100
+ // supervisor reports `{ok:false, reason:'admin_rejected', error:'native_lead_listener_closed'}`,
1101
+ // which is exactly the handoff condition an operator needs. Exact match or `unknown`; the raw
1102
+ // `error` text is never printed and never promoted to a reason.
1103
+ _emitNativeProxyFailure(sessionId, {
1104
+ reason: [adoptedNative && adoptedNative.reason, adoptedNative && adoptedNative.code],
1105
+ cause: [adoptedNative && adoptedNative.error],
1106
+ });
1107
+ return { ok: false, reason: NATIVE_ADOPTION_GENERIC_REASON, lease, partialLease: lease };
945
1108
  }
946
1109
  // The ACTUAL adopted lease is handed to the claim set (the record binds it), never kept here.
947
1110
  return { ok: true, lease };
@@ -954,7 +1117,12 @@ async function adoptLeadRouteForSession(sessionId, deps = {}, actual = {}) {
954
1117
  expectedEndpoint: configuredEndpoint,
955
1118
  });
956
1119
  if (!claim.ok) {
957
- process.stderr.write(`[lead-route] native auth adopt refused session=${sessionId}: ${String(claim.reason || 'lifetime_claim_failed').slice(0, 64)}\n`);
1120
+ // §5 D-6 (WP-2, S7): the finite stage/reason/cause line was already emitted by the verification
1121
+ // that failed, so this generic refusal line is reserved for claim-state refusals that never reached
1122
+ // it. One diagnostic per failure — never the same failure twice under two different names.
1123
+ if (claim.reason !== NATIVE_ADOPTION_GENERIC_REASON) {
1124
+ process.stderr.write(`[lead-route] native auth adopt refused session=${sessionId}: ${String(claim.reason || 'lifetime_claim_failed').slice(0, 64)}\n`);
1125
+ }
958
1126
  return null;
959
1127
  }
960
1128
  // §6.4: THIS attempt's own current/abort state is what decides whether its claim survives — checked
@@ -981,7 +1149,12 @@ async function adoptLeadRouteForSession(sessionId, deps = {}, actual = {}) {
981
1149
  harness: 'claude-code', providerThreadId,
982
1150
  });
983
1151
  } catch (error) {
984
- process.stderr.write(`[lead-route] native auth adopt failed session=${sessionId}: ${String((error && error.message) || error).slice(0, 200)}\n`);
1152
+ // §5 D-6 (WP-2, S7): the legacy (non-mTLS) replay reports the same finite vocabulary — its exception
1153
+ // text is never printed here either, so no branch of this function can widen a diagnostic.
1154
+ _emitNativeProxyFailure(sessionId, {
1155
+ reason: [error && error.code],
1156
+ cause: [error && error.code, error && error.cause, error && error.message],
1157
+ });
985
1158
  return null;
986
1159
  }
987
1160
  if (!adoptedNative?.ok) return null;
@@ -322,10 +322,32 @@ async function claimLeadRouteAdoption(options = {}) {
322
322
  const key = _coalesceKey(tuple);
323
323
  if (!record.adoption || record.adoption.key !== key) record.adoption = { key, promise: null };
324
324
  if (!record.adoption.promise) {
325
+ // §5 D-5 (WP-2, S8, race 2): the client-tracking release latch belongs to the ADMISSION ATTEMPT, not to
326
+ // the record — and the settings client publishes ONE lease per `adopt()` call, so a NEW verification is
327
+ // about to obtain its OWN partial lease. The OLD attempt's release is therefore a BARRIER this
328
+ // verification waits behind: `_releaseAbandonedLease` coalesces on `record.inflightClientRelease`, so a
329
+ // fresh verification that ran while that release was in flight would join the OLD release, return, and
330
+ // leak its own lease (the reproduced overlap: firstLeaseReleases=1, secondLeaseReleases=0). The latch is
331
+ // re-armed only AFTER the barrier settles, and a failure the old release recorded keeps its obligation.
332
+ const releaseBarrier = record.inflightClientRelease || null;
325
333
  // ONE operation per full tuple. The verify result carries the ACTUAL lease this attempt set is
326
334
  // about to attach, so the record never binds a lease the verification did not vouch for.
327
335
  record.adoption.promise = Promise.resolve()
328
- .then(() => (typeof options.verify === 'function' ? options.verify() : { ok: true }))
336
+ .then(async () => {
337
+ if (releaseBarrier) {
338
+ try { await releaseBarrier; }
339
+ catch (error) {
340
+ // REPORT: the earlier release retained its OWN obligation on the record; waiting for its failure
341
+ // is not swallowing it, and this attempt must still get its own release.
342
+ void error;
343
+ }
344
+ }
345
+ // §6.1 (gen-6 bug C): a host PROVEN gone while we waited is refused BEFORE this attempt borrows
346
+ // anything — the retired/exit-proof latch is re-checked here, not only after the await below.
347
+ if (record.retired || record.exitProof) return { ok: false, reason: LIFETIME_CODES.RECORD_RETIRED };
348
+ record.clientTrackingReleased = false;
349
+ return typeof options.verify === 'function' ? options.verify() : { ok: true };
350
+ })
329
351
  .then(
330
352
  // §7.3 (gen-7 item 3): a FAILED result is carried through VERBATIM — never normalized down to
331
353
  // `{ok:false, reason}` — because the attempt may already hold a partially obtained adopted lease
@@ -341,12 +363,17 @@ async function claimLeadRouteAdoption(options = {}) {
341
363
  // §7.3 (gen-7 item 3): the attempt may have obtained a lease before the proxy replay refused. That
342
364
  // partial resource is carried on the SHARED result and released exactly ONCE — by the LAST claimant,
343
365
  // through the same shared abandonment path — with `removeFiles:false` (never a survivor's files or row).
366
+ // §5 D-5 (WP-2, S8): `verificationFailed` is what keeps that same path off the GRANT phase. A refused
367
+ // or aborted verification never replayed a grant, so the token this record names still belongs to the
368
+ // SURVIVING host — revoking it is exactly the live failure this package repairs.
344
369
  const partialLease = verification.lease || verification.partialLease || options.lease || null;
345
- const abandoned = await _abandonClaim(record, claimId, { partialLease });
370
+ const abandoned = await _abandonClaim(record, claimId, { partialLease, verificationFailed: true });
346
371
  return {
347
372
  ok: false,
348
373
  reason: (verification && verification.reason) || LIFETIME_CODES.ADOPTION_FAILED,
349
374
  claimDropped: true,
375
+ grantRevoked: abandoned.grantRevoked === true,
376
+ grantRetained: abandoned.grantRetained === true,
350
377
  associationRetained: abandoned.associationRetained !== false,
351
378
  };
352
379
  }
@@ -823,8 +850,14 @@ async function releaseLeadRouteLifetime(capture, options = {}) {
823
850
  * * otherwise the exact newly replayed grant is revoked once and the attempt's partial lease releases its
824
851
  * CLIENT tracking once (`removeFiles:false`): a survivor's files and its durable row are never touched.
825
852
  * A failed cleanup keeps its obligation and stays reachable for a caller-driven retry.
853
+ *
854
+ * §5 D-5 (WP-2, S8): `verificationFailed: true` marks the ONE caller that is NOT "this attempt replayed a
855
+ * grant" — a refused or aborted verification. The terminal/attached guards above keep their meaning; for
856
+ * the LAST claimant the GRANT phase is then skipped entirely and the borrowed partial lease releases its
857
+ * client tracking exactly once, so a failed adoption can never unauthenticate the survivor it borrowed
858
+ * from. Every other caller keeps the base cleanup bit-for-bit.
826
859
  */
827
- async function _abandonClaim(record, claimId, { partialLease = null } = {}) {
860
+ async function _abandonClaim(record, claimId, { partialLease = null, verificationFailed = false } = {}) {
828
861
  const claim = record.claims.get(claimId);
829
862
  if (claim) record.claims.delete(claimId);
830
863
  if (record.attachedClaimId === claimId) record.attachedClaimId = null;
@@ -836,6 +869,25 @@ async function _abandonClaim(record, claimId, { partialLease = null } = {}) {
836
869
  const discharged = _dischargeIfComplete(record);
837
870
  return { ok: true, claimDropped: true, terminal: true, discharged, associationRetained: !discharged };
838
871
  }
872
+ if (verificationFailed === true) {
873
+ // §5 D-5: no grant phase, no row phase — this attempt borrowed the survivor's identity and never
874
+ // created that grant. Only the partial client-side tracking it obtained is released, exactly once.
875
+ // The lease released here is ONLY the one THIS failed verification carried (`partialLease`): the
876
+ // record's own `record.lease` belongs to an EARLIER, possibly still-live attempt, and reusing it would
877
+ // release tracking this attempt never obtained.
878
+ try { await _releaseAbandonedLease(record, partialLease); }
879
+ catch (error) {
880
+ void error; // REPORT: `_releaseAbandonedLease` retained the obligation (and the record), so the failure stays observable
881
+ return { ok: false, code: 'lifetime_client_release_failed', claimDropped: true, verificationFailed: true,
882
+ grantRevoked: false, grantRetained: true, filesRetained: true, associationRetained: true };
883
+ }
884
+ // Nothing else references an unattached adopted record, so its association goes: the NEXT attempt must
885
+ // start from a FRESH record (and a fresh release latch) instead of inheriting a released one. The cached
886
+ // `record.adoption` is deliberately NOT cleared here — it belongs to whoever started it.
887
+ const dropped = _dropUnreferencedRecord(record);
888
+ return { ok: true, claimDropped: true, verificationFailed: true, grantRevoked: false, grantRetained: true,
889
+ filesRetained: true, associationRetained: !dropped };
890
+ }
839
891
  const grant = await _runPhase(record, 'grantRevoked', record.grantRevoke);
840
892
  if (!grant.ok) {
841
893
  _retainObligation(record, { code: 'grant_revoke_failed' });
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ // WP-2 (docs/opencode-model-selection-round-2-shared-route-logic-2026-10-30.html §5 R-3/R-4/R-6,
4
+ // §6.2): the OpenCode twin of Codex's `model_providers.ctm-lead` -c block and Claude's
5
+ // ANTHROPIC_BASE_URL env. An OpenCode routed lead reaches CTM's model proxy as ONE custom AI-SDK
6
+ // provider entry inside its inline OPENCODE_CONFIG_CONTENT -- CTM never writes ~/.config/opencode/*
7
+ // (R-6). The entry points @ai-sdk/anthropic at the proxy's anthropic face (D-1: OpenCode leads speak
8
+ // the claude wire) and carries the lead token ONLY as `{env:CTM_LEAD_TOKEN}`: OpenCode's own config
9
+ // loader substitutes the env value, so the literal token is never written into config text (probe
10
+ // P-R1/P-R2 confirm this on the installed binary).
11
+ //
12
+ // The model ref is FIXED at `ctm-lead/lead` (R-4): the route and the wire model live in the provider
13
+ // entry (`options.baseURL` alias, `models.lead.id`), so a routed->routed switch on a prompted 1.x tab
14
+ // keeps the ref the resumed conversation is pinned to and only moves where it points.
15
+ //
16
+ // PURE: no fs, no env reads. Same input -> same output.
17
+
18
+ const OPENCODE_LEAD_PROVIDER_ID = 'ctm-lead';
19
+ const OPENCODE_LEAD_MODEL_REF = 'ctm-lead/lead';
20
+
21
+ /**
22
+ * @param {{ proxyPort: number|string, alias: string, wireModelId: string, display?: string,
23
+ * contextTokens?: number|null, maxOutputTokens?: number|null }} [spec]
24
+ * @returns {{ npm:string, name:string, options:{baseURL:string, authToken:string},
25
+ * models:{ lead:{ id:string, name:(string|undefined), limit?:{context:number, output:number} } } }}
26
+ */
27
+ function opencodeLeadProvider({ proxyPort, alias, wireModelId, display, contextTokens, maxOutputTokens } = {}) {
28
+ return {
29
+ npm: '@ai-sdk/anthropic',
30
+ name: 'CTM lead route',
31
+ options: {
32
+ baseURL: `http://127.0.0.1:${proxyPort}/r/${alias}/v1`,
33
+ authToken: '{env:CTM_LEAD_TOKEN}',
34
+ },
35
+ models: {
36
+ lead: {
37
+ id: wireModelId,
38
+ name: display,
39
+ // Probe P-R3 (scripts/opencode-lead-route-probe.js, OpenCode 1.19.5): a `limit` block must carry
40
+ // BOTH keys -- `limit.context` alone is refused ("Missing key ...limit.output") and the TUI exits
41
+ // before any request. So `limit` is emitted only when the route's deployment facts know both
42
+ // (shared/coding-model-deployment.js contextTokens/maxOutputTokens); otherwise it is omitted and
43
+ // the proxy still enforces the route's own caps.
44
+ ...(contextTokens && maxOutputTokens ? { limit: { context: contextTokens, output: maxOutputTokens } } : {}),
45
+ },
46
+ },
47
+ };
48
+ }
49
+
50
+ module.exports = { opencodeLeadProvider, OPENCODE_LEAD_PROVIDER_ID, OPENCODE_LEAD_MODEL_REF };