create-walle 0.10.0 → 0.10.2

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 (381) hide show
  1. package/README.md +88 -41
  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 +7 -5
  6. package/package.json +10 -4
  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 +10 -22
  10. package/template/coding-task-manager/bin/capture-codex-rollout-records.js +417 -0
  11. package/template/coding-task-manager/bin/census-codex-lead-history.js +325 -0
  12. package/template/coding-task-manager/bin/claude-hook.js +7 -3
  13. package/template/coding-task-manager/bin/claude-table-parity.js +307 -0
  14. package/template/coding-task-manager/bin/conversation-storage-auto-migration-lib.js +16 -1
  15. package/template/coding-task-manager/bin/conversation-storage-generation-evidence.js +9 -2
  16. package/template/coding-task-manager/bin/conversation-storage-service-entry-lib.js +16 -1
  17. package/template/coding-task-manager/bin/conversation-storage-walle-owner.js +247 -0
  18. package/template/coding-task-manager/bin/ctm-machine-pair.js +160 -0
  19. package/template/coding-task-manager/bin/lead-wait-census.js +1348 -0
  20. package/template/coding-task-manager/bin/repair-foreign-clone.js +564 -0
  21. package/template/coding-task-manager/bin/repair-resume-echo-titles.js +248 -0
  22. package/template/coding-task-manager/bin/seam-replay-codex.js +301 -0
  23. package/template/coding-task-manager/bin/write-lock-bench.js +111 -0
  24. package/template/coding-task-manager/db.js +705 -286
  25. package/template/coding-task-manager/git-utils.js +44 -0
  26. package/template/coding-task-manager/lib/adopted-host-redial.js +4 -0
  27. package/template/coding-task-manager/lib/agent-presets.js +15 -0
  28. package/template/coding-task-manager/lib/agent-title-apply.js +88 -0
  29. package/template/coding-task-manager/lib/agent-title-backfill-read.js +92 -0
  30. package/template/coding-task-manager/lib/api/host-stats.js +98 -0
  31. package/template/coding-task-manager/lib/api/ingress.js +35 -12
  32. package/template/coding-task-manager/lib/api/machine-pairing.js +285 -0
  33. package/template/coding-task-manager/lib/api/machine-pool.js +307 -0
  34. package/template/coding-task-manager/lib/api/machines.js +461 -0
  35. package/template/coding-task-manager/lib/api/misc-ops.js +20 -5
  36. package/template/coding-task-manager/lib/api/providers.js +53 -6
  37. package/template/coding-task-manager/lib/api/resume-from-store.js +25 -0
  38. package/template/coding-task-manager/lib/api/sessions.js +160 -8
  39. package/template/coding-task-manager/lib/api/transcript-history.js +17 -4
  40. package/template/coding-task-manager/lib/api/worktrees.js +38 -37
  41. package/template/coding-task-manager/lib/approval-drift.js +16 -1
  42. package/template/coding-task-manager/lib/approval-logical-frame.js +5 -1
  43. package/template/coding-task-manager/lib/approval-scope.js +68 -4
  44. package/template/coding-task-manager/lib/auth-context.js +32 -2
  45. package/template/coding-task-manager/lib/auth-rate-limit.js +41 -1
  46. package/template/coding-task-manager/lib/auth-rules.js +186 -45
  47. package/template/coding-task-manager/lib/broadcast-serialize.js +2 -1
  48. package/template/coding-task-manager/lib/browser-session-broker.js +9 -1
  49. package/template/coding-task-manager/lib/browser-use-adapter.js +33 -2
  50. package/template/coding-task-manager/lib/claude-markdown-ansi.js +27 -85
  51. package/template/coding-task-manager/lib/claude-session-title.js +6 -30
  52. package/template/coding-task-manager/lib/claude-table-layout.js +322 -0
  53. package/template/coding-task-manager/lib/client-diag-handler.js +25 -0
  54. package/template/coding-task-manager/lib/codex-config-guard.js +33 -3
  55. package/template/coding-task-manager/lib/codex-harness-qualification.js +12 -0
  56. package/template/coding-task-manager/lib/codex-history-terminal-renderer.js +33 -33
  57. package/template/coding-task-manager/lib/codex-launch-health.js +29 -2
  58. package/template/coding-task-manager/lib/codex-link-preparation.js +9 -8
  59. package/template/coding-task-manager/lib/codex-local-links.js +267 -0
  60. package/template/coding-task-manager/lib/codex-markdown-lists.js +160 -0
  61. package/template/coding-task-manager/lib/codex-native-history-prefix.js +4 -0
  62. package/template/coding-task-manager/lib/codex-paths.js +2 -1
  63. package/template/coding-task-manager/lib/codex-source-handoff.js +186 -0
  64. package/template/coding-task-manager/lib/coding-agent-models.js +21 -30
  65. package/template/coding-task-manager/lib/coding-session-model-adapters.js +27 -2
  66. package/template/coding-task-manager/lib/coding-session-model-projection.js +5 -0
  67. package/template/coding-task-manager/lib/coding-session-model-runtime.js +1 -2
  68. package/template/coding-task-manager/lib/coding-session-model-state.js +10 -0
  69. package/template/coding-task-manager/lib/coding-session-model-sync-state.js +0 -1
  70. package/template/coding-task-manager/lib/conversation-import/cursor-guard-owner.js +10 -0
  71. package/template/coding-task-manager/lib/create/resolve-launch-params.js +8 -1
  72. package/template/coding-task-manager/lib/ctm-boot-lifecycle.js +17 -1
  73. package/template/coding-task-manager/lib/db-domain-tables.js +7 -0
  74. package/template/coding-task-manager/lib/db-domains.js +21 -2
  75. package/template/coding-task-manager/lib/db-owner-op-registry.js +7 -0
  76. package/template/coding-task-manager/lib/db-owner-worker-client.js +22 -0
  77. package/template/coding-task-manager/lib/db-schema-source-files.js +1 -0
  78. package/template/coding-task-manager/lib/feature-manifest.js +1 -3
  79. package/template/coding-task-manager/lib/fs-watcher.js +3 -2
  80. package/template/coding-task-manager/lib/harness-history-transition.js +41 -14
  81. package/template/coding-task-manager/lib/headless-inflight-ops.js +203 -0
  82. package/template/coding-task-manager/lib/headless-missing-reply.js +42 -0
  83. package/template/coding-task-manager/lib/headless-term-service.js +60 -23
  84. package/template/coding-task-manager/lib/history-transition-read-op.js +179 -23
  85. package/template/coding-task-manager/lib/host-control-dial.js +167 -0
  86. package/template/coding-task-manager/lib/host-handoff-orchestrator.js +16 -2
  87. package/template/coding-task-manager/lib/host-handoff.js +51 -13
  88. package/template/coding-task-manager/lib/host-health-ledger.js +164 -12
  89. package/template/coding-task-manager/lib/host-self-truth-watchdog.js +4 -0
  90. package/template/coding-task-manager/lib/host-stats.js +328 -0
  91. package/template/coding-task-manager/lib/host-threadpool-evacuation.js +160 -0
  92. package/template/coding-task-manager/lib/host-threadpool-monitor.js +14 -1
  93. package/template/coding-task-manager/lib/hosted-input-dispatch.js +203 -0
  94. package/template/coding-task-manager/lib/hosted-sync-worker.js +113 -5
  95. package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +4 -0
  96. package/template/coding-task-manager/lib/instance-manifest-runtime.js +3 -0
  97. package/template/coding-task-manager/lib/instance-manifest.js +13 -1
  98. package/template/coding-task-manager/lib/instance-sync-status.js +15 -0
  99. package/template/coding-task-manager/lib/kernel/diag-log.js +12 -0
  100. package/template/coding-task-manager/lib/launch-model-override.js +160 -1
  101. package/template/coding-task-manager/lib/launch-plan-worker.js +59 -2
  102. package/template/coding-task-manager/lib/lead-model-observer.js +17 -2
  103. package/template/coding-task-manager/lib/lead-model-switch-runtime.js +57 -4
  104. package/template/coding-task-manager/lib/lead-model-switch.js +11 -2
  105. package/template/coding-task-manager/lib/lead-model-transition-runtime.js +42 -4
  106. package/template/coding-task-manager/lib/lead-model-transition-store.js +61 -3
  107. package/template/coding-task-manager/lib/legacy-draft-cancellation-recovery.js +111 -0
  108. package/template/coding-task-manager/lib/login-tripwire.js +18 -0
  109. package/template/coding-task-manager/lib/machine-pairing.js +238 -0
  110. package/template/coding-task-manager/lib/machine-pool.js +409 -0
  111. package/template/coding-task-manager/lib/machine-registry.js +749 -0
  112. package/template/coding-task-manager/lib/machine-self.js +66 -0
  113. package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +56 -4
  114. package/template/coding-task-manager/lib/media-journal-control-reader.js +473 -0
  115. package/template/coding-task-manager/lib/media-journal.js +84 -27
  116. package/template/coding-task-manager/lib/media-store-options.js +43 -15
  117. package/template/coding-task-manager/lib/migrations/v56-host-samples-and-machine-pool.js +76 -0
  118. package/template/coding-task-manager/lib/mirror-feed-sanitize.js +12 -3
  119. package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +16 -3
  120. package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
  121. package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
  122. package/template/coding-task-manager/lib/model-proxy/collaboration-codec.js +94 -0
  123. package/template/coding-task-manager/lib/model-proxy/handoff.js +494 -0
  124. package/template/coding-task-manager/lib/model-proxy/lead-worker-picks.js +25 -0
  125. package/template/coding-task-manager/lib/model-proxy/native-lead-listener.js +61 -7
  126. package/template/coding-task-manager/lib/model-proxy/proxy-cli.js +200 -0
  127. package/template/coding-task-manager/lib/model-proxy/proxy-instance-record.js +257 -0
  128. package/template/coding-task-manager/lib/model-proxy/responses-face.js +24 -2
  129. package/template/coding-task-manager/lib/model-proxy/stream-accounting.js +205 -0
  130. package/template/coding-task-manager/lib/model-proxy/tokens.js +78 -0
  131. package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
  132. package/template/coding-task-manager/lib/native-history-control.js +62 -14
  133. package/template/coding-task-manager/lib/native-lead-settings-client.js +2 -1
  134. package/template/coding-task-manager/lib/native-lead-tls.js +18 -4
  135. package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +628 -64
  136. package/template/coding-task-manager/lib/owner-action-manifest-data.json +14 -0
  137. package/template/coding-task-manager/lib/painted-row-recorder.js +9 -1
  138. package/template/coding-task-manager/lib/prompt-admission-trace.js +69 -0
  139. package/template/coding-task-manager/lib/prompt-submission-contract.js +21 -1
  140. package/template/coding-task-manager/lib/provider-login-broker.js +192 -9
  141. package/template/coding-task-manager/lib/provider-login-capture.js +153 -0
  142. package/template/coding-task-manager/lib/queue-draft-status-overlay.js +36 -0
  143. package/template/coding-task-manager/lib/raw-codex-history-window.js +5 -3
  144. package/template/coding-task-manager/lib/raw-history-block.js +3 -1
  145. package/template/coding-task-manager/lib/read-pool-client.js +36 -24
  146. package/template/coding-task-manager/lib/read-pool-op-registry.js +10 -1
  147. package/template/coding-task-manager/lib/read-pool-telemetry.js +14 -5
  148. package/template/coding-task-manager/lib/recent-catalog-query.js +26 -0
  149. package/template/coding-task-manager/lib/recent-session-catalog-response.js +9 -0
  150. package/template/coding-task-manager/lib/remote-command-context.js +12 -0
  151. package/template/coding-task-manager/lib/remote-command-runtime.js +18 -5
  152. package/template/coding-task-manager/lib/remote-machine-catalog.js +1062 -0
  153. package/template/coding-task-manager/lib/remote-machine-create.js +693 -0
  154. package/template/coding-task-manager/lib/remote-machine-link.js +939 -0
  155. package/template/coding-task-manager/lib/remote-machine-proxy.js +520 -0
  156. package/template/coding-task-manager/lib/remote-session-forward.js +306 -0
  157. package/template/coding-task-manager/lib/remote-submission-status.js +6 -0
  158. package/template/coding-task-manager/lib/restart-outcome-truth.js +20 -3
  159. package/template/coding-task-manager/lib/restart-preflight.js +9 -2
  160. package/template/coding-task-manager/lib/restore-backoff-gate.js +10 -2
  161. package/template/coding-task-manager/lib/restore-prepare-retry.js +12 -5
  162. package/template/coding-task-manager/lib/restore-resume-batch.js +22 -1
  163. package/template/coding-task-manager/lib/resume-blocked-wire.js +62 -1
  164. package/template/coding-task-manager/lib/resume-cwd.js +13 -0
  165. package/template/coding-task-manager/lib/resume-from-store.js +12 -1
  166. package/template/coding-task-manager/lib/resume-origin-facts.js +38 -1
  167. package/template/coding-task-manager/lib/resume-preflight.js +21 -16
  168. package/template/coding-task-manager/lib/review-repo-admission.js +39 -6
  169. package/template/coding-task-manager/lib/review-repo-registry.js +17 -0
  170. package/template/coding-task-manager/lib/root-delivery-runtime.js +72 -15
  171. package/template/coding-task-manager/lib/root-delivery-selection.js +37 -1
  172. package/template/coding-task-manager/lib/root-prompt-admission.js +43 -11
  173. package/template/coding-task-manager/lib/root-prompt-flow.js +175 -38
  174. package/template/coding-task-manager/lib/scrollback-archive-store.js +7 -4
  175. package/template/coding-task-manager/lib/server-memory-sampler-runtime.js +10 -0
  176. package/template/coding-task-manager/lib/server-memory-sampler.js +41 -2
  177. package/template/coding-task-manager/lib/session-analysis-memory.js +2 -0
  178. package/template/coding-task-manager/lib/session-create/codex-native-provider-gate.js +218 -0
  179. package/template/coding-task-manager/lib/session-create/codex-resume-exit-classify.js +52 -0
  180. package/template/coding-task-manager/lib/session-create/delegate-worker.js +95 -6
  181. package/template/coding-task-manager/lib/session-create/identity.js +20 -1
  182. package/template/coding-task-manager/lib/session-create/prepared.js +69 -1
  183. package/template/coding-task-manager/lib/session-create/provider-launch-context.js +77 -0
  184. package/template/coding-task-manager/lib/session-create/provider-process.js +38 -39
  185. package/template/coding-task-manager/lib/session-create/response.js +30 -12
  186. package/template/coding-task-manager/lib/session-create/transcript.js +13 -4
  187. package/template/coding-task-manager/lib/session-create/worker-continuation.js +43 -1
  188. package/template/coding-task-manager/lib/session-create/worker-notices.js +94 -5
  189. package/template/coding-task-manager/lib/session-create/worker-observability.js +99 -7
  190. package/template/coding-task-manager/lib/session-create/worker-stop.js +11 -3
  191. package/template/coding-task-manager/lib/session-create/worker-wait-watcher.js +315 -0
  192. package/template/coding-task-manager/lib/session-geometry-authority-handler.js +10 -1
  193. package/template/coding-task-manager/lib/session-host-manager.js +152 -206
  194. package/template/coding-task-manager/lib/session-jobs.js +17 -9
  195. package/template/coding-task-manager/lib/session-lifecycle.js +20 -50
  196. package/template/coding-task-manager/lib/session-model-action-preconditions.js +68 -3
  197. package/template/coding-task-manager/lib/session-resource-sampler.js +67 -9
  198. package/template/coding-task-manager/lib/session-standup.js +67 -4
  199. package/template/coding-task-manager/lib/session-status-ledger.js +42 -3
  200. package/template/coding-task-manager/lib/session-status-runtime.js +45 -1
  201. package/template/coding-task-manager/lib/session-status.js +2 -2
  202. package/template/coding-task-manager/lib/session-title-mirror.js +25 -57
  203. package/template/coding-task-manager/lib/session-transcript-trash.js +8 -1
  204. package/template/coding-task-manager/lib/startup-pointer-write.js +57 -0
  205. package/template/coding-task-manager/lib/state-sync/painted-frame-field.js +11 -0
  206. package/template/coding-task-manager/lib/storage/coding-session-model-store.js +21 -22
  207. package/template/coding-task-manager/lib/surviving-owner-bootstrap.js +7 -2
  208. package/template/coding-task-manager/lib/surviving-owner-recovery.js +2 -1
  209. package/template/coding-task-manager/lib/terminal-draft-http-status.js +25 -0
  210. package/template/coding-task-manager/lib/transcript-archiver.js +229 -229
  211. package/template/coding-task-manager/lib/transcript-frame-cache.js +12 -2
  212. package/template/coding-task-manager/lib/transcript-guard-job.js +55 -4
  213. package/template/coding-task-manager/lib/transcript-link.js +77 -0
  214. package/template/coding-task-manager/lib/transcript-manifest-store.js +8 -4
  215. package/template/coding-task-manager/lib/transcript-source.js +8 -3
  216. package/template/coding-task-manager/lib/transcript-store.js +40 -0
  217. package/template/coding-task-manager/lib/tunnel-lane-governor.js +6 -3
  218. package/template/coding-task-manager/lib/typing-interaction-trace.js +136 -2
  219. package/template/coding-task-manager/lib/typing-worker-stages.js +208 -1
  220. package/template/coding-task-manager/lib/usage-ledger/claude-parse.js +53 -2
  221. package/template/coding-task-manager/lib/usage-ledger/ingest.js +13 -4
  222. package/template/coding-task-manager/lib/usage-ledger/read.js +14 -0
  223. package/template/coding-task-manager/lib/usage-ledger/schema.js +49 -1
  224. package/template/coding-task-manager/lib/usage-ledger/store.js +337 -6
  225. package/template/coding-task-manager/lib/usage-ledger/task-read.js +123 -5
  226. package/template/coding-task-manager/lib/visible-revision-watchdog.js +8 -12
  227. package/template/coding-task-manager/lib/wake-skip-reasons.js +46 -0
  228. package/template/coding-task-manager/lib/walle-supervisor.js +98 -14
  229. package/template/coding-task-manager/lib/worker-failure-classify.js +13 -1
  230. package/template/coding-task-manager/lib/ws/input.js +1 -0
  231. package/template/coding-task-manager/lib/ws/state-sync.js +19 -2
  232. package/template/coding-task-manager/lib/ws/terminal-attach.js +32 -1
  233. package/template/coding-task-manager/lib/ws-router.js +68 -1
  234. package/template/coding-task-manager/lib/ws-send-admission.js +22 -4
  235. package/template/coding-task-manager/oauth-proxy.js +99 -55
  236. package/template/coding-task-manager/package-lock.json +24 -0
  237. package/template/coding-task-manager/package.json +3 -0
  238. package/template/coding-task-manager/protocol/message-table.json +0 -10
  239. package/template/coding-task-manager/protocol/messages.js +0 -10
  240. package/template/coding-task-manager/protocol/ws-schema.json +0 -20
  241. package/template/coding-task-manager/protocol/ws-schema.md +0 -2
  242. package/template/coding-task-manager/providers/codex-mcp-extract.js +121 -19
  243. package/template/coding-task-manager/providers/codex-mcp.js +14 -5
  244. package/template/coding-task-manager/public/css/app.css +279 -2
  245. package/template/coding-task-manager/public/css/reviews.css +4 -0
  246. package/template/coding-task-manager/public/index.html +297 -240
  247. package/template/coding-task-manager/public/js/app/machines-page.js +1252 -0
  248. package/template/coding-task-manager/public/js/app/models-tab.js +546 -36
  249. package/template/coding-task-manager/public/js/app/worktrees-panel.js +7 -5
  250. package/template/coding-task-manager/public/js/background-work.js +13 -7
  251. package/template/coding-task-manager/public/js/client-health-core.js +81 -0
  252. package/template/coding-task-manager/public/js/client-health-main.js +61 -0
  253. package/template/coding-task-manager/public/js/coding-session-model-presentation.js +44 -4
  254. package/template/coding-task-manager/public/js/core/session-commands.js +676 -0
  255. package/template/coding-task-manager/public/js/core/session-selectors.js +5 -1
  256. package/template/coding-task-manager/public/js/history-app-seam.js +26 -2
  257. package/template/coding-task-manager/public/js/history-painted-rows.js +17 -2
  258. package/template/coding-task-manager/public/js/history-reader-park.js +13 -1
  259. package/template/coding-task-manager/public/js/history-scroller.js +187 -9
  260. package/template/coding-task-manager/public/js/history-transcript-pages.js +5 -5
  261. package/template/coding-task-manager/public/js/machine-pool-shared.js +436 -0
  262. package/template/coding-task-manager/public/js/private-state-scope.js +31 -3
  263. package/template/coding-task-manager/public/js/prompt-submission-client.js +173 -4
  264. package/template/coding-task-manager/public/js/prompt-submission-tray.js +281 -0
  265. package/template/coding-task-manager/public/js/protocol.js +0 -10
  266. package/template/coding-task-manager/public/js/queue-panel-submission-reconcile.js +174 -1
  267. package/template/coding-task-manager/public/js/reviews.js +7 -3
  268. package/template/coding-task-manager/public/js/root-draft-lifetime.js +139 -2
  269. package/template/coding-task-manager/public/js/root-queue-builder-lifetime.js +16 -0
  270. package/template/coding-task-manager/public/js/row-join.js +18 -3
  271. package/template/coding-task-manager/public/js/session-model-picker.js +1 -1
  272. package/template/coding-task-manager/public/js/session-search-utils.js +46 -19
  273. package/template/coding-task-manager/public/js/session-usage-view.js +1 -0
  274. package/template/coding-task-manager/public/js/state-sync-client.js +4 -0
  275. package/template/coding-task-manager/public/js/terminal/runtime-02.js +16 -7
  276. package/template/coding-task-manager/public/js/terminal/runtime-03.js +41 -0
  277. package/template/coding-task-manager/public/js/terminal/runtime-04.js +41 -4
  278. package/template/coding-task-manager/public/js/terminal/runtime-12.js +52 -2
  279. package/template/coding-task-manager/public/js/terminal/runtime-16.js +12 -12
  280. package/template/coding-task-manager/public/js/terminal/runtime-18.js +14 -0
  281. package/template/coding-task-manager/public/js/terminal/runtime-19.js +8 -4
  282. package/template/coding-task-manager/public/js/terminal/runtime-20.js +210 -73
  283. package/template/coding-task-manager/public/js/terminal/runtime-21.js +19 -6
  284. package/template/coding-task-manager/public/js/terminal/runtime-22.js +86 -0
  285. package/template/coding-task-manager/public/js/terminal-history-viewport.js +1 -3
  286. package/template/coding-task-manager/public/js/terminal-wheel.js +39 -2
  287. package/template/coding-task-manager/public/js/walle/chat-conversation.js +11 -3
  288. package/template/coding-task-manager/public/js/walle-session.js +30 -7
  289. package/template/coding-task-manager/public/m/app.css +226 -8
  290. package/template/coding-task-manager/public/m/app.js +502 -9
  291. package/template/coding-task-manager/public/m/index.html +38 -1
  292. package/template/coding-task-manager/public/m/machines.js +1313 -0
  293. package/template/coding-task-manager/public/m/pool-failover.js +391 -0
  294. package/template/coding-task-manager/public/m/private-queue-actions.js +26 -7
  295. package/template/coding-task-manager/public/m/sw.js +5 -0
  296. package/template/coding-task-manager/queue-engine.js +13 -0
  297. package/template/coding-task-manager/server/approvals.js +5 -6
  298. package/template/coding-task-manager/server/boot.js +136 -17
  299. package/template/coding-task-manager/server.js +964 -425
  300. package/template/coding-task-manager/session-integrity.js +7 -9
  301. package/template/coding-task-manager/workers/db-owner-worker.js +53 -7
  302. package/template/coding-task-manager/workers/read-pool-worker.js +17 -6
  303. package/template/coding-task-manager/workers/session-host-pool-process.js +18 -4
  304. package/template/coding-task-manager/workers/session-host-process.js +14 -3
  305. package/template/coding-task-manager/workers/transcript-archive-worker.js +1 -1
  306. package/template/coding-task-manager/workers/worktree-worker.js +34 -0
  307. package/template/package-lock.json +2 -2
  308. package/template/package.json +1 -1
  309. package/template/scripts/conversation-storage-v2-migration.js +78 -11
  310. package/template/shared/conversation-storage-v2-contract.js +42 -6
  311. package/template/shared/fixtures/worker-status-payloads.json +392 -0
  312. package/template/shared/git-remote-key.js +83 -0
  313. package/template/shared/host-identity.js +98 -2
  314. package/template/shared/owner-write-safety.js +135 -0
  315. package/template/shared/public-runtime.js +13 -5
  316. package/template/shared/release-schema.json +3 -2
  317. package/template/shared/report-citations.js +14 -0
  318. package/template/shared/sqlite-write-lock.js +361 -223
  319. package/template/shared/storage/contract.js +35 -3
  320. package/template/wall-e/agent.js +21 -0
  321. package/template/wall-e/api-walle.js +5 -0
  322. package/template/wall-e/bin/brain-purge-legacy-ctm.js +3 -2
  323. package/template/wall-e/bin/walle-mcp-stdio.js +12 -6
  324. package/template/wall-e/brain/helper-rules-schema.js +129 -0
  325. package/template/wall-e/brain/migrations.js +51 -22
  326. package/template/wall-e/brain/model-deployment-facts.js +31 -1
  327. package/template/wall-e/brain/owner-call-whitelist.js +16 -0
  328. package/template/wall-e/brain/schema-ensures.js +22 -0
  329. package/template/wall-e/brain.js +1 -1
  330. package/template/wall-e/coding/host-capabilities.js +2 -2
  331. package/template/wall-e/coding/journal-dispatcher.js +51 -0
  332. package/template/wall-e/coding/session-journal.js +28 -40
  333. package/template/wall-e/coding-orchestrator.js +23 -26
  334. package/template/wall-e/fly.toml +1 -1
  335. package/template/wall-e/http/auth.js +18 -1
  336. package/template/wall-e/http/blog-views-api.js +318 -0
  337. package/template/wall-e/http/helper-rules-api.js +321 -0
  338. package/template/wall-e/http/model-proxy-providers.js +3 -1
  339. package/template/wall-e/http/telemetry-api.js +12 -0
  340. package/template/wall-e/lib/blog-view-policy.js +88 -0
  341. package/template/wall-e/lib/blog-view-store.js +169 -0
  342. package/template/wall-e/lib/client-config-lock.js +2 -1
  343. package/template/wall-e/lib/coding-journal-writer-child-client.js +67 -18
  344. package/template/wall-e/lib/error-kinds.js +10 -1
  345. package/template/wall-e/lib/feature-manifest.js +1 -1
  346. package/template/wall-e/lib/helper-rules/cell-state.js +123 -0
  347. package/template/wall-e/lib/helper-rules/evaluate.js +357 -0
  348. package/template/wall-e/lib/helper-rules/explore-rubric.md +12 -0
  349. package/template/wall-e/lib/helper-rules/grade.js +277 -0
  350. package/template/wall-e/lib/helper-rules/label.js +247 -0
  351. package/template/wall-e/lib/helper-rules/lead-call-hook.js +522 -0
  352. package/template/wall-e/lib/helper-rules/store.js +667 -0
  353. package/template/wall-e/lib/mcp-integration.js +5 -6
  354. package/template/wall-e/lib/runtime-worker-pool.js +1 -0
  355. package/template/wall-e/lib/scheduler-worker-jobs.js +6 -0
  356. package/template/wall-e/lib/telemetry-db-schema.js +37 -0
  357. package/template/wall-e/lib/telemetry-process-client.js +76 -1
  358. package/template/wall-e/llm/default-fallback.js +4 -0
  359. package/template/wall-e/llm/model-catalog.js +13 -4
  360. package/template/wall-e/llm/model-roles.js +6 -0
  361. package/template/wall-e/llm/portkey-http.js +150 -0
  362. package/template/wall-e/llm/portkey-sync.js +15 -145
  363. package/template/wall-e/llm/worker-mcp-routing.js +61 -0
  364. package/template/wall-e/llm/worker-route.js +43 -1
  365. package/template/wall-e/loops/brain-custom-writes.js +45 -0
  366. package/template/wall-e/mcp-protocol-contract.js +41 -1
  367. package/template/wall-e/mcp-server.js +13 -2
  368. package/template/wall-e/mcp-worker-schemas.js +20 -2
  369. package/template/wall-e/memory/ctm-context-client.js +25 -5
  370. package/template/wall-e/shared/release-schema.json +3 -2
  371. package/template/wall-e/shared/sqlite-write-lock.js +361 -223
  372. package/template/wall-e/shared/storage/contract.js +35 -3
  373. package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
  374. package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +6 -0
  375. package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +7 -2
  376. package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +7 -2
  377. package/template/wall-e/tools/local-tools.js +12 -5
  378. package/template/wall-e/workers/brain-owner-worker.js +9 -0
  379. package/template/wall-e/workers/coding-journal-writer-child.js +8 -1
  380. package/template/wall-e/workers/telemetry-worker.js +8 -0
  381. package/template/coding-task-manager/lib/giant-freeze-park.js +0 -31
@@ -1447,9 +1447,10 @@ function _wtProgressDuration(ms) {
1447
1447
  return min + 'm ' + String(rem).padStart(2, '0') + 's';
1448
1448
  }
1449
1449
 
1450
- function _wtProgressApi(path) {
1450
+ // `machine` (hub WP-5): the box owning the job — create, poll and cancel must all name it.
1451
+ function _wtProgressApi(path, machine) {
1451
1452
  var token = (state && state.token) ? state.token : '';
1452
- return path + (path.indexOf('?') === -1 ? '?' : '&') + 'token=' + encodeURIComponent(token);
1453
+ return path + (path.indexOf('?') === -1 ? '?' : '&') + 'token=' + encodeURIComponent(token) + (machine ? '&machine=' + encodeURIComponent(machine) : '');
1453
1454
  }
1454
1455
 
1455
1456
  function _wtProgressTerminalStatus(status) {
@@ -1536,7 +1537,7 @@ async function _wtCancelWorktreeProgressJob() {
1536
1537
  var killBtn = document.getElementById('wt-progress-kill-btn');
1537
1538
  if (killBtn) { killBtn.disabled = true; killBtn.textContent = 'Stopping...'; }
1538
1539
  try {
1539
- var r = await fetch(_wtProgressApi('/api/worktrees/create-jobs/' + encodeURIComponent(st.jobId) + '/cancel'), { method: 'POST' });
1540
+ var r = await fetch(_wtProgressApi('/api/worktrees/create-jobs/' + encodeURIComponent(st.jobId) + '/cancel', st.machine), { method: 'POST' });
1540
1541
  var d = await r.json().catch(function() { return {}; });
1541
1542
  if (!r.ok || d.error) throw new Error(d.error || ('HTTP ' + r.status));
1542
1543
  _wtRenderWorktreeProgress(d);
@@ -1558,7 +1559,7 @@ async function _wtCreateWithProgress(body, options) {
1558
1559
  var lastCreateError = null;
1559
1560
  for (var createAttempt = 1; createAttempt <= maxCreateAttempts; createAttempt++) {
1560
1561
  try {
1561
- var createResponse = await _wtFetchJsonWithTimeout(_wtProgressApi('/api/worktrees/create?async=1'), {
1562
+ var createResponse = await _wtFetchJsonWithTimeout(_wtProgressApi('/api/worktrees/create?async=1', options.machine), {
1562
1563
  method: 'POST',
1563
1564
  headers: { 'Content-Type': 'application/json' },
1564
1565
  body: JSON.stringify(createBody),
@@ -1591,6 +1592,7 @@ async function _wtCreateWithProgress(body, options) {
1591
1592
 
1592
1593
  var st = {
1593
1594
  jobId: first.jobId,
1595
+ machine: options.machine || '',
1594
1596
  branch: options.branch || body.name || first.name || '',
1595
1597
  title: options.title || 'Creating worktree',
1596
1598
  subtitle: options.subtitle || '',
@@ -1613,7 +1615,7 @@ async function _wtCreateWithProgress(body, options) {
1613
1615
  if (st.done) return;
1614
1616
  try {
1615
1617
  var pollResponse = await _wtFetchJsonWithTimeout(
1616
- _wtProgressApi('/api/worktrees/create-jobs/' + encodeURIComponent(st.jobId)),
1618
+ _wtProgressApi('/api/worktrees/create-jobs/' + encodeURIComponent(st.jobId), st.machine),
1617
1619
  {},
1618
1620
  Math.max(1, Number(options.pollTimeoutMs) || 10000),
1619
1621
  );
@@ -16,15 +16,15 @@
16
16
  }
17
17
 
18
18
  // D-15: bg shell / bg agent / bg terminal / bg task for one entry, bg ×N for more.
19
- function pillText(work) {
19
+ // D-8: when every listed task is quiet the pill says so (a quiet shell carries no park protection).
20
+ function pillText(work, now = Date.now()) {
20
21
  const tasks = tasksOf(work);
21
22
  const count = Number(work && work.count) || tasks.length;
22
- if (count > 1) return 'bg ×' + count;
23
+ const allQuiet = tasks.length > 0 && tasks.every((t) => t && t.quiet === true);
24
+ if (count > 1) return 'bg ×' + count + (allQuiet ? ' · quiet' : '');
23
25
  const type = (tasks[0] && tasks[0].type) || Object.keys((work && work.types) || {})[0] || '';
24
- if (type === 'shell') return 'bg shell';
25
- if (type === 'subagent') return 'bg agent';
26
- if (type === 'terminal') return 'bg terminal';
27
- return 'bg task';
26
+ const word = type === 'shell' ? 'shell' : type === 'subagent' ? 'agent' : type === 'terminal' ? 'terminal' : 'task';
27
+ return 'bg ' + word + (allQuiet ? ' · quiet ' + ageText(tasks[0].activeAt, now) : '');
28
28
  }
29
29
 
30
30
  function clip(label) {
@@ -42,7 +42,7 @@
42
42
 
43
43
  // Pill title: one `<type>: <label clipped to 80> · <age>` line per task.
44
44
  function titleLines(work, now) {
45
- return tasksOf(work).map((t) => ((t && t.type) || 'task') + ': ' + clip(t && t.label) + ' · ' + ageText(t && t.since, now)).join('\n');
45
+ return tasksOf(work).map((t) => ((t && t.type) || 'task') + ': ' + clip(t && t.label) + ' · ' + ageText(t && t.since, now) + (t && t.quiet === true ? ' · quiet ' + ageText(t.activeAt, now) : '')).join('\n');
46
46
  }
47
47
 
48
48
  // Hover-card body: one row per task (type, label, age). fmt.cap(text, n) and fmt.age(ms) are the card's own
@@ -65,6 +65,12 @@
65
65
  age.style.cssText = 'flex:0 0 auto;color:var(--fg-dim,#727aa1);font-size:11px;';
66
66
  age.textContent = fmt.age(task.since);
67
67
  line.append(type, label, age);
68
+ if (task.quiet === true) {
69
+ const quiet = doc.createElement('span');
70
+ quiet.style.cssText = 'flex:0 0 auto;color:var(--fg-dim,#727aa1);';
71
+ quiet.textContent = 'quiet ' + fmt.age(task.activeAt); // fmt.age takes a timestamp (stream-view _tooltipAge)
72
+ line.appendChild(quiet);
73
+ }
68
74
  body.appendChild(line);
69
75
  }
70
76
  return body;
@@ -25,6 +25,12 @@
25
25
  return Math.max(0, Math.round(number));
26
26
  }
27
27
 
28
+ // A field that is already a safe integer passes through; anything else (absent key, NaN, a
29
+ // string, a float) falls back. Used for the probe fields whose "unknown" sentinel is -1.
30
+ function safeIntOr(value, fallback) {
31
+ return Number.isSafeInteger(value) ? value : fallback;
32
+ }
33
+
28
34
  function boundedPush(array, value, limit) {
29
35
  const max = Math.max(1, Math.floor(finite(limit, 1)));
30
36
  array.push(value);
@@ -209,6 +215,55 @@
209
215
  return { capture, observe };
210
216
  }
211
217
 
218
+ // WP-B frame-stall probe: two pure helpers that turn a LoAF entry's OWN window into the answer a
219
+ // single burst row could not give — "the renderer main thread was idle and Chrome never sent a
220
+ // frame" vs "the main thread itself was not running". Both take plain numbers, never `performance`.
221
+ // C-2: given the main-thread heartbeat ticks (performance.now() samples, ascending) and one frame
222
+ // window [startTime, startTime + duration], report how many ticks landed inside the window and the
223
+ // LARGEST gap between consecutive ticks across it. The last tick BEFORE the window seeds the first
224
+ // gap (a thread that stopped running before the frame began shows up as a leading gap) and the
225
+ // window end closes the last one, so a window with no ticks at all reports ~duration.
226
+ // Interpretation: many ticks with gaps at the tick cadence mean the main thread was free and the
227
+ // frame was starved upstream (compositor/GPU/browser), even though the frame lasted seconds; a
228
+ // maxGap near the frame duration means the main thread itself was not running. Hidden tabs throttle
229
+ // timers, so read `visibility` next to it — a throttled page is not a blocked one.
230
+ function summarizeHeartbeatGap(ticks, startTime, duration) {
231
+ const list = Array.isArray(ticks) ? ticks : [];
232
+ const start = Math.max(0, finite(startTime, 0));
233
+ const end = start + Math.max(0, finite(duration, 0));
234
+ let cursor = start;
235
+ let count = 0;
236
+ let maxGapMs = 0;
237
+ for (const tick of list) {
238
+ const value = Number(tick);
239
+ if (!Number.isFinite(value)) continue;
240
+ if (value < start) { cursor = value; continue; }
241
+ if (value > end) break;
242
+ maxGapMs = Math.max(maxGapMs, value - cursor);
243
+ cursor = value;
244
+ count += 1;
245
+ }
246
+ return { ticks: count, maxGapMs: Math.round(Math.max(maxGapMs, end - cursor)) };
247
+ }
248
+
249
+ // C-3: the visibility state as it was DURING the frame. The burst row's own visibility/
250
+ // sinceVisibleMs are read when the burst is REPORTED — after the frame — so they describe the
251
+ // wrong instant. Reconstructed from the single run-scoped visibilitychange timestamp: a change
252
+ // inside the window means the state at startTime was the opposite of the current state, none
253
+ // inside it means the state at startTime was the current state.
254
+ function resolveVisibilityInWindow(input) {
255
+ const frame = input || {};
256
+ const start = Math.max(0, finite(frame.startTime, 0));
257
+ const end = start + Math.max(0, finite(frame.duration, 0));
258
+ const changedAt = finite(frame.lastChangeAt, -1);
259
+ const current = String(frame.current || '').slice(0, 16);
260
+ const changedInWindow = changedAt >= start && changedAt <= end;
261
+ return {
262
+ visibilityChangedInFrame: changedInWindow ? 1 : 0,
263
+ visibilityAtStart: changedInWindow ? (current === 'visible' ? 'hidden' : 'visible') : current,
264
+ };
265
+ }
266
+
212
267
  // WP-3 (docs/mainloop-composer-freeze-2026-08-20.html §5 D-6, §6, §8 WP-3, §9 C-9): pure
213
268
  // burst-detection so it's unit-testable without a PerformanceObserver/DOM (client-health-
214
269
  // main.js owns the observer + the actual send; this owns only "when does a burst fire").
@@ -266,6 +321,20 @@
266
321
  const scriptsAllCount = nonNegativeRounded(frame && frame.scriptsAllCount, scripts.length);
267
322
  const scriptsAllSumMs = nonNegativeRounded(frame && frame.scriptsAllSumMs, Math.round(scriptsTotalMs));
268
323
  const dominantRepeat = nonNegativeRounded(frame && frame.dominantRepeat, 0);
324
+ // WP-B C-1: the frame's own timeline, so a 35s frame reads as idle-and-starved rather than
325
+ // busy from one row. renderStart > 0 is the browser's own "rendering had begun" marker; with
326
+ // it, renderDelayMs is the time from frame start until rendering began (script time is NOT in
327
+ // it — a 35,000ms delay with scriptsAllSumMs 73 is a starved frame, not a busy main thread).
328
+ // wallStartAt lines the frame up with host logs without a second beacon (the core never reads
329
+ // `performance`; client-health-main.js puts its `timeOrigin` on the frame).
330
+ const frameStart = Math.max(0, finite(frame && frame.startTime, 0));
331
+ const renderStart = Math.max(0, finite(frame && frame.renderStart, 0));
332
+ const renderDelayMs = renderStart > 0 ? Math.round(renderStart - frameStart) : -1;
333
+ const firstUIEvent = Math.max(0, finite(frame && frame.firstUIEventTimestamp, 0));
334
+ const firstUIEventMs = firstUIEvent > 0 ? Math.round(firstUIEvent) : -1;
335
+ const wallStartAt = frame && Number.isFinite(frame.timeOrigin)
336
+ ? Math.round(frame.timeOrigin + frameStart)
337
+ : -1;
269
338
  return {
270
339
  fn: String((dominant && dominant.fn) || '').slice(0, 80),
271
340
  src: String((dominant && dominant.source) || '').slice(0, 160),
@@ -291,6 +360,16 @@
291
360
  const value = Number(getSinceVisibleMs());
292
361
  return Number.isFinite(value) && value >= 0 ? Math.floor(value) : -1;
293
362
  })(),
363
+ // WP-B C-1/C-2: the frame timeline, carried through verbatim when the caller measured it
364
+ // (-1 = not measured). C-3's visibility pair is carried the same way.
365
+ startMs: frameStart,
366
+ renderDelayMs,
367
+ firstUIEventMs,
368
+ wallStartAt,
369
+ heartbeatTicks: safeIntOr(frame && frame.heartbeatTicks, -1),
370
+ heartbeatMaxGapMs: safeIntOr(frame && frame.heartbeatMaxGapMs, -1),
371
+ visibilityChangedInFrame: nonNegativeRounded(frame && frame.visibilityChangedInFrame, 0),
372
+ visibilityAtStart: String((frame && frame.visibilityAtStart) || '').slice(0, 16),
294
373
  };
295
374
  }
296
375
 
@@ -417,6 +496,8 @@
417
496
  classifyInteractionTiming,
418
497
  createKeyboardInteractionTracker,
419
498
  createLoafBurstTracker,
499
+ summarizeHeartbeatGap,
500
+ resolveVisibilityInWindow,
420
501
  sameWatchdogGap,
421
502
  classifyTerminalBoundary,
422
503
  firstTerminalBoundary,
@@ -31,7 +31,16 @@
31
31
  let lastLifecycleMarker = null;
32
32
  let lifecyclePersisted = false;
33
33
  let activeRun = null;
34
+ // WP-B C-2/C-3: the run's main-thread heartbeat ring (performance.now() samples) and the
35
+ // performance.now() of the last visibilitychange. Both are per-run evidence, reset with the run.
36
+ let mainHeartbeatTicks = [];
37
+ let lastVisibilityChangeAt = -1;
34
38
  const LIFECYCLE_STORAGE_KEY = 'ctm_client_health_lifecycle_v2';
39
+ // C-2: the tick cadence and ring length (240 x 500ms = the last 2 minutes), and the frame length
40
+ // from which the ring is worth summarizing (the LoAF burst solo threshold).
41
+ const MAIN_HEARTBEAT_TICK_MS = 500;
42
+ const MAIN_HEARTBEAT_RING = 240;
43
+ const MAIN_HEARTBEAT_FRAME_MS = 1000;
35
44
 
36
45
  function isPrivateContextCurrent(privateContext) {
37
46
  try { return privateContext?.isCurrent?.() === true; } catch { return false; }
@@ -562,6 +571,16 @@
562
571
  try { return performance.timeOrigin + performance.now(); } catch { return Date.now(); }
563
572
  }
564
573
 
574
+ // C-2: LoAF's startTime/duration are on the same monotonic clock as performance.now(), so the
575
+ // heartbeat ring must sample that clock — not the epoch clock above.
576
+ function monotonicNow() {
577
+ try { return performance.now(); } catch { return 0; }
578
+ }
579
+
580
+ function performanceTimeOrigin() {
581
+ try { return performance.timeOrigin; } catch { return -1; }
582
+ }
583
+
565
584
  function ring(target, value, limit) {
566
585
  return Core.boundedPush(target, value, limit);
567
586
  }
@@ -596,6 +615,40 @@
596
615
  return typeof window === 'undefined' || window.CTM_CLIENT_PERF_SPANS !== false;
597
616
  }
598
617
 
618
+ // WP-B C-2: one 500ms run-scoped ticker — the only positive evidence that the renderer main
619
+ // thread was RUNNING during a long frame. Owned by the run like every other timer here
620
+ // (scheduleRunInterval -> run.intervals -> retireRun), so a retired/new run inherits nothing.
621
+ function startMainHeartbeat(run) {
622
+ if (!isRunCurrent(run)) return;
623
+ scheduleRunInterval(run, () => {
624
+ ring(mainHeartbeatTicks, monotonicNow(), MAIN_HEARTBEAT_RING);
625
+ }, MAIN_HEARTBEAT_TICK_MS);
626
+ }
627
+
628
+ // WP-B C-1/C-2/C-3: the frame-stall probe fields, measured at frame-report time but describing the
629
+ // frame's OWN window — so one burst row answers "was the main thread idle while Chrome never gave
630
+ // it a frame" without a second beacon or a hand-mapped wall clock. `performance` is read here, in
631
+ // the browser module, never in core.
632
+ function frameStallProbe(entry) {
633
+ const startTime = Math.max(0, Number(entry?.startTime) || 0);
634
+ const duration = Math.max(0, Number(entry?.duration) || 0);
635
+ const probe = { timeOrigin: performanceTimeOrigin() };
636
+ if (Core && typeof Core.resolveVisibilityInWindow === 'function') {
637
+ Object.assign(probe, Core.resolveVisibilityInWindow({
638
+ startTime,
639
+ duration,
640
+ lastChangeAt: lastVisibilityChangeAt,
641
+ current: typeof document !== 'undefined' ? document.visibilityState : '',
642
+ }));
643
+ }
644
+ if (duration >= MAIN_HEARTBEAT_FRAME_MS && Core && typeof Core.summarizeHeartbeatGap === 'function') {
645
+ const gap = Core.summarizeHeartbeatGap(mainHeartbeatTicks, startTime, duration);
646
+ probe.heartbeatTicks = gap.ticks;
647
+ probe.heartbeatMaxGapMs = gap.maxGapMs;
648
+ }
649
+ return probe;
650
+ }
651
+
599
652
  function _recordLoafBurstCandidate(frame, run = activeRun) {
600
653
  if (!isRunCurrent(run) || !loafBurstTracker || !_ctmClientPerfSpansEnabled()) return;
601
654
  const burst = loafBurstTracker.record(frame, monotonicEpochNow());
@@ -751,6 +804,8 @@
751
804
  invokerType: script.invokerType || '',
752
805
  forcedStyleAndLayoutDuration: script.forcedStyleAndLayoutDuration || 0,
753
806
  })),
807
+ // WP-B frame-stall probe (C-1/C-2/C-3): additive fields only.
808
+ ...frameStallProbe(entry),
754
809
  };
755
810
  ring(performanceData.longAnimationFrames, frame, 20);
756
811
  performanceEvidenceVersion += 1;
@@ -852,6 +907,9 @@
852
907
  }
853
908
  });
854
909
  addRunListener(run, document, 'visibilitychange', () => {
910
+ // WP-B C-3: the single run-scoped visibilitychange timestamp a later frame reads to recover
911
+ // the state it actually ran under (the burst row's own visibility is read after the fact).
912
+ lastVisibilityChangeAt = monotonicNow();
855
913
  lifecycleState = document.visibilityState === 'visible' ? 'active' : 'hidden';
856
914
  if (document.visibilityState === 'visible') {
857
915
  visibleSinceMs = monotonicEpochNow();
@@ -1243,6 +1301,8 @@
1243
1301
  lastLifecycleMarker = null;
1244
1302
  lifecyclePersisted = false;
1245
1303
  loafBurstTracker = _createLoafBurstTracker();
1304
+ mainHeartbeatTicks = [];
1305
+ lastVisibilityChangeAt = -1;
1246
1306
  }
1247
1307
 
1248
1308
  function retireRun(run) {
@@ -1399,6 +1459,7 @@
1399
1459
  drainBootErrors();
1400
1460
  if (document.visibilityState === 'visible') visibleSinceMs = monotonicEpochNow();
1401
1461
  startPaintProgressLoop(run);
1462
+ startMainHeartbeat(run);
1402
1463
  scheduleHeartbeat(run);
1403
1464
  sendHeartbeat(run);
1404
1465
  run.memorySampler = createClientMemorySampler({
@@ -8,6 +8,22 @@
8
8
  if (typeof module !== 'undefined' && module.exports) module.exports = api;
9
9
  if (root) root.CTMCodingModelPresentation = api;
10
10
  })(typeof globalThis !== 'undefined' ? globalThis : this, function () {
11
+ // WP-0: the reserved delegate alias, mirrored from lib/model-proxy/lead-worker-picks.js
12
+ // (WORKER_MODEL_ALIAS) — browser code cannot require CommonJS, so a parity test pins the literal.
13
+ // It names what a lead's SUBAGENTS ask for; it is never the lead's own model.
14
+ var RESERVED_MODEL_ALIAS = 'walle-worker';
15
+
16
+ // Reviewed finding: the id is normalised through the SAME one marker rule the server's decoders
17
+ // apply (`modelClass` strips a trailing `[1m]`), so the alias wearing the session's context marker
18
+ // is the same reserved alias — exactly one marker, and no lookalike (`walle-worker-2`,
19
+ // `claude-opus-5-5[1m]`) is affected.
20
+ function isReservedModelAlias(value) {
21
+ if (typeof value !== 'string') return false;
22
+ var folded = value.trim().toLowerCase();
23
+ var base = folded.slice(-4) === '[1m]' ? folded.slice(0, -4) : folded;
24
+ return base === RESERVED_MODEL_ALIAS;
25
+ }
26
+
11
27
  function cleanString(value) {
12
28
  if (typeof value !== 'string') return null;
13
29
  const text = value.trim();
@@ -34,6 +50,9 @@
34
50
  if (!value || typeof observedAtMs !== 'number' || !Number.isFinite(observedAtMs) || observedAtMs < 0 || !source
35
51
  || (kind !== null && !['concrete', 'alias', 'policy'].includes(kind))) return null;
36
52
  if ((role === 'resolved' || role === 'turn') && (kind === 'alias' || kind === 'policy')) return null;
53
+ // WP-0: a historical alias fact is IGNORED before any precedence rule runs, so the real
54
+ // selection/turn headlines instead (an alias-only ledger stays unknown).
55
+ if (isReservedModelAlias(value)) return null;
37
56
  return {
38
57
  value,
39
58
  providerId: optionalString(fact.providerId),
@@ -198,7 +217,9 @@
198
217
  const selection = readFact(state.selection, 'selection');
199
218
  const resolved = readFact(state.resolved, 'resolved');
200
219
  const turn = readFact(state.lastCompletedTurn, 'turn');
201
- const fallback = hasDurableLedger(state) ? null : cleanString(fallbackModelId);
220
+ // WP-0: the raw id a legacy caller observed is a fallback, never a licence to show the reserved
221
+ // delegate alias as the lead model.
222
+ const fallback = hasDurableLedger(state) || isReservedModelAlias(fallbackModelId) ? null : cleanString(fallbackModelId);
202
223
  const lastUsed = turn ? turn.value : null;
203
224
  const observed = turn ? turn.value : resolved ? resolved.value : fallback;
204
225
  const base = {
@@ -274,8 +295,15 @@
274
295
  // bare `{model_owner, model_observation_health, model_switch_event}` envelope works too). It must
275
296
  // be forwarded EVEN WHEN there is no durable ledger — an explicit `model_owner: null` is an
276
297
  // authoritative unknown and must never fall back to the raw observed id.
298
+ //
299
+ // WP-0 (reviewed finding): the reserved delegate alias is NOT evidence, so a compat caller that has
300
+ // nothing else (no typed ledger, no authority) gets the presenter's EXISTING true unknown — the same
301
+ // projection an explicit null owner produces — instead of an `observed` state carrying an empty id.
302
+ // A pending request transition and every other non-alias id keep their established behavior.
303
+ var NO_MODEL_EVIDENCE_AUTHORITY = Object.freeze({ model_owner: null });
277
304
  function presentLeadModelCompat(observedModelId, request, modelState, authority = null) {
278
- const observed = String(observedModelId || '');
305
+ const reserved = isReservedModelAlias(observedModelId);
306
+ const observed = reserved ? '' : String(observedModelId || '');
279
307
  if (modelState || authorityOfSession(authority)) {
280
308
  return presentLeadModel(modelState || {}, request || null, observed || null, authority);
281
309
  }
@@ -283,6 +311,7 @@
283
311
  if (request && transition && transition.headline === 'target-pending' && !request.effort_only && request.model_id) {
284
312
  return { modelId: String(request.model_id), observedModelId: observed, state: 'awaiting_turn' };
285
313
  }
314
+ if (reserved) return presentLeadModel({}, null, null, NO_MODEL_EVIDENCE_AUTHORITY);
286
315
  return { modelId: observed, observedModelId: observed, state: 'observed' };
287
316
  }
288
317
 
@@ -632,16 +661,22 @@
632
661
  walle: 'Wall-E tabs pick their model in the Wall-E picker.',
633
662
  agent_unknown: 'CTM cannot switch this agent’s model.',
634
663
  no_resume_id: 'This session has not been restored yet, so its model cannot change. Open it first.',
664
+ source_launch_environment_unavailable: 'CTM cannot recover this session’s original launch environment (it was restored after a restart), so its model and effort are frozen. Close and reopen the session to switch.',
635
665
  };
636
666
  function leadErrorMessage(status, body) {
637
667
  const b = body || {};
638
668
  if (b.code === MODEL_ACTION_SNAPSHOT_STALE_CODE) return MODEL_ACTION_SNAPSHOT_STALE_GUIDANCE;
639
- if (b.code === 'lead_switch_unsupported') return UNSUPPORTED_SENTENCES[b.reason] || 'This session cannot switch its lead model.';
669
+ if (b.code === 'lead_switch_unsupported') return UNSUPPORTED_SENTENCES[b.reason] || b.message || 'This session cannot switch its lead model.';
640
670
  // U-8: the routed refusals carry server facts (a reason / a message), so they are built here.
641
671
  if (b.code === 'lead_route_invalid') return 'That gateway route can’t run this model as your lead right now'
642
672
  + (b.reason ? ' (' + String(b.reason).replace(/_/g, ' ') + ')' : '') + '.';
643
673
  if (b.code === 'lead_default_routed_unsupported') return b.message || 'A gateway model can’t be your CLI default.';
644
674
  if (b.code === 'lead_route_unavailable') return b.message || 'The gateway route is unavailable, so the session stays on its current model.';
675
+ // WP-1 (§5 D-4, §9 S-8): the launch-time native-provider gate refused this Codex thread. The
676
+ // message names the gateway provider the thread was created on, so the user knows the picker —
677
+ // not a retry — is the way out. Server-built sentence wins; the fallback keeps the same meaning.
678
+ if (b.code === 'codex_provider_missing') return b.message
679
+ || 'This Codex thread was created on a gateway provider; pick a model for this session to relaunch it.';
645
680
  return LEAD_ERROR_SENTENCES[b.code] || b.message || b.detail || b.error || ('HTTP ' + status);
646
681
  }
647
682
 
@@ -729,12 +764,17 @@
729
764
  for (const note of authorityDetailNotes(presentation)) details.push(note);
730
765
  return {
731
766
  modelId, providerId, awaitingModelTurn, unknown, tags, title: details.join(' · '),
732
- tokenModelId: presentation.lastUsedValue || presentation.observedModelId || (unknown ? null : currentModelId),
767
+ tokenModelId: presentation.lastUsedValue || presentation.observedModelId
768
+ || (unknown || isReservedModelAlias(currentModelId) ? null : currentModelId),
733
769
  };
734
770
  }
735
771
 
736
772
  function sessionModelChipView(presentation, modelState, currentModelId, hasActiveRequest, context, session) {
737
773
  presentation = presentation || {};
774
+ // WP-0: the raw session `model_id` is a legacy fallback; the reserved delegate alias is never a
775
+ // lead model, so it can neither headline the chip nor title it. (`readFact` already dropped it
776
+ // from any durable fact.)
777
+ if (isReservedModelAlias(currentModelId)) currentModelId = null;
738
778
  // WP1C: every public entry point is fail-closed for a typed unknown. A caller that hands us the
739
779
  // carrier rather than a typed projection still gets the SAME shared projection — never a raw
740
780
  // provider borrow or a '(detecting…)' placeholder. A typed projection the caller already holds