create-walle 0.10.1 → 0.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (681) hide show
  1. package/README.md +7 -1
  2. package/lib/owner-write-safety.js +135 -0
  3. package/lib/public-runtime.js +13 -5
  4. package/lib/release-schema.json +3 -2
  5. package/lib/runtime-closure-policy.json +11 -8
  6. package/package.json +1 -1
  7. package/template/bin/deps-doctor.js +1 -1
  8. package/template/bin/node-bin.sh +11 -0
  9. package/template/coding-task-manager/api-prompts.js +55 -29
  10. package/template/coding-task-manager/bin/claude-hook.js +62 -4
  11. package/template/coding-task-manager/bin/claude-table-parity.js +307 -0
  12. package/template/coding-task-manager/bin/conversation-storage-auto-migration-lib.js +16 -1
  13. package/template/coding-task-manager/bin/conversation-storage-generation-evidence.js +9 -2
  14. package/template/coding-task-manager/bin/conversation-storage-service-entry-lib.js +16 -1
  15. package/template/coding-task-manager/bin/conversation-storage-walle-owner.js +247 -0
  16. package/template/coding-task-manager/bin/ctm-machine-pair.js +160 -0
  17. package/template/coding-task-manager/bin/ctm-relay-client.js +35 -12
  18. package/template/coding-task-manager/bin/land.js +2069 -0
  19. package/template/coding-task-manager/bin/lead-wait-census.js +1348 -0
  20. package/template/coding-task-manager/bin/memory-census.js +4 -2
  21. package/template/coding-task-manager/bin/memory-sync-verify.js +151 -0
  22. package/template/coding-task-manager/bin/probe-refusal-scope.js +530 -0
  23. package/template/coding-task-manager/bin/repair-foreign-clone.js +564 -0
  24. package/template/coding-task-manager/bin/repair-resume-echo-titles.js +248 -0
  25. package/template/coding-task-manager/bin/write-lock-bench.js +111 -0
  26. package/template/coding-task-manager/db.js +860 -317
  27. package/template/coding-task-manager/git-utils.js +44 -0
  28. package/template/coding-task-manager/lib/acp/acp-client.js +383 -0
  29. package/template/coding-task-manager/lib/acp/dsh-context-truth.js +176 -0
  30. package/template/coding-task-manager/lib/acp/dsh-launch-model.js +302 -0
  31. package/template/coding-task-manager/lib/acp/dsh-mcp-servers.js +194 -0
  32. package/template/coding-task-manager/lib/acp/dsh-prompt-lane.js +616 -0
  33. package/template/coding-task-manager/lib/acp/dsh-route-patch.js +308 -0
  34. package/template/coding-task-manager/lib/acp/dsh-session-runtime.js +522 -0
  35. package/template/coding-task-manager/lib/acp/dsh-transcript.js +395 -0
  36. package/template/coding-task-manager/lib/acp/dsh-usage-log.js +162 -0
  37. package/template/coding-task-manager/lib/acp/ndjson-stdio-transport.js +225 -0
  38. package/template/coding-task-manager/lib/adopted-host-redial.js +47 -7
  39. package/template/coding-task-manager/lib/adopted-launch-environment.js +123 -0
  40. package/template/coding-task-manager/lib/agent-auto-update-runtime.js +0 -3
  41. package/template/coding-task-manager/lib/agent-auto-update.js +26 -10
  42. package/template/coding-task-manager/lib/agent-bundle/build.js +657 -0
  43. package/template/coding-task-manager/lib/agent-bundle/codex-install.js +558 -0
  44. package/template/coding-task-manager/lib/agent-bundle/drift.js +120 -0
  45. package/template/coding-task-manager/lib/agent-bundle/gc.js +522 -0
  46. package/template/coding-task-manager/lib/agent-bundle/inventory.js +346 -0
  47. package/template/coding-task-manager/lib/agent-bundle/push.js +717 -0
  48. package/template/coding-task-manager/lib/agent-bundle/skill-transfer.js +724 -0
  49. package/template/coding-task-manager/lib/agent-bundle/spawn.js +119 -0
  50. package/template/coding-task-manager/lib/agent-bundle/store.js +568 -0
  51. package/template/coding-task-manager/lib/agent-capabilities.js +142 -12
  52. package/template/coding-task-manager/lib/agent-cli-cache.js +30 -5
  53. package/template/coding-task-manager/lib/agent-definitions.js +19 -0
  54. package/template/coding-task-manager/lib/agent-hooks-codex-toml.js +28 -16
  55. package/template/coding-task-manager/lib/agent-hooks-codex-workspace.js +9 -1
  56. package/template/coding-task-manager/lib/agent-hooks-installer.js +23 -8
  57. package/template/coding-task-manager/lib/agent-hooks-prune.js +37 -11
  58. package/template/coding-task-manager/lib/agent-hooks-shim.js +105 -0
  59. package/template/coding-task-manager/lib/agent-presets.js +99 -1
  60. package/template/coding-task-manager/lib/agent-title-apply.js +88 -0
  61. package/template/coding-task-manager/lib/agent-title-backfill-read.js +92 -0
  62. package/template/coding-task-manager/lib/agent-upgrade-jobs.js +12 -1
  63. package/template/coding-task-manager/lib/agent-version-service.js +74 -11
  64. package/template/coding-task-manager/lib/all-sessions-query.js +6 -2
  65. package/template/coding-task-manager/lib/api/agent-bundles.js +436 -0
  66. package/template/coding-task-manager/lib/api/backup-retention.js +83 -0
  67. package/template/coding-task-manager/lib/api/conversation-sync-routes.js +124 -0
  68. package/template/coding-task-manager/lib/api/diagnostics.js +549 -69
  69. package/template/coding-task-manager/lib/api/fleet.js +118 -0
  70. package/template/coding-task-manager/lib/api/host-stats.js +98 -0
  71. package/template/coding-task-manager/lib/api/hub-bridge.js +243 -0
  72. package/template/coding-task-manager/lib/api/ingress.js +43 -12
  73. package/template/coding-task-manager/lib/api/landing.js +403 -0
  74. package/template/coding-task-manager/lib/api/machine-pairing.js +285 -0
  75. package/template/coding-task-manager/lib/api/machine-pool.js +307 -0
  76. package/template/coding-task-manager/lib/api/machines.js +1150 -0
  77. package/template/coding-task-manager/lib/api/memory-sync-routes.js +335 -0
  78. package/template/coding-task-manager/lib/api/misc-ops.js +25 -5
  79. package/template/coding-task-manager/lib/api/providers.js +53 -6
  80. package/template/coding-task-manager/lib/api/remote-sessions.js +1326 -0
  81. package/template/coding-task-manager/lib/api/resume-from-store.js +25 -0
  82. package/template/coding-task-manager/lib/api/session-attach.js +623 -0
  83. package/template/coding-task-manager/lib/api/session-messages.js +1384 -0
  84. package/template/coding-task-manager/lib/api/sessions.js +237 -59
  85. package/template/coding-task-manager/lib/api/setup-network.js +544 -16
  86. package/template/coding-task-manager/lib/api/setup-wizard-handlers.js +884 -0
  87. package/template/coding-task-manager/lib/api/setup.js +829 -10
  88. package/template/coding-task-manager/lib/api/transcript-history.js +17 -4
  89. package/template/coding-task-manager/lib/api/walle-bridge.js +9 -1
  90. package/template/coding-task-manager/lib/api/worktrees.js +38 -37
  91. package/template/coding-task-manager/lib/approval-drift.js +16 -1
  92. package/template/coding-task-manager/lib/approval-logical-frame.js +5 -1
  93. package/template/coding-task-manager/lib/approval-scope.js +68 -4
  94. package/template/coding-task-manager/lib/attachment-reconciler-wiring.js +5 -2
  95. package/template/coding-task-manager/lib/auth-context.js +32 -2
  96. package/template/coding-task-manager/lib/auth-rate-limit.js +64 -1
  97. package/template/coding-task-manager/lib/auth-rules.js +474 -62
  98. package/template/coding-task-manager/lib/background-stop.js +369 -0
  99. package/template/coding-task-manager/lib/best-of-attempts.js +4 -1
  100. package/template/coding-task-manager/lib/best-of-launch-plan.js +52 -0
  101. package/template/coding-task-manager/lib/box-keep-awake.js +89 -0
  102. package/template/coding-task-manager/lib/broadcast-reason-stats.js +152 -0
  103. package/template/coding-task-manager/lib/broadcast-serialize.js +7 -1
  104. package/template/coding-task-manager/lib/browser-session-broker.js +9 -1
  105. package/template/coding-task-manager/lib/browser-use-adapter.js +33 -2
  106. package/template/coding-task-manager/lib/build-info.js +4 -2
  107. package/template/coding-task-manager/lib/claude-markdown-ansi.js +27 -85
  108. package/template/coding-task-manager/lib/claude-model-truth.js +13 -2
  109. package/template/coding-task-manager/lib/claude-session-title.js +6 -30
  110. package/template/coding-task-manager/lib/claude-table-layout.js +322 -0
  111. package/template/coding-task-manager/lib/claude-transcript-terminal-renderer.js +17 -13
  112. package/template/coding-task-manager/lib/client-diag-handler.js +69 -2
  113. package/template/coding-task-manager/lib/codex-app-server-client.js +14 -16
  114. package/template/coding-task-manager/lib/codex-config-guard.js +33 -3
  115. package/template/coding-task-manager/lib/codex-configuration-history.js +55 -0
  116. package/template/coding-task-manager/lib/codex-harness-qualification.js +55 -20
  117. package/template/coding-task-manager/lib/codex-launch-health.js +29 -2
  118. package/template/coding-task-manager/lib/codex-link-preparation.js +9 -8
  119. package/template/coding-task-manager/lib/codex-paths.js +2 -1
  120. package/template/coding-task-manager/lib/codex-rollout-history.js +743 -0
  121. package/template/coding-task-manager/lib/coding-agent-models.js +48 -42
  122. package/template/coding-task-manager/lib/coding-cli-skill-installer.js +44 -14
  123. package/template/coding-task-manager/lib/coding-session-model-adapters.js +70 -4
  124. package/template/coding-task-manager/lib/coding-session-model-owner.js +1 -1
  125. package/template/coding-task-manager/lib/coding-session-model-projection.js +5 -0
  126. package/template/coding-task-manager/lib/coding-session-model-public.js +7 -1
  127. package/template/coding-task-manager/lib/coding-session-model-runtime.js +24 -6
  128. package/template/coding-task-manager/lib/coding-session-model-scan.js +31 -0
  129. package/template/coding-task-manager/lib/coding-session-model-state.js +17 -0
  130. package/template/coding-task-manager/lib/coding-session-model-sync-state.js +0 -1
  131. package/template/coding-task-manager/lib/conversation-freshness-diagnostics.js +280 -0
  132. package/template/coding-task-manager/lib/conversation-import/cursor-guard-owner.js +10 -0
  133. package/template/coding-task-manager/lib/conversation-item-clock.js +261 -0
  134. package/template/coding-task-manager/lib/conversation-source-registry.js +5 -0
  135. package/template/coding-task-manager/lib/conversation-store-v2.js +44 -0
  136. package/template/coding-task-manager/lib/conversation-sync.js +355 -0
  137. package/template/coding-task-manager/lib/create/resolve-launch-params.js +104 -13
  138. package/template/coding-task-manager/lib/create/worker-role-profile.js +4 -4
  139. package/template/coding-task-manager/lib/create-intent-lease.js +51 -0
  140. package/template/coding-task-manager/lib/ctm-boot-lifecycle.js +17 -1
  141. package/template/coding-task-manager/lib/ctm-session-context-api.js +97 -6
  142. package/template/coding-task-manager/lib/db-domain-tables.js +8 -0
  143. package/template/coding-task-manager/lib/db-domains.js +22 -2
  144. package/template/coding-task-manager/lib/db-owner-dispatch-probe.js +32 -0
  145. package/template/coding-task-manager/lib/db-owner-op-registry.js +7 -0
  146. package/template/coding-task-manager/lib/db-owner-request-counts.js +178 -0
  147. package/template/coding-task-manager/lib/db-owner-worker-client.js +68 -14
  148. package/template/coding-task-manager/lib/db-schema-source-files.js +6 -0
  149. package/template/coding-task-manager/lib/deferred-restore-attempt.js +6 -2
  150. package/template/coding-task-manager/lib/feature-manifest.js +5 -1
  151. package/template/coding-task-manager/lib/fleet-conversation-route.js +97 -0
  152. package/template/coding-task-manager/lib/fleet-fanout.js +78 -0
  153. package/template/coding-task-manager/lib/fleet-hub.js +762 -0
  154. package/template/coding-task-manager/lib/fleet-origin-follower.js +252 -0
  155. package/template/coding-task-manager/lib/fleet-resolver-effects.js +147 -0
  156. package/template/coding-task-manager/lib/fleet-resolver-tick.js +148 -0
  157. package/template/coding-task-manager/lib/fleet-resolver.js +454 -0
  158. package/template/coding-task-manager/lib/fleet-session-list-routes.js +114 -0
  159. package/template/coding-task-manager/lib/fleet-session-lists.js +672 -0
  160. package/template/coding-task-manager/lib/fleet-update.js +798 -0
  161. package/template/coding-task-manager/lib/fs-watcher-root-watch.js +141 -0
  162. package/template/coding-task-manager/lib/fs-watcher.js +61 -44
  163. package/template/coding-task-manager/lib/harness-history-transition.js +52 -11
  164. package/template/coding-task-manager/lib/headless-inflight-ops.js +203 -0
  165. package/template/coding-task-manager/lib/headless-missing-reply.js +42 -0
  166. package/template/coding-task-manager/lib/headless-term-service.js +139 -25
  167. package/template/coding-task-manager/lib/hermetic-agent-launch-guard.js +10 -0
  168. package/template/coding-task-manager/lib/history-transition-read-op.js +175 -8
  169. package/template/coding-task-manager/lib/host-control-dial.js +167 -0
  170. package/template/coding-task-manager/lib/host-cpu-categories.js +310 -0
  171. package/template/coding-task-manager/lib/host-fseventsd-sampler.js +399 -0
  172. package/template/coding-task-manager/lib/host-handoff-orchestrator.js +16 -2
  173. package/template/coding-task-manager/lib/host-handoff.js +50 -15
  174. package/template/coding-task-manager/lib/host-health-ledger.js +164 -12
  175. package/template/coding-task-manager/lib/host-self-truth-watchdog.js +4 -0
  176. package/template/coding-task-manager/lib/host-stats.js +475 -0
  177. package/template/coding-task-manager/lib/host-threadpool-evacuation.js +160 -0
  178. package/template/coding-task-manager/lib/host-threadpool-monitor.js +14 -1
  179. package/template/coding-task-manager/lib/hosted-input-dispatch.js +203 -0
  180. package/template/coding-task-manager/lib/hosted-sync-worker.js +141 -310
  181. package/template/coding-task-manager/lib/hub-bridge-access.js +798 -0
  182. package/template/coding-task-manager/lib/hub-bridge-box.js +409 -0
  183. package/template/coding-task-manager/lib/hub-bridge-mcp.js +380 -0
  184. package/template/coding-task-manager/lib/hub-bridge-mesh.js +313 -0
  185. package/template/coding-task-manager/lib/hub-bridge-ops.js +721 -0
  186. package/template/coding-task-manager/lib/hub-bridge.js +398 -0
  187. package/template/coding-task-manager/lib/idle-notify.js +491 -0
  188. package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +12 -0
  189. package/template/coding-task-manager/lib/instance-manifest-runtime.js +3 -0
  190. package/template/coding-task-manager/lib/instance-manifest.js +18 -2
  191. package/template/coding-task-manager/lib/instance-sync-status.js +33 -8
  192. package/template/coding-task-manager/lib/landing/agent-rule.txt +1 -0
  193. package/template/coding-task-manager/lib/landing/batch-runner.js +366 -0
  194. package/template/coding-task-manager/lib/landing/config.js +536 -0
  195. package/template/coding-task-manager/lib/landing/ctm-view.js +256 -0
  196. package/template/coding-task-manager/lib/landing/gate.js +360 -0
  197. package/template/coding-task-manager/lib/landing/git.js +344 -0
  198. package/template/coding-task-manager/lib/landing/lease.js +247 -0
  199. package/template/coding-task-manager/lib/landing/merge-delta.js +380 -0
  200. package/template/coding-task-manager/lib/landing/proof.js +223 -0
  201. package/template/coding-task-manager/lib/landing/queue.js +998 -0
  202. package/template/coding-task-manager/lib/landing/radar.js +489 -0
  203. package/template/coding-task-manager/lib/landing/resolve-cli.js +424 -0
  204. package/template/coding-task-manager/lib/landing/state.js +263 -0
  205. package/template/coding-task-manager/lib/landing/stop.js +49 -0
  206. package/template/coding-task-manager/lib/landing/sync-cli.js +475 -0
  207. package/template/coding-task-manager/lib/landing/sync.js +456 -0
  208. package/template/coding-task-manager/lib/landing/train.js +885 -0
  209. package/template/coding-task-manager/lib/landing/window.js +57 -0
  210. package/template/coding-task-manager/lib/launch-environment.js +121 -0
  211. package/template/coding-task-manager/lib/launch-model-override.js +193 -8
  212. package/template/coding-task-manager/lib/launch-plan-pool.js +2 -1
  213. package/template/coding-task-manager/lib/launch-plan-warm-cache.js +6 -0
  214. package/template/coding-task-manager/lib/launch-plan-worker.js +59 -2
  215. package/template/coding-task-manager/lib/lead-model-observer.js +57 -1
  216. package/template/coding-task-manager/lib/lead-model-options.js +160 -3
  217. package/template/coding-task-manager/lib/lead-model-restore-reconciliation.js +106 -24
  218. package/template/coding-task-manager/lib/lead-model-switch-runtime.js +409 -72
  219. package/template/coding-task-manager/lib/lead-model-switch.js +115 -10
  220. package/template/coding-task-manager/lib/lead-model-transition-runtime.js +14 -2
  221. package/template/coding-task-manager/lib/lead-model-transition-store.js +85 -9
  222. package/template/coding-task-manager/lib/lead-route-preflight.js +179 -0
  223. package/template/coding-task-manager/lib/lead-switch-history-mode.js +110 -0
  224. package/template/coding-task-manager/lib/lead-wire-agent.js +7 -0
  225. package/template/coding-task-manager/lib/legacy-draft-cancellation-recovery.js +111 -0
  226. package/template/coding-task-manager/lib/lifecycle-wake-experiment.js +9 -2
  227. package/template/coding-task-manager/lib/live-defer-announce.js +45 -0
  228. package/template/coding-task-manager/lib/login-tripwire.js +1 -0
  229. package/template/coding-task-manager/lib/machine-pairing.js +238 -0
  230. package/template/coding-task-manager/lib/machine-pool.js +409 -0
  231. package/template/coding-task-manager/lib/machine-registry.js +1494 -0
  232. package/template/coding-task-manager/lib/machine-self.js +66 -0
  233. package/template/coding-task-manager/lib/macos-capabilities.js +32 -15
  234. package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +485 -57
  235. package/template/coding-task-manager/lib/mainloop-observability.js +14 -9
  236. package/template/coding-task-manager/lib/media-draft-owner.js +16 -3
  237. package/template/coding-task-manager/lib/media-journal-control-reader.js +473 -0
  238. package/template/coding-task-manager/lib/media-journal.js +84 -27
  239. package/template/coding-task-manager/lib/media-store-options.js +43 -15
  240. package/template/coding-task-manager/lib/memory-join.js +337 -0
  241. package/template/coding-task-manager/lib/memory-sync-verify.js +393 -0
  242. package/template/coding-task-manager/lib/memory-sync.js +565 -0
  243. package/template/coding-task-manager/lib/migrations/v56-host-samples-and-machine-pool.js +76 -0
  244. package/template/coding-task-manager/lib/migrations/v57-delegate-pref-mirror-opencode.js +68 -0
  245. package/template/coding-task-manager/lib/migrations/v58-subagent-launch-native-subagents.js +42 -0
  246. package/template/coding-task-manager/lib/migrations/v59-coding-session-model-state-dsh.js +73 -0
  247. package/template/coding-task-manager/lib/migrations/v60-delegate-pref-mirror-dsh.js +78 -0
  248. package/template/coding-task-manager/lib/migrations/v61-conversation-item-clock.js +71 -0
  249. package/template/coding-task-manager/lib/mirror-feed-sanitize.js +12 -3
  250. package/template/coding-task-manager/lib/model-availability.js +727 -0
  251. package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +4 -6
  252. package/template/coding-task-manager/lib/model-host-receipt.js +6 -3
  253. package/template/coding-task-manager/lib/model-id-rule.js +19 -0
  254. package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +8 -0
  255. package/template/coding-task-manager/lib/model-proxy/auto-mode-review.js +110 -23
  256. package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +6 -0
  257. package/template/coding-task-manager/lib/model-proxy/generation-probe.js +60 -17
  258. package/template/coding-task-manager/lib/model-proxy/handoff.js +494 -0
  259. package/template/coding-task-manager/lib/model-proxy/historical-tool-declarations.js +37 -0
  260. package/template/coding-task-manager/lib/model-proxy/lead-request-validation.js +1 -0
  261. package/template/coding-task-manager/lib/model-proxy/lead-token-admin.js +130 -0
  262. package/template/coding-task-manager/lib/model-proxy/lead-worker-picks.js +25 -0
  263. package/template/coding-task-manager/lib/model-proxy/native-lead-listener.js +61 -7
  264. package/template/coding-task-manager/lib/model-proxy/proxy-cli.js +200 -0
  265. package/template/coding-task-manager/lib/model-proxy/proxy-instance-record.js +257 -0
  266. package/template/coding-task-manager/lib/model-proxy/refusal-scope.js +151 -0
  267. package/template/coding-task-manager/lib/model-proxy/request-budget-store.js +11 -2
  268. package/template/coding-task-manager/lib/model-proxy/stream-accounting.js +205 -0
  269. package/template/coding-task-manager/lib/model-proxy/tokens.js +147 -5
  270. package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +18 -0
  271. package/template/coding-task-manager/lib/native-agent-model-args.js +25 -22
  272. package/template/coding-task-manager/lib/native-history-control.js +7 -5
  273. package/template/coding-task-manager/lib/native-lead-settings-client.js +46 -5
  274. package/template/coding-task-manager/lib/native-lead-tls.js +18 -4
  275. package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +776 -75
  276. package/template/coding-task-manager/lib/online-backup-worker-client.js +2 -0
  277. package/template/coding-task-manager/lib/opencode-cli.js +480 -0
  278. package/template/coding-task-manager/lib/opencode-launch-model.js +471 -0
  279. package/template/coding-task-manager/lib/opencode-v1-plugin/model-carrier.mjs +35 -0
  280. package/template/coding-task-manager/lib/opencode-v2-plugin/server.js +118 -0
  281. package/template/coding-task-manager/lib/owner-action-manifest-data.json +15 -1
  282. package/template/coding-task-manager/lib/painted-row-recorder.js +9 -1
  283. package/template/coding-task-manager/lib/park-composer-draft.js +54 -0
  284. package/template/coding-task-manager/lib/park-fresh-relaunch.js +41 -10
  285. package/template/coding-task-manager/lib/perf-phase-trace.js +72 -0
  286. package/template/coding-task-manager/lib/perf-summary.js +7 -0
  287. package/template/coding-task-manager/lib/perf-tracker.js +63 -2
  288. package/template/coding-task-manager/lib/project-config.js +7 -0
  289. package/template/coding-task-manager/lib/prompt-purge-v2.js +52 -1
  290. package/template/coding-task-manager/lib/prompt-submission-contract.js +21 -1
  291. package/template/coding-task-manager/lib/provider-login-broker.js +264 -24
  292. package/template/coding-task-manager/lib/provider-login-capture.js +153 -0
  293. package/template/coding-task-manager/lib/provider-login-tab.js +10 -2
  294. package/template/coding-task-manager/lib/queue-draft-status-overlay.js +36 -0
  295. package/template/coding-task-manager/lib/raw-codex-history-window.js +5 -3
  296. package/template/coding-task-manager/lib/read-pool-client.js +94 -4
  297. package/template/coding-task-manager/lib/read-pool-op-registry.js +10 -1
  298. package/template/coding-task-manager/lib/read-pool-worker-handle.js +29 -4
  299. package/template/coding-task-manager/lib/recent-catalog-query.js +41 -0
  300. package/template/coding-task-manager/lib/recent-session-catalog-response.js +76 -10
  301. package/template/coding-task-manager/lib/recovery-evidence.js +26 -11
  302. package/template/coding-task-manager/lib/relay-client.js +57 -3
  303. package/template/coding-task-manager/lib/relink-audit.js +34 -5
  304. package/template/coding-task-manager/lib/remote-command-context.js +12 -0
  305. package/template/coding-task-manager/lib/remote-command-runtime.js +13 -1
  306. package/template/coding-task-manager/lib/remote-machine-catalog.js +1357 -0
  307. package/template/coding-task-manager/lib/remote-machine-create.js +1233 -0
  308. package/template/coding-task-manager/lib/remote-machine-link.js +1426 -0
  309. package/template/coding-task-manager/lib/remote-machine-proxy.js +654 -0
  310. package/template/coding-task-manager/lib/remote-session-forward.js +364 -0
  311. package/template/coding-task-manager/lib/remote-submission-status.js +6 -0
  312. package/template/coding-task-manager/lib/remote-terminal-target.js +9 -2
  313. package/template/coding-task-manager/lib/restart-guard.js +18 -6
  314. package/template/coding-task-manager/lib/restart-outcome-truth.js +20 -3
  315. package/template/coding-task-manager/lib/restart-preflight.js +9 -2
  316. package/template/coding-task-manager/lib/restore-backoff-gate.js +10 -2
  317. package/template/coding-task-manager/lib/restore-prepare-retry.js +12 -5
  318. package/template/coding-task-manager/lib/restore-resume-batch.js +22 -1
  319. package/template/coding-task-manager/lib/restore-seed-modes.js +87 -0
  320. package/template/coding-task-manager/lib/restored-scrollback-hydration-runtime.js +22 -2
  321. package/template/coding-task-manager/lib/resume-admission.js +17 -3
  322. package/template/coding-task-manager/lib/resume-blocked-wire.js +62 -1
  323. package/template/coding-task-manager/lib/resume-cwd.js +13 -0
  324. package/template/coding-task-manager/lib/resume-from-store.js +12 -1
  325. package/template/coding-task-manager/lib/resume-origin-facts.js +38 -1
  326. package/template/coding-task-manager/lib/resume-preflight.js +21 -16
  327. package/template/coding-task-manager/lib/review-repo-admission.js +39 -6
  328. package/template/coding-task-manager/lib/review-repo-registry.js +74 -18
  329. package/template/coding-task-manager/lib/root-delivery-runtime.js +74 -17
  330. package/template/coding-task-manager/lib/root-delivery-selection.js +37 -1
  331. package/template/coding-task-manager/lib/root-prompt-admission.js +33 -2
  332. package/template/coding-task-manager/lib/root-prompt-flow.js +168 -34
  333. package/template/coding-task-manager/lib/runtime-contract.js +3 -1
  334. package/template/coding-task-manager/lib/schema-indexes.js +1 -0
  335. package/template/coding-task-manager/lib/scrollback-archive-store.js +7 -4
  336. package/template/coding-task-manager/lib/session-analysis-memory.js +2 -0
  337. package/template/coding-task-manager/lib/session-context-locator.js +742 -0
  338. package/template/coding-task-manager/lib/session-create/attachment.js +2 -2
  339. package/template/coding-task-manager/lib/session-create/codex-native-provider-gate.js +218 -0
  340. package/template/coding-task-manager/lib/session-create/codex-resume-exit-classify.js +52 -0
  341. package/template/coding-task-manager/lib/session-create/create-phases.js +118 -0
  342. package/template/coding-task-manager/lib/session-create/delegate-worker.js +179 -20
  343. package/template/coding-task-manager/lib/session-create/dsh-session.js +930 -0
  344. package/template/coding-task-manager/lib/session-create/identity.js +20 -1
  345. package/template/coding-task-manager/lib/session-create/lead-route-launch.js +186 -13
  346. package/template/coding-task-manager/lib/session-create/native-lead-lifetime.js +55 -3
  347. package/template/coding-task-manager/lib/session-create/opencode-lead-provider.js +50 -0
  348. package/template/coding-task-manager/lib/session-create/prepared.js +201 -9
  349. package/template/coding-task-manager/lib/session-create/provider-launch-context.js +77 -0
  350. package/template/coding-task-manager/lib/session-create/provider-process.js +193 -64
  351. package/template/coding-task-manager/lib/session-create/response.js +37 -19
  352. package/template/coding-task-manager/lib/session-create/structured-session.js +27 -0
  353. package/template/coding-task-manager/lib/session-create/subagent-pick-table.js +3 -1
  354. package/template/coding-task-manager/lib/session-create/subagent-pick.js +458 -9
  355. package/template/coding-task-manager/lib/session-create/transcript.js +14 -5
  356. package/template/coding-task-manager/lib/session-create/worker-budget-setup.js +21 -2
  357. package/template/coding-task-manager/lib/session-create/worker-continuation.js +50 -2
  358. package/template/coding-task-manager/lib/session-create/worker-launch-sandbox.js +39 -10
  359. package/template/coding-task-manager/lib/session-create/worker-notices.js +94 -5
  360. package/template/coding-task-manager/lib/session-create/worker-observability.js +101 -9
  361. package/template/coding-task-manager/lib/session-create/worker-stop.js +11 -3
  362. package/template/coding-task-manager/lib/session-create/worker-wait-watcher.js +315 -0
  363. package/template/coding-task-manager/lib/session-empty.js +13 -10
  364. package/template/coding-task-manager/lib/session-geometry-authority-handler.js +10 -1
  365. package/template/coding-task-manager/lib/session-host-manager.js +212 -206
  366. package/template/coding-task-manager/lib/session-jobs.js +20 -10
  367. package/template/coding-task-manager/lib/session-lifecycle.js +28 -4
  368. package/template/coding-task-manager/lib/session-model-action-preconditions.js +15 -2
  369. package/template/coding-task-manager/lib/session-model-intent-contract.js +11 -8
  370. package/template/coding-task-manager/lib/session-park.js +738 -0
  371. package/template/coding-task-manager/lib/session-path-grant.js +13 -4
  372. package/template/coding-task-manager/lib/session-resource-sampler.js +19 -9
  373. package/template/coding-task-manager/lib/session-standup.js +67 -4
  374. package/template/coding-task-manager/lib/session-status-ledger.js +147 -6
  375. package/template/coding-task-manager/lib/session-status-runtime.js +45 -1
  376. package/template/coding-task-manager/lib/session-title-mirror.js +25 -57
  377. package/template/coding-task-manager/lib/session-transcript-trash.js +8 -1
  378. package/template/coding-task-manager/lib/session-transport.js +17 -0
  379. package/template/coding-task-manager/lib/session-workspace-projection.js +54 -5
  380. package/template/coding-task-manager/lib/session-workspace-tracking-runtime.js +213 -1
  381. package/template/coding-task-manager/lib/skill-autocomplete-query.js +120 -3
  382. package/template/coding-task-manager/lib/skill-autocomplete.js +15 -1
  383. package/template/coding-task-manager/lib/sqlite-file-set.js +39 -0
  384. package/template/coding-task-manager/lib/standup-search-adapter.js +16 -2
  385. package/template/coding-task-manager/lib/startup-pointer-write.js +57 -0
  386. package/template/coding-task-manager/lib/state-sync/client-ledger.js +12 -0
  387. package/template/coding-task-manager/lib/state-sync/frame-emitter.js +319 -100
  388. package/template/coding-task-manager/lib/state-sync/painted-frame-field.js +11 -0
  389. package/template/coding-task-manager/lib/storage/coding-session-model-store.js +25 -23
  390. package/template/coding-task-manager/lib/storage/delegate-pref-mirror-store.js +32 -9
  391. package/template/coding-task-manager/lib/structured-session-boot-sweep.js +235 -0
  392. package/template/coding-task-manager/lib/submission-ack.js +90 -2
  393. package/template/coding-task-manager/lib/surviving-owner-bootstrap.js +7 -2
  394. package/template/coding-task-manager/lib/surviving-owner-recovery.js +2 -1
  395. package/template/coding-task-manager/lib/systemd-scope.js +115 -0
  396. package/template/coding-task-manager/lib/telemetry-receiver.js +39 -0
  397. package/template/coding-task-manager/lib/terminal-attach-geometry.js +985 -0
  398. package/template/coding-task-manager/lib/terminal-bootstrap.js +30 -0
  399. package/template/coding-task-manager/lib/terminal-draft-http-status.js +25 -0
  400. package/template/coding-task-manager/lib/terminal-draft-operation.js +357 -0
  401. package/template/coding-task-manager/lib/terminal-input-admission.js +17 -1
  402. package/template/coding-task-manager/lib/terminal-input-prepared.js +563 -0
  403. package/template/coding-task-manager/lib/transcript-archiver.js +229 -229
  404. package/template/coding-task-manager/lib/transcript-cache-temps.js +171 -0
  405. package/template/coding-task-manager/lib/transcript-frame-cache.js +20 -5
  406. package/template/coding-task-manager/lib/transcript-guard-job.js +55 -4
  407. package/template/coding-task-manager/lib/transcript-link.js +77 -0
  408. package/template/coding-task-manager/lib/transcript-manifest-store.js +8 -4
  409. package/template/coding-task-manager/lib/transcript-source.js +44 -7
  410. package/template/coding-task-manager/lib/transcript-store.js +49 -0
  411. package/template/coding-task-manager/lib/tunnel-lane-governor.js +6 -3
  412. package/template/coding-task-manager/lib/typing-interaction-trace.js +198 -3
  413. package/template/coding-task-manager/lib/typing-worker-stages.js +60 -0
  414. package/template/coding-task-manager/lib/usage-ledger/backfill.js +40 -5
  415. package/template/coding-task-manager/lib/usage-ledger/client.js +4 -1
  416. package/template/coding-task-manager/lib/usage-ledger/dsh-parse.js +152 -0
  417. package/template/coding-task-manager/lib/usage-ledger/dsh-read.js +73 -0
  418. package/template/coding-task-manager/lib/usage-ledger/ingest.js +34 -6
  419. package/template/coding-task-manager/lib/usage-ledger/live.js +35 -8
  420. package/template/coding-task-manager/lib/usage-ledger/read.js +29 -20
  421. package/template/coding-task-manager/lib/usage-ledger/schema.js +61 -1
  422. package/template/coding-task-manager/lib/usage-ledger/task-coordinator.js +4 -2
  423. package/template/coding-task-manager/lib/visible-revision-watchdog.js +8 -12
  424. package/template/coding-task-manager/lib/wake-skip-reasons.js +47 -0
  425. package/template/coding-task-manager/lib/walle/turn.js +1 -1
  426. package/template/coding-task-manager/lib/walle-history-serve.js +838 -0
  427. package/template/coding-task-manager/lib/walle-kill-authority.js +2 -2
  428. package/template/coding-task-manager/lib/walle-log-rotation.js +164 -1
  429. package/template/coding-task-manager/lib/walle-mcp-auto-config.js +56 -2
  430. package/template/coding-task-manager/lib/walle-row-history.js +495 -0
  431. package/template/coding-task-manager/lib/walle-supervisor.js +130 -27
  432. package/template/coding-task-manager/lib/watch-worker-client.js +203 -0
  433. package/template/coding-task-manager/lib/worker-failure-classify.js +13 -1
  434. package/template/coding-task-manager/lib/worker-terminal-output.js +5 -2
  435. package/template/coding-task-manager/lib/ws/hub-bridge.js +35 -0
  436. package/template/coding-task-manager/lib/ws/lifecycle.js +6 -11
  437. package/template/coding-task-manager/lib/ws/misc.js +1 -1
  438. package/template/coding-task-manager/lib/ws/state-sync.js +125 -6
  439. package/template/coding-task-manager/lib/ws/terminal-attach.js +123 -1
  440. package/template/coding-task-manager/lib/ws-router.js +68 -1
  441. package/template/coding-task-manager/lib/ws-send-admission.js +22 -4
  442. package/template/coding-task-manager/oauth-proxy.js +211 -170
  443. package/template/coding-task-manager/package-lock.json +34 -94
  444. package/template/coding-task-manager/package.json +7 -3
  445. package/template/coding-task-manager/protocol/message-table.json +10 -0
  446. package/template/coding-task-manager/protocol/messages.js +10 -0
  447. package/template/coding-task-manager/protocol/ws-schema.json +20 -0
  448. package/template/coding-task-manager/protocol/ws-schema.md +2 -0
  449. package/template/coding-task-manager/providers/codex-mcp-extract.js +121 -19
  450. package/template/coding-task-manager/providers/codex-mcp.js +14 -5
  451. package/template/coding-task-manager/public/css/app.css +449 -1
  452. package/template/coding-task-manager/public/css/reviews.css +4 -0
  453. package/template/coding-task-manager/public/css/walle-session.css +4 -0
  454. package/template/coding-task-manager/public/index.html +766 -465
  455. package/template/coding-task-manager/public/js/agent-command.js +86 -0
  456. package/template/coding-task-manager/public/js/app/backups-panel.js +111 -5
  457. package/template/coding-task-manager/public/js/app/coding-agent-upgrade.js +103 -4
  458. package/template/coding-task-manager/public/js/app/machines-page.js +2572 -0
  459. package/template/coding-task-manager/public/js/app/models-tab.js +658 -73
  460. package/template/coding-task-manager/public/js/app/restart-banner.js +53 -0
  461. package/template/coding-task-manager/public/js/app/worktrees-panel.js +191 -7
  462. package/template/coding-task-manager/public/js/background-work.js +203 -28
  463. package/template/coding-task-manager/public/js/coding-session-model-presentation.js +181 -13
  464. package/template/coding-task-manager/public/js/core/active-session-groups.js +179 -0
  465. package/template/coding-task-manager/public/js/core/pending-create.js +238 -0
  466. package/template/coding-task-manager/public/js/core/recent-machine-source.js +228 -0
  467. package/template/coding-task-manager/public/js/core/session-commands.js +847 -5
  468. package/template/coding-task-manager/public/js/core/session-selectors.js +5 -1
  469. package/template/coding-task-manager/public/js/dashboard-client-function-order.json +8 -0
  470. package/template/coding-task-manager/public/js/document-review-links.js +9 -1
  471. package/template/coding-task-manager/public/js/file-resolution-client.js +52 -1
  472. package/template/coding-task-manager/public/js/history-app-seam.js +48 -4
  473. package/template/coding-task-manager/public/js/history-painted-rows.js +17 -2
  474. package/template/coding-task-manager/public/js/history-reader-park.js +13 -1
  475. package/template/coding-task-manager/public/js/history-scroller.js +187 -9
  476. package/template/coding-task-manager/public/js/history-transcript-pages.js +5 -5
  477. package/template/coding-task-manager/public/js/machine-pool-shared.js +991 -0
  478. package/template/coding-task-manager/public/js/message-renderer.js +4 -3
  479. package/template/coding-task-manager/public/js/model-picker.js +3 -1
  480. package/template/coding-task-manager/public/js/native-subagent-review.js +15 -2
  481. package/template/coding-task-manager/public/js/new-session-agent-grid.js +346 -0
  482. package/template/coding-task-manager/public/js/pasted-content.js +236 -0
  483. package/template/coding-task-manager/public/js/pe-private-content-lifetime.js +39 -7
  484. package/template/coding-task-manager/public/js/private-model-lifetime.js +6 -2
  485. package/template/coding-task-manager/public/js/private-state-scope.js +31 -3
  486. package/template/coding-task-manager/public/js/prompt-submission-client.js +173 -8
  487. package/template/coding-task-manager/public/js/prompt-submission-tray.js +281 -0
  488. package/template/coding-task-manager/public/js/prompts.js +11 -10
  489. package/template/coding-task-manager/public/js/protocol.js +10 -0
  490. package/template/coding-task-manager/public/js/queue-panel-submission-reconcile.js +174 -1
  491. package/template/coding-task-manager/public/js/restart-banner-policy.js +29 -1
  492. package/template/coding-task-manager/public/js/reviews.js +7 -3
  493. package/template/coding-task-manager/public/js/root-draft-lifetime.js +139 -2
  494. package/template/coding-task-manager/public/js/root-queue-builder-lifetime.js +16 -0
  495. package/template/coding-task-manager/public/js/row-join.js +4 -2
  496. package/template/coding-task-manager/public/js/session-model-picker.js +447 -57
  497. package/template/coding-task-manager/public/js/session-search-utils.js +64 -21
  498. package/template/coding-task-manager/public/js/session-usage-view.js +2 -1
  499. package/template/coding-task-manager/public/js/session-workspace-tracking.js +51 -1
  500. package/template/coding-task-manager/public/js/state-sync-client.js +14 -1
  501. package/template/coding-task-manager/public/js/stream-view.js +6 -5
  502. package/template/coding-task-manager/public/js/terminal/conv-only-session.js +287 -0
  503. package/template/coding-task-manager/public/js/terminal/runtime-02.js +16 -7
  504. package/template/coding-task-manager/public/js/terminal/runtime-03.js +41 -0
  505. package/template/coding-task-manager/public/js/terminal/runtime-04.js +41 -4
  506. package/template/coding-task-manager/public/js/terminal/runtime-09.js +2 -0
  507. package/template/coding-task-manager/public/js/terminal/runtime-10.js +5 -5
  508. package/template/coding-task-manager/public/js/terminal/runtime-12.js +60 -3
  509. package/template/coding-task-manager/public/js/terminal/runtime-16.js +16 -12
  510. package/template/coding-task-manager/public/js/terminal/runtime-18.js +14 -0
  511. package/template/coding-task-manager/public/js/terminal/runtime-19.js +8 -4
  512. package/template/coding-task-manager/public/js/terminal/runtime-20.js +211 -74
  513. package/template/coding-task-manager/public/js/terminal/runtime-21.js +19 -6
  514. package/template/coding-task-manager/public/js/terminal/runtime-22.js +86 -0
  515. package/template/coding-task-manager/public/js/terminal-attachment-draft.js +67 -13
  516. package/template/coding-task-manager/public/js/terminal-history-viewport.js +1 -1
  517. package/template/coding-task-manager/public/js/terminal-image-orchestration.js +52 -6
  518. package/template/coding-task-manager/public/js/terminal-wheel.js +62 -5
  519. package/template/coding-task-manager/public/js/walle/chat-conversation.js +15 -7
  520. package/template/coding-task-manager/public/js/walle-session.js +30 -7
  521. package/template/coding-task-manager/public/js/walle.js +6 -0
  522. package/template/coding-task-manager/public/js/ws/live-dispatch.js +10 -0
  523. package/template/coding-task-manager/public/m/app.css +366 -8
  524. package/template/coding-task-manager/public/m/app.js +1006 -74
  525. package/template/coding-task-manager/public/m/index.html +55 -1
  526. package/template/coding-task-manager/public/m/machines.js +2147 -0
  527. package/template/coding-task-manager/public/m/pool-failover.js +391 -0
  528. package/template/coding-task-manager/public/m/private-api.js +31 -1
  529. package/template/coding-task-manager/public/m/private-queue-actions.js +26 -7
  530. package/template/coding-task-manager/public/m/sw.js +5 -0
  531. package/template/coding-task-manager/public/usage.html +1 -0
  532. package/template/coding-task-manager/queue-engine.js +13 -0
  533. package/template/coding-task-manager/scripts/dev-route-fixture/synthetic-route-upstream.js +104 -0
  534. package/template/coding-task-manager/scripts/dev-route-fixture.js +339 -0
  535. package/template/coding-task-manager/scripts/opencode-lead-route-probe.js +195 -0
  536. package/template/coding-task-manager/scripts/opencode-v2-contract-probe/fake-anthropic.js +168 -0
  537. package/template/coding-task-manager/scripts/opencode-v2-contract-probe/probe-plugin/server.js +95 -0
  538. package/template/coding-task-manager/scripts/opencode-v2-contract-probe.js +673 -0
  539. package/template/coding-task-manager/server/approvals.js +5 -6
  540. package/template/coding-task-manager/server/boot.js +136 -17
  541. package/template/coding-task-manager/server.js +2819 -11885
  542. package/template/coding-task-manager/session-integrity.js +71 -13
  543. package/template/coding-task-manager/workers/db-owner-worker.js +72 -9
  544. package/template/coding-task-manager/workers/online-backup-worker.js +1 -0
  545. package/template/coding-task-manager/workers/read-pool-model-collector.js +51 -3
  546. package/template/coding-task-manager/workers/read-pool-worker.js +93 -12
  547. package/template/coding-task-manager/workers/session-host-pool-process.js +24 -10
  548. package/template/coding-task-manager/workers/session-host-process.js +19 -8
  549. package/template/coding-task-manager/workers/transcript-archive-worker.js +1 -1
  550. package/template/coding-task-manager/workers/watch-worker.js +105 -0
  551. package/template/coding-task-manager/workers/worktree-worker.js +202 -33
  552. package/template/ctm-relay/lib/protocol.js +14 -1
  553. package/template/package-lock.json +2 -2
  554. package/template/package.json +1 -1
  555. package/template/scripts/conversation-storage-v2-migration.js +78 -11
  556. package/template/shared/backup-retention.js +82 -0
  557. package/template/shared/conversation-admission.js +2 -0
  558. package/template/shared/conversation-provenance.js +3 -7
  559. package/template/shared/conversation-storage-v2-contract.js +47 -6
  560. package/template/shared/fixtures/worker-status-payloads.json +392 -0
  561. package/template/shared/git-remote-key.js +83 -0
  562. package/template/shared/host-identity.js +98 -2
  563. package/template/shared/linked-worktree.js +51 -0
  564. package/template/shared/macos-fda-target.js +57 -0
  565. package/template/shared/orphan-parents.js +55 -0
  566. package/template/shared/owner-write-safety.js +135 -0
  567. package/template/shared/public-runtime.js +13 -5
  568. package/template/shared/release-schema.json +3 -2
  569. package/template/shared/report-citations.js +14 -0
  570. package/template/shared/sqlite-write-lock.js +361 -223
  571. package/template/shared/storage/contract.js +38 -3
  572. package/template/wall-e/adapters/imessage.js +12 -0
  573. package/template/wall-e/agent.js +92 -4
  574. package/template/wall-e/api-walle.js +26 -1
  575. package/template/wall-e/bin/brain-purge-legacy-ctm.js +3 -2
  576. package/template/wall-e/bin/train-gemma-e4b-tooluse.js +2 -2
  577. package/template/wall-e/bin/walle-mcp-stdio.js +14 -8
  578. package/template/wall-e/brain/brain-join.js +859 -0
  579. package/template/wall-e/brain/brain-sync-membership.js +20 -0
  580. package/template/wall-e/brain/brain-sync-store.js +131 -77
  581. package/template/wall-e/brain/brain-sync-v2-schema.js +203 -0
  582. package/template/wall-e/brain/brain-sync-v2.js +578 -0
  583. package/template/wall-e/brain/delegate-model-prefs-store.js +13 -4
  584. package/template/wall-e/brain/deterministic-id.js +51 -0
  585. package/template/wall-e/brain/helper-rules-schema.js +129 -0
  586. package/template/wall-e/brain/memories.js +2 -2
  587. package/template/wall-e/brain/migrations.js +91 -28
  588. package/template/wall-e/brain/model-deployment-facts.js +31 -1
  589. package/template/wall-e/brain/model-identity-migration.js +1 -1
  590. package/template/wall-e/brain/owner-call-whitelist.js +39 -7
  591. package/template/wall-e/brain/schema-ensures.js +22 -0
  592. package/template/wall-e/brain/schema.js +45 -85
  593. package/template/wall-e/brain.js +172 -36
  594. package/template/wall-e/chat.js +3 -3
  595. package/template/wall-e/coding/agent-shell-env.js +7 -2
  596. package/template/wall-e/coding/journal-dispatcher.js +51 -0
  597. package/template/wall-e/coding/prompt-bundle.js +66 -21
  598. package/template/wall-e/coding/session-journal.js +28 -40
  599. package/template/wall-e/coding-orchestrator.js +23 -26
  600. package/template/wall-e/config/main-loop-exemptions.json +2 -2
  601. package/template/wall-e/http/admin-api.js +37 -0
  602. package/template/wall-e/http/auth.js +18 -1
  603. package/template/wall-e/http/blog-views-api.js +318 -0
  604. package/template/wall-e/http/gws-api.js +4 -0
  605. package/template/wall-e/http/helper-rules-api.js +327 -0
  606. package/template/wall-e/http/model-admin.js +8 -1
  607. package/template/wall-e/http/model-delegate-pref-admin.js +3 -3
  608. package/template/wall-e/http/model-proxy-providers.js +177 -2
  609. package/template/wall-e/http/model-route-health.js +157 -0
  610. package/template/wall-e/http/sync-api.js +278 -464
  611. package/template/wall-e/http/telemetry-api.js +12 -0
  612. package/template/wall-e/jobs/job-runner.js +28 -1
  613. package/template/wall-e/lib/blog-view-policy.js +88 -0
  614. package/template/wall-e/lib/blog-view-store.js +169 -0
  615. package/template/wall-e/lib/brain-owner-op-priority.js +9 -1
  616. package/template/wall-e/lib/client-config-lock.js +2 -1
  617. package/template/wall-e/lib/coding-journal-writer-child-client.js +67 -18
  618. package/template/wall-e/lib/ctm-data-dir.js +26 -0
  619. package/template/wall-e/lib/derivation-home.js +147 -0
  620. package/template/wall-e/lib/error-kinds.js +10 -1
  621. package/template/wall-e/lib/feature-manifest.js +1 -1
  622. package/template/wall-e/lib/helper-rules/cell-state.js +123 -0
  623. package/template/wall-e/lib/helper-rules/evaluate.js +398 -0
  624. package/template/wall-e/lib/helper-rules/explore-rubric.md +12 -0
  625. package/template/wall-e/lib/helper-rules/grade.js +320 -0
  626. package/template/wall-e/lib/helper-rules/label.js +247 -0
  627. package/template/wall-e/lib/helper-rules/lead-call-hook.js +555 -0
  628. package/template/wall-e/lib/helper-rules/store.js +669 -0
  629. package/template/wall-e/lib/landing-mcp-tools.js +170 -0
  630. package/template/wall-e/lib/mcp-client-config.js +133 -14
  631. package/template/wall-e/lib/mcp-gateway-migrate.js +28 -64
  632. package/template/wall-e/lib/mcp-integration.js +63 -19
  633. package/template/wall-e/lib/parent-death.js +7 -1
  634. package/template/wall-e/lib/runtime-worker-pool.js +1 -0
  635. package/template/wall-e/lib/scheduler-worker-jobs.js +12 -4
  636. package/template/wall-e/lib/telemetry-db-schema.js +37 -0
  637. package/template/wall-e/lib/telemetry-process-client.js +76 -1
  638. package/template/wall-e/llm/default-fallback.js +4 -0
  639. package/template/wall-e/llm/delegate-lead-prefs.js +16 -1
  640. package/template/wall-e/llm/delegate-vendor-default.js +12 -5
  641. package/template/wall-e/llm/model-catalog.js +13 -4
  642. package/template/wall-e/llm/model-roles.js +7 -1
  643. package/template/wall-e/llm/native-delegate-selection.js +56 -8
  644. package/template/wall-e/llm/portkey-http.js +150 -0
  645. package/template/wall-e/llm/portkey-sync.js +15 -145
  646. package/template/wall-e/llm/worker-delegate-args.js +72 -7
  647. package/template/wall-e/llm/worker-mcp-routing.js +117 -7
  648. package/template/wall-e/llm/worker-route.js +43 -1
  649. package/template/wall-e/loops/brain-custom-writes.js +64 -0
  650. package/template/wall-e/loops/ingest.js +17 -1
  651. package/template/wall-e/loops/think.js +19 -4
  652. package/template/wall-e/mcp-contract.js +222 -6
  653. package/template/wall-e/mcp-protocol-contract.js +77 -2
  654. package/template/wall-e/mcp-server.js +141 -31
  655. package/template/wall-e/mcp-worker-schemas.js +25 -7
  656. package/template/wall-e/memory/ctm-context-client.js +110 -5
  657. package/template/wall-e/memory/ctm-session-context.js +9 -3
  658. package/template/wall-e/memory/hub-bridge-client.js +388 -0
  659. package/template/wall-e/memory/replica-origin.js +56 -0
  660. package/template/wall-e/memory/session-pool.js +135 -0
  661. package/template/wall-e/runtime/live-capabilities.js +8 -3
  662. package/template/wall-e/server.js +4 -2
  663. package/template/wall-e/shared/release-schema.json +3 -2
  664. package/template/wall-e/shared/sqlite-file-set.js +39 -0
  665. package/template/wall-e/shared/sqlite-write-lock.js +361 -223
  666. package/template/wall-e/shared/storage/contract.js +38 -3
  667. package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
  668. package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +13 -1
  669. package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +11 -6
  670. package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +13 -8
  671. package/template/wall-e/skills/_templates/fleet-sync/VERSION +1 -0
  672. package/template/wall-e/skills/_templates/fleet-sync/released-sha256.json +16 -0
  673. package/template/wall-e/skills/_templates/fleet-sync/templates/claude/SKILL.md +64 -0
  674. package/template/wall-e/skills/_templates/fleet-sync/templates/codex/SKILL.md +64 -0
  675. package/template/wall-e/tools/chrome-automation.js +6 -0
  676. package/template/wall-e/tools/local-tools.js +6 -4
  677. package/template/wall-e/training/setup-cuda-train-env.sh +2 -2
  678. package/template/wall-e/workers/brain-owner-worker.js +27 -4
  679. package/template/wall-e/workers/coding-journal-writer-child.js +8 -1
  680. package/template/wall-e/workers/mcp-gateway-process.js +5 -5
  681. package/template/wall-e/workers/telemetry-worker.js +8 -0
@@ -0,0 +1,256 @@
1
+ 'use strict';
2
+
3
+ // WP-3a (docs/local-landing-queue-multi-session-integration-2026-10-26.html §6.3): the CTM side of
4
+ // the landing queue is a PURE VIEW over the `land` CLI's own `--json` payload. Nothing here reads a
5
+ // file, spawns a process, or talks to the network: the CLI is the single source of truth (§5 D-1),
6
+ // the server only reshapes what `land status --json [--radar-for a,b]` printed.
7
+ //
8
+ // Two shapes live here:
9
+ //
10
+ // landingForSession(statusPayload, { sessionId, branch, sessionsByBranch })
11
+ // -> the per-session `workspaceTracking.landing` object (§6.3), or `null` when the repository
12
+ // has nothing to say about this branch at all.
13
+ // { jobId, state, position, total, eta_s, conflictPreview, radar: { max, with: [...] } }
14
+ // `conflictPreview` is `null` or `{ paths }` — D-5's "this job will not merge as it stands,
15
+ // merge <target> now", read straight off the job record the CLI wrote.
16
+ //
17
+ // landingStatusForRepo(statusPayload, sessions)
18
+ // -> the `GET /api/landing/status` body: { queue, runner, jobs, radar, forSession }
19
+ //
20
+ // Reading rules, stated once so the CLI and the view cannot drift:
21
+ // * `queue.order` is the priority-sorted list of non-terminal job ids — the only position
22
+ // authority (in_progress first, then priority descending, then arrival; the CLI sorts it).
23
+ // * `jobs[]` is chronological (newest last), so "newest" is a comparison, never an array index.
24
+ // * A TERMINAL job is only worth showing for 2 h (the session has moved on long before that).
25
+ // * `radar.pairs` only exists when the caller probed with `--radar-for`; without it the radar is
26
+ // a cache-only summary and there is no per-branch pair data to join.
27
+ // * `unknown` is NOT a level: a pair this sweep did not look at never produces a claim.
28
+
29
+ const TERMINAL_STATES = Object.freeze(['landed', 'failed', 'blocked', 'canceled']);
30
+ // §6.3: the echo of a finished job lasts two hours.
31
+ const TERMINAL_WINDOW_MS = 2 * 60 * 60 * 1000;
32
+ const LEVELS = Object.freeze(['L0', 'L1', 'L1*', 'L2', 'L3']);
33
+ // The `with` list is about pairs a reader must actually look at: L1 (a shared changed file) and up.
34
+ const L1_RANK = LEVELS.indexOf('L1');
35
+
36
+ function levelRank(level) {
37
+ if (level === 'unknown') return -1;
38
+ const index = LEVELS.indexOf(level);
39
+ return index === -1 ? 0 : index;
40
+ }
41
+
42
+ function nowMsOf(options) {
43
+ const value = options && options.now;
44
+ if (typeof value === 'number' && Number.isFinite(value)) return value;
45
+ if (value instanceof Date) return value.getTime();
46
+ return Date.now();
47
+ }
48
+
49
+ // Tolerant readers: a payload the CLI wrote is trusted, but a partial/older one must degrade to
50
+ // "nothing to say" rather than throw inside a broadcast.
51
+ function readStatus(statusPayload) {
52
+ const payload = statusPayload && typeof statusPayload === 'object' ? statusPayload : {};
53
+ const rawQueue = payload.queue && typeof payload.queue === 'object' ? payload.queue : {};
54
+ const order = Array.isArray(rawQueue.order)
55
+ ? rawQueue.order.filter((id) => typeof id === 'string' && id)
56
+ : [];
57
+ const jobs = Array.isArray(payload.jobs) ? payload.jobs.filter((job) => job && typeof job === 'object') : [];
58
+ const radar = payload.radar && typeof payload.radar === 'object' ? payload.radar : {};
59
+ const pairs = Array.isArray(radar.pairs) ? radar.pairs.filter((pair) => pair && typeof pair === 'object') : [];
60
+ return {
61
+ target: typeof payload.target === 'string' && payload.target ? payload.target : null,
62
+ runner: payload.runner && typeof payload.runner === 'object' ? payload.runner : null,
63
+ order,
64
+ jobs,
65
+ pairs,
66
+ };
67
+ }
68
+
69
+ // The last timestamp a job ever recorded, as epoch ms — the only ordering key that survives the
70
+ // CLI's 50-job window. An unparseable/absent timestamps object sorts last (never ahead of a dated
71
+ // job), which is exactly the degradation a job file torn mid-write deserves.
72
+ function jobTimeMs(job) {
73
+ const timestamps = job && job.timestamps && typeof job.timestamps === 'object' ? job.timestamps : {};
74
+ for (const key of ['landed', 'canceled', 'gated', 'started', 'queued']) {
75
+ const parsed = Date.parse(timestamps[key]);
76
+ if (Number.isFinite(parsed)) return parsed;
77
+ }
78
+ return null;
79
+ }
80
+
81
+ function newerJob(candidate, current) {
82
+ if (!current) return candidate;
83
+ const left = jobTimeMs(candidate);
84
+ const right = jobTimeMs(current);
85
+ if (left === null) return right === null ? current : current;
86
+ if (right === null) return candidate;
87
+ if (left !== right) return left > right ? candidate : current;
88
+ return String(candidate.id || '') >= String(current.id || '') ? candidate : current;
89
+ }
90
+
91
+ // §6.3/D-10: the job this session should see. A job still in the queue wins outright; a finished one
92
+ // is echoed for TERMINAL_WINDOW_MS. "The session's branch" is the qualification for BOTH - a landing
93
+ // on someone else's branch is not this session's news.
94
+ function pickJob(jobs, branch, nowMs) {
95
+ let active = null;
96
+ let recent = null;
97
+ for (const job of jobs) {
98
+ if (job.branch !== branch) continue;
99
+ if (TERMINAL_STATES.includes(job.state)) {
100
+ const at = jobTimeMs(job);
101
+ if (at === null || nowMs - at > TERMINAL_WINDOW_MS) continue;
102
+ recent = newerJob(job, recent);
103
+ continue;
104
+ }
105
+ active = newerJob(job, active);
106
+ }
107
+ return active || recent;
108
+ }
109
+
110
+ function sessionIdsFor(sessionsByBranch, branch) {
111
+ const entry = sessionsByBranch && typeof sessionsByBranch === 'object' ? sessionsByBranch[branch] : null;
112
+ if (!Array.isArray(entry)) return [];
113
+ return entry.filter((id) => typeof id === 'string' && id);
114
+ }
115
+
116
+ // D-5 (§6 job record): `conflictPreview` is either `null` or `{ base, paths, checkedAt }`. The chip
117
+ // only ever needs the paths, and a record torn mid-write (or written by an older CLI) degrades to
118
+ // `null` rather than throwing inside a broadcast — the same tolerant-reader rule as `readStatus`.
119
+ function readConflictPreview(job) {
120
+ const preview = job && job.conflictPreview;
121
+ if (!preview || typeof preview !== 'object') return null;
122
+ const paths = Array.isArray(preview.paths) ? preview.paths.filter((file) => typeof file === 'string' && file) : [];
123
+ return paths.length ? { paths } : null;
124
+ }
125
+
126
+ // WP-1 D-1 (§6 job record): `batch` is either `null` or `{ id, members, attempt, index }`. The view
127
+ // carries it through for a reader that wants it, degrading to `null` for a record torn mid-write or
128
+ // written by an older CLI — the same tolerant-reader rule as `readConflictPreview`.
129
+ function readBatch(job) {
130
+ const batch = job && job.batch;
131
+ if (!batch || typeof batch !== 'object' || typeof batch.id !== 'string') return null;
132
+ const members = Array.isArray(batch.members) ? batch.members.filter((id) => typeof id === 'string' && id) : [];
133
+ return {
134
+ id: batch.id,
135
+ members,
136
+ attempt: Number.isInteger(batch.attempt) ? batch.attempt : null,
137
+ index: Number.isInteger(batch.index) ? batch.index : null,
138
+ };
139
+ }
140
+
141
+ function higherLevel(left, right) {
142
+ if (left === null || left === undefined) return right === null || right === undefined ? null : right;
143
+ if (right === null || right === undefined) return left;
144
+ return levelRank(right) > levelRank(left) ? right : left;
145
+ }
146
+
147
+ /**
148
+ * The per-session view (§6.3). `sessionId` is the CALLER's CTM session id (excluded from `with`);
149
+ * `sessionsByBranch` maps a branch name to the CTM session ids currently on it, so a pair between
150
+ * two branches becomes a pair between two sessions - which is what the chip renders.
151
+ */
152
+ function landingForSession(statusPayload, options = {}) {
153
+ const status = readStatus(statusPayload);
154
+ const sessionId = options.sessionId === undefined || options.sessionId === null ? null : String(options.sessionId);
155
+ const branch = typeof options.branch === 'string' && options.branch ? options.branch : null;
156
+ const sessionsByBranch = options.sessionsByBranch && typeof options.sessionsByBranch === 'object'
157
+ ? options.sessionsByBranch
158
+ : {};
159
+ if (!branch) return null;
160
+
161
+ const job = pickJob(status.jobs, branch, nowMsOf(options));
162
+
163
+ const with_ = [];
164
+ let max = null;
165
+ let conflicts = 0;
166
+ for (const pair of status.pairs) {
167
+ const other = pair.a === branch ? pair.b : (pair.b === branch ? pair.a : null);
168
+ if (other === null || other === branch || typeof other !== 'string') continue;
169
+ const rank = levelRank(pair.level);
170
+ // `unknown` (rank -1) is "this sweep did not look", never a claim about the pair.
171
+ if (rank < 0) continue;
172
+ const isTarget = status.target !== null && other === status.target;
173
+ if (rank >= L1_RANK) {
174
+ conflicts += 1;
175
+ for (const id of sessionIdsFor(sessionsByBranch, other)) {
176
+ if (sessionId !== null && id === sessionId) continue;
177
+ with_.push({ session: id, branch: other, level: pair.level });
178
+ }
179
+ }
180
+ // "max over those pairs and the target pair": the target pair counts at ANY level, because
181
+ // "my branch has not moved relative to main" is itself the answer to the chip's question.
182
+ if (isTarget) max = higherLevel(max, pair.level);
183
+ }
184
+ for (const entry of with_) max = higherLevel(max, entry.level);
185
+
186
+ with_.sort((left, right) => (levelRank(right.level) - levelRank(left.level))
187
+ || left.branch.localeCompare(right.branch)
188
+ || left.session.localeCompare(right.session));
189
+
190
+ const hasJobs = status.jobs.length > 0;
191
+ const hasQueue = status.order.length > 0;
192
+ // "the repo has nothing to say": no jobs, no queue, and no pair involving this branch at L1+.
193
+ if (!hasJobs && !hasQueue && conflicts === 0) return null;
194
+
195
+ const index = job ? status.order.indexOf(job.id) : -1;
196
+ return {
197
+ jobId: job ? job.id : null,
198
+ state: job ? job.state : null,
199
+ position: index === -1 ? null : index + 1,
200
+ total: status.order.length,
201
+ eta_s: job && Number.isFinite(job.eta_s) ? job.eta_s : null,
202
+ conflictPreview: readConflictPreview(job),
203
+ // WP-1 (§9 S-15): the batch this job is being gated in, for a reader that wants it. No UI here.
204
+ batch: readBatch(job),
205
+ radar: { max, with: with_ },
206
+ };
207
+ }
208
+
209
+ /**
210
+ * The `GET /api/landing/status` body (§6.3): the repository's own read model, plus a
211
+ * `forSession` map so one request answers both "what is this repo's queue" and "what does MY
212
+ * session see". A session with nothing to show is simply absent from the map.
213
+ */
214
+ function landingStatusForRepo(statusPayload, sessions, options = {}) {
215
+ const status = readStatus(statusPayload);
216
+ const list = (Array.isArray(sessions) ? sessions : [])
217
+ .filter((session) => session && session.id !== undefined && session.id !== null)
218
+ .map((session) => ({ id: String(session.id), branch: typeof session.branch === 'string' ? session.branch : null }));
219
+
220
+ const sessionsByBranch = {};
221
+ for (const session of list) {
222
+ if (!session.branch) continue;
223
+ if (!sessionsByBranch[session.branch]) sessionsByBranch[session.branch] = [];
224
+ sessionsByBranch[session.branch].push(session.id);
225
+ }
226
+
227
+ const forSession = {};
228
+ for (const session of list) {
229
+ const view = landingForSession(statusPayload, {
230
+ sessionId: session.id,
231
+ branch: session.branch,
232
+ sessionsByBranch,
233
+ now: options.now,
234
+ });
235
+ if (view) forSession[session.id] = view;
236
+ }
237
+
238
+ return {
239
+ queue: { depth: status.order.length, order: status.order.slice() },
240
+ runner: status.runner,
241
+ jobs: status.jobs,
242
+ radar: statusPayload && typeof statusPayload === 'object' && statusPayload.radar
243
+ ? statusPayload.radar
244
+ : { max: null, atLeastL2: null, unknown: null },
245
+ forSession,
246
+ };
247
+ }
248
+
249
+ module.exports = {
250
+ TERMINAL_STATES,
251
+ TERMINAL_WINDOW_MS,
252
+ LEVELS,
253
+ levelRank,
254
+ landingForSession,
255
+ landingStatusForRepo,
256
+ };
@@ -0,0 +1,360 @@
1
+ 'use strict';
2
+ // WP-1 (docs/local-landing-queue-multi-session-integration-2026-10-26.html §5 D-4, §6.3, §11 Risks,
3
+ // §8 WP-1): the train gate and its tree-keyed verdict cache.
4
+ //
5
+ // D-4: the gate runs ONCE, on the train commit, in a locked detached worktree that the queue owns
6
+ // (`<repo>/.worktrees/land-<jobId>` when that lives inside the repository and is ignored, else
7
+ // `<common-dir>/landing/trains/<jobId>`), with `landing.cachePaths` symlinked in and the §4 GIT_*
8
+ // list scrubbed from the child env. A gate that leaves the worktree changed is a FAIL
9
+ // (`gate_dirtied_tree`) — a gate is a read-only observer of the tree it is given.
10
+ //
11
+ // The verdict is cached by (train tree oid, sha256 of the gates array) at
12
+ // `landing/verdicts/<tree>.json`, so re-landing the same tree after a `target_dirty` block costs no
13
+ // gate run at all (AC-1e). The queue never reruns a failed gate by itself.
14
+
15
+ const fs = require('fs');
16
+ const path = require('path');
17
+
18
+ const state = require('./state');
19
+ const { runGitRaw } = require('./git');
20
+ const { gatesHash } = require('./config');
21
+ const train = require('./train');
22
+
23
+ function verdictFile(root, tree) {
24
+ return path.join(root, 'verdicts', `${tree}.json`);
25
+ }
26
+
27
+ // A cached verdict is reusable only when the gates array is byte-identical in meaning (same hash)
28
+ // AND the recorded verdict is a PASS. A cached FAIL is evidence, never a decision: replaying it
29
+ // would make a tree permanently unlandable after one flake, with no way to retry it short of
30
+ // editing the verdict store by hand. FAIL records are still written (see `runGate`).
31
+ function readCachedVerdict(root, tree, hash) {
32
+ if (!tree || !hash) return null;
33
+ const raw = state.readJsonSafe(verdictFile(root, tree));
34
+ if (!raw) return null;
35
+ if (raw.gatesHash !== hash) return null;
36
+ if (raw.verdict !== 'PASS') return null;
37
+ return raw;
38
+ }
39
+
40
+ function recordVerdict(root, entry) {
41
+ state.writeJsonAtomic(verdictFile(root, entry.tree), { contract: state.CONTRACT, ...entry });
42
+ return verdictFile(root, entry.tree);
43
+ }
44
+
45
+ // `landing.cachePaths` are validated to be git-ignored in the config directory, but a train tree is
46
+ // the target's content, not the config directory's, so the exclusion is written into the train
47
+ // worktree's own `info/exclude` as well — and, as the authority, applied as a path filter on the
48
+ // post-gate status (see `cacheDirt`).
49
+ function excludeCachePaths(dir, cachePaths) {
50
+ if (!cachePaths.length) return null;
51
+ const res = runGitRaw(dir, ['rev-parse', '--path-format=absolute', '--git-path', 'info/exclude']);
52
+ if (res.status !== 0) return null;
53
+ const file = res.stdout.trim();
54
+ const lines = cachePaths.flatMap((rel) => [`/${rel}`, `/${rel.replace(/\/+$/, '')}/`]);
55
+ fs.mkdirSync(path.dirname(file), { recursive: true });
56
+ let existing = '';
57
+ try {
58
+ existing = fs.readFileSync(file, 'utf8');
59
+ } catch (error) {
60
+ /* expected: the worktree's info/exclude has never been written — start from empty */
61
+ existing = '';
62
+ }
63
+ const have = new Set(existing.split('\n'));
64
+ const missing = lines.filter((line) => !have.has(line));
65
+ if (missing.length) fs.appendFileSync(file, `${existing && !existing.endsWith('\n') ? '\n' : ''}${missing.join('\n')}\n`);
66
+ return file;
67
+ }
68
+
69
+ function isUnderCachePath(file, cachePaths) {
70
+ return cachePaths.some((rel) => {
71
+ const clean = rel.replace(/\/+$/, '');
72
+ return clean !== '' && (file === clean || file.startsWith(`${clean}/`));
73
+ });
74
+ }
75
+
76
+ // Everything `git status --porcelain` reports about the train worktree EXCEPT the cache paths we
77
+ // linked in ourselves. Non-empty means the gate dirtied the tree.
78
+ function cacheDirt(dir, cachePaths) {
79
+ const res = runGitRaw(dir, ['status', '--porcelain']);
80
+ if (res.status !== 0) return [`status_failed: ${String(res.stderr || '').trim()}`];
81
+ return res.stdout
82
+ .split('\n')
83
+ .map((line) => line.trimEnd())
84
+ .filter((line) => line.length > 3)
85
+ .map((line) => {
86
+ const body = line.slice(3);
87
+ const renamed = body.includes(' -> ') ? body.split(' -> ').pop() : body;
88
+ return renamed.startsWith('"') && renamed.endsWith('"') ? renamed.slice(1, -1) : renamed;
89
+ })
90
+ .filter((file) => !isUnderCachePath(file, cachePaths));
91
+ }
92
+
93
+ // WP-2 (docs/shared-memory-join-followups-2026-10-31.html §5 R-8..R-10, §6, §8 WP-2, §9 I-5): a dirt
94
+ // verdict is an OBSERVATION, so the log has to say what was actually left behind. Observed once in 41
95
+ // landing logs: git 2.52 killed by a signal while an external merge driver ran left its three
96
+ // `.merge_file_XXXXXX` (%O/%A/%B) temps in the train worktree top — created with `xmkstemp` relative to
97
+ // git's working directory and unlinked only on a normal return (merge-ll.c) — and the log kept only the
98
+ // names. Those files name the ledger being merged and their mtime places the merge inside or outside the
99
+ // gate's own run; this is the instrumentation that makes the next occurrence diagnosable.
100
+ //
101
+ // Nothing here changes the outcome: the dirt is still a FAIL (`gate_dirtied_tree`), the files are still
102
+ // neither deleted nor filtered out of `cacheDirt` (a sweep would hide the evidence, §3 anti-goal).
103
+ const DIRT_EVIDENCE_MAX_PATHS = 20;
104
+ const DIRT_HEAD_BYTES = 160;
105
+ // git's own spelling of the merge-driver temporaries (`xmkstemp(".merge_file_XXXXXX")`, merge-ll.c):
106
+ // six alphanumerics, in the worktree top. Only a basename matching this gets any content recorded.
107
+ const MERGE_FILE_RE = /^\.merge_file_[A-Za-z0-9]{6}$/;
108
+
109
+ function statKind(stat) {
110
+ if (stat.isFile()) return 'file';
111
+ if (stat.isDirectory()) return 'dir';
112
+ if (stat.isSymbolicLink()) return 'symlink';
113
+ return 'other';
114
+ }
115
+
116
+ // The content HEAD of a merge-driver temporary, and only its head: the file is a %O/%A/%B blob whose
117
+ // first bytes name the ledger being merged. Opened/read/closed rather than `readFileSync` so a 1 GB
118
+ // stray costs DIRT_HEAD_BYTES, and decoded as UTF-8 so `JSON.stringify` escapes whatever control bytes
119
+ // the blob contains. `undefined` means "no content to report" — never a throw.
120
+ function readDirtHead(full) {
121
+ let fd = null;
122
+ try {
123
+ fd = fs.openSync(full, 'r');
124
+ const buf = Buffer.alloc(DIRT_HEAD_BYTES);
125
+ const read = fs.readSync(fd, buf, 0, DIRT_HEAD_BYTES, 0);
126
+ return buf.subarray(0, read).toString('utf8');
127
+ } catch (error) {
128
+ /* expected: the path went away (or is unreadable) between the status and this open — no head is a complete answer (HANDLE: report nothing rather than throw) */
129
+ return undefined;
130
+ } finally {
131
+ if (fd !== null) {
132
+ try {
133
+ fs.closeSync(fd);
134
+ } catch (error) {
135
+ /* expected: EBADF — the fd is already closed and nothing is left to release (HANDLE: ignore) */
136
+ }
137
+ }
138
+ }
139
+ }
140
+
141
+ // One `[gate] dirt:` record for one path `cacheDirt` reported. NEVER throws: this runs while the gate
142
+ // result is already a FAIL, and an exception here would replace `gate_dirtied_tree` with a crash inside
143
+ // the one log line that exists to explain it. `cacheDirt`'s own `status_failed: <stderr>` sentinel is
144
+ // passed through as its own kind rather than lstat'ed — it is not a path.
145
+ function dirtEvidence(dir, relPath) {
146
+ if (String(relPath).startsWith('status_failed:')) return { path: relPath, kind: 'status_failed' };
147
+ let stat;
148
+ try {
149
+ stat = fs.lstatSync(path.join(dir, relPath));
150
+ } catch (error) {
151
+ if (error && error.code === 'ENOENT') return { path: relPath, kind: 'missing' };
152
+ /* expected: any other lstat failure (EACCES, ELOOP, a vanished parent) is reported, not fatal (HANDLE: the code is the evidence) */
153
+ return {
154
+ path: relPath,
155
+ kind: 'error',
156
+ code: error && error.code ? error.code : String((error && error.message) || error),
157
+ };
158
+ }
159
+ const kind = statKind(stat);
160
+ const evidence = {
161
+ path: relPath,
162
+ kind,
163
+ size: stat.size,
164
+ mtime: stat.mtime.toISOString(),
165
+ birthtime: stat.birthtime.toISOString(),
166
+ };
167
+ if (kind === 'file' && MERGE_FILE_RE.test(path.basename(relPath))) {
168
+ const head = readDirtHead(path.join(dir, relPath));
169
+ if (head !== undefined) evidence.head = head;
170
+ }
171
+ return evidence;
172
+ }
173
+
174
+ // R-9 then R-8: the window first (so an mtime can be placed against the gate's own run), then at most
175
+ // DIRT_EVIDENCE_MAX_PATHS records, then one line naming how many were not shown — a path count is not
176
+ // evidence, and a dirt of ten thousand paths must not fill the job log.
177
+ function writeDirtEvidence(write, dir, paths) {
178
+ const shown = paths.slice(0, DIRT_EVIDENCE_MAX_PATHS);
179
+ for (const relPath of shown) write(`[gate] dirt: ${JSON.stringify(dirtEvidence(dir, relPath))}`);
180
+ if (paths.length > shown.length) write(`[gate] dirt: … ${paths.length - shown.length} more`);
181
+ }
182
+
183
+ function linkCachePaths(dir, sourceDir, cachePaths) {
184
+ // WP-2 (§5 D-6): the base rerun materializes its own worktree and needs exactly the same cache
185
+ // symlinks, so the implementation lives in `train.js` (which `gate.js` already depends on, and
186
+ // the reverse dependency would be a cycle) and this is the one spelling of it.
187
+ return train.linkCachePaths(dir, sourceDir, cachePaths);
188
+ }
189
+
190
+ // D-6 (§9 S-10, WP-2): the test files a FAILING gate log names, and whether the failure is a lint
191
+ // one. The runner reruns these on the base commit to separate a broken main from a broken branch.
192
+ // The parser itself lives in `train.js` beside the base rerun that consumes it (this module already
193
+ // requires `train.js`, so the dependency cannot be reversed) and is re-exported here, next to the
194
+ // gate whose log format it reads.
195
+ const { failedFilesFromLog } = train;
196
+
197
+ // D-4. Returns `{ verdict, reason, seconds, dirtyPaths, logPath, hash, selection, shadow }`;
198
+ // `verdict` is 'PASS' or 'FAIL', `reason` is null on PASS, `selection` is the WP-0 `--selection-out`
199
+ // object (null when the gate wrote none or wrote something unparseable), and `shadow` is the WP-3a
200
+ // merge-delta measurement (§6.5, null when the runner asked for none). Async because gates are: the
201
+ // runner must stay responsive (the lease heartbeat is an interval) and gate output goes straight
202
+ // into the job log file.
203
+ //
204
+ // WP-2 (§5 D-5, D-6): `ctx.signal` is the job's AbortSignal. An aborted entry stops the loop with
205
+ // `reason: 'gate_stopped'`, skips the dirt check and records NO verdict — only PASS is ever
206
+ // replayed, so a recorded FAIL would sit there as a real failure the `land inspect` reader would
207
+ // report, and a stopped gate is not a failure. The train worktree is still removed (the `finally`).
208
+ //
209
+ // WP-3a (§5 D-3, §6.5, §8 WP-3a): `ctx.onTrainReady` is an optional `async (dir) => any` the runner
210
+ // uses to take its SHADOW merge-delta measurement. It is called ONCE, after the train worktree exists
211
+ // and its cache paths are linked, and BEFORE the gates run — so the two planner passes see the tree the
212
+ // gates will see — and its return value comes back as `result.shadow`. A throw is caught and recorded
213
+ // as `{ mode: 'fallback', reason: 'plan_error', detail }`: the measurement is an observation, and no
214
+ // gate might ever be failed, skipped or reordered because of it.
215
+ async function runGate(ctx) {
216
+ const { cwd, dir, config, job, built, token, root, logFile, sourceDir, signal, onTrainReady } = ctx;
217
+ // WP-1 §9 S-4: the train id is the batch id for a batch and the job id for a singleton, so every
218
+ // member of a batch reads the SAME selection record (the gate ran once, on the batch's tree).
219
+ const trainId = ctx.trainId || job.id;
220
+ const hash = gatesHash(config.gates);
221
+ // WP-0 (design doc §5 D-8, §6.1 --selection-out, §6.6, §9 S-8): where the gate writes
222
+ // its own self-description. Handed to the gate as an env var (`.ctm.json`'s gate
223
+ // command forwards it as `--selection-out "$LAND_SELECTION_OUT"`), beside
224
+ // LAND_TRAIN/LAND_BASE. A gate that predates the flag ignores it; a gate that
225
+ // cannot write it leaves the file absent, which reads as `selection: null`.
226
+ const selectionFile = path.join(root, 'logs', `${trainId}.selection.json`);
227
+ // A retrained round (cas_lost) reuses the job id: never let it read the previous round's record.
228
+ fs.rmSync(selectionFile, { force: true });
229
+ const started = Date.now();
230
+ fs.mkdirSync(path.dirname(logFile), { recursive: true });
231
+ const logFd = fs.openSync(logFile, 'a');
232
+ const write = (text) => { fs.writeSync(logFd, `${text}\n`); };
233
+ let reason = null;
234
+ let dirtyPaths = [];
235
+ let added = false;
236
+ let shadow = null;
237
+ try {
238
+ write(`[gate] job=${job.id} train=${built.train} base=${built.base} tip=${job.tip} tree=${built.tree}`);
239
+ train.addTrainWorktree(cwd, dir, built.train, trainId);
240
+ added = true;
241
+ const linked = linkCachePaths(dir, sourceDir, config.cachePaths);
242
+ excludeCachePaths(dir, config.cachePaths);
243
+ if (linked.length) write(`[cachePaths] ${linked.join(' ')}`);
244
+
245
+ // WP-3a (§6.5): the shadow measurement runs here — the tree is materialized and the cache paths
246
+ // are linked, but no gate has run yet. A throw from it (a git read behind a proof lookup, a planner
247
+ // that cannot be spawned) is a `plan_error` fallback, never a gate failure.
248
+ if (typeof onTrainReady === 'function') {
249
+ try {
250
+ shadow = await onTrainReady(dir);
251
+ } catch (error) {
252
+ shadow = { mode: 'fallback', reason: 'plan_error', detail: error && error.message ? error.message : String(error) };
253
+ }
254
+ if (shadow) write(`[merge-delta] shadow ${shadow.mode}${shadow.reason ? ` (${shadow.reason})` : ''}`);
255
+ }
256
+
257
+ for (const entry of config.gates) {
258
+ write(`$ ${entry.run}`);
259
+ // Gates run in the configured order and each may depend on the previous one.
260
+ // eslint-disable-next-line no-await-in-loop
261
+ const res = await train.runShell(entry.run, {
262
+ cwd: dir,
263
+ extra: {
264
+ LAND_TRAIN: dir,
265
+ LAND_BASE: built.base,
266
+ LAND_TIP: job.tip,
267
+ LAND_JOB: job.id,
268
+ LAND_TOKEN: token,
269
+ LAND_SELECTION_OUT: selectionFile,
270
+ },
271
+ timeoutMs: Math.round(entry.timeoutSeconds * 1000),
272
+ logFd,
273
+ signal,
274
+ });
275
+ // D-5/D-6: a stopped gate ends the loop here, with no verdict and no dirt check.
276
+ if (res.aborted) {
277
+ write(`[gate] ${entry.name}: stopped`);
278
+ reason = 'gate_stopped';
279
+ break;
280
+ }
281
+ if (res.timedOut) {
282
+ write(`[gate] ${entry.name}: timed out after ${entry.timeoutSeconds}s; process group signalled`);
283
+ reason = 'gate_timeout';
284
+ break;
285
+ }
286
+ if (res.error) {
287
+ write(`[gate] ${entry.name}: could not be run: ${res.error.message}`);
288
+ reason = 'gate_spawn_failed';
289
+ break;
290
+ }
291
+ if (res.status !== 0) {
292
+ write(`[gate] ${entry.name}: exited ${res.status}${res.signal ? ` (${res.signal})` : ''}`);
293
+ reason = 'gate_failed';
294
+ break;
295
+ }
296
+ write(`[gate] ${entry.name}: ok`);
297
+ }
298
+
299
+ // D-6: a stopped gate is not a verdict. Return before the dirt check and before `recordVerdict`;
300
+ // the `finally` still removes this job's train worktree.
301
+ if (reason === 'gate_stopped') {
302
+ return {
303
+ verdict: null,
304
+ reason: 'gate_stopped',
305
+ seconds: Number(((Date.now() - started) / 1000).toFixed(3)),
306
+ dirtyPaths: [],
307
+ logPath: logFile,
308
+ hash,
309
+ selection: state.readJsonSafe(selectionFile),
310
+ shadow,
311
+ };
312
+ }
313
+
314
+ // D-4: a gate must leave the train worktree unchanged.
315
+ if (!reason) {
316
+ dirtyPaths = cacheDirt(dir, config.cachePaths);
317
+ if (dirtyPaths.length) {
318
+ write(`[gate] dirtied the train worktree: ${dirtyPaths.join(', ')}`);
319
+ // WP-2 (§5 R-8/R-9): what was left behind, and when this gate was running while it happened.
320
+ write(`[gate] window: ${JSON.stringify({ startedAt: new Date(started).toISOString(), finishedAt: new Date().toISOString() })}`);
321
+ writeDirtEvidence(write, dir, dirtyPaths);
322
+ reason = 'gate_dirtied_tree';
323
+ }
324
+ }
325
+ } finally {
326
+ // Only this job's own train directory, created above and owned by this call.
327
+ if (added) write(`[worktree] ${JSON.stringify(train.removeTrainWorktree(cwd, dir))}`);
328
+ fs.closeSync(logFd);
329
+ }
330
+
331
+ const seconds = Number(((Date.now() - started) / 1000).toFixed(3));
332
+ const verdict = reason ? 'FAIL' : 'PASS';
333
+ recordVerdict(root, {
334
+ tree: built.tree,
335
+ verdict,
336
+ gatesHash: hash,
337
+ at: new Date().toISOString(),
338
+ seconds,
339
+ jobId: job.id,
340
+ logPath: logFile,
341
+ reason,
342
+ });
343
+ return { verdict, reason, seconds, dirtyPaths, logPath: logFile, hash, selection: state.readJsonSafe(selectionFile), shadow };
344
+ }
345
+
346
+ module.exports = {
347
+ verdictFile,
348
+ readCachedVerdict,
349
+ recordVerdict,
350
+ excludeCachePaths,
351
+ isUnderCachePath,
352
+ cacheDirt,
353
+ DIRT_EVIDENCE_MAX_PATHS,
354
+ DIRT_HEAD_BYTES,
355
+ dirtEvidence,
356
+ writeDirtEvidence,
357
+ linkCachePaths,
358
+ failedFilesFromLog,
359
+ runGate,
360
+ };