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
@@ -19,6 +19,7 @@
19
19
  native_prompt_unresolved: 'Native turn has no matching human prompt',
20
20
  native_spawn_unresolved: 'Parent link not recorded',
21
21
  native_spawn_ambiguous: 'Parent link is ambiguous',
22
+ native_spawn_missing: 'Subagent spawn record missing',
22
23
  native_agent_cycle: 'Agent parent links form a cycle',
23
24
  delegation_edge_missing: 'Worker launch not recorded in the lead transcript',
24
25
  delegation_edge_ambiguous: 'Worker launch matches several lead prompts',
@@ -125,6 +125,10 @@
125
125
  if (!ok) return { painted: null, invalid: true };
126
126
  const base = { epoch: p.epoch, top: p.top, pinned: p.pinned, floor: p.floor, revision: p.revision, breaks: Object.freeze(breaks.map((b) => Object.freeze({ at: b.at, reason: b.reason }))), below: Number.isSafeInteger(p.below) && p.below > 0 ? p.below : 0 }; // R-F2: rows the app holds below its screen; an older host omits it (0), and it is never a rejection reason
127
127
  if (p.revisedFrom !== undefined) base.revisedFrom = p.revisedFrom;
128
+ // Clock-free tests (WP-6): the recorder's observe count and its uncommitted hold pass through (HistoryPaintedRows publishes them);
129
+ // an older host sends neither, and a malformed value is dropped, never a rejection reason.
130
+ if (integer(p.samples) && p.samples >= 0) base.samples = p.samples;
131
+ if (p.hold && typeof p.hold === 'object' && integer(p.hold.rows)) base.hold = Object.freeze({ kind: typeof p.hold.kind === 'string' ? p.hold.kind : null, rows: p.hold.rows, top: integer(p.hold.top) ? p.hold.top : null });
128
132
  return { painted: Object.freeze(withRows ? { ...base, from: p.from, rows: Object.freeze(p.rows.slice()) } : base), invalid: false };
129
133
  }
130
134
 
@@ -81,12 +81,15 @@ function _onTerminalGeometryClaimAckV2(msg) {
81
81
  s._sessionGeometryRuntime?.setQueued(true);
82
82
  // A correction fit has already resized the local xterm to the proposed
83
83
  // grid, but a queued ACK proves the PTY is still on the incumbent grid.
84
- // Roll the presentation back immediately; the exact target proof remains
85
- // in the ledger and the server's queued claim for the later terminal ACK.
84
+ // Roll the presentation back immediately. WP-1 (docs/codex-terminal-geometry-sticky-cols-
85
+ // 2026-10-24.html; tests/geometry-queued-rollback.test.js): the rollback is presentation only
86
+ // and records no measurement, so the queued claim's proof stays the ledger's current proof and
87
+ // the server's bounded replay can commit it. Recording here replaced that proof (single-slot
88
+ // ledger), and the replay was rejected `measurement-stale` -- the widening never committed.
86
89
  const committedCols = Number(msg.committedGrid?.cols || 0);
87
90
  const committedRows = Number(msg.committedGrid?.rows || 0);
88
91
  if (s._terminalGeometryPendingResizeV2 && committedCols > 0 && committedRows > 0) {
89
- _applyTerminalActivationGrid(s, { cols: committedCols, rows: committedRows });
92
+ _applyTerminalActivationGrid(s, { cols: committedCols, rows: committedRows }, undefined, { recordMeasurement: false });
90
93
  }
91
94
  _syncTerminalInputOwnership(s, _resumeStateForSession(s));
92
95
  return false;
@@ -1313,15 +1316,21 @@ function _syncCodexActiveComposerGeometry(s, id, reason, opts) {
1313
1316
  }
1314
1317
  }
1315
1318
 
1319
+ // G-4 (D-2): report the grid xterm HOLDS after the resize above, never the proposal. The local
1320
+ // agent-TUI cols pin refuses a narrower proposal, so `cols`/`rows` are often not what the client
1321
+ // ended up with -- and `_sendTerminalResizeIfChanged` puts opts.cols on the wire verbatim, which
1322
+ // would tell the server to resize its PTY to a width this client does not hold.
1323
+ const heldCols = Number(s.term.cols) || currentCols;
1324
+ const heldRows = Number(s.term.rows) || currentRows;
1316
1325
  const sent = _sendTerminalResizeIfChanged(s, id, reason || 'codex-active-composer-geometry', {
1317
- cols: allowTermResize ? cols : currentCols,
1318
- rows: allowTermResize ? rows : currentRows,
1326
+ cols: allowTermResize ? heldCols : currentCols,
1327
+ rows: allowTermResize ? heldRows : currentRows,
1319
1328
  });
1320
1329
  if (resizeNeeded || sent) {
1321
1330
  s._codexActiveComposerGeometrySyncedAt = now;
1322
1331
  s._codexActiveComposerGeometrySyncReason = reason || 'codex-active-composer-geometry';
1323
- s._codexActiveComposerGeometrySyncedCols = allowTermResize ? cols : currentCols;
1324
- s._codexActiveComposerGeometrySyncedRows = allowTermResize ? rows : currentRows;
1332
+ s._codexActiveComposerGeometrySyncedCols = allowTermResize ? heldCols : currentCols;
1333
+ s._codexActiveComposerGeometrySyncedRows = allowTermResize ? heldRows : currentRows;
1325
1334
  }
1326
1335
  return !!(resizeNeeded || sent);
1327
1336
  }
@@ -22,6 +22,46 @@ function _reportReadinessViolationOnce(s, kind, since, gates, extraDetails) {
22
22
  _reportResumeBeacon('readiness-violation', s._id, since, { kind, gates: gates || [], ...(extraDetails || {}) });
23
23
  }
24
24
 
25
+ // WP-4a (§5 OQ-4, §6, S-21): the durable cover-over-content row recorded only gates=[], so a cover
26
+ // that outlived its session by ~11 min could not be attributed. This snapshot names the three
27
+ // candidate holders beside the mounted element: H-A storeLifecycle null/'active' with an overlay
28
+ // still in the DOM (the store forgot the session or already cleared it, so the clear is a silent
29
+ // no-op), H-B storeLifecycle 'resume-blocked' (shared element, every dismissal refuses it),
30
+ // H-C lastDismiss null or older than the cover (no dismissal ran). Instrumentation only: it reads
31
+ // state and never shows, dismisses or re-mounts anything (A-9). A missing/blocked DOM or CSS.escape
32
+ // degrades to 0/'' -- instrumentation must never be able to break the readiness sweep.
33
+ function _coverTruthSnapshot(s) {
34
+ const id = String(s?._id || '');
35
+ let containers = [];
36
+ let overlaysInDom = 0;
37
+ let label = null;
38
+ try {
39
+ if (id && typeof document !== 'undefined' && typeof document.querySelectorAll === 'function') {
40
+ const escaped = typeof CSS !== 'undefined' && typeof CSS.escape === 'function' ? CSS.escape(id) : id;
41
+ containers = Array.from(document.querySelectorAll('.term-container[data-session-id="' + escaped + '"]'));
42
+ }
43
+ overlaysInDom = containers.reduce((n, c) => n + (c?.querySelectorAll?.(':scope > .snapshot-loading-overlay')?.length || 0), 0);
44
+ label = s?.container?.querySelector?.('.snapshot-loading-overlay .snapshot-loading-text') || null;
45
+ } catch (_) { /* expected: a missing/blocked DOM or CSS.escape must degrade the snapshot to zeros, never break the sweep */ }
46
+ const rs = _resumeStateForSession(s);
47
+ return {
48
+ storeLifecycle: _presentationStore.getSessionState(id)?.lifecycle ?? null,
49
+ termContainers: containers.length,
50
+ overlaysInDom,
51
+ labelHead: String(label?.textContent || '').slice(0, 48),
52
+ rsState: String(rs?.state || ''),
53
+ rsDismissBlocked: rs?.dismissBlocked === true,
54
+ restoreFlags: {
55
+ resumeLoading: s?.resumeLoading === true,
56
+ deferred: !!s?._restoreDeferred,
57
+ resuming: !!s?._restoreResuming,
58
+ starting: !!s?._restoreStarting,
59
+ },
60
+ bootstrapPending: s?._terminalBootstrapPending === true,
61
+ lastDismiss: s?._lastOverlayDismiss || null,
62
+ };
63
+ }
64
+
25
65
  // Invariant: while a view is visible, blocked and not excluded, exactly one backstop is pending,
26
66
  // armed with the current epoch tuple (a re-arm on a changed tuple replaces the timer; a fire on a
27
67
  // stale tuple re-arms), so a blocked visible terminal can never be left without a rescue.
@@ -183,6 +223,7 @@ function _sweepVisibleSessionReadinessAndPaint(now) {
183
223
  if (now - s._readinessCoverContentSince >= 1000) {
184
224
  _reportReadinessViolationOnce(s, 'cover-over-content', s._readinessCoverContentSince, blockers, {
185
225
  predicate: 'cover-over-content',
226
+ coverTruth: _coverTruthSnapshot(s),
186
227
  });
187
228
  }
188
229
  } else {
@@ -46,7 +46,13 @@ function _terminalLocalFitProposal(s) {
46
46
  return cols > 0 && rows > 0 ? { cols, rows } : null;
47
47
  }
48
48
 
49
- function _applyTerminalActivationGrid(s, grid, viewportIntent) {
49
+ // WP-1 (docs/codex-terminal-geometry-sticky-cols-2026-10-24.html): `opts.recordMeasurement: false`
50
+ // is a PRESENTATION-ONLY adoption -- no ledger write, no claim, no bare resize report. Its one
51
+ // caller is the queued claim-ACK rollback: the ledger is single-slot, so recording there replaced
52
+ // the queued claim's proof and its server replay was rejected `measurement-stale`. Every other
53
+ // caller omits `opts` and records exactly as before.
54
+ function _applyTerminalActivationGrid(s, grid, viewportIntent, opts = {}) {
55
+ const recordMeasurement = opts.recordMeasurement !== false;
50
56
  const cols = Math.floor(Number(grid?.cols) || 0); const rows = Math.floor(Number(grid?.rows) || 0);
51
57
  if (!s?.term || cols < 1 || rows < 1) return false;
52
58
  if (s.term.cols === cols && s.term.rows === rows) {
@@ -55,7 +61,7 @@ function _applyTerminalActivationGrid(s, grid, viewportIntent) {
55
61
  // is already at the PTY grid (seeded there, or a repeat apply) never reaches it, never
56
62
  // gets a measurement ledger, and `_sendTerminalGeometryClaimV2` vetoes every claim on
57
63
  // the missing ledger forever (wedge-two-viewer.spec.js test 2 -- zero claim rows for B).
58
- if (!s._terminalMeasurementLedger && s._id
64
+ if (recordMeasurement && !s._terminalMeasurementLedger && s._id
59
65
  && typeof _recordTerminalFitMeasurement === 'function'
60
66
  && typeof window !== 'undefined' && window.TerminalGeometryClaim) {
61
67
  _recordTerminalFitMeasurement(s, s._id, { cols, rows });
@@ -94,9 +100,9 @@ function _applyTerminalActivationGrid(s, grid, viewportIntent) {
94
100
  const canRecordMeasurement = !!(s._id
95
101
  && typeof _recordTerminalFitMeasurement === 'function'
96
102
  && typeof window !== 'undefined' && window.TerminalGeometryClaim);
97
- if (canRecordMeasurement) {
103
+ if (recordMeasurement && canRecordMeasurement) {
98
104
  _recordTerminalFitMeasurement(s, s._id || '', { cols, rows });
99
- } else if (typeof _sendTerminalResizeIfChanged === 'function') {
105
+ } else if (recordMeasurement && typeof _sendTerminalResizeIfChanged === 'function') {
100
106
  _sendTerminalResizeIfChanged(s, s._id || '', 'activation-grid-apply');
101
107
  }
102
108
  }
@@ -139,6 +145,37 @@ function _undoRefusedTerminalGridAdoption(s, cols, rows) {
139
145
  return true;
140
146
  }
141
147
 
148
+ // WP-1 (docs/nightly-browser-tier-round2-2026-10-21.html §5 D-1, §9 G-1..G-3): the ONE
149
+ // all-or-nothing grid-adoption primitive. Every resize whose grid the client did NOT fit itself --
150
+ // the authoritative snapshot replay (index.html onSnapshot), the rows-only restore (runtime-19.js),
151
+ // the dims-reassert capitulation (runtime-16.js) -- goes through here, and each caller stops on a
152
+ // `false` (no replay of grid-relative bytes, no `_lastResizeSentCols/Rows` seed, no recorded fit).
153
+ // Applies, reads back the grid xterm actually holds, and on mismatch restores the prior grid
154
+ // through _undoRefusedTerminalGridAdoption. It never sends and never records a fit: reporting the
155
+ // held grid is the caller's job (D-2), which is why callers must not report the requested values.
156
+ function _adoptTerminalGrid(s, cols, rows, reason) {
157
+ if (!s || !s.term) return false;
158
+ const c = Math.floor(Number(cols) || 0);
159
+ const r = Math.floor(Number(rows) || 0);
160
+ if (c < 1 || r < 1) return false;
161
+ const priorCols = Number(s.term.cols || 0);
162
+ const priorRows = Number(s.term.rows || 0);
163
+ if (priorCols === c && priorRows === r) return true;
164
+ const wasSuppressed = !!s._suppressResize;
165
+ s._suppressResize = true;
166
+ try {
167
+ _runTerminalMutation(s, reason || 'terminal-grid-adopt', () => s.term.resize(c, r));
168
+ } catch (_) {
169
+ /* expected: a refused/throwing resize must not escape an adoption that only restores the
170
+ caller's prior grid below; the read-back decides, not the throw */
171
+ } finally {
172
+ s._suppressResize = wasSuppressed;
173
+ }
174
+ if (Number(s.term.cols) === c && Number(s.term.rows) === r) return true;
175
+ _undoRefusedTerminalGridAdoption(s, priorCols, priorRows);
176
+ return false;
177
+ }
178
+
142
179
  // 2026-10-11 incident: every .term-container measured half of #terminal-area; this names the in-flow element that took the other half (flat keys survive lib/client-diag-handler.js sanitizer).
143
180
  function _terminalAreaLayoutCensus(container) {
144
181
  try {
@@ -1030,6 +1030,21 @@ function _terminalDraftUploadOwnership(id) {
1030
1030
  return { lifetime, context };
1031
1031
  }
1032
1032
 
1033
+ // This adapter has no terminal-local captures; the lifetime owns its HTTP work and abort signal.
1034
+ async function _terminalDeleteServerDraft(id, attachment, options = {}, operation = {}) {
1035
+ const lifetime = _terminalRootDraftLifetime;
1036
+ const owned = operation.context ? null : _terminalDraftUploadOwnership(id);
1037
+ const context = operation.context || (owned && !owned.reason ? owned.context : null);
1038
+ if (!lifetime || !context || typeof lifetime.deleteServerDraft !== 'function') return false;
1039
+ const isCurrent = () => lifetime === _terminalRootDraftLifetime && context.id === id
1040
+ && lifetime.current(context) && (typeof operation.isCurrent !== 'function' || operation.isCurrent() === true);
1041
+ if (!isCurrent()) return false;
1042
+ const retry = (url, request, retryOptions) => lifetime.fetchWithRetry(fetch, url, request, retryOptions);
1043
+ const accepted = await lifetime.deleteServerDraft({ id, attachment, options, context, isCurrent,
1044
+ token: String(state.token || ''), retry });
1045
+ return accepted === true && isCurrent();
1046
+ }
1047
+
1033
1048
  // §6.3.1 + review finding 4: the verified private continuity key is the ROOT SCOPE's own
1034
1049
  // continuity hash for the live lease -- not a host+session string (which would let the same
1035
1050
  // host/session under a different authenticated principal reactivate an old proof). Fail closed.
@@ -1127,6 +1142,23 @@ function _terminalFailAttachmentUpload(id, attachment, error) {
1127
1142
  return true;
1128
1143
  }
1129
1144
 
1145
+ // R-4: a verified upload whose server snapshot this tab refused must not hang on "Uploading". The
1146
+ // server already holds (and may deliver) the draft, so this is NOT retryable -- a re-upload would
1147
+ // paste the same image twice; a reload restores the true row from the list. Every silent caller of a
1148
+ // verified-adoption result reports here so a refused publication is visible with a reason.
1149
+ function _terminalRejectedUploadOutcome(id, attachment, outcome, deps) {
1150
+ const reason = String(outcome && outcome.reason || 'rejected');
1151
+ const failed = _terminalFailAttachmentUpload(id, attachment, {
1152
+ code: 'CTM_UPLOAD_PUBLICATION_REJECTED',
1153
+ message: 'Uploaded, but this tab could not confirm it (' + reason + '). Reload to see its real state.',
1154
+ retryable: false,
1155
+ });
1156
+ if (!failed) return false;
1157
+ deps.metric(id, 'upload_publication_rejected', { reason, attachmentOrdinal: attachment.ordinal });
1158
+ void deps.postDiagnostic(id, 'upload_publication_rejected', attachment, { reason });
1159
+ return true;
1160
+ }
1161
+
1130
1162
  // Review finding 9 (§9 rows: index.html retry / edit conflict / submission resume, runtime-10.js
1131
1163
  // freeze): the ONE server-derived-metadata entry for call sites that used to Object.assign() a
1132
1164
  // response body straight onto a draft row. A payload carrying a lifecycle version is adopted
@@ -1181,7 +1213,10 @@ async function _terminalRetryAttachmentUploadOwned(id, attachment, deps) {
1181
1213
  return false;
1182
1214
  }
1183
1215
  const outcome = _terminalFinishAttachmentUpload(id, attachment, uploaded); // WP-3 §6: adopt or legacy ready
1184
- if (outcome.outcome === 'rejected') return false;
1216
+ if (outcome.outcome === 'rejected') {
1217
+ _terminalRejectedUploadOutcome(id, attachment, outcome, { metric: deps.metric, postDiagnostic: deps.postDiagnostic });
1218
+ return false;
1219
+ }
1185
1220
  // The server's 'create' op (inside _terminalUploadPastedImage) already nudged the
1186
1221
  // reconciler for this newly-created draft row -- do not also race it here.
1187
1222
  if (serverDeliveryOn) return true;
@@ -1281,7 +1316,22 @@ function onTerminalImageDraftState(msg) {
1281
1316
  reservation = owned.lifetime.imageUploadReservation(owned.context, requestId);
1282
1317
  if (reservation) attachment = reservation.attachment;
1283
1318
  }
1284
- if (!attachment) return;
1319
+ if (!attachment) {
1320
+ // B9: an upload this client never started -- the usual shape right after a reload, or in a
1321
+ // second tab on a session with a durable draft -- has no row yet even though the server may
1322
+ // already have published its terminal outcome: the restore LIST is what creates the row, and
1323
+ // it can still be in flight. Dropping the publication here left the restored chip frozen on
1324
+ // the list's older state (`delivery_pending` -> 'attaching') for the life of the page, while
1325
+ // the chip title already claimed "Attached ✓" from the local client hint. Retain it instead
1326
+ // (identity-fenced, newest-version-wins) and let the restore that creates the row adopt it.
1327
+ // The publication is only ever retained against a LIVE captured context: `owned.reason`
1328
+ // means there is no restore in flight for this session, and the list read that follows is
1329
+ // necessarily fresh.
1330
+ if (owned.context && !owned.reason && typeof owned.lifetime.retainUnmatchedPublication === 'function') {
1331
+ owned.lifetime.retainUnmatchedPublication(owned.context, msg, msg.hint);
1332
+ }
1333
+ return;
1334
+ }
1285
1335
 
1286
1336
  const stateVersion = typeof Draft.stateVersionOf === 'function' ? Draft.stateVersionOf(msg.stateVersion) : null;
1287
1337
  if (stateVersion === null) {
@@ -712,18 +712,18 @@ function _maybeReassertStateSyncDims(s, msg) {
712
712
  });
713
713
  if (bounded.action === 'capitulate') {
714
714
  s._stateSyncDimsSkipStreak = 0;
715
- const wasSuppressed = !!s._suppressResize;
716
- s._suppressResize = true;
717
- let resizeSucceeded = false;
718
- try {
719
- resizeSucceeded = _runFrameGateMutation(
720
- s,
721
- 'dims-reassert-capitulation',
722
- () => s.term.resize(mCols, mRows),
723
- );
724
- } finally {
725
- s._suppressResize = wasSuppressed;
726
- }
715
+ // WP-1 (D-1, G-3): the losing viewer adopts the mirror grid through the shared all-or-nothing
716
+ // primitive -- the cols-pin chokepoint refuses a narrower mirror, so a bare resize would land
717
+ // a hybrid AND seed _lastResizeSentCols/Rows with a grid that was never sent. The frame gate
718
+ // still owns this mutation (withOwnedTerminalMutation); _adoptTerminalGrid reads the grid
719
+ // back, so a mutation the gate only QUEUED is not an adoption.
720
+ let adopted = false;
721
+ const gated = _runFrameGateMutation(
722
+ s,
723
+ 'dims-reassert-capitulation',
724
+ () => { adopted = _adoptTerminalGrid(s, mCols, mRows, 'dims-reassert-capitulation') === true; },
725
+ );
726
+ const resizeSucceeded = gated === true && adopted;
727
727
  if (resizeSucceeded) {
728
728
  const cellHeight = Number(s.term?._core?._renderService?.dimensions?.css?.cell?.height) || 0;
729
729
  const containerHeight = Number(s.container?.clientHeight) || 0;
@@ -151,6 +151,11 @@ function _normalizeTerminalColsToFitBaseline(s, id, proposal) {
151
151
  // count (up OR down) so the rendered/serialized width stays consistent.
152
152
  try {
153
153
  _runTerminalMutation(s, 'fit-baseline-correction', () => s.term.resize(baseline.cols, s.term.rows));
154
+ // WP-1 (D-3, G-5): only claim a correction that actually happened. The cols-pin chokepoint
155
+ // can refuse this snap (a narrowing onto the remembered col count), and reporting
156
+ // "corrected" plus refreshing the baseline would then describe a grid this client never
157
+ // held -- the next fit would keep snapping toward it.
158
+ if (Number(s.term.cols) !== baseline.cols) return false;
154
159
  baseline.width = width;
155
160
  baseline.at = Date.now();
156
161
  s._fitBaselineCorrectedAt = Date.now();
@@ -179,6 +184,15 @@ function _normalizeTerminalColsToFitBaseline(s, id, proposal) {
179
184
  toCols: cols,
180
185
  widthPx: Math.round(width),
181
186
  reason: 'large-divergence',
187
+ // WP-2 (docs/codex-terminal-geometry-sticky-cols-2026-10-24.html §5): the fit width
188
+ // alone could not explain a "pane measured 721 px" incident -- the browser viewport width
189
+ // and whether split view was on are the layout facts that separate a real pane resize from
190
+ // a transient container reading. `window` is probed (not dereferenced bare) because this
191
+ // function is evaluated by several existing windowless harnesses
192
+ // (tests/terminal-fit-baseline-adopted-beacon.test.js, tests/terminal-grid-pane-fit.test.js);
193
+ // it is always defined in the page, and the guard only keeps the beacon from throwing there.
194
+ viewportWidthPx: Math.round(Number(typeof window === 'undefined' ? 0 : window.innerWidth) || 0),
195
+ split: !!state.splitRoot,
182
196
  });
183
197
  baseline.cols = cols;
184
198
  baseline.width = width;
@@ -319,11 +319,15 @@ function _restoreSnapshotDataImpl(s, data, onDone, opts) {
319
319
  && rowsOnlyCols > 0
320
320
  && rowsOnlyCols === Math.floor(Number(s._snapshotRestoreGridCols) || 0)
321
321
  && opts.snapshotScrollbackFp === s._snapshotScrollbackFp;
322
- if (rowsOnlyEligible) {
322
+ // WP-1 (D-1, G-2): the rows-only fast path replays a grid-relative viewport slice, so it may
323
+ // only run on a grid this client actually adopted. A narrow refused at the cols-pin chokepoint
324
+ // lands as a hybrid (local cols, snapshot rows), and the slice would then be replayed onto a
325
+ // grid nobody holds -- skip the fast path and fall through to the full restore below.
326
+ const rowsOnlyAdopted = rowsOnlyEligible
327
+ ? _adoptTerminalGrid(s, rowsOnlyCols, rowsOnlyRows, 'rows-only-restore-resize')
328
+ : false;
329
+ if (rowsOnlyEligible && rowsOnlyAdopted) {
323
330
  try {
324
- if (s.term.cols !== rowsOnlyCols || s.term.rows !== rowsOnlyRows) {
325
- _runTerminalMutation(s, 'rows-only-restore-resize', () => s.term.resize(rowsOnlyCols, rowsOnlyRows));
326
- }
327
331
  // Slice raw data at the server-stamped boundary, then use the same transform chain as
328
332
  // the full restore. The existing scrollback remains untouched.
329
333
  const rowsOnlySource = restoreOpts.source || restoreOpts.kind || 'snapshot';