@indigoai-us/hq-cli 5.312.2-beta.0 → 5.314.0

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 (1144) hide show
  1. package/CHANGELOG.md +1 -4293
  2. package/assets/scaffold/core/scripts/checkpoint-stop-gate.sh +43 -281
  3. package/assets/scaffold/core/scripts/hook-lib.sh +50 -345
  4. package/assets/scaffold/core/scripts/hq-session.sh +23 -184
  5. package/assets/scaffold/core/scripts/lib/session-id.sh +2 -3
  6. package/assets/scaffold/core/scripts/lib/session-scope-capability.sh +1 -1
  7. package/assets/scaffold/core/scripts/lib/work-mesh-enqueue.sh +1 -2
  8. package/assets/scaffold/core/scripts/qmd-reindex-after-sync.sh +87 -10
  9. package/assets/scaffold/core/scripts/rebuild-company-knowledge-index.sh +3 -36
  10. package/assets/scaffold/core/scripts/rebuild-projects-index.sh +12 -99
  11. package/assets/scaffold/core/scripts/token-usage-report.sh +20 -81
  12. package/dist/bin/hq-auth-refresh.d.ts +0 -2
  13. package/dist/bin/hq-auth-refresh.js +6 -12
  14. package/dist/commands/__fixtures__/access-vault.d.ts +0 -2
  15. package/dist/commands/__fixtures__/access-vault.js +1 -1
  16. package/dist/commands/_patterns.d.ts +0 -16
  17. package/dist/commands/_patterns.js +3 -20
  18. package/dist/commands/access.d.ts +1 -2
  19. package/dist/commands/access.js +49 -58
  20. package/dist/commands/agents.d.ts +4 -106
  21. package/dist/commands/agents.js +45 -924
  22. package/dist/commands/auth.d.ts +0 -1
  23. package/dist/commands/auth.js +19 -189
  24. package/dist/commands/billing.d.ts +0 -3
  25. package/dist/commands/billing.js +1 -6
  26. package/dist/commands/channels.js +1 -56
  27. package/dist/commands/cloud-demote.js +2 -3
  28. package/dist/commands/cloud-provision.d.ts +0 -14
  29. package/dist/commands/cloud-provision.js +58 -232
  30. package/dist/commands/cloud.d.ts +15 -49
  31. package/dist/commands/cloud.js +122 -358
  32. package/dist/commands/company-transfer.d.ts +28 -4
  33. package/dist/commands/company-transfer.js +49 -5
  34. package/dist/commands/company.js +3 -66
  35. package/dist/commands/core-checkpoint.d.ts +9 -19
  36. package/dist/commands/core-checkpoint.js +37 -301
  37. package/dist/commands/core.d.ts +0 -4
  38. package/dist/commands/core.js +80 -270
  39. package/dist/commands/crm.js +3 -52
  40. package/dist/commands/db-provision.js +4 -4
  41. package/dist/commands/db-sql.js +21 -7
  42. package/dist/commands/dm.d.ts +12 -119
  43. package/dist/commands/dm.js +38 -388
  44. package/dist/commands/doctor.d.ts +0 -12
  45. package/dist/commands/doctor.js +12 -158
  46. package/dist/commands/feedback.d.ts +0 -6
  47. package/dist/commands/feedback.js +37 -86
  48. package/dist/commands/files-browse.d.ts +12 -32
  49. package/dist/commands/files-browse.js +60 -176
  50. package/dist/commands/files.d.ts +0 -17
  51. package/dist/commands/files.js +47 -300
  52. package/dist/commands/group-grants.js +2 -3
  53. package/dist/commands/groups.js +5 -6
  54. package/dist/commands/index-cmd.d.ts +1 -19
  55. package/dist/commands/index-cmd.js +7 -74
  56. package/dist/commands/integrations-api.d.ts +10 -15
  57. package/dist/commands/integrations-api.js +22 -27
  58. package/dist/commands/integrations-connect.d.ts +13 -51
  59. package/dist/commands/integrations-connect.js +71 -86
  60. package/dist/commands/integrations-core.d.ts +6 -6
  61. package/dist/commands/integrations-core.js +11 -25
  62. package/dist/commands/integrations-import.d.ts +1 -1
  63. package/dist/commands/integrations-import.js +24 -43
  64. package/dist/commands/integrations-manage.js +13 -20
  65. package/dist/commands/integrations.d.ts +0 -8
  66. package/dist/commands/integrations.js +7 -94
  67. package/dist/commands/login.js +6 -49
  68. package/dist/commands/mcp-registration.d.ts +25 -32
  69. package/dist/commands/mcp-registration.js +23 -256
  70. package/dist/commands/mcp-status.js +0 -1
  71. package/dist/commands/meetings.js +34 -55
  72. package/dist/commands/members.js +1 -5
  73. package/dist/commands/mesh.d.ts +0 -11
  74. package/dist/commands/mesh.js +76 -1086
  75. package/dist/commands/onboard-identity-guard.d.ts +1 -1
  76. package/dist/commands/onboard.js +5 -24
  77. package/dist/commands/pack-install.js +1 -3
  78. package/dist/commands/packs.js +1 -11
  79. package/dist/commands/people.d.ts +0 -4
  80. package/dist/commands/people.js +3 -37
  81. package/dist/commands/publish.d.ts +1 -8
  82. package/dist/commands/publish.js +4 -17
  83. package/dist/commands/reindex.js +6 -56
  84. package/dist/commands/rescue.d.ts +0 -4
  85. package/dist/commands/rescue.js +17 -27
  86. package/dist/commands/run.js +4 -18
  87. package/dist/commands/safe-extract.d.ts +2 -11
  88. package/dist/commands/safe-extract.js +8 -36
  89. package/dist/commands/scaffold-fast.d.ts +41 -0
  90. package/dist/commands/scaffold-fast.js +57 -0
  91. package/dist/commands/secrets.d.ts +2 -20
  92. package/dist/commands/secrets.js +71 -175
  93. package/dist/commands/skill.d.ts +4 -35
  94. package/dist/commands/skill.js +18 -357
  95. package/dist/commands/sync-mode.d.ts +0 -11
  96. package/dist/commands/sync-mode.js +0 -30
  97. package/dist/commands/sync-narrow.js +5 -36
  98. package/dist/commands/team-sync.js +10 -71
  99. package/dist/commands/update.js +0 -6
  100. package/dist/commands/whoami.d.ts +0 -22
  101. package/dist/commands/whoami.js +4 -137
  102. package/dist/commands/workers.d.ts +14 -2
  103. package/dist/commands/workers.js +10 -7
  104. package/dist/fast-core.d.ts +7 -6
  105. package/dist/fast-core.js +24 -80
  106. package/dist/index.d.ts +4 -3
  107. package/dist/index.js +9 -59
  108. package/dist/lazy-commands.d.ts +44 -20
  109. package/dist/lazy-commands.js +58 -60
  110. package/dist/lib/company-skill-wrapper.d.ts +0 -1
  111. package/dist/lib/company-skill-wrapper.js +29 -121
  112. package/dist/lib/core-utils/codex-skill-bridge.d.ts +1 -2
  113. package/dist/lib/core-utils/qmd-reindex-after-sync.d.ts +1 -14
  114. package/dist/lib/core-utils/qmd-reindex-after-sync.js +17 -101
  115. package/dist/lib/core-utils/soft-timeout.js +1 -1
  116. package/dist/lib/core-utils/timeout-guard.d.ts +3 -3
  117. package/dist/lib/core-utils/timeout-guard.js +13 -28
  118. package/dist/lib/core-utils/token-usage-report.js +3 -17
  119. package/dist/lib/db/control-plane.js +0 -6
  120. package/dist/lib/db/local.d.ts +5 -0
  121. package/dist/lib/db/local.js +1 -1
  122. package/dist/lib/db/migrate.d.ts +12 -0
  123. package/dist/lib/db/migrate.js +5 -5
  124. package/dist/lib/db/remote-sql.d.ts +2 -2
  125. package/dist/lib/db/remote-sql.js +3 -3
  126. package/dist/lib/db/sql.d.ts +10 -0
  127. package/dist/lib/db/sql.js +8 -4
  128. package/dist/lib/doctor/__testing__/fake-hq-tree.d.ts +1 -1
  129. package/dist/lib/doctor/__testing__/fake-hq-tree.js +1 -1
  130. package/dist/lib/doctor/checks/claude-wiring.js +1 -70
  131. package/dist/lib/doctor/checks/codex-wiring.d.ts +4 -0
  132. package/dist/lib/doctor/checks/codex-wiring.js +35 -3
  133. package/dist/lib/doctor/checks/grok-wiring.js +34 -1
  134. package/dist/lib/doctor/checks/integrations.js +0 -11
  135. package/dist/lib/doctor/checks/runtime-health.d.ts +17 -4
  136. package/dist/lib/doctor/checks/runtime-health.js +7 -20
  137. package/dist/lib/doctor/checks/sync-health.d.ts +0 -21
  138. package/dist/lib/doctor/checks/sync-health.js +2 -72
  139. package/dist/lib/doctor/checks/work-context.js +6 -12
  140. package/dist/lib/doctor/compat.d.ts +16 -0
  141. package/dist/lib/doctor/compat.js +3 -4
  142. package/dist/lib/doctor/deep/effects.js +3 -1
  143. package/dist/lib/doctor/deep/executor.d.ts +10 -4
  144. package/dist/lib/doctor/deep/executor.js +1 -1
  145. package/dist/lib/doctor/deep/parity.d.ts +29 -2
  146. package/dist/lib/doctor/deep/parity.js +7 -7
  147. package/dist/lib/doctor/deep/sandbox.d.ts +25 -7
  148. package/dist/lib/doctor/deep/sandbox.js +7 -5
  149. package/dist/lib/doctor/fix/apply.d.ts +8 -79
  150. package/dist/lib/doctor/fix/apply.js +80 -292
  151. package/dist/lib/doctor/fix/remediation.d.ts +6 -14
  152. package/dist/lib/doctor/fix/remediation.js +9 -49
  153. package/dist/lib/doctor/fixtures/schema.js +3 -1
  154. package/dist/lib/doctor/json-output.d.ts +1 -17
  155. package/dist/lib/doctor/json-output.js +2 -7
  156. package/dist/lib/doctor/platform.d.ts +26 -0
  157. package/dist/lib/doctor/platform.js +5 -5
  158. package/dist/lib/doctor/registry.d.ts +0 -14
  159. package/dist/lib/doctor/registry.js +0 -71
  160. package/dist/lib/doctor/report.js +1 -1
  161. package/dist/lib/doctor/types.d.ts +0 -5
  162. package/dist/lib/doctor/types.js +0 -20
  163. package/dist/lib/flag-registry-worker.js +1 -12
  164. package/dist/lib/flag-registry.d.ts +6 -26
  165. package/dist/lib/flag-registry.js +16 -133
  166. package/dist/lib/index-render/companies.d.ts +1 -4
  167. package/dist/lib/index-render/companies.js +3 -66
  168. package/dist/lib/index-render/company-knowledge.js +17 -80
  169. package/dist/lib/index-render/index.d.ts +0 -1
  170. package/dist/lib/index-render/index.js +1 -2
  171. package/dist/lib/index-render/projects.js +5 -82
  172. package/dist/lib/index-render/shared.d.ts +1 -13
  173. package/dist/lib/index-render/shared.js +2 -41
  174. package/dist/lib/mesh/api.d.ts +10 -103
  175. package/dist/lib/mesh/api.js +64 -334
  176. package/dist/lib/mesh/client.d.ts +2 -3
  177. package/dist/lib/mesh/client.js +2 -3
  178. package/dist/lib/mesh/live/backfill-held.d.ts +16 -67
  179. package/dist/lib/mesh/live/backfill-held.js +61 -415
  180. package/dist/lib/mesh/live/backoff.d.ts +2 -2
  181. package/dist/lib/mesh/live/backoff.js +3 -16
  182. package/dist/lib/mesh/live/daemon/board-refresh.d.ts +1 -7
  183. package/dist/lib/mesh/live/daemon/board-refresh.js +30 -78
  184. package/dist/lib/mesh/live/daemon/credentials.d.ts +10 -64
  185. package/dist/lib/mesh/live/daemon/credentials.js +20 -270
  186. package/dist/lib/mesh/live/daemon/doctor.d.ts +0 -51
  187. package/dist/lib/mesh/live/daemon/doctor.js +6 -180
  188. package/dist/lib/mesh/live/daemon/index.d.ts +10 -13
  189. package/dist/lib/mesh/live/daemon/index.js +6 -7
  190. package/dist/lib/mesh/live/daemon/install.d.ts +1 -255
  191. package/dist/lib/mesh/live/daemon/install.js +13 -811
  192. package/dist/lib/mesh/live/daemon/paths.d.ts +0 -2
  193. package/dist/lib/mesh/live/daemon/paths.js +0 -2
  194. package/dist/lib/mesh/live/daemon/presence.d.ts +5 -24
  195. package/dist/lib/mesh/live/daemon/presence.js +10 -79
  196. package/dist/lib/mesh/live/daemon/run.d.ts +2 -48
  197. package/dist/lib/mesh/live/daemon/run.js +33 -485
  198. package/dist/lib/mesh/live/daemon/state.d.ts +2 -19
  199. package/dist/lib/mesh/live/daemon/state.js +2 -34
  200. package/dist/lib/mesh/live/daemon/transcript-watch.d.ts +9 -45
  201. package/dist/lib/mesh/live/daemon/transcript-watch.js +31 -227
  202. package/dist/lib/mesh/live/emit-client.d.ts +0 -8
  203. package/dist/lib/mesh/live/emit-client.js +8 -23
  204. package/dist/lib/mesh/live/emit-evidence.d.ts +0 -19
  205. package/dist/lib/mesh/live/emit-evidence.js +2 -20
  206. package/dist/lib/mesh/live/emit.d.ts +0 -9
  207. package/dist/lib/mesh/live/emit.js +2 -28
  208. package/dist/lib/mesh/live/enqueue.d.ts +0 -5
  209. package/dist/lib/mesh/live/enqueue.js +0 -19
  210. package/dist/lib/mesh/live/flush.d.ts +5 -17
  211. package/dist/lib/mesh/live/flush.js +38 -391
  212. package/dist/lib/mesh/live/format-spool-line.d.ts +2 -5
  213. package/dist/lib/mesh/live/format-spool-line.js +0 -10
  214. package/dist/lib/mesh/live/paths.d.ts +0 -2
  215. package/dist/lib/mesh/live/paths.js +0 -4
  216. package/dist/lib/mesh/live/session-event.schema.json +1 -24
  217. package/dist/lib/mesh/live/session-events-client.d.ts +0 -2
  218. package/dist/lib/mesh/live/session-events-client.js +0 -26
  219. package/dist/lib/mesh/live/spool.d.ts +0 -19
  220. package/dist/lib/mesh/live/spool.js +3 -269
  221. package/dist/lib/mesh/live/validate-session-event.d.ts +1 -1
  222. package/dist/lib/mesh/live/validate-session-event.js +1 -1
  223. package/dist/lib/plan-limit-nag.d.ts +6 -102
  224. package/dist/lib/plan-limit-nag.js +43 -348
  225. package/dist/lib/scan-packages/index.d.ts +0 -2
  226. package/dist/lib/scan-packages/index.js +6 -168
  227. package/dist/lib/search-index/background.d.ts +1 -8
  228. package/dist/lib/search-index/background.js +200 -55
  229. package/dist/lib/search-index/index.d.ts +0 -12
  230. package/dist/lib/search-index/index.js +7 -153
  231. package/dist/lib/work-context/company.d.ts +20 -22
  232. package/dist/lib/work-context/company.js +40 -124
  233. package/dist/lib/work-context/config.d.ts +11 -58
  234. package/dist/lib/work-context/config.js +83 -334
  235. package/dist/lib/work-context/contract.d.ts +0 -10
  236. package/dist/lib/work-context/index.d.ts +25 -0
  237. package/dist/lib/work-context/index.js +21 -0
  238. package/dist/lib/work-context/outbox.d.ts +1 -14
  239. package/dist/lib/work-context/outbox.js +1 -87
  240. package/dist/lib/work-context/reconcile.d.ts +0 -15
  241. package/dist/lib/work-context/reconcile.js +25 -380
  242. package/dist/lib/work-context/state.d.ts +10 -93
  243. package/dist/lib/work-context/state.js +29 -342
  244. package/dist/lib/workers-registry/index.js +8 -62
  245. package/dist/main.d.ts +0 -12
  246. package/dist/main.js +73 -266
  247. package/dist/node-network-compat.d.ts +30 -2
  248. package/dist/node-network-compat.js +51 -4
  249. package/dist/node-preflight.d.ts +1 -7
  250. package/dist/node-preflight.js +5 -5
  251. package/dist/register-all.d.ts +29 -4
  252. package/dist/register-all.js +233 -4
  253. package/dist/run/discover-schemas.d.ts +1 -2
  254. package/dist/run/env-graph-guard.d.ts +2 -2
  255. package/dist/run/env-graph-guard.js +2 -5
  256. package/dist/run/hq-plugin.d.ts +0 -4
  257. package/dist/run/hq-plugin.js +8 -36
  258. package/dist/sentry-before-send.js +0 -80
  259. package/dist/sentry.d.ts +2 -8
  260. package/dist/sentry.js +13 -117
  261. package/dist/startup-registration.d.ts +2 -26
  262. package/dist/startup-registration.js +15 -116
  263. package/dist/utils/cli-telemetry.d.ts +1 -74
  264. package/dist/utils/cli-telemetry.js +7 -434
  265. package/dist/utils/client-health.d.ts +4 -0
  266. package/dist/utils/client-health.js +2 -2
  267. package/dist/utils/cognito-session.d.ts +0 -71
  268. package/dist/utils/cognito-session.js +27 -481
  269. package/dist/utils/contribution-table.d.ts +1 -1
  270. package/dist/utils/environmental-error.d.ts +0 -18
  271. package/dist/utils/environmental-error.js +7 -240
  272. package/dist/utils/expected-cli-error.d.ts +0 -2
  273. package/dist/utils/expected-cli-error.js +0 -4
  274. package/dist/utils/feedback-diagnostics.d.ts +1 -2
  275. package/dist/utils/feedback-log-bundle.d.ts +26 -51
  276. package/dist/utils/feedback-log-bundle.js +31 -211
  277. package/dist/utils/feedback-logs.d.ts +47 -18
  278. package/dist/utils/feedback-logs.js +21 -50
  279. package/dist/utils/feedback-screenshots.d.ts +1 -0
  280. package/dist/utils/feedback-screenshots.js +1 -1
  281. package/dist/utils/hq-roots.d.ts +2 -25
  282. package/dist/utils/hq-roots.js +7 -67
  283. package/dist/utils/incomplete-install-error.d.ts +19 -87
  284. package/dist/utils/incomplete-install-error.js +68 -319
  285. package/dist/utils/install-tree-torn.d.ts +24 -260
  286. package/dist/utils/install-tree-torn.js +51 -998
  287. package/dist/utils/large-file-guard.d.ts +10 -0
  288. package/dist/utils/large-file-guard.js +1 -1
  289. package/dist/utils/local-files-overview.d.ts +8 -4
  290. package/dist/utils/local-files-overview.js +7 -48
  291. package/dist/utils/login-provider.d.ts +0 -7
  292. package/dist/utils/login-provider.js +0 -34
  293. package/dist/utils/pack-contributions.d.ts +9 -2
  294. package/dist/utils/pack-contributions.js +43 -6
  295. package/dist/utils/package-root-diagnostics.d.ts +1 -1
  296. package/dist/utils/people.d.ts +11 -7
  297. package/dist/utils/people.js +20 -5
  298. package/dist/utils/plan-gate-error.d.ts +10 -52
  299. package/dist/utils/plan-gate-error.js +41 -364
  300. package/dist/utils/qmd-model-download-error.d.ts +8 -0
  301. package/dist/utils/qmd-model-download-error.js +1 -1
  302. package/dist/utils/qmd-query-document-error.d.ts +6 -0
  303. package/dist/utils/qmd-query-document-error.js +1 -1
  304. package/dist/utils/redact-error-text.js +1 -2
  305. package/dist/utils/run-bundled-script.d.ts +0 -6
  306. package/dist/utils/run-bundled-script.js +4 -117
  307. package/dist/utils/secrets-cache.d.ts +3 -7
  308. package/dist/utils/secrets-cache.js +14 -162
  309. package/dist/utils/self-update.d.ts +1 -34
  310. package/dist/utils/self-update.js +42 -660
  311. package/dist/utils/sentry-fingerprint.d.ts +1 -23
  312. package/dist/utils/sentry-fingerprint.js +31 -223
  313. package/dist/utils/team-upgrade.d.ts +1 -1
  314. package/dist/utils/team-upgrade.js +3 -4
  315. package/dist/utils/vault-api.d.ts +1 -21
  316. package/dist/utils/vault-api.js +84 -251
  317. package/dist/utils/version-check.d.ts +1 -11
  318. package/dist/utils/version-check.js +3 -32
  319. package/dist/utils/version-gate.d.ts +17 -101
  320. package/dist/utils/version-gate.js +70 -645
  321. package/dist/utils/windows-spawn.d.ts +0 -6
  322. package/dist/utils/windows-spawn.js +0 -37
  323. package/package.json +8 -20
  324. package/README.md +0 -113
  325. package/assets/bot-workers/setup/context/USER-GUIDE.md +0 -404
  326. package/assets/bot-workers/setup/context/quick-reference.md +0 -199
  327. package/assets/bot-workers/setup/skills/agents-and-team.md +0 -167
  328. package/assets/bot-workers/setup/skills/explain-hq.md +0 -35
  329. package/assets/bot-workers/setup/skills/first-company.md +0 -74
  330. package/assets/bot-workers/setup/skills/joining-a-team.md +0 -125
  331. package/assets/bot-workers/setup/skills/pricing.md +0 -92
  332. package/assets/bot-workers/setup/skills/standing-help.md +0 -81
  333. package/assets/bot-workers/setup/skills/your-business.md +0 -281
  334. package/assets/bot-workers/setup/worker.yaml +0 -791
  335. package/assets/lanes-hooks/hq-lanes-drain.json +0 -15
  336. package/assets/lanes-hooks/hq-lanes-drain.mjs +0 -275
  337. package/assets/lanes-hooks/hq-lanes-drain.sh +0 -21
  338. package/assets/lanes-reconcile/hq-lanes-reconcile.service +0 -11
  339. package/assets/lanes-reconcile/hq-lanes-reconcile.timer +0 -12
  340. package/assets/scaffold/.claude/hooks/validate-policy-frontmatter.sh +0 -485
  341. package/assets/scaffold/core/scripts/audit-log.sh +0 -384
  342. package/assets/scaffold/core/scripts/clean-worktree-reconcile-handoff.sh +0 -171
  343. package/assets/scaffold/core/scripts/eval-trigger.sh +0 -193
  344. package/assets/scaffold/core/scripts/git-pack-extension-check.sh +0 -164
  345. package/assets/scaffold/core/scripts/handoff-finalize.sh +0 -688
  346. package/assets/scaffold/core/scripts/handoff-open-steps.sh +0 -81
  347. package/assets/scaffold/core/scripts/handoff-post.sh +0 -252
  348. package/assets/scaffold/core/scripts/hq-delegate-bundle.sh +0 -307
  349. package/assets/scaffold/core/scripts/hq-delegate-grant.sh +0 -252
  350. package/assets/scaffold/core/scripts/hq-delegate-pickup.sh +0 -99
  351. package/assets/scaffold/core/scripts/hq-delegate-publish.sh +0 -91
  352. package/assets/scaffold/core/scripts/hq-delegate-repo.sh +0 -158
  353. package/assets/scaffold/core/scripts/hq-delegate-resolve.sh +0 -145
  354. package/assets/scaffold/core/scripts/hq-delegate-secrets.sh +0 -129
  355. package/assets/scaffold/core/scripts/hq-delegate-send.sh +0 -259
  356. package/assets/scaffold/core/scripts/hq-delegate-transfer.sh +0 -175
  357. package/assets/scaffold/core/scripts/hq-delegate-verify.sh +0 -238
  358. package/assets/scaffold/core/scripts/hq-dm-bind.sh +0 -585
  359. package/assets/scaffold/core/scripts/hq-job-notify.sh +0 -389
  360. package/assets/scaffold/core/scripts/hq-job-probe.sh +0 -835
  361. package/assets/scaffold/core/scripts/hq-job-remediate.sh +0 -359
  362. package/assets/scaffold/core/scripts/hq-job-run.sh +0 -1025
  363. package/assets/scaffold/core/scripts/hq-pin.sh +0 -118
  364. package/assets/scaffold/core/scripts/jobs-schedule-parse.sh +0 -310
  365. package/assets/scaffold/core/scripts/jobs-validate.sh +0 -451
  366. package/assets/scaffold/core/scripts/knowledge-prefs.sh +0 -55
  367. package/assets/scaffold/core/scripts/lib/portable.sh +0 -211
  368. package/assets/scaffold/core/scripts/lib/secret-patterns.sh +0 -58
  369. package/assets/scaffold/core/scripts/ontology-audience-grant.sh +0 -81
  370. package/assets/scaffold/core/scripts/ontology-brief.mjs +0 -93
  371. package/assets/scaffold/core/scripts/ontology-candidate.sh +0 -100
  372. package/assets/scaffold/core/scripts/ontology-garden.mjs +0 -238
  373. package/assets/scaffold/core/scripts/ontology-source-worklist.sh +0 -79
  374. package/assets/scaffold/core/scripts/outpost-jobs-reconcile.sh +0 -834
  375. package/assets/scaffold/core/scripts/policy-age-report.sh +0 -156
  376. package/assets/scaffold/core/scripts/policy-retire.sh +0 -199
  377. package/assets/scaffold/core/scripts/qmd-reindex-bg.sh +0 -40
  378. package/assets/scaffold/core/scripts/read-policy-frontmatter.sh +0 -32
  379. package/assets/scaffold/core/scripts/refresh-vault-access.sh +0 -188
  380. package/assets/scaffold/core/scripts/resolve-company.sh +0 -199
  381. package/assets/scaffold/core/scripts/resume-thread-lock.sh +0 -285
  382. package/assets/scaffold/core/scripts/source-yaml-validate.sh +0 -36
  383. package/assets/scaffold/core/scripts/verify-story-deliverables.sh +0 -148
  384. package/assets/scaffold/core/scripts/work-mesh-live-bind-trusted.sh +0 -152
  385. package/assets/scaffold/core/scripts/worktree-gc.sh +0 -362
  386. package/contracts/preflight/v1/fixtures.json +0 -87
  387. package/contracts/preflight/v1/schema.json +0 -58
  388. package/dist/command-catalog.generated.d.ts +0 -10655
  389. package/dist/command-catalog.generated.js +0 -13737
  390. package/dist/command-registration-plan.d.ts +0 -474
  391. package/dist/command-registration-plan.js +0 -136
  392. package/dist/commands/agent-enroll.d.ts +0 -146
  393. package/dist/commands/agent-enroll.js +0 -401
  394. package/dist/commands/agent-inbox.d.ts +0 -9
  395. package/dist/commands/agent-inbox.js +0 -102
  396. package/dist/commands/agent-kit.d.ts +0 -87
  397. package/dist/commands/agent-kit.js +0 -480
  398. package/dist/commands/agent-mcp.d.ts +0 -24
  399. package/dist/commands/agent-mcp.js +0 -127
  400. package/dist/commands/agent-probe.d.ts +0 -77
  401. package/dist/commands/agent-probe.js +0 -335
  402. package/dist/commands/agent.d.ts +0 -13
  403. package/dist/commands/agent.js +0 -40
  404. package/dist/commands/billing-sponsor.d.ts +0 -83
  405. package/dist/commands/billing-sponsor.js +0 -344
  406. package/dist/commands/bot-companies.d.ts +0 -40
  407. package/dist/commands/bot-companies.js +0 -64
  408. package/dist/commands/bot-continuity.d.ts +0 -28
  409. package/dist/commands/bot-continuity.js +0 -68
  410. package/dist/commands/bot-jobs.d.ts +0 -127
  411. package/dist/commands/bot-jobs.js +0 -454
  412. package/dist/commands/bot.d.ts +0 -278
  413. package/dist/commands/bot.js +0 -1982
  414. package/dist/commands/cloud-retire.d.ts +0 -51
  415. package/dist/commands/cloud-retire.js +0 -154
  416. package/dist/commands/core-audit-log-native.d.ts +0 -9
  417. package/dist/commands/core-audit-log-native.js +0 -257
  418. package/dist/commands/core-checkpoint-gate-setting.d.ts +0 -59
  419. package/dist/commands/core-checkpoint-gate-setting.js +0 -163
  420. package/dist/commands/core-checkpoint-stop-gate-native.d.ts +0 -34
  421. package/dist/commands/core-checkpoint-stop-gate-native.js +0 -725
  422. package/dist/commands/core-command-catalog.d.ts +0 -34
  423. package/dist/commands/core-command-catalog.js +0 -62
  424. package/dist/commands/core-company-index-scope-flag.d.ts +0 -3
  425. package/dist/commands/core-company-index-scope-flag.js +0 -6
  426. package/dist/commands/core-delegate-w1b.d.ts +0 -10
  427. package/dist/commands/core-delegate-w1b.js +0 -1219
  428. package/dist/commands/core-delegate.d.ts +0 -46
  429. package/dist/commands/core-delegate.js +0 -1040
  430. package/dist/commands/core-dm-bind-native.d.ts +0 -32
  431. package/dist/commands/core-dm-bind-native.js +0 -668
  432. package/dist/commands/core-git-pack-extension-check-native.d.ts +0 -22
  433. package/dist/commands/core-git-pack-extension-check-native.js +0 -190
  434. package/dist/commands/core-handoff-fast.d.ts +0 -18
  435. package/dist/commands/core-handoff-fast.js +0 -104
  436. package/dist/commands/core-handoff-open-steps.d.ts +0 -21
  437. package/dist/commands/core-handoff-open-steps.js +0 -264
  438. package/dist/commands/core-handoff.d.ts +0 -24
  439. package/dist/commands/core-handoff.js +0 -1144
  440. package/dist/commands/core-hq-session-native.d.ts +0 -39
  441. package/dist/commands/core-hq-session-native.js +0 -579
  442. package/dist/commands/core-job-native-utils.d.ts +0 -6
  443. package/dist/commands/core-job-native-utils.js +0 -80
  444. package/dist/commands/core-job-native.d.ts +0 -5
  445. package/dist/commands/core-job-native.js +0 -16
  446. package/dist/commands/core-job-notify-native.d.ts +0 -36
  447. package/dist/commands/core-job-notify-native.js +0 -359
  448. package/dist/commands/core-job-probe-native.d.ts +0 -45
  449. package/dist/commands/core-job-probe-native.js +0 -564
  450. package/dist/commands/core-job-remediate-native.d.ts +0 -26
  451. package/dist/commands/core-job-remediate-native.js +0 -374
  452. package/dist/commands/core-job-remote-launcher.d.ts +0 -7
  453. package/dist/commands/core-job-remote-launcher.js +0 -51
  454. package/dist/commands/core-job-run-native.d.ts +0 -47
  455. package/dist/commands/core-job-run-native.js +0 -1215
  456. package/dist/commands/core-jobs-native.d.ts +0 -25
  457. package/dist/commands/core-jobs-native.js +0 -1339
  458. package/dist/commands/core-knowledge-prefs.d.ts +0 -12
  459. package/dist/commands/core-knowledge-prefs.js +0 -137
  460. package/dist/commands/core-native-handoff-flag.d.ts +0 -4
  461. package/dist/commands/core-native-handoff-flag.js +0 -7
  462. package/dist/commands/core-native-jobs-flag.d.ts +0 -4
  463. package/dist/commands/core-native-jobs-flag.js +0 -7
  464. package/dist/commands/core-native-policy-flag.d.ts +0 -9
  465. package/dist/commands/core-native-policy-flag.js +0 -12
  466. package/dist/commands/core-native-session-flag.d.ts +0 -4
  467. package/dist/commands/core-native-session-flag.js +0 -7
  468. package/dist/commands/core-native-utilities-flag.d.ts +0 -4
  469. package/dist/commands/core-native-utilities-flag.js +0 -7
  470. package/dist/commands/core-native-utilities.d.ts +0 -29
  471. package/dist/commands/core-native-utilities.js +0 -54
  472. package/dist/commands/core-native-worker-skills-flag.d.ts +0 -4
  473. package/dist/commands/core-native-worker-skills-flag.js +0 -7
  474. package/dist/commands/core-ontology-native.d.ts +0 -17
  475. package/dist/commands/core-ontology-native.js +0 -916
  476. package/dist/commands/core-ontology.d.ts +0 -66
  477. package/dist/commands/core-ontology.js +0 -430
  478. package/dist/commands/core-pin-native.d.ts +0 -14
  479. package/dist/commands/core-pin-native.js +0 -236
  480. package/dist/commands/core-policy-frontmatter.d.ts +0 -8
  481. package/dist/commands/core-policy-frontmatter.js +0 -52
  482. package/dist/commands/core-policy.d.ts +0 -14
  483. package/dist/commands/core-policy.js +0 -1018
  484. package/dist/commands/core-refresh-vault-access-native.d.ts +0 -20
  485. package/dist/commands/core-refresh-vault-access-native.js +0 -229
  486. package/dist/commands/core-resolve-company-command.d.ts +0 -4
  487. package/dist/commands/core-resolve-company-command.js +0 -42
  488. package/dist/commands/core-resolve-company-native.d.ts +0 -28
  489. package/dist/commands/core-resolve-company-native.js +0 -408
  490. package/dist/commands/core-work-mesh-bind-trusted-native.d.ts +0 -32
  491. package/dist/commands/core-work-mesh-bind-trusted-native.js +0 -190
  492. package/dist/commands/core-worker-lint-native.d.ts +0 -4
  493. package/dist/commands/core-worker-lint-native.js +0 -160
  494. package/dist/commands/core-worker-share-native.d.ts +0 -5
  495. package/dist/commands/core-worker-share-native.js +0 -260
  496. package/dist/commands/core-worker-skills-command.d.ts +0 -8
  497. package/dist/commands/core-worker-skills-command.js +0 -33
  498. package/dist/commands/core-worker-skills-runtime.d.ts +0 -33
  499. package/dist/commands/core-worker-skills-runtime.js +0 -86
  500. package/dist/commands/daemon.d.ts +0 -63
  501. package/dist/commands/daemon.js +0 -877
  502. package/dist/commands/deploy-comments.d.ts +0 -3
  503. package/dist/commands/deploy-comments.js +0 -162
  504. package/dist/commands/lanes-accounts.d.ts +0 -28
  505. package/dist/commands/lanes-accounts.js +0 -595
  506. package/dist/commands/lanes-autopilot.d.ts +0 -11
  507. package/dist/commands/lanes-autopilot.js +0 -336
  508. package/dist/commands/lanes-checks.d.ts +0 -51
  509. package/dist/commands/lanes-checks.js +0 -941
  510. package/dist/commands/lanes-hold.d.ts +0 -43
  511. package/dist/commands/lanes-hold.js +0 -655
  512. package/dist/commands/lanes-kpis.d.ts +0 -11
  513. package/dist/commands/lanes-kpis.js +0 -34
  514. package/dist/commands/lanes-message.d.ts +0 -9
  515. package/dist/commands/lanes-message.js +0 -934
  516. package/dist/commands/lanes-move.d.ts +0 -12
  517. package/dist/commands/lanes-move.js +0 -397
  518. package/dist/commands/lanes-questions.d.ts +0 -36
  519. package/dist/commands/lanes-questions.js +0 -1004
  520. package/dist/commands/lanes-report.d.ts +0 -11
  521. package/dist/commands/lanes-report.js +0 -333
  522. package/dist/commands/lanes-resume.d.ts +0 -6
  523. package/dist/commands/lanes-resume.js +0 -561
  524. package/dist/commands/lanes-review.d.ts +0 -10
  525. package/dist/commands/lanes-review.js +0 -56
  526. package/dist/commands/lanes-shared.d.ts +0 -448
  527. package/dist/commands/lanes-shared.js +0 -170
  528. package/dist/commands/lanes-stories.d.ts +0 -15
  529. package/dist/commands/lanes-stories.js +0 -347
  530. package/dist/commands/lanes-watch.d.ts +0 -7
  531. package/dist/commands/lanes-watch.js +0 -216
  532. package/dist/commands/lanes.d.ts +0 -149
  533. package/dist/commands/lanes.js +0 -8843
  534. package/dist/commands/monitor.d.ts +0 -58
  535. package/dist/commands/monitor.js +0 -980
  536. package/dist/commands/onboard-bot-membership.d.ts +0 -32
  537. package/dist/commands/onboard-bot-membership.js +0 -40
  538. package/dist/commands/onboard-create-identity.d.ts +0 -26
  539. package/dist/commands/onboard-create-identity.js +0 -23
  540. package/dist/commands/outpost-pruner.d.ts +0 -3
  541. package/dist/commands/outpost-pruner.js +0 -125
  542. package/dist/commands/personal-connector-settings-flag.d.ts +0 -4
  543. package/dist/commands/personal-connector-settings-flag.js +0 -7
  544. package/dist/commands/personal-targeted-push-flag.d.ts +0 -4
  545. package/dist/commands/personal-targeted-push-flag.js +0 -7
  546. package/dist/commands/personal-targeted-push-paths.d.ts +0 -3
  547. package/dist/commands/personal-targeted-push-paths.js +0 -67
  548. package/dist/commands/report.d.ts +0 -19
  549. package/dist/commands/report.js +0 -537
  550. package/dist/commands/run-feature-telemetry.d.ts +0 -3
  551. package/dist/commands/run-feature-telemetry.js +0 -6
  552. package/dist/commands/staff/reset-test-account.d.ts +0 -110
  553. package/dist/commands/staff/reset-test-account.js +0 -268
  554. package/dist/commands/staff/test-account.d.ts +0 -51
  555. package/dist/commands/staff/test-account.js +0 -196
  556. package/dist/commands/vault-retention-flag.d.ts +0 -3
  557. package/dist/commands/vault-retention-flag.js +0 -9
  558. package/dist/commands/vault-retention.d.ts +0 -11
  559. package/dist/commands/vault-retention.js +0 -69
  560. package/dist/commands/version.d.ts +0 -10
  561. package/dist/commands/version.js +0 -11
  562. package/dist/fast-scaffold.d.ts +0 -84
  563. package/dist/fast-scaffold.js +0 -353
  564. package/dist/lanes-drain-hook.d.ts +0 -14
  565. package/dist/lanes-drain-hook.js +0 -203
  566. package/dist/lib/agent-kit/adopt-identity.d.ts +0 -27
  567. package/dist/lib/agent-kit/adopt-identity.js +0 -60
  568. package/dist/lib/agent-kit/attachment-download.d.ts +0 -24
  569. package/dist/lib/agent-kit/attachment-download.js +0 -47
  570. package/dist/lib/agent-kit/creds.d.ts +0 -106
  571. package/dist/lib/agent-kit/creds.js +0 -163
  572. package/dist/lib/agent-kit/fallback.d.ts +0 -78
  573. package/dist/lib/agent-kit/fallback.js +0 -210
  574. package/dist/lib/agent-kit/inbox-state.d.ts +0 -83
  575. package/dist/lib/agent-kit/inbox-state.js +0 -159
  576. package/dist/lib/agent-kit/kit-config.d.ts +0 -56
  577. package/dist/lib/agent-kit/kit-config.js +0 -65
  578. package/dist/lib/agent-kit/log.d.ts +0 -16
  579. package/dist/lib/agent-kit/log.js +0 -46
  580. package/dist/lib/agent-kit/mcp/attachments.d.ts +0 -126
  581. package/dist/lib/agent-kit/mcp/attachments.js +0 -222
  582. package/dist/lib/agent-kit/mcp/jsonrpc.d.ts +0 -75
  583. package/dist/lib/agent-kit/mcp/jsonrpc.js +0 -164
  584. package/dist/lib/agent-kit/mcp/tools.d.ts +0 -64
  585. package/dist/lib/agent-kit/mcp/tools.js +0 -397
  586. package/dist/lib/agent-kit/paths.d.ts +0 -65
  587. package/dist/lib/agent-kit/paths.js +0 -118
  588. package/dist/lib/agent-kit/private-file.d.ts +0 -29
  589. package/dist/lib/agent-kit/private-file.js +0 -91
  590. package/dist/lib/agent-kit/run/heartbeat.d.ts +0 -72
  591. package/dist/lib/agent-kit/run/heartbeat.js +0 -128
  592. package/dist/lib/agent-kit/run/inbox.d.ts +0 -76
  593. package/dist/lib/agent-kit/run/inbox.js +0 -205
  594. package/dist/lib/agent-kit/run/supervisor.d.ts +0 -35
  595. package/dist/lib/agent-kit/run/supervisor.js +0 -85
  596. package/dist/lib/agent-kit/run/sync.d.ts +0 -33
  597. package/dist/lib/agent-kit/run/sync.js +0 -58
  598. package/dist/lib/agent-kit/services.d.ts +0 -31
  599. package/dist/lib/agent-kit/services.js +0 -55
  600. package/dist/lib/agent-kit/skills.d.ts +0 -18
  601. package/dist/lib/agent-kit/skills.js +0 -151
  602. package/dist/lib/agent-kit/wake.d.ts +0 -83
  603. package/dist/lib/agent-kit/wake.js +0 -243
  604. package/dist/lib/agents/model-catalog.d.ts +0 -62
  605. package/dist/lib/agents/model-catalog.js +0 -275
  606. package/dist/lib/auth-login-provider-state.d.ts +0 -8
  607. package/dist/lib/auth-login-provider-state.js +0 -63
  608. package/dist/lib/aws-sdk-node-warning-output.d.ts +0 -12
  609. package/dist/lib/aws-sdk-node-warning-output.js +0 -22
  610. package/dist/lib/billing/free-month.d.ts +0 -18
  611. package/dist/lib/billing/free-month.js +0 -31
  612. package/dist/lib/billing/plan-limit-refusals.d.ts +0 -69
  613. package/dist/lib/billing/plan-limit-refusals.js +0 -187
  614. package/dist/lib/billing/plan-limit-upgrade-url.d.ts +0 -11
  615. package/dist/lib/billing/plan-limit-upgrade-url.js +0 -66
  616. package/dist/lib/billing/plan-lock.d.ts +0 -143
  617. package/dist/lib/billing/plan-lock.js +0 -439
  618. package/dist/lib/bot/api.d.ts +0 -349
  619. package/dist/lib/bot/api.js +0 -316
  620. package/dist/lib/bot/attachments.d.ts +0 -45
  621. package/dist/lib/bot/attachments.js +0 -89
  622. package/dist/lib/bot/cli-update.d.ts +0 -138
  623. package/dist/lib/bot/cli-update.js +0 -278
  624. package/dist/lib/bot/company-bind.d.ts +0 -27
  625. package/dist/lib/bot/company-bind.js +0 -62
  626. package/dist/lib/bot/config.d.ts +0 -153
  627. package/dist/lib/bot/config.js +0 -233
  628. package/dist/lib/bot/continuity-download.d.ts +0 -28
  629. package/dist/lib/bot/continuity-download.js +0 -75
  630. package/dist/lib/bot/continuity-install.d.ts +0 -14
  631. package/dist/lib/bot/continuity-install.js +0 -101
  632. package/dist/lib/bot/continuity.d.ts +0 -67
  633. package/dist/lib/bot/continuity.js +0 -301
  634. package/dist/lib/bot/creds.d.ts +0 -24
  635. package/dist/lib/bot/creds.js +0 -51
  636. package/dist/lib/bot/daemon.d.ts +0 -173
  637. package/dist/lib/bot/daemon.js +0 -552
  638. package/dist/lib/bot/inbox-poll-backoff-flag.d.ts +0 -24
  639. package/dist/lib/bot/inbox-poll-backoff-flag.js +0 -135
  640. package/dist/lib/bot/inbox-state.d.ts +0 -18
  641. package/dist/lib/bot/inbox-state.js +0 -51
  642. package/dist/lib/bot/index.d.ts +0 -23
  643. package/dist/lib/bot/index.js +0 -23
  644. package/dist/lib/bot/inflight.d.ts +0 -119
  645. package/dist/lib/bot/inflight.js +0 -83
  646. package/dist/lib/bot/job-completions.d.ts +0 -89
  647. package/dist/lib/bot/job-completions.js +0 -132
  648. package/dist/lib/bot/job-run.d.ts +0 -109
  649. package/dist/lib/bot/job-run.js +0 -246
  650. package/dist/lib/bot/local-config.d.ts +0 -61
  651. package/dist/lib/bot/local-config.js +0 -145
  652. package/dist/lib/bot/local-jobs.d.ts +0 -89
  653. package/dist/lib/bot/local-jobs.js +0 -459
  654. package/dist/lib/bot/local-name.d.ts +0 -54
  655. package/dist/lib/bot/local-name.js +0 -114
  656. package/dist/lib/bot/log.d.ts +0 -13
  657. package/dist/lib/bot/log.js +0 -59
  658. package/dist/lib/bot/owner-context.d.ts +0 -79
  659. package/dist/lib/bot/owner-context.js +0 -175
  660. package/dist/lib/bot/paths.d.ts +0 -76
  661. package/dist/lib/bot/paths.js +0 -131
  662. package/dist/lib/bot/progress.d.ts +0 -132
  663. package/dist/lib/bot/progress.js +0 -289
  664. package/dist/lib/bot/promote.d.ts +0 -16
  665. package/dist/lib/bot/promote.js +0 -106
  666. package/dist/lib/bot/promotion-hold.d.ts +0 -24
  667. package/dist/lib/bot/promotion-hold.js +0 -103
  668. package/dist/lib/bot/promotion-receipt.d.ts +0 -9
  669. package/dist/lib/bot/promotion-receipt.js +0 -56
  670. package/dist/lib/bot/promotion-upload.d.ts +0 -16
  671. package/dist/lib/bot/promotion-upload.js +0 -80
  672. package/dist/lib/bot/prompt.d.ts +0 -136
  673. package/dist/lib/bot/prompt.js +0 -433
  674. package/dist/lib/bot/room-policy.d.ts +0 -63
  675. package/dist/lib/bot/room-policy.js +0 -91
  676. package/dist/lib/bot/run.d.ts +0 -217
  677. package/dist/lib/bot/run.js +0 -1869
  678. package/dist/lib/bot/runnable.d.ts +0 -51
  679. package/dist/lib/bot/runnable.js +0 -65
  680. package/dist/lib/bot/runtime/claude.d.ts +0 -50
  681. package/dist/lib/bot/runtime/claude.js +0 -170
  682. package/dist/lib/bot/runtime/codex.d.ts +0 -28
  683. package/dist/lib/bot/runtime/codex.js +0 -153
  684. package/dist/lib/bot/runtime/grok-acp.d.ts +0 -40
  685. package/dist/lib/bot/runtime/grok-acp.js +0 -265
  686. package/dist/lib/bot/runtime/grok.d.ts +0 -41
  687. package/dist/lib/bot/runtime/grok.js +0 -169
  688. package/dist/lib/bot/runtime/index.d.ts +0 -36
  689. package/dist/lib/bot/runtime/index.js +0 -417
  690. package/dist/lib/bot/runtime/messages-stream.d.ts +0 -56
  691. package/dist/lib/bot/runtime/messages-stream.js +0 -194
  692. package/dist/lib/bot/runtime/sanitize.d.ts +0 -18
  693. package/dist/lib/bot/runtime/sanitize.js +0 -28
  694. package/dist/lib/bot/runtime/types.d.ts +0 -159
  695. package/dist/lib/bot/runtime/types.js +0 -51
  696. package/dist/lib/bot/runtime/windows.d.ts +0 -10
  697. package/dist/lib/bot/runtime/windows.js +0 -53
  698. package/dist/lib/bot/runtime-sign-in.d.ts +0 -24
  699. package/dist/lib/bot/runtime-sign-in.js +0 -31
  700. package/dist/lib/bot/scaffold.d.ts +0 -38
  701. package/dist/lib/bot/scaffold.js +0 -94
  702. package/dist/lib/bot/self-heal.d.ts +0 -52
  703. package/dist/lib/bot/self-heal.js +0 -79
  704. package/dist/lib/bot/self-process.d.ts +0 -19
  705. package/dist/lib/bot/self-process.js +0 -35
  706. package/dist/lib/bot/session.d.ts +0 -19
  707. package/dist/lib/bot/session.js +0 -39
  708. package/dist/lib/bot/setup-explain.d.ts +0 -64
  709. package/dist/lib/bot/setup-explain.js +0 -141
  710. package/dist/lib/bot/split.d.ts +0 -32
  711. package/dist/lib/bot/split.js +0 -241
  712. package/dist/lib/bot/status.d.ts +0 -57
  713. package/dist/lib/bot/status.js +0 -66
  714. package/dist/lib/bot/worker-source.d.ts +0 -66
  715. package/dist/lib/bot/worker-source.js +0 -283
  716. package/dist/lib/checkpoint-ontology/aliases.d.ts +0 -17
  717. package/dist/lib/checkpoint-ontology/aliases.js +0 -44
  718. package/dist/lib/checkpoint-ontology/apply.d.ts +0 -110
  719. package/dist/lib/checkpoint-ontology/apply.js +0 -777
  720. package/dist/lib/checkpoint-ontology/company-brief.d.ts +0 -18
  721. package/dist/lib/checkpoint-ontology/company-brief.js +0 -337
  722. package/dist/lib/checkpoint-ontology/company.d.ts +0 -44
  723. package/dist/lib/checkpoint-ontology/company.js +0 -118
  724. package/dist/lib/checkpoint-ontology/drop-aliases.d.ts +0 -41
  725. package/dist/lib/checkpoint-ontology/drop-aliases.js +0 -76
  726. package/dist/lib/checkpoint-ontology/entity-file.d.ts +0 -109
  727. package/dist/lib/checkpoint-ontology/entity-file.js +0 -371
  728. package/dist/lib/checkpoint-ontology/identity.d.ts +0 -38
  729. package/dist/lib/checkpoint-ontology/identity.js +0 -95
  730. package/dist/lib/checkpoint-ontology/merge-copies.d.ts +0 -199
  731. package/dist/lib/checkpoint-ontology/merge-copies.js +0 -1086
  732. package/dist/lib/checkpoint-ontology/multi-writer.d.ts +0 -101
  733. package/dist/lib/checkpoint-ontology/multi-writer.js +0 -394
  734. package/dist/lib/checkpoint-ontology/plan.d.ts +0 -193
  735. package/dist/lib/checkpoint-ontology/plan.js +0 -504
  736. package/dist/lib/checkpoint-ontology/queued-touches.d.ts +0 -29
  737. package/dist/lib/checkpoint-ontology/queued-touches.js +0 -193
  738. package/dist/lib/checkpoint-ontology/sync-client.d.ts +0 -38
  739. package/dist/lib/checkpoint-ontology/sync-client.js +0 -84
  740. package/dist/lib/checkpoint-ontology/tree.d.ts +0 -55
  741. package/dist/lib/checkpoint-ontology/tree.js +0 -198
  742. package/dist/lib/company-errors-sdk-warning-flag.d.ts +0 -5
  743. package/dist/lib/company-errors-sdk-warning-flag.js +0 -8
  744. package/dist/lib/core-utils/hook-timeout-debug-context-flag.d.ts +0 -20
  745. package/dist/lib/core-utils/hook-timeout-debug-context-flag.js +0 -81
  746. package/dist/lib/core-utils/jq-json-serializer.d.ts +0 -5
  747. package/dist/lib/core-utils/jq-json-serializer.js +0 -10
  748. package/dist/lib/core-utils/secret-patterns.d.ts +0 -43
  749. package/dist/lib/core-utils/secret-patterns.js +0 -34
  750. package/dist/lib/core-utils/sentry-report.d.ts +0 -114
  751. package/dist/lib/core-utils/sentry-report.js +0 -1034
  752. package/dist/lib/core-utils/timeout-guard-native.d.ts +0 -7
  753. package/dist/lib/core-utils/timeout-guard-native.js +0 -40
  754. package/dist/lib/core-utils/worktree-resume.d.ts +0 -20
  755. package/dist/lib/core-utils/worktree-resume.js +0 -1198
  756. package/dist/lib/daemon/catalog.d.ts +0 -134
  757. package/dist/lib/daemon/catalog.js +0 -358
  758. package/dist/lib/daemon/config.d.ts +0 -35
  759. package/dist/lib/daemon/config.js +0 -108
  760. package/dist/lib/daemon/flag.d.ts +0 -25
  761. package/dist/lib/daemon/flag.js +0 -59
  762. package/dist/lib/daemon/handoff.d.ts +0 -56
  763. package/dist/lib/daemon/handoff.js +0 -161
  764. package/dist/lib/daemon/hq-cloud.d.ts +0 -79
  765. package/dist/lib/daemon/hq-cloud.js +0 -183
  766. package/dist/lib/daemon/install.d.ts +0 -85
  767. package/dist/lib/daemon/install.js +0 -320
  768. package/dist/lib/daemon/legacy-sync-env.d.ts +0 -10
  769. package/dist/lib/daemon/legacy-sync-env.js +0 -58
  770. package/dist/lib/daemon/legacy.d.ts +0 -45
  771. package/dist/lib/daemon/legacy.js +0 -133
  772. package/dist/lib/daemon/lock.d.ts +0 -47
  773. package/dist/lib/daemon/lock.js +0 -138
  774. package/dist/lib/daemon/machine-type.d.ts +0 -50
  775. package/dist/lib/daemon/machine-type.js +0 -159
  776. package/dist/lib/daemon/migrate.d.ts +0 -77
  777. package/dist/lib/daemon/migrate.js +0 -265
  778. package/dist/lib/daemon/paths.d.ts +0 -24
  779. package/dist/lib/daemon/paths.js +0 -43
  780. package/dist/lib/daemon/protocol-tail.d.ts +0 -33
  781. package/dist/lib/daemon/protocol-tail.js +0 -131
  782. package/dist/lib/daemon/remote-control.d.ts +0 -74
  783. package/dist/lib/daemon/remote-control.js +0 -153
  784. package/dist/lib/daemon/requests.d.ts +0 -28
  785. package/dist/lib/daemon/requests.js +0 -65
  786. package/dist/lib/daemon/run.d.ts +0 -79
  787. package/dist/lib/daemon/run.js +0 -755
  788. package/dist/lib/daemon/succession.d.ts +0 -118
  789. package/dist/lib/daemon/succession.js +0 -263
  790. package/dist/lib/daemon/supervisor.d.ts +0 -132
  791. package/dist/lib/daemon/supervisor.js +0 -836
  792. package/dist/lib/daemon/sync-runner.d.ts +0 -58
  793. package/dist/lib/daemon/sync-runner.js +0 -277
  794. package/dist/lib/daemon/tools.d.ts +0 -52
  795. package/dist/lib/daemon/tools.js +0 -95
  796. package/dist/lib/daemon/updater.d.ts +0 -57
  797. package/dist/lib/daemon/updater.js +0 -163
  798. package/dist/lib/deploy-api.d.ts +0 -5
  799. package/dist/lib/deploy-api.js +0 -21
  800. package/dist/lib/deploy-apps.d.ts +0 -13
  801. package/dist/lib/deploy-apps.js +0 -29
  802. package/dist/lib/doctor/__testing__/run-doctor.d.ts +0 -8
  803. package/dist/lib/doctor/__testing__/run-doctor.js +0 -52
  804. package/dist/lib/doctor/checks/bots.d.ts +0 -13
  805. package/dist/lib/doctor/checks/bots.js +0 -189
  806. package/dist/lib/doctor/checks/scaffold-cli-floor.d.ts +0 -6
  807. package/dist/lib/doctor/checks/scaffold-cli-floor.js +0 -73
  808. package/dist/lib/doctor/checks/sync-runtime.d.ts +0 -11
  809. package/dist/lib/doctor/checks/sync-runtime.js +0 -216
  810. package/dist/lib/doctor/client-health-flag-token.d.ts +0 -15
  811. package/dist/lib/doctor/client-health-flag-token.js +0 -66
  812. package/dist/lib/doctor/client-health-reason-codes-flag.d.ts +0 -27
  813. package/dist/lib/doctor/client-health-reason-codes-flag.js +0 -106
  814. package/dist/lib/doctor/fix/json-output.d.ts +0 -28
  815. package/dist/lib/doctor/fix/json-output.js +0 -33
  816. package/dist/lib/doctor/fix/refresh-sync-outcome.d.ts +0 -12
  817. package/dist/lib/doctor/fix/refresh-sync-outcome.js +0 -25
  818. package/dist/lib/doctor/shared.d.ts +0 -8
  819. package/dist/lib/doctor/shared.js +0 -38
  820. package/dist/lib/doctor/stray-gate-entries.d.ts +0 -35
  821. package/dist/lib/doctor/stray-gate-entries.js +0 -83
  822. package/dist/lib/first-sync-next-step.d.ts +0 -37
  823. package/dist/lib/first-sync-next-step.js +0 -189
  824. package/dist/lib/flag-registry-endpoint.d.ts +0 -5
  825. package/dist/lib/flag-registry-endpoint.js +0 -9
  826. package/dist/lib/flag-registry-worker-source.generated.d.ts +0 -2
  827. package/dist/lib/flag-registry-worker-source.generated.js +0 -3
  828. package/dist/lib/flag-snapshot-file.d.ts +0 -20
  829. package/dist/lib/flag-snapshot-file.js +0 -91
  830. package/dist/lib/heartbeat-identity.d.ts +0 -30
  831. package/dist/lib/heartbeat-identity.js +0 -76
  832. package/dist/lib/lanes/account-home.d.ts +0 -8
  833. package/dist/lib/lanes/account-home.js +0 -10
  834. package/dist/lib/lanes/accounts.d.ts +0 -117
  835. package/dist/lib/lanes/accounts.js +0 -366
  836. package/dist/lib/lanes/admission-host.d.ts +0 -22
  837. package/dist/lib/lanes/admission-host.js +0 -37
  838. package/dist/lib/lanes/admission.d.ts +0 -26
  839. package/dist/lib/lanes/admission.js +0 -210
  840. package/dist/lib/lanes/approval-gate.d.ts +0 -8
  841. package/dist/lib/lanes/approval-gate.js +0 -90
  842. package/dist/lib/lanes/autopilot-metrics.d.ts +0 -99
  843. package/dist/lib/lanes/autopilot-metrics.js +0 -301
  844. package/dist/lib/lanes/autopilot-registry.d.ts +0 -62
  845. package/dist/lib/lanes/autopilot-registry.js +0 -192
  846. package/dist/lib/lanes/autopilot.d.ts +0 -120
  847. package/dist/lib/lanes/autopilot.js +0 -1061
  848. package/dist/lib/lanes/blocker-freshness.d.ts +0 -31
  849. package/dist/lib/lanes/blocker-freshness.js +0 -168
  850. package/dist/lib/lanes/checked-company-path.d.ts +0 -3
  851. package/dist/lib/lanes/checked-company-path.js +0 -39
  852. package/dist/lib/lanes/claude-balance.d.ts +0 -97
  853. package/dist/lib/lanes/claude-balance.js +0 -319
  854. package/dist/lib/lanes/compaction.d.ts +0 -110
  855. package/dist/lib/lanes/compaction.js +0 -293
  856. package/dist/lib/lanes/config.d.ts +0 -91
  857. package/dist/lib/lanes/config.js +0 -592
  858. package/dist/lib/lanes/constants.d.ts +0 -3
  859. package/dist/lib/lanes/constants.js +0 -3
  860. package/dist/lib/lanes/delivery-core.d.ts +0 -15
  861. package/dist/lib/lanes/delivery-core.js +0 -21
  862. package/dist/lib/lanes/delivery.d.ts +0 -180
  863. package/dist/lib/lanes/delivery.js +0 -443
  864. package/dist/lib/lanes/dropbox.d.ts +0 -129
  865. package/dist/lib/lanes/dropbox.js +0 -601
  866. package/dist/lib/lanes/effort.d.ts +0 -51
  867. package/dist/lib/lanes/effort.js +0 -113
  868. package/dist/lib/lanes/envelope-repair-dispatch.d.ts +0 -26
  869. package/dist/lib/lanes/envelope-repair-dispatch.js +0 -74
  870. package/dist/lib/lanes/errors.d.ts +0 -39
  871. package/dist/lib/lanes/errors.js +0 -72
  872. package/dist/lib/lanes/flag-keys.d.ts +0 -13
  873. package/dist/lib/lanes/flag-keys.js +0 -13
  874. package/dist/lib/lanes/grants.d.ts +0 -29
  875. package/dist/lib/lanes/grants.js +0 -166
  876. package/dist/lib/lanes/hire-grant-dispatch.d.ts +0 -29
  877. package/dist/lib/lanes/hire-grant-dispatch.js +0 -316
  878. package/dist/lib/lanes/hooks-install.d.ts +0 -82
  879. package/dist/lib/lanes/hooks-install.js +0 -479
  880. package/dist/lib/lanes/host-capacity.d.ts +0 -69
  881. package/dist/lib/lanes/host-capacity.js +0 -254
  882. package/dist/lib/lanes/hq-root.d.ts +0 -19
  883. package/dist/lib/lanes/hq-root.js +0 -28
  884. package/dist/lib/lanes/index.d.ts +0 -76
  885. package/dist/lib/lanes/index.js +0 -42
  886. package/dist/lib/lanes/keep-alive.d.ts +0 -68
  887. package/dist/lib/lanes/keep-alive.js +0 -343
  888. package/dist/lib/lanes/kr-freshness.d.ts +0 -76
  889. package/dist/lib/lanes/kr-freshness.js +0 -413
  890. package/dist/lib/lanes/lane-company.d.ts +0 -10
  891. package/dist/lib/lanes/lane-company.js +0 -41
  892. package/dist/lib/lanes/liveness.d.ts +0 -108
  893. package/dist/lib/lanes/liveness.js +0 -396
  894. package/dist/lib/lanes/machine-identity.d.ts +0 -34
  895. package/dist/lib/lanes/machine-identity.js +0 -92
  896. package/dist/lib/lanes/manager-status-gate.d.ts +0 -17
  897. package/dist/lib/lanes/manager-status-gate.js +0 -133
  898. package/dist/lib/lanes/merge-command.d.ts +0 -15
  899. package/dist/lib/lanes/merge-command.js +0 -629
  900. package/dist/lib/lanes/mesh-events.d.ts +0 -127
  901. package/dist/lib/lanes/mesh-events.js +0 -564
  902. package/dist/lib/lanes/message-replay.d.ts +0 -21
  903. package/dist/lib/lanes/message-replay.js +0 -122
  904. package/dist/lib/lanes/models.d.ts +0 -86
  905. package/dist/lib/lanes/models.js +0 -234
  906. package/dist/lib/lanes/monitor.d.ts +0 -48
  907. package/dist/lib/lanes/monitor.js +0 -428
  908. package/dist/lib/lanes/move-account.d.ts +0 -56
  909. package/dist/lib/lanes/move-account.js +0 -193
  910. package/dist/lib/lanes/orphans.d.ts +0 -25
  911. package/dist/lib/lanes/orphans.js +0 -102
  912. package/dist/lib/lanes/outpost-dispatch.d.ts +0 -147
  913. package/dist/lib/lanes/outpost-dispatch.js +0 -271
  914. package/dist/lib/lanes/outpost-hire-cache.d.ts +0 -22
  915. package/dist/lib/lanes/outpost-hire-cache.js +0 -153
  916. package/dist/lib/lanes/outpost-identity.d.ts +0 -33
  917. package/dist/lib/lanes/outpost-identity.js +0 -59
  918. package/dist/lib/lanes/outpost-profile-repin.d.ts +0 -17
  919. package/dist/lib/lanes/outpost-profile-repin.js +0 -84
  920. package/dist/lib/lanes/outpost-pruner-install.d.ts +0 -37
  921. package/dist/lib/lanes/outpost-pruner-install.js +0 -238
  922. package/dist/lib/lanes/outpost-registry-worker-approval.d.ts +0 -18
  923. package/dist/lib/lanes/outpost-registry-worker-approval.js +0 -109
  924. package/dist/lib/lanes/outpost-snapshot-memo.d.ts +0 -6
  925. package/dist/lib/lanes/outpost-snapshot-memo.js +0 -14
  926. package/dist/lib/lanes/outpost-worktree-pruner-flag.d.ts +0 -19
  927. package/dist/lib/lanes/outpost-worktree-pruner-flag.js +0 -86
  928. package/dist/lib/lanes/outpost-worktree-pruner.d.ts +0 -62
  929. package/dist/lib/lanes/outpost-worktree-pruner.js +0 -1201
  930. package/dist/lib/lanes/profile.d.ts +0 -69
  931. package/dist/lib/lanes/profile.js +0 -552
  932. package/dist/lib/lanes/provider-rejection.d.ts +0 -86
  933. package/dist/lib/lanes/provider-rejection.js +0 -286
  934. package/dist/lib/lanes/questions.d.ts +0 -90
  935. package/dist/lib/lanes/questions.js +0 -384
  936. package/dist/lib/lanes/quota.d.ts +0 -134
  937. package/dist/lib/lanes/quota.js +0 -471
  938. package/dist/lib/lanes/reconcile-install.d.ts +0 -90
  939. package/dist/lib/lanes/reconcile-install.js +0 -257
  940. package/dist/lib/lanes/reconcile.d.ts +0 -155
  941. package/dist/lib/lanes/reconcile.js +0 -3193
  942. package/dist/lib/lanes/registry-flag.d.ts +0 -29
  943. package/dist/lib/lanes/registry-flag.js +0 -139
  944. package/dist/lib/lanes/registry-persona.d.ts +0 -20
  945. package/dist/lib/lanes/registry-persona.js +0 -329
  946. package/dist/lib/lanes/registry.d.ts +0 -122
  947. package/dist/lib/lanes/registry.js +0 -570
  948. package/dist/lib/lanes/reviews.d.ts +0 -38
  949. package/dist/lib/lanes/reviews.js +0 -395
  950. package/dist/lib/lanes/runaway-tool-guard.d.ts +0 -38
  951. package/dist/lib/lanes/runaway-tool-guard.js +0 -284
  952. package/dist/lib/lanes/session-relink.d.ts +0 -25
  953. package/dist/lib/lanes/session-relink.js +0 -216
  954. package/dist/lib/lanes/spawn.d.ts +0 -350
  955. package/dist/lib/lanes/spawn.js +0 -2643
  956. package/dist/lib/lanes/ssm-command-context.d.ts +0 -12
  957. package/dist/lib/lanes/ssm-command-context.js +0 -52
  958. package/dist/lib/lanes/store.d.ts +0 -91
  959. package/dist/lib/lanes/store.js +0 -1811
  960. package/dist/lib/lanes/stories.d.ts +0 -23
  961. package/dist/lib/lanes/stories.js +0 -92
  962. package/dist/lib/lanes/story-ledger.d.ts +0 -80
  963. package/dist/lib/lanes/story-ledger.js +0 -815
  964. package/dist/lib/lanes/story-switch.d.ts +0 -21
  965. package/dist/lib/lanes/story-switch.js +0 -75
  966. package/dist/lib/lanes/text-scan.d.ts +0 -11
  967. package/dist/lib/lanes/text-scan.js +0 -103
  968. package/dist/lib/lanes/throttle.d.ts +0 -116
  969. package/dist/lib/lanes/throttle.js +0 -437
  970. package/dist/lib/lanes/timestamp.d.ts +0 -3
  971. package/dist/lib/lanes/timestamp.js +0 -26
  972. package/dist/lib/lanes/tracker-checks.d.ts +0 -77
  973. package/dist/lib/lanes/tracker-checks.js +0 -134
  974. package/dist/lib/lanes/tracker-report-state.d.ts +0 -10
  975. package/dist/lib/lanes/tracker-report-state.js +0 -124
  976. package/dist/lib/lanes/tracker-report.d.ts +0 -203
  977. package/dist/lib/lanes/tracker-report.js +0 -522
  978. package/dist/lib/lanes/tracker-store.d.ts +0 -18
  979. package/dist/lib/lanes/tracker-store.js +0 -106
  980. package/dist/lib/lanes/types.d.ts +0 -1020
  981. package/dist/lib/lanes/types.js +0 -417
  982. package/dist/lib/lanes/wait.d.ts +0 -39
  983. package/dist/lib/lanes/wait.js +0 -159
  984. package/dist/lib/lanes/watch.d.ts +0 -39
  985. package/dist/lib/lanes/watch.js +0 -249
  986. package/dist/lib/lanes/watcher-main.d.ts +0 -11
  987. package/dist/lib/lanes/watcher-main.js +0 -108
  988. package/dist/lib/lanes/watcher.d.ts +0 -287
  989. package/dist/lib/lanes/watcher.js +0 -1972
  990. package/dist/lib/mesh/live/daemon/config.d.ts +0 -36
  991. package/dist/lib/mesh/live/daemon/config.js +0 -120
  992. package/dist/lib/mesh/live/daemon/legacy-listen.d.ts +0 -43
  993. package/dist/lib/mesh/live/daemon/legacy-listen.js +0 -89
  994. package/dist/lib/mesh/live/daemon/live-cache.d.ts +0 -26
  995. package/dist/lib/mesh/live/daemon/live-cache.js +0 -116
  996. package/dist/lib/mesh/live/daemon/mqtt-events.d.ts +0 -7
  997. package/dist/lib/mesh/live/daemon/mqtt-events.js +0 -2
  998. package/dist/lib/mesh/live/daemon/mqtt-events.test-d.d.ts +0 -2
  999. package/dist/lib/mesh/live/daemon/mqtt-events.test-d.js +0 -10
  1000. package/dist/lib/mesh/live/daemon/version-drift.d.ts +0 -5
  1001. package/dist/lib/mesh/live/daemon/version-drift.js +0 -47
  1002. package/dist/lib/mesh/live/daemon/work-subscribe.d.ts +0 -32
  1003. package/dist/lib/mesh/live/daemon/work-subscribe.js +0 -262
  1004. package/dist/lib/mesh/live/report-summary.d.ts +0 -45
  1005. package/dist/lib/mesh/live/report-summary.js +0 -234
  1006. package/dist/lib/mesh/live/session-seq.d.ts +0 -4
  1007. package/dist/lib/mesh/live/session-seq.js +0 -33
  1008. package/dist/lib/mesh/project-board.d.ts +0 -65
  1009. package/dist/lib/mesh/project-board.js +0 -181
  1010. package/dist/lib/mesh/story-status.d.ts +0 -22
  1011. package/dist/lib/mesh/story-status.js +0 -49
  1012. package/dist/lib/monitor.d.ts +0 -149
  1013. package/dist/lib/monitor.js +0 -519
  1014. package/dist/lib/node-binary.d.ts +0 -50
  1015. package/dist/lib/node-binary.js +0 -133
  1016. package/dist/lib/notify-recipient.d.ts +0 -7
  1017. package/dist/lib/notify-recipient.js +0 -11
  1018. package/dist/lib/onboarding/checkpoint.d.ts +0 -13
  1019. package/dist/lib/onboarding/checkpoint.js +0 -44
  1020. package/dist/lib/onboarding/cli/onboard.d.ts +0 -53
  1021. package/dist/lib/onboarding/cli/onboard.js +0 -135
  1022. package/dist/lib/onboarding/cli/prompts.d.ts +0 -28
  1023. package/dist/lib/onboarding/cli/prompts.js +0 -83
  1024. package/dist/lib/onboarding/errors.d.ts +0 -34
  1025. package/dist/lib/onboarding/errors.js +0 -59
  1026. package/dist/lib/onboarding/index.d.ts +0 -13
  1027. package/dist/lib/onboarding/index.js +0 -13
  1028. package/dist/lib/onboarding/orchestrator.d.ts +0 -47
  1029. package/dist/lib/onboarding/orchestrator.js +0 -569
  1030. package/dist/lib/onboarding/types.d.ts +0 -79
  1031. package/dist/lib/onboarding/types.js +0 -8
  1032. package/dist/lib/policy-validator.d.ts +0 -7
  1033. package/dist/lib/policy-validator.js +0 -187
  1034. package/dist/lib/process-flag-company-context.d.ts +0 -8
  1035. package/dist/lib/process-flag-company-context.js +0 -67
  1036. package/dist/lib/report-publish.d.ts +0 -175
  1037. package/dist/lib/report-publish.js +0 -421
  1038. package/dist/lib/report-run.d.ts +0 -62
  1039. package/dist/lib/report-run.js +0 -123
  1040. package/dist/lib/report-snapshot.d.ts +0 -12
  1041. package/dist/lib/report-snapshot.js +0 -135
  1042. package/dist/lib/report-templates.d.ts +0 -9
  1043. package/dist/lib/report-templates.js +0 -21
  1044. package/dist/lib/scaffold-cli-floor.d.ts +0 -8
  1045. package/dist/lib/scaffold-cli-floor.js +0 -50
  1046. package/dist/lib/search-index/collection-path-repair-flag.d.ts +0 -4
  1047. package/dist/lib/search-index/collection-path-repair-flag.js +0 -7
  1048. package/dist/lib/search-index/embed-lock.d.ts +0 -32
  1049. package/dist/lib/search-index/embed-lock.js +0 -286
  1050. package/dist/lib/search-index/load-gate.d.ts +0 -57
  1051. package/dist/lib/search-index/load-gate.js +0 -270
  1052. package/dist/lib/search-index/max-doc-bytes.d.ts +0 -219
  1053. package/dist/lib/search-index/max-doc-bytes.js +0 -463
  1054. package/dist/lib/search-index/qmd-exit-diagnostics.d.ts +0 -5
  1055. package/dist/lib/search-index/qmd-exit-diagnostics.js +0 -40
  1056. package/dist/lib/search-index/reindex-single-flight-flag.d.ts +0 -5
  1057. package/dist/lib/search-index/reindex-single-flight-flag.js +0 -8
  1058. package/dist/lib/service-manager/index.d.ts +0 -42
  1059. package/dist/lib/service-manager/index.js +0 -105
  1060. package/dist/lib/service-manager/launchd.d.ts +0 -81
  1061. package/dist/lib/service-manager/launchd.js +0 -212
  1062. package/dist/lib/service-manager/systemd.d.ts +0 -19
  1063. package/dist/lib/service-manager/systemd.js +0 -72
  1064. package/dist/lib/service-manager/types.d.ts +0 -34
  1065. package/dist/lib/service-manager/types.js +0 -26
  1066. package/dist/lib/test-utils/isolated-flag-company-context.d.ts +0 -3
  1067. package/dist/lib/test-utils/isolated-flag-company-context.js +0 -18
  1068. package/dist/lib/work-context/bind-best.d.ts +0 -66
  1069. package/dist/lib/work-context/bind-best.js +0 -344
  1070. package/dist/lib/work-context/bind-calling-session.d.ts +0 -26
  1071. package/dist/lib/work-context/bind-calling-session.js +0 -63
  1072. package/dist/lib/work-context/company-rebind.d.ts +0 -23
  1073. package/dist/lib/work-context/company-rebind.js +0 -59
  1074. package/dist/lib/work-context/default-company.d.ts +0 -43
  1075. package/dist/lib/work-context/default-company.js +0 -83
  1076. package/dist/lib/work-context/outbox-quarantine-status-flag.d.ts +0 -4
  1077. package/dist/lib/work-context/outbox-quarantine-status-flag.js +0 -7
  1078. package/dist/lib/work-context/prd-sync.d.ts +0 -56
  1079. package/dist/lib/work-context/prd-sync.js +0 -197
  1080. package/dist/lib/work-context/preflight-contract.d.ts +0 -28
  1081. package/dist/lib/work-context/preflight-contract.js +0 -85
  1082. package/dist/lib/work-context/prompt-rebind.d.ts +0 -25
  1083. package/dist/lib/work-context/prompt-rebind.js +0 -85
  1084. package/dist/lib/work-context/windows-acl.d.ts +0 -123
  1085. package/dist/lib/work-context/windows-acl.js +0 -425
  1086. package/dist/lib/workers-registry/read.d.ts +0 -15
  1087. package/dist/lib/workers-registry/read.js +0 -17
  1088. package/dist/native-fast-route.d.ts +0 -7
  1089. package/dist/native-fast-route.js +0 -45
  1090. package/dist/node-network-compat-core.d.ts +0 -12
  1091. package/dist/node-network-compat-core.js +0 -41
  1092. package/dist/node-network-compat-fast.d.ts +0 -7
  1093. package/dist/node-network-compat-fast.js +0 -23
  1094. package/dist/secrets-env-fast-path.d.ts +0 -5
  1095. package/dist/secrets-env-fast-path.js +0 -16
  1096. package/dist/secrets-env-fast-route.d.ts +0 -18
  1097. package/dist/secrets-env-fast-route.js +0 -54
  1098. package/dist/utils/checkpoint-stamp-write-error.d.ts +0 -28
  1099. package/dist/utils/checkpoint-stamp-write-error.js +0 -99
  1100. package/dist/utils/cli-network-lifecycle.d.ts +0 -4
  1101. package/dist/utils/cli-network-lifecycle.js +0 -11
  1102. package/dist/utils/cognito-refresh-sentry.d.ts +0 -3
  1103. package/dist/utils/cognito-refresh-sentry.js +0 -49
  1104. package/dist/utils/console-origin.d.ts +0 -9
  1105. package/dist/utils/console-origin.js +0 -28
  1106. package/dist/utils/exclusive-lock.d.ts +0 -32
  1107. package/dist/utils/exclusive-lock.js +0 -75
  1108. package/dist/utils/fast-stream-errors.d.ts +0 -12
  1109. package/dist/utils/fast-stream-errors.js +0 -18
  1110. package/dist/utils/files-browse-acl.d.ts +0 -5
  1111. package/dist/utils/files-browse-acl.js +0 -11
  1112. package/dist/utils/hq-core-yaml.d.ts +0 -10
  1113. package/dist/utils/hq-core-yaml.js +0 -40
  1114. package/dist/utils/hq-root-resolver.d.ts +0 -13
  1115. package/dist/utils/hq-root-resolver.js +0 -103
  1116. package/dist/utils/redact-url.d.ts +0 -14
  1117. package/dist/utils/redact-url.js +0 -218
  1118. package/dist/utils/scaffold-fast-import-guard.d.ts +0 -2
  1119. package/dist/utils/scaffold-fast-import-guard.js +0 -40
  1120. package/dist/utils/scaffold-packlist-guard.d.ts +0 -7
  1121. package/dist/utils/scaffold-packlist-guard.js +0 -23
  1122. package/dist/utils/scaffold-sibling-references.d.ts +0 -22
  1123. package/dist/utils/scaffold-sibling-references.js +0 -156
  1124. package/dist/utils/secret-load-availability.d.ts +0 -8
  1125. package/dist/utils/secret-load-availability.js +0 -54
  1126. package/dist/utils/staged-install.d.ts +0 -34
  1127. package/dist/utils/staged-install.js +0 -346
  1128. package/dist/utils/staged-npm-install.d.ts +0 -16
  1129. package/dist/utils/staged-npm-install.js +0 -264
  1130. package/dist/utils/sync-log-sources.d.ts +0 -15
  1131. package/dist/utils/sync-log-sources.js +0 -36
  1132. package/dist/utils/table-width.d.ts +0 -7
  1133. package/dist/utils/table-width.js +0 -15
  1134. package/dist/utils/update-command-supervisor.cjs +0 -247
  1135. package/dist/utils/upload-author.d.ts +0 -15
  1136. package/dist/utils/upload-author.js +0 -39
  1137. package/dist/utils/version-report.d.ts +0 -27
  1138. package/dist/utils/version-report.js +0 -105
  1139. package/dist/version-request.d.ts +0 -14
  1140. package/dist/version-request.js +0 -36
  1141. package/scripts/mesh-daemon-if-stale.mjs +0 -20
  1142. package/templates/reports/blank.md +0 -3
  1143. package/templates/reports/daily-digest.md +0 -11
  1144. package/templates/runbooks/update-report.md +0 -21
@@ -1,1972 +0,0 @@
1
- /**
2
- * Per-lane watcher (spec §5.7).
3
- *
4
- * Armed at spawn, detached from the caller. Emits on progress, terminal, and
5
- * silence (20 minutes with the process still alive). Terminal classification
6
- * follows spec §5: an envelope decides done/ask/blocked; a process that exits
7
- * with partial output and no envelope is `interrupted`; silence is never
8
- * success.
9
- *
10
- * Progress has two sources. Output files (worker.out, worker.err,
11
- * last-message.txt) cover codex and grok, which stream as they work. They do
12
- * not cover Claude: `claude -p --output-format json` writes nothing until it
13
- * exits, so a healthy Claude lane used to hit the silence deadline at exactly
14
- * 20 minutes every time, and a hung one looked identical. The second source
15
- * is logs/tool-activity.json, which the drain hook rewrites on every
16
- * PreToolUse call (dropbox.ts). A worker that is working calls tools; a
17
- * worker that has not called a tool or written output for the whole window
18
- * is `stalled`, and the watcher says so on the lane record.
19
- *
20
- * What this cannot tell apart: a worker hung inside one tool call from a
21
- * worker running one legitimately long tool call (a 25-minute build); a
22
- * worker looping on tool calls without making progress from a working one;
23
- * a model stuck mid-generation with no tool call from one that is writing a
24
- * long answer. It also depends on the drain hook being registered in the
25
- * provider home (hooks-install.ts): with no hook there is no touch, and the
26
- * lane reads as stalled every window, which is the pre-existing behaviour.
27
- * Distinguishing a hung tool from a slow one needs the provider to report
28
- * per-call state, which none of the three CLIs expose today. `stalled` is
29
- * therefore a flag for the senior to look at, never a kill.
30
- *
31
- * Queue admission of the next lane when a slot frees is owned by the
32
- * periodic reconcile pass and is out of scope here.
33
- */
34
- import * as fs from "node:fs";
35
- import * as path from "node:path";
36
- import { LanesError } from "./errors.js";
37
- import { questionRecordRefusalCode, raiseEnvelopeQuestions, resolveQuestionCompanyWithFallback, } from "./questions.js";
38
- import { isTerminalLaneState, ENVELOPE_INVALID_REASON, parseLaneEnvelope, STORY_STATUSES, LANE_PROVIDERS, } from "./types.js";
39
- import { laneStories, terminalEnvelopeStoryStatus } from "./stories.js";
40
- import { applyStorySwitchEnvelope } from "./story-switch.js";
41
- import { appendCappedHistory, listQuestionIds, readLane, readQuestion, retryUpdateLane, withLaneHireLocks } from "./store.js";
42
- import { enforceRegistryApprovalGate } from "./approval-gate.js";
43
- import { readWorkerRunResult } from "./delivery.js";
44
- import { applyDefaultQuotaHold, clearAccountQuotaAfterSuccessfulTurnBestEffort, quotaSignalFromFields, readQuotaSignal, recordAccountQuota, } from "./quota.js";
45
- import { PROVIDER_REJECTED_REASON, QUOTA_STATUS, isProviderLoginFailure, providerRejectionDetails, readProviderRejection, } from "./provider-rejection.js";
46
- import { appendDropboxMessageAtPath, dropboxInboxHasMessages, readToolActivity, toolActivityPath } from "./dropbox.js";
47
- import { loadLanesConfig, providerProgressEventMinIntervalMs, providerQuotaDefaultHoldMs } from "./config.js";
48
- import { resolveAdmissionHost as resolveProcessAdmissionHost } from "./admission-host.js";
49
- import { createLaneMesh, emitLaneDecisionEvents, emitLaneProgressEvent, emitLaneTerminalStateEvent, laneStoryStatusSuppressionKey, progressEventDue, } from "./mesh-events.js";
50
- import { envelopeQuestionId } from "./questions.js";
51
- import { readLanesRegistryFlag } from "./registry-flag.js";
52
- import { laneCompanyUidSource, resolveLaneCompany } from "./lane-company.js";
53
- import { blockerFreshnessFingerprint, resolveBlockerFreshnessForLane, } from "./blocker-freshness.js";
54
- import { krFreshnessFingerprint, resolveKrFreshnessForLane, } from "./kr-freshness.js";
55
- import { managerStatusWasWritten, readStatusSnapshot, resolveManagerStatusTarget, } from "./manager-status-gate.js";
56
- import { LEAD_LANE_KEEP_ALIVE_FIRST_RESUME_SETTLE_MS, LEAD_LANE_KEEP_ALIVE_FLAG, LEAD_LANE_KEEP_ALIVE_IMMEDIATE_FIRST_RESUME_FLAG, LEAD_LANE_KEEP_ALIVE_TERMINAL_TRIGGER_FLAG, queueLaneTerminalResume, queueManagerStatusGateResume, } from "./keep-alive.js";
57
- import { LANE_ENVELOPE_REPAIR_CONTINUE_FLAG } from "./flag-keys.js";
58
- import { monitorSessionDir } from "../monitor.js";
59
- import { laneRunDir, missingPidProbe, probePidRecord, readPidRecord, readProcStarttime, readSpawnManifest, envelopeRepairMode, spawnEnvelopeRepair, writePidRecord, retryLaneOnAlternateAccount, } from "./spawn.js";
60
- /** Spec §5.7: no signal for 20 minutes while the process is still alive. */
61
- export const SILENCE_MS = 20 * 60 * 1000;
62
- export const WATCHER_POLL_MS = 5_000;
63
- export const ENVELOPE_REPAIR_CONTINUE_TEXT = "continue the task; the previous turn ended without an envelope.";
64
- /** Synced last_host_report_at cadence. Reconcile dead-host TTL is 20 minutes. */
65
- export const WATCHER_HEARTBEAT_MS = 60 * 1000;
66
- /**
67
- * Cap on logs/watcher.out. A decision line is typically under 300 bytes, so
68
- * 256 KiB holds hundreds of transitions. A stuck lane cannot fill the disk:
69
- * once the file would exceed this, the oldest complete lines are dropped.
70
- */
71
- export const WATCHER_OUT_MAX_BYTES = 256 * 1024;
72
- export const WATCHER_DECISION_EVENTS = [
73
- "liveness_transition",
74
- "silence_deadline",
75
- "envelope_observed",
76
- "envelope_invalid",
77
- "envelope_repair",
78
- "envelope_repair_continue",
79
- "classification",
80
- "terminal_write",
81
- "message_recovery",
82
- "message_recovery_failed",
83
- "message_undeliverable",
84
- "mesh_event",
85
- "mesh_event_failed",
86
- ];
87
- /** Terminal reason when the envelope failed to parse after the repair turn (spec §4). */
88
- export { ENVELOPE_INVALID_REASON };
89
- export const WATCHER_SIGNAL_KINDS = ["progress", "terminal", "silence"];
90
- export function parseWatcherSignalKind(value) {
91
- if (typeof value === "string" &&
92
- WATCHER_SIGNAL_KINDS.includes(value)) {
93
- return value;
94
- }
95
- throw new LanesError("unknown_watcher_signal", `Unknown watcher signal ${JSON.stringify(value)}. Accepted: ${WATCHER_SIGNAL_KINDS.join(", ")}`, { accepted: [...WATCHER_SIGNAL_KINDS], value });
96
- }
97
- export function classifyLaneExit(input) {
98
- if (input.envelope) {
99
- if (input.envelope.decision === "done")
100
- return { state: "done" };
101
- if (input.envelope.decision === "ask")
102
- return { state: "awaiting_input" };
103
- if (input.envelope.decision === "blocked")
104
- return { state: "blocked" };
105
- throw new LanesError("unknown_envelope_decision", `Unknown envelope decision ${JSON.stringify(input.envelope.decision)}. Accepted: done, ask, blocked`, { accepted: ["done", "ask", "blocked"], value: input.envelope.decision });
106
- }
107
- if (input.providerRejection) {
108
- return {
109
- state: "failed",
110
- reason: isProviderLoginFailure(input.providerRejection)
111
- ? "account_not_logged_in"
112
- : PROVIDER_REJECTED_REASON,
113
- };
114
- }
115
- if (input.invalidEnvelope) {
116
- return { state: "failed", reason: ENVELOPE_INVALID_REASON };
117
- }
118
- if (input.quota) {
119
- return {
120
- state: input.hasPartialOutput ? "interrupted" : "failed",
121
- reason: input.quota.reason,
122
- };
123
- }
124
- if (input.hasPartialOutput) {
125
- return { state: "interrupted", reason: "exited_with_partial_output" };
126
- }
127
- return { state: "failed", reason: "exited_without_envelope" };
128
- }
129
- /**
130
- * One decision for an exited worker's output. An explicit provider status
131
- * wins over the quota text heuristics: a 429 from any provider (including
132
- * codex `turn.failed` and grok error objects, which the claude-shaped quota
133
- * reader never sees) becomes a quota signal; any other explicit status is a
134
- * rejection even when its text sounds like a quota message (a 402 "requires
135
- * usage credits" is a rejection, not a hold). A failure with no status at
136
- * all is matched against the quota text heuristics first: a status-less
137
- * "usage limit" / "rate limit" turn.failed still creates the account hold;
138
- * any other status-less message is a rejection. Only when the stream
139
- * carries no failure object does the quota reader's own read apply.
140
- */
141
- export function routeProviderFailure(failure, readQuota, model, now) {
142
- if (failure && failure.status === QUOTA_STATUS) {
143
- return {
144
- quota: quotaSignalFromFields({ api_error_status: QUOTA_STATUS, is_error: true, result: failure.message }, model, now),
145
- rejection: null,
146
- };
147
- }
148
- if (failure && failure.status === null) {
149
- const quota = quotaSignalFromFields({ api_error_status: undefined, is_error: true, result: failure.message }, model, now);
150
- if (quota)
151
- return { quota, rejection: null };
152
- }
153
- if (failure)
154
- return { quota: null, rejection: failure };
155
- return { quota: readQuota(), rejection: null };
156
- }
157
- export function tickWatcher(input) {
158
- const silenceMs = input.silenceMs ?? SILENCE_MS;
159
- const at = new Date(input.nowMs).toISOString();
160
- if (!input.processAlive) {
161
- const classification = classifyLaneExit({
162
- envelope: input.envelope,
163
- hasPartialOutput: input.hasPartialOutput,
164
- quota: input.quota,
165
- invalidEnvelope: input.invalidEnvelope,
166
- providerRejection: input.providerRejection,
167
- });
168
- return {
169
- emit: { kind: "terminal", at, classification },
170
- nextLastSignalMs: input.nowMs,
171
- done: true,
172
- };
173
- }
174
- if (input.progressed) {
175
- return {
176
- emit: { kind: "progress", at },
177
- nextLastSignalMs: input.nowMs,
178
- done: false,
179
- };
180
- }
181
- if (input.nowMs - input.lastSignalMs >= silenceMs) {
182
- return {
183
- emit: { kind: "silence", at },
184
- nextLastSignalMs: input.nowMs,
185
- done: false,
186
- };
187
- }
188
- return { nextLastSignalMs: input.lastSignalMs, done: false };
189
- }
190
- export function watcherEventsPath(hqRoot, laneId) {
191
- return path.join(laneRunDir(hqRoot, laneId), "watcher", "events.jsonl");
192
- }
193
- export function watcherOutLogPath(hqRoot, laneId) {
194
- return path.join(laneRunDir(hqRoot, laneId), "logs", "watcher.out");
195
- }
196
- export function appendCappedLog(filePath, line, maxBytes = WATCHER_OUT_MAX_BYTES) {
197
- const payload = line.endsWith("\n") ? line : `${line}\n`;
198
- const payloadBytes = Buffer.byteLength(payload, "utf8");
199
- if (payloadBytes > maxBytes)
200
- return;
201
- let existing = "";
202
- try {
203
- existing = fs.readFileSync(filePath, "utf8");
204
- }
205
- catch (err) {
206
- const code = err.code;
207
- if (code !== "ENOENT")
208
- throw err;
209
- }
210
- let body = existing;
211
- while (Buffer.byteLength(body, "utf8") + payloadBytes > maxBytes) {
212
- const nl = body.indexOf("\n");
213
- if (nl === -1) {
214
- body = "";
215
- break;
216
- }
217
- body = body.slice(nl + 1);
218
- }
219
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
220
- fs.writeFileSync(filePath, body + payload, "utf8");
221
- }
222
- export function writeWatcherDecision(filePath, record, maxBytes = WATCHER_OUT_MAX_BYTES) {
223
- const compact = {};
224
- for (const [key, value] of Object.entries(record)) {
225
- if (value !== undefined)
226
- compact[key] = value;
227
- }
228
- appendCappedLog(filePath, JSON.stringify(compact), maxBytes);
229
- }
230
- /** Append a decision to the shared event stream without a read-modify-write. */
231
- export function appendWatcherEvent(filePath, record, appendLine = (target, line) => fs.appendFileSync(target, line, "utf8")) {
232
- const compact = {};
233
- for (const [key, value] of Object.entries(record)) {
234
- if (value !== undefined)
235
- compact[key] = value;
236
- }
237
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
238
- appendLine(filePath, `${JSON.stringify(compact)}\n`);
239
- }
240
- export function watcherLastSignalPath(hqRoot, laneId) {
241
- return path.join(laneRunDir(hqRoot, laneId), "watcher", "last-signal.json");
242
- }
243
- export function appendWatcherSignal(hqRoot, laneId, signal) {
244
- const eventsPath = watcherEventsPath(hqRoot, laneId);
245
- fs.mkdirSync(path.dirname(eventsPath), { recursive: true });
246
- fs.appendFileSync(eventsPath, `${JSON.stringify(signal)}\n`, "utf8");
247
- fs.writeFileSync(watcherLastSignalPath(hqRoot, laneId), `${JSON.stringify(signal, null, 2)}\n`, "utf8");
248
- }
249
- /**
250
- * Slot-free notification. The periodic reconcile pass admits the next queued
251
- * lane; this watcher must not do it. Intentionally empty.
252
- */
253
- export function notifySlotFreed(_input) {
254
- // Reconcile lane owns admission when a running slot frees (spec §5.7).
255
- }
256
- /**
257
- * On exit, read the worker's own result for a resumable provider and copy
258
- * only the session id and the two cache counters onto the record. A missing
259
- * or unparseable id is recorded as absent with its reason, never invented.
260
- * Non-resumable providers return null and the record is left as it was.
261
- */
262
- function runResultFields(hqRoot, lane, at) {
263
- const runDir = laneRunDir(hqRoot, lane.lane_id);
264
- const result = readWorkerRunResult(runDir, lane.provider, readSpawnManifest(runDir).worker_out_offset ?? 0);
265
- if (result === null)
266
- return {};
267
- const fields = {
268
- last_run_usage: {
269
- cache_read_input_tokens: result.cache_read_input_tokens,
270
- cache_creation_input_tokens: result.cache_creation_input_tokens,
271
- },
272
- last_run_usage_at: at,
273
- };
274
- if (result.session_id !== null) {
275
- fields.provider_session_id = result.session_id;
276
- fields.provider_session_id_absent = undefined;
277
- }
278
- else {
279
- // A resumed provider may exit before it emits a new result object. Keep
280
- // the prior session id so the lane remains resumable; only describe an
281
- // absent id when no earlier run recorded one.
282
- if (lane.provider_session_id || lane.last_resume?.session_id) {
283
- fields.provider_session_id_absent = undefined;
284
- }
285
- else {
286
- fields.provider_session_id_absent = result.session_id_absent ?? "no_result_json";
287
- }
288
- }
289
- return fields;
290
- }
291
- function maybeHeartbeatLane(hqRoot, laneId, nowMs) {
292
- try {
293
- retryUpdateLane(hqRoot, laneId, "watcher", (current) => {
294
- if (current.state !== "running")
295
- return current;
296
- const last = Date.parse(current.last_host_report_at ?? "");
297
- if (Number.isFinite(last) && nowMs - last < WATCHER_HEARTBEAT_MS) {
298
- return current;
299
- }
300
- return { ...current, last_host_report_at: new Date(nowMs).toISOString() };
301
- });
302
- }
303
- catch (err) {
304
- process.stderr.write(`hq lanes watcher: heartbeat failed for ${laneId}: ${err instanceof Error ? err.message : String(err)}\n`);
305
- }
306
- }
307
- export function stalledReason(silenceMs) {
308
- return `no_tool_call_or_output_for_${Math.round(silenceMs / 1000)}s`;
309
- }
310
- /**
311
- * The consumer of the silence signal. A silence emit on a running lane sets
312
- * `stalled` on the record so `hq lanes list` and `show` surface it; the next
313
- * progress emit clears it. Nothing here changes `state`.
314
- */
315
- export function markLaneStalled(hqRoot, laneId, at, reason) {
316
- return retryUpdateLane(hqRoot, laneId, "watcher", (current) => {
317
- if (current.state !== "running")
318
- return current;
319
- if (current.stalled === true && current.stalled_reason === reason)
320
- return current;
321
- return { ...current, stalled: true, stalled_at: at, stalled_reason: reason };
322
- });
323
- }
324
- export function clearLaneStalled(hqRoot, laneId) {
325
- return retryUpdateLane(hqRoot, laneId, "watcher", (current) => {
326
- if (current.stalled === undefined && current.stalled_at === undefined)
327
- return current;
328
- return { ...current, stalled: undefined, stalled_at: undefined, stalled_reason: undefined };
329
- });
330
- }
331
- export function applyTerminalToLane(hqRoot, laneId, classification, opts = {}) {
332
- return applyTerminalToLaneWithResult(hqRoot, laneId, classification, opts).record;
333
- }
334
- /** Terminal write outcome for emitters: only the CAS winner may publish mesh effects. */
335
- export function applyTerminalToLaneWithResult(hqRoot, laneId, classification, opts = {}) {
336
- const at = opts.at ?? new Date().toISOString();
337
- const envelopeRef = opts.envelopeRef ?? "envelopes/unknown.json";
338
- const existing = readLane(hqRoot, laneId);
339
- let questionRefusalCode = null;
340
- if (!isTerminalLaneState(existing.state) &&
341
- classification.state === "awaiting_input" &&
342
- opts.envelope &&
343
- (opts.envelope.questions?.length ?? 0) > 0) {
344
- try {
345
- raiseEnvelopeQuestions(hqRoot, existing, opts.envelope, opts.envelopeRef ?? "envelopes/unknown.json", at, opts.questionIndexes, opts.activeCompany);
346
- }
347
- catch (err) {
348
- questionRefusalCode = questionRecordRefusalCode(err);
349
- if (questionRefusalCode === null)
350
- throw err;
351
- process.stderr.write(`hq lanes watcher: terminal ask refused for ${laneId}: ${questionRefusalCode}\n`);
352
- }
353
- }
354
- const terminalClassification = questionRefusalCode === null
355
- ? classification
356
- : {
357
- state: "failed",
358
- reason: `question_record_refused:${questionRefusalCode}`,
359
- };
360
- let changed = false;
361
- let effectiveEnvelope = opts.envelope ?? undefined;
362
- let effectiveClassification = terminalClassification;
363
- const updated = retryUpdateLane(hqRoot, laneId, "watcher", (current) => {
364
- const approvalGate = opts.envelope !== undefined && opts.envelope !== null
365
- ? enforceRegistryApprovalGate(current, opts.envelope)
366
- : undefined;
367
- effectiveEnvelope = approvalGate?.envelope ?? opts.envelope ?? undefined;
368
- effectiveClassification = approvalGate?.violation
369
- ? { state: "blocked", reason: "approval_gate_violated" }
370
- : terminalClassification;
371
- const terminal = current.state === "done" ||
372
- current.state === "failed" ||
373
- current.state === "interrupted" ||
374
- current.state === "cancelled" ||
375
- current.state === "killed";
376
- if (terminal)
377
- return current;
378
- if (current.state === "awaiting_input" || current.state === "blocked") {
379
- if (current.state === effectiveClassification.state)
380
- return current;
381
- }
382
- const next = {
383
- ...current,
384
- ...runResultFields(hqRoot, current, at),
385
- state: effectiveClassification.state,
386
- queued_reason: undefined,
387
- queued_details: undefined,
388
- stalled: undefined,
389
- stalled_at: undefined,
390
- stalled_reason: undefined,
391
- interrupted_at: effectiveClassification.state === "interrupted" ? at : undefined,
392
- envelope_validation_errors: opts.envelopeValidationErrors,
393
- };
394
- changed = true;
395
- if (effectiveClassification.reason) {
396
- next.terminal_reason =
397
- effectiveClassification.reason;
398
- }
399
- if (opts.quota?.quota_reset_at) {
400
- next.quota_reset_at = opts.quota.quota_reset_at;
401
- }
402
- if (opts.quota?.marker) {
403
- next.model_quota_marker = opts.quota.marker;
404
- }
405
- if (opts.providerRejection) {
406
- next.terminal_details = providerRejectionDetails(opts.providerRejection, current);
407
- }
408
- const envelope = effectiveEnvelope;
409
- if (approvalGate && !approvalGate.violation && approvalGate.approvedIdsToConsume.length > 0) {
410
- next.registry_worker_approval_history = approvalGate.approvedIdsToConsume.reduce((history, approvalId) => appendCappedHistory(history, {
411
- event: "consumed",
412
- approval_id: approvalId,
413
- envelope_ref: envelopeRef,
414
- at,
415
- }), current.registry_worker_approval_history ?? []);
416
- }
417
- if (envelope) {
418
- const storySwitch = applyStorySwitchEnvelope(current, envelope, at, envelopeRef);
419
- if (envelope.decision !== "blocked")
420
- next.keep_alive_blocked_resume_streak = 0;
421
- next.last_envelope = {
422
- ref: envelopeRef,
423
- decision: envelope.decision,
424
- at,
425
- artifacts: envelope.artifacts,
426
- ...(envelope.blocked_reason !== undefined ? { blocked_reason: envelope.blocked_reason } : {}),
427
- ...(envelope.next_check_at !== undefined ? { next_check_at: envelope.next_check_at } : {}),
428
- };
429
- if (storySwitch.clearPending) {
430
- next.story_switch_pending = undefined;
431
- }
432
- if (storySwitch.storySwitchUnacknowledged !== undefined) {
433
- next.story_switch_unacknowledged = storySwitch.storySwitchUnacknowledged;
434
- next.attribution_history = storySwitch.attributionHistory ?? current.attribution_history;
435
- }
436
- const storyStatus = storySwitch.suppressCompletion
437
- ? "in_progress"
438
- : terminalEnvelopeStoryStatus(current, envelope.decision, envelope.story_status);
439
- if (storyStatus !== undefined) {
440
- next.story_status = storySwitch.suppressCompletion ? "in_progress" : envelope.story_status;
441
- next.story_complete = storySwitch.suppressCompletion ? false : envelope.story_complete;
442
- next.story_complete_reason = storySwitch.suppressCompletion ? undefined : envelope.story_complete_reason;
443
- const currentProject = current.project_id;
444
- const currentStory = current.story_id;
445
- const updatedStories = laneStories(current).map((story) => story.project_id === currentProject && story.story_id === currentStory
446
- ? {
447
- ...story,
448
- status: storyStatus,
449
- updated_at: at,
450
- ...(envelope.decision === "blocked"
451
- ? { blocked_reason: envelope.blocked_reason ?? "" }
452
- : { blocked_reason: undefined }),
453
- }
454
- : story);
455
- next.stories = updatedStories;
456
- }
457
- }
458
- return next;
459
- });
460
- if (updated.state === "done" &&
461
- effectiveClassification.state === "done" &&
462
- effectiveEnvelope?.decision === "done" &&
463
- opts.quota == null &&
464
- opts.providerRejection == null &&
465
- updated.account &&
466
- updated.model) {
467
- clearAccountQuotaAfterSuccessfulTurnBestEffort(hqRoot, updated.provider, updated.account, updated.model, new Date(at));
468
- }
469
- notifySlotFreed({
470
- hqRoot,
471
- provider: updated.provider,
472
- account: updated.account,
473
- });
474
- return {
475
- record: updated,
476
- changed,
477
- ...(effectiveEnvelope !== undefined ? { envelope: effectiveEnvelope } : {}),
478
- classification: effectiveClassification,
479
- };
480
- }
481
- export function isPidAlive(pid) {
482
- try {
483
- process.kill(pid, 0);
484
- return true;
485
- }
486
- catch (err) {
487
- const code = err.code;
488
- if (code === "ESRCH")
489
- return false;
490
- if (code === "EPERM")
491
- return true;
492
- process.stderr.write(`hq lanes watcher: liveness probe for pid ${pid} failed: ${err instanceof Error ? err.message : String(err)}\n`);
493
- throw err;
494
- }
495
- }
496
- function fileMtimeMs(filePath) {
497
- try {
498
- return fs.statSync(filePath).mtimeMs;
499
- }
500
- catch (err) {
501
- const code = err.code;
502
- if (code === "ENOENT")
503
- return null;
504
- process.stderr.write(`hq lanes watcher: failed to stat ${filePath}: ${err instanceof Error ? err.message : String(err)}\n`);
505
- throw err;
506
- }
507
- }
508
- function fileNonEmpty(filePath) {
509
- try {
510
- return fs.statSync(filePath).size > 0;
511
- }
512
- catch (err) {
513
- const code = err.code;
514
- if (code === "ENOENT")
515
- return false;
516
- process.stderr.write(`hq lanes watcher: failed to stat ${filePath}: ${err instanceof Error ? err.message : String(err)}\n`);
517
- throw err;
518
- }
519
- }
520
- function isPlainObject(value) {
521
- return value !== null && typeof value === "object" && !Array.isArray(value);
522
- }
523
- /** Keep only questions that the normal envelope parser accepts. */
524
- function recoverAskEnvelope(text, validationErrors) {
525
- const raw = JSON.parse(text);
526
- if (!isPlainObject(raw) || raw.decision !== "ask" || !Array.isArray(raw.questions)) {
527
- return null;
528
- }
529
- const validQuestions = [];
530
- const questionIndexes = [];
531
- const questionErrors = [];
532
- for (let index = 0; index < raw.questions.length; index += 1) {
533
- const question = raw.questions[index];
534
- try {
535
- const parsed = parseLaneEnvelope({
536
- schema_version: "hq-lane-envelope.v1",
537
- decision: "ask",
538
- summary: "Recovered operator question",
539
- story_status: "in_progress",
540
- artifacts: [],
541
- questions: [question],
542
- });
543
- const item = parsed.questions?.[0];
544
- if (item === undefined) {
545
- throw new Error("question parser returned no question");
546
- }
547
- validQuestions.push(item);
548
- questionIndexes.push(index);
549
- }
550
- catch (err) {
551
- questionErrors.push(`questions[${index}] is invalid: ${err instanceof Error ? err.message : String(err)}`);
552
- }
553
- }
554
- if (validQuestions.length === 0) {
555
- return {
556
- envelope: {
557
- schema_version: "hq-lane-envelope.v1",
558
- decision: "ask",
559
- summary: "The worker needs operator input after envelope validation failed.",
560
- story_status: STORY_STATUSES.includes(raw.story_status)
561
- ? raw.story_status
562
- : "in_progress",
563
- artifacts: [],
564
- questions: [],
565
- },
566
- questionIndexes,
567
- questionErrors,
568
- sourceQuestionCount: raw.questions.length,
569
- };
570
- }
571
- const contextErrors = [...new Set([...validationErrors, ...questionErrors])];
572
- const storyStatus = STORY_STATUSES.includes(raw.story_status) && raw.story_status !== "done"
573
- ? raw.story_status
574
- : "in_progress";
575
- const questions = validQuestions.map((question) => ({
576
- ...question,
577
- context: `${question.context}\n\nEnvelope validation errors:\n${contextErrors.map((error) => `- ${error}`).join("\n")}`,
578
- }));
579
- return {
580
- envelope: {
581
- schema_version: "hq-lane-envelope.v1",
582
- decision: "ask",
583
- summary: typeof raw.summary === "string" && raw.summary.length > 0
584
- ? raw.summary
585
- : "The worker needs operator input after envelope validation failed.",
586
- story_status: storyStatus,
587
- artifacts: [],
588
- questions,
589
- },
590
- questionIndexes,
591
- questionErrors,
592
- sourceQuestionCount: raw.questions.length,
593
- };
594
- }
595
- export function readLatestEnvelope(hqRoot, laneId, minName) {
596
- return readLatestEnvelopeRecord(hqRoot, laneId, minName)?.envelope ?? null;
597
- }
598
- /** Valid-only view over `readLatestEnvelopeFile`; an unparseable file reads as absent. */
599
- export function readLatestEnvelopeRecord(hqRoot, laneId, minName) {
600
- const latest = readLatestEnvelopeFile(hqRoot, laneId, minName);
601
- if (latest === null)
602
- return null;
603
- if (latest.envelope === null) {
604
- process.stderr.write(`hq lanes watcher: envelope ${latest.path} is not a valid hq-lane-envelope.v1: ${latest.error}\n`);
605
- return null;
606
- }
607
- return { envelope: latest.envelope, ref: latest.ref };
608
- }
609
- /**
610
- * `minName` is this run's envelope slot (basename from spawn.json). Envelopes
611
- * that sort before it belong to an earlier run of the same lane and must not
612
- * classify this exit: a resumed run that dies before writing its own envelope
613
- * would otherwise be marked done again from the previous one.
614
- */
615
- export function readLatestEnvelopeFile(hqRoot, laneId, minName) {
616
- const dir = path.join(laneRunDir(hqRoot, laneId), "envelopes");
617
- let names;
618
- try {
619
- names = fs
620
- .readdirSync(dir)
621
- .filter((name) => name.endsWith(".json"))
622
- .filter((name) => minName === undefined || name >= minName)
623
- .sort();
624
- }
625
- catch (err) {
626
- const code = err.code;
627
- if (code === "ENOENT")
628
- return null;
629
- process.stderr.write(`hq lanes watcher: failed to list envelopes for ${laneId}: ${err instanceof Error ? err.message : String(err)}\n`);
630
- throw err;
631
- }
632
- if (names.length === 0)
633
- return null;
634
- const latest = names[names.length - 1];
635
- const filePath = path.join(dir, latest);
636
- let text;
637
- try {
638
- text = fs.readFileSync(filePath, "utf8");
639
- }
640
- catch (err) {
641
- process.stderr.write(`hq lanes watcher: failed to read envelope ${filePath}: ${err instanceof Error ? err.message : String(err)}\n`);
642
- throw err;
643
- }
644
- const ref = path.posix.join("envelopes", latest);
645
- try {
646
- return {
647
- ref,
648
- path: filePath,
649
- text,
650
- envelope: parseLaneEnvelope(JSON.parse(text)),
651
- error: null,
652
- };
653
- }
654
- catch (err) {
655
- return {
656
- ref,
657
- path: filePath,
658
- text,
659
- envelope: null,
660
- error: err instanceof Error ? err.message : String(err),
661
- };
662
- }
663
- }
664
- /** A descriptor for this run's manifest slot when no envelope file was written. */
665
- export function missingExpectedEnvelopeFile(hqRoot, laneId, envelopePath) {
666
- if (!envelopePath || !path.isAbsolute(envelopePath))
667
- return null;
668
- const runDir = laneRunDir(hqRoot, laneId);
669
- const expectedPath = path.resolve(envelopePath);
670
- const expectedDir = path.resolve(runDir, "envelopes");
671
- const filename = path.basename(expectedPath);
672
- if (path.dirname(expectedPath) !== expectedDir || !filename.endsWith(".json"))
673
- return null;
674
- return {
675
- ref: path.posix.join("envelopes", filename),
676
- path: expectedPath,
677
- text: "",
678
- envelope: null,
679
- error: `Missing expected envelope file: ${expectedPath}`,
680
- missing: true,
681
- };
682
- }
683
- async function settleManagerStatusGate(hqRoot, lane, manifestTurnId, at, deps, logDecision) {
684
- let target;
685
- try {
686
- resolveLaneCompany(hqRoot, lane);
687
- target = resolveManagerStatusTarget(hqRoot, lane);
688
- }
689
- catch (err) {
690
- process.stderr.write(`hq lanes watcher: manager status mapping failed for ${lane.lane_id}: ${err instanceof Error ? err.message : String(err)}\n`);
691
- logDecision({ event: "status_gate_mapping_failed", at, error: err instanceof Error ? err.message : String(err) });
692
- return lane;
693
- }
694
- const gate = lane.status_gate;
695
- if (!target.manager || target.statusPath === undefined || gate === undefined)
696
- return lane;
697
- if (manifestTurnId !== undefined && manifestTurnId !== gate.turn_id ||
698
- target.statusPath !== gate.status_path) {
699
- logDecision({ event: "status_gate_baseline_mismatch", at, turn_id: gate.turn_id });
700
- return lane;
701
- }
702
- let written;
703
- try {
704
- written = managerStatusWasWritten(gate, readStatusSnapshot(gate.status_path));
705
- }
706
- catch (err) {
707
- process.stderr.write(`hq lanes watcher: manager status read failed for ${lane.lane_id}: ${err instanceof Error ? err.message : String(err)}\n`);
708
- logDecision({ event: "status_gate_status_read_failed", at, error: err instanceof Error ? err.message : String(err) });
709
- written = false;
710
- }
711
- if (written) {
712
- return retryUpdateLane(hqRoot, lane.lane_id, "watcher", (current) => {
713
- if (current.status_gate?.turn_id !== gate.turn_id || current.status_gate.consecutive_misses === 0)
714
- return current;
715
- return { ...current, status_gate: { ...current.status_gate, consecutive_misses: 0 } };
716
- });
717
- }
718
- const resumeText = `Your turn ended without updating ${gate.status_path}. Write your status now: update updated_at, kpis and current_work, then end the turn.`;
719
- const updated = queueManagerStatusGateResume(hqRoot, lane.lane_id, {
720
- turn_id: gate.turn_id,
721
- path: gate.status_path,
722
- at,
723
- identified_by: target.identified_by ?? "juniors",
724
- }, resumeText);
725
- const miss = updated.status_gate_history?.find((entry) => entry.event === "status_missed" && entry.turn_id === gate.turn_id);
726
- if (miss) {
727
- logDecision({
728
- event: "status_missed",
729
- at,
730
- turn_id: gate.turn_id,
731
- path: gate.status_path,
732
- consecutive_misses: updated.status_gate?.consecutive_misses ?? 0,
733
- resume_queued: "resume_queued" in miss && miss.resume_queued === true,
734
- resume_skipped_reason: "resume_skipped_reason" in miss ? miss.resume_skipped_reason : undefined,
735
- state: updated.state,
736
- });
737
- }
738
- return updated;
739
- }
740
- async function settleBlockerFreshness(hqRoot, lane, manifestTurnId, at, deps, mesh, logDecision) {
741
- let errorLogged = false;
742
- const resolution = await resolveBlockerFreshnessForLane(hqRoot, lane, {
743
- readFlag: deps.readBlockerFreshnessFlag ?? readLanesRegistryFlag,
744
- now: Date.parse(at),
745
- onError: (error) => {
746
- if (errorLogged)
747
- return;
748
- errorLogged = true;
749
- const code = error instanceof LanesError ? error.error : "blocker_freshness_unavailable";
750
- process.stderr.write(`hq lanes watcher: blocker freshness disabled for ${lane.lane_id}: ${code}\n`);
751
- logDecision({ event: "blocker_freshness_disabled", at, error: code });
752
- },
753
- });
754
- if (!resolution.enabled || resolution.statusPath === undefined || resolution.error !== undefined)
755
- return lane;
756
- if (manifestTurnId !== undefined && lane.status_gate !== undefined && lane.status_gate.turn_id !== manifestTurnId) {
757
- logDecision({ event: "blocker_freshness_baseline_mismatch", at, turn_id: lane.status_gate.turn_id });
758
- return lane;
759
- }
760
- if (resolution.stale.length === 0) {
761
- if (lane.blocker_freshness_state === undefined)
762
- return lane;
763
- return retryUpdateLane(hqRoot, lane.lane_id, "watcher", (current) => current.blocker_freshness_state === undefined
764
- ? current
765
- : { ...current, blocker_freshness_state: undefined });
766
- }
767
- const staleKeys = resolution.stale.map((blocker) => blocker.key).sort();
768
- const staleLabels = resolution.stale.map((blocker) => blocker.label);
769
- const fingerprint = blockerFreshnessFingerprint(resolution.stale);
770
- const turnId = manifestTurnId ?? lane.status_gate?.turn_id ?? `unknown-${at}`;
771
- const resumeText = `These open blockers in ${resolution.statusPath} were not re-verified in the last ${resolution.windowHours}h: ${staleLabels.join(", ")}. Check each one now; set verified_at on the ones that still hold and close the rest, then end the turn.`;
772
- let deliverEscalation = false;
773
- let deliverFallback = false;
774
- let retryUndeliverable = false;
775
- let undeliverableReason;
776
- let escalationText = "";
777
- const sessionInbox = lane.senior.kind === "session"
778
- ? lane.senior.id
779
- ? findBlockerFreshnessSessionInbox(hqRoot, lane.senior.id)
780
- : { reason: "The session senior has no session id" }
781
- : undefined;
782
- let updated = retryUpdateLane(hqRoot, lane.lane_id, "watcher", (current) => {
783
- deliverEscalation = false;
784
- deliverFallback = false;
785
- retryUndeliverable = false;
786
- undeliverableReason = undefined;
787
- const prior = current.blocker_freshness_state;
788
- const repeated = prior !== undefined && staleKeys.some((key) => prior.stale_keys.includes(key));
789
- const history = current.status_gate_history ?? [];
790
- const alreadyEscalatedThisTurn = history.some((entry) => entry.event === "blocker_stale_escalated" && entry.turn_id === turnId && entry.fingerprint === fingerprint);
791
- const escalate = repeated && prior?.escalated_fingerprint !== fingerprint && !alreadyEscalatedThisTurn;
792
- const alreadyEscalatedSet = prior?.escalated_fingerprint === fingerprint;
793
- const pendingUndeliverable = prior?.undeliverable_fingerprint === fingerprint;
794
- const failedFallback = history.find((entry) => entry.event === "blocker_stale_escalation_undeliverable" &&
795
- entry.fingerprint === fingerprint && entry.delivery_failed === true &&
796
- entry.delivery_recovered !== true);
797
- const statusResumeQueued = history.some((entry) => entry.event === "status_missed" && entry.turn_id === turnId && entry.resume_queued === true);
798
- let resumeQueued = false;
799
- let resumeSkippedReason;
800
- let nextLane = current;
801
- if (!escalate && !alreadyEscalatedSet) {
802
- const resume = queueLaneTerminalResume(current, at, resumeText, {
803
- mergeExisting: statusResumeQueued,
804
- });
805
- resumeQueued = resume.resumeQueued;
806
- resumeSkippedReason = resume.resumeSkippedReason;
807
- nextLane = resume.lane;
808
- }
809
- const staleEntry = {
810
- event: "blocker_stale",
811
- turn_id: turnId,
812
- path: resolution.statusPath,
813
- at,
814
- labels: staleLabels,
815
- count: resolution.stale.length,
816
- fingerprint,
817
- ...(resumeQueued ? { resume_queued: true } : {}),
818
- ...(resumeSkippedReason !== undefined ? { resume_skipped_reason: resumeSkippedReason } : {}),
819
- };
820
- let nextHistory = history.some((entry) => entry.event === "blocker_stale" && entry.turn_id === turnId)
821
- ? [...history]
822
- : appendCappedHistory(history, staleEntry);
823
- let escalatedFingerprint = prior?.escalated_fingerprint;
824
- if (escalate) {
825
- const escalatedEntry = {
826
- event: "blocker_stale_escalated",
827
- turn_id: turnId,
828
- path: resolution.statusPath,
829
- at,
830
- labels: staleLabels,
831
- count: resolution.stale.length,
832
- fingerprint,
833
- };
834
- nextHistory = appendCappedHistory(nextHistory, escalatedEntry);
835
- escalatedFingerprint = fingerprint;
836
- deliverEscalation = true;
837
- escalationText = `Blocker freshness escalation for ${current.lane_id}: these blockers remain stale after consecutive turns: ${staleLabels.join(", ")}. Status file: ${resolution.statusPath}.`;
838
- if (lane.senior.kind === "session" && sessionInbox !== undefined && !("inbox" in sessionInbox)) {
839
- deliverFallback = true;
840
- undeliverableReason = sessionInbox.reason;
841
- nextHistory = appendCappedHistory(nextHistory, {
842
- event: "blocker_stale_escalation_undeliverable",
843
- turn_id: turnId,
844
- path: resolution.statusPath,
845
- at,
846
- labels: staleLabels,
847
- count: resolution.stale.length,
848
- fingerprint,
849
- reason: sessionInbox.reason,
850
- });
851
- }
852
- }
853
- else if (pendingUndeliverable && sessionInbox !== undefined && "inbox" in sessionInbox) {
854
- // A monitor inbox registered after the local fallback appeared; retry delivery once.
855
- deliverEscalation = true;
856
- retryUndeliverable = true;
857
- escalationText = `Blocker freshness escalation for ${current.lane_id}: these blockers remain stale after consecutive turns: ${staleLabels.join(", ")}. Status file: ${resolution.statusPath}.`;
858
- }
859
- else if (failedFallback !== undefined && sessionInbox !== undefined && "inbox" in sessionInbox) {
860
- // Prefer the newly available senior inbox over retrying a failed local fallback.
861
- deliverEscalation = true;
862
- retryUndeliverable = true;
863
- escalationText = `Blocker freshness escalation for ${current.lane_id}: these blockers remain stale after consecutive turns: ${staleLabels.join(", ")}. Status file: ${resolution.statusPath}.`;
864
- }
865
- else if (failedFallback !== undefined) {
866
- deliverFallback = true;
867
- undeliverableReason = failedFallback.reason ?? prior?.undeliverable_reason ?? "The session senior inbox is unavailable";
868
- escalationText = `Blocker freshness escalation for ${current.lane_id}: these blockers remain stale after consecutive turns: ${staleLabels.join(", ")}. Status file: ${resolution.statusPath}.`;
869
- }
870
- else if (prior !== undefined && blockerFreshnessFingerprint(prior.stale_keys.map((key, index) => ({ key, label: prior.stale_labels[index] ?? "" }))) !== fingerprint) {
871
- escalatedFingerprint = undefined;
872
- }
873
- return {
874
- ...nextLane,
875
- blocker_freshness_state: {
876
- stale_keys: staleKeys,
877
- stale_labels: staleLabels,
878
- ...(escalatedFingerprint !== undefined ? { escalated_fingerprint: escalatedFingerprint } : {}),
879
- ...(undeliverableReason !== undefined
880
- ? { undeliverable_fingerprint: fingerprint, undeliverable_reason: undeliverableReason }
881
- : prior?.undeliverable_fingerprint === fingerprint
882
- ? { undeliverable_fingerprint: fingerprint, undeliverable_reason: prior.undeliverable_reason }
883
- : {}),
884
- },
885
- status_gate_history: nextHistory,
886
- };
887
- });
888
- logDecision({ event: "blocker_stale", at, turn_id: turnId, path: resolution.statusPath, labels: staleLabels, count: staleLabels.length });
889
- const escalated = updated.status_gate_history?.find((entry) => entry.event === "blocker_stale_escalated" && entry.fingerprint === fingerprint &&
890
- (entry.turn_id === turnId || retryUndeliverable || deliverFallback));
891
- if (escalated && deliverFallback) {
892
- const reason = undeliverableReason ?? "The session senior has no unique monitor-session inbox";
893
- try {
894
- appendDropboxMessageAtPath(path.join(laneRunDir(hqRoot, lane.lane_id), "dropbox"), {
895
- at,
896
- message_id: `blocker-freshness-undeliverable:${lane.lane_id}:${fingerprint}`,
897
- kind: "blocker_stale_escalation_undeliverable",
898
- text: `${escalationText} The session senior inbox is unavailable (${reason}); this escalation is recorded in the lane inbox for its next turn.`,
899
- });
900
- updated = retryUpdateLane(hqRoot, lane.lane_id, "watcher", (current) => {
901
- const state = current.blocker_freshness_state;
902
- if (state === undefined)
903
- return current;
904
- return {
905
- ...current,
906
- blocker_freshness_state: {
907
- ...state,
908
- undeliverable_fingerprint: fingerprint,
909
- undeliverable_reason: reason,
910
- },
911
- status_gate_history: (current.status_gate_history ?? []).map((entry) => entry.event === "blocker_stale_escalation_undeliverable" &&
912
- entry.fingerprint === fingerprint && entry.delivery_failed === true
913
- ? { ...entry, delivery_recovered: true }
914
- : entry),
915
- };
916
- });
917
- logDecision({ event: "blocker_stale_escalation_undeliverable", at, turn_id: turnId, fingerprint, reason, fallback: "lane_dropbox" });
918
- }
919
- catch (error) {
920
- const message = error instanceof Error ? error.message : String(error);
921
- process.stderr.write(`hq lanes watcher: blocker freshness fallback delivery failed for ${lane.lane_id}: ${message}\n`);
922
- logDecision({ event: "blocker_stale_escalation_fallback_failed", at, turn_id: turnId, fingerprint, error: message });
923
- updated = retryUpdateLane(hqRoot, lane.lane_id, "watcher", (current) => {
924
- const state = current.blocker_freshness_state;
925
- const retryableState = state === undefined ? undefined : { ...state };
926
- if (retryableState !== undefined) {
927
- delete retryableState.undeliverable_fingerprint;
928
- delete retryableState.undeliverable_reason;
929
- }
930
- return {
931
- ...current,
932
- ...(retryableState !== undefined ? { blocker_freshness_state: retryableState } : {}),
933
- status_gate_history: (current.status_gate_history ?? []).map((entry) => entry.event === "blocker_stale_escalation_undeliverable" && entry.fingerprint === fingerprint
934
- ? { ...entry, delivery_failed: true }
935
- : entry),
936
- };
937
- });
938
- }
939
- }
940
- if ((escalated || retryUndeliverable) && deliverEscalation && !deliverFallback) {
941
- try {
942
- if (lane.senior.kind === "lane" && lane.senior.id) {
943
- if (deps.deliverLaneSeniorMessage === undefined) {
944
- throw new LanesError("blocker_freshness_delivery_unavailable", "Lane-senior blocker escalations require the lane-message delivery path", { lane_id: lane.lane_id, senior_lane_id: lane.senior.id });
945
- }
946
- await deps.deliverLaneSeniorMessage(lane.senior.id, escalationText);
947
- }
948
- else if (lane.senior.kind === "session" && lane.senior.id) {
949
- const inbox = sessionInbox !== undefined && "inbox" in sessionInbox
950
- ? sessionInbox.inbox
951
- : resolveBlockerFreshnessSessionInbox(hqRoot, lane.senior.id);
952
- appendDropboxMessageAtPath(inbox, {
953
- at,
954
- message_id: `blocker-freshness:${lane.lane_id}:${fingerprint}:${turnId}`,
955
- kind: "blocker_stale_escalation",
956
- text: escalationText,
957
- });
958
- }
959
- else {
960
- throw new LanesError("blocker_freshness_delivery_unavailable", "No durable senior inbox is available for this blocker escalation", { lane_id: lane.lane_id, senior_kind: lane.senior.kind });
961
- }
962
- logDecision({ event: "blocker_stale_escalation_delivered", at, turn_id: turnId, senior_kind: lane.senior.kind });
963
- if (retryUndeliverable) {
964
- updated = retryUpdateLane(hqRoot, lane.lane_id, "watcher", (current) => {
965
- const state = current.blocker_freshness_state;
966
- const failedFallbackStillOpen = (current.status_gate_history ?? []).some((entry) => entry.event === "blocker_stale_escalation_undeliverable" &&
967
- entry.fingerprint === fingerprint && entry.delivery_failed === true &&
968
- entry.delivery_recovered !== true);
969
- if (state?.undeliverable_fingerprint !== fingerprint && !failedFallbackStillOpen)
970
- return current;
971
- const recoveredHistory = (current.status_gate_history ?? []).map((entry) => entry.event === "blocker_stale_escalation_undeliverable" && entry.fingerprint === fingerprint
972
- ? { ...entry, delivery_recovered: true }
973
- : entry);
974
- if (state?.undeliverable_fingerprint === fingerprint) {
975
- const recoveredState = { ...state };
976
- delete recoveredState.undeliverable_fingerprint;
977
- delete recoveredState.undeliverable_reason;
978
- return { ...current, blocker_freshness_state: recoveredState, status_gate_history: recoveredHistory };
979
- }
980
- return { ...current, status_gate_history: recoveredHistory };
981
- });
982
- }
983
- }
984
- catch (error) {
985
- const message = error instanceof Error ? error.message : String(error);
986
- process.stderr.write(`hq lanes watcher: blocker freshness escalation delivery failed for ${lane.lane_id}: ${message}\n`);
987
- logDecision({ event: "blocker_stale_escalation_delivery_failed", at, turn_id: turnId, error: message });
988
- updated = retryUpdateLane(hqRoot, lane.lane_id, "watcher", (current) => {
989
- const state = current.blocker_freshness_state;
990
- if (state?.escalated_fingerprint !== fingerprint)
991
- return current;
992
- const retryableState = { ...state };
993
- delete retryableState.escalated_fingerprint;
994
- return {
995
- ...current,
996
- blocker_freshness_state: retryableState,
997
- status_gate_history: (current.status_gate_history ?? []).map((entry) => entry.event === "blocker_stale_escalated"
998
- && entry.turn_id === turnId
999
- && entry.fingerprint === fingerprint
1000
- ? { ...entry, delivery_failed: true }
1001
- : entry),
1002
- };
1003
- });
1004
- }
1005
- if (mesh !== null) {
1006
- await emitMeshSoft("blocker_freshness_escalation_signal", logDecision, at, (signal) => emitLaneProgressEvent(mesh, lane, escalationText, signal));
1007
- }
1008
- }
1009
- return updated;
1010
- }
1011
- async function settleKrFreshness(hqRoot, lane, manifestTurnId, at, deps, logDecision) {
1012
- if (manifestTurnId !== undefined && lane.status_gate !== undefined && lane.status_gate.turn_id !== manifestTurnId) {
1013
- logDecision({ event: "kr_freshness_baseline_mismatch", at, turn_id: lane.status_gate.turn_id });
1014
- return lane;
1015
- }
1016
- let errorLogged = false;
1017
- const resolution = await resolveKrFreshnessForLane(hqRoot, lane, {
1018
- readFlag: deps.readKrFreshnessFlag ?? readLanesRegistryFlag,
1019
- now: Date.parse(at),
1020
- onError: (error) => {
1021
- if (errorLogged)
1022
- return;
1023
- errorLogged = true;
1024
- const code = error instanceof LanesError ? error.error : "kr_freshness_unavailable";
1025
- process.stderr.write(`hq lanes watcher: KR freshness disabled for ${lane.lane_id}: ${code}\n`);
1026
- logDecision({ event: "kr_freshness_disabled", at, error: code });
1027
- },
1028
- });
1029
- if (!resolution.enabled || resolution.statusPath === undefined || resolution.error !== undefined)
1030
- return lane;
1031
- const stalled = resolution.kpis.filter((kpi) => kpi.verdict === "stalled");
1032
- if (stalled.length === 0) {
1033
- if (lane.kr_freshness_state === undefined)
1034
- return lane;
1035
- return retryUpdateLane(hqRoot, lane.lane_id, "watcher", (current) => current.kr_freshness_state === undefined
1036
- ? current
1037
- : { ...current, kr_freshness_state: undefined });
1038
- }
1039
- const fingerprint = krFreshnessFingerprint(resolution.stalledKeys);
1040
- const names = stalled.map((kpi) => kpi.name);
1041
- const turnId = manifestTurnId ?? lane.status_gate?.turn_id ?? `unknown-${at}`;
1042
- const resumeText = `These KPIs in ${resolution.statusPath} were not re-measured in the last ${resolution.windowHours}h: ${names.join(", ")}. Measure each one now, update value and measured_at, then end the turn.`;
1043
- return retryUpdateLane(hqRoot, lane.lane_id, "watcher", (current) => {
1044
- const history = current.status_gate_history ?? [];
1045
- if (history.some((entry) => entry.event === "kr_stalled" && entry.turn_id === turnId))
1046
- return current;
1047
- const sameStalledSet = current.kr_freshness_state?.stalled_fingerprint === fingerprint;
1048
- let nextLane = current;
1049
- let resumeQueued = false;
1050
- let resumeSkippedReason;
1051
- if (!sameStalledSet) {
1052
- const mergeExisting = current.pending_resume !== undefined &&
1053
- current.state !== "blocked" && current.state !== "awaiting_input";
1054
- const resume = queueLaneTerminalResume(current, at, resumeText, { mergeExisting });
1055
- nextLane = resume.lane;
1056
- resumeQueued = resume.resumeQueued;
1057
- resumeSkippedReason = resume.resumeSkippedReason;
1058
- }
1059
- const entry = {
1060
- event: "kr_stalled",
1061
- turn_id: turnId,
1062
- path: resolution.statusPath,
1063
- at,
1064
- names,
1065
- count: stalled.length,
1066
- fingerprint,
1067
- ...(resumeQueued ? { resume_queued: true } : {}),
1068
- ...(resumeSkippedReason !== undefined ? { resume_skipped_reason: resumeSkippedReason } : {}),
1069
- };
1070
- return {
1071
- ...nextLane,
1072
- kr_freshness_state: { stalled_fingerprint: fingerprint },
1073
- status_gate_history: appendCappedHistory(history, entry),
1074
- };
1075
- });
1076
- }
1077
- function findBlockerFreshnessSessionInbox(hqRoot, sessionId) {
1078
- let candidates;
1079
- try {
1080
- candidates = LANE_PROVIDERS
1081
- .map((provider) => monitorSessionDir(hqRoot, provider, sessionId))
1082
- .filter((sessionDir) => fs.existsSync(sessionDir));
1083
- }
1084
- catch (error) {
1085
- return { reason: `Could not resolve the monitor inbox for session senior: ${error instanceof Error ? error.message : String(error)}` };
1086
- }
1087
- if (candidates.length !== 1) {
1088
- return { reason: candidates.length === 0
1089
- ? "No monitor-session inbox is registered for the session senior"
1090
- : "The session senior matches more than one monitor-session inbox" };
1091
- }
1092
- return { inbox: path.join(candidates[0], "dropbox") };
1093
- }
1094
- function resolveBlockerFreshnessSessionInbox(hqRoot, sessionId) {
1095
- const result = findBlockerFreshnessSessionInbox(hqRoot, sessionId);
1096
- if ("inbox" in result)
1097
- return result.inbox;
1098
- throw new LanesError("blocker_freshness_session_inbox_unavailable", result.reason, { session_id: sessionId });
1099
- }
1100
- /**
1101
- * Wrap one mesh call. A failed emit is logged as `mesh_event_failed` with
1102
- * the event name and the error message, and never propagates: the lane's
1103
- * state is decided by the envelope and the process, not by the network.
1104
- */
1105
- export async function emitMeshSoft(event, logDecision, at, fn, timeoutMs = 10_000) {
1106
- let timer;
1107
- try {
1108
- const controller = new AbortController();
1109
- await Promise.race([
1110
- fn(controller.signal),
1111
- new Promise((_resolve, reject) => {
1112
- timer = setTimeout(() => { controller.abort(); reject(new Error(`mesh request timed out after ${timeoutMs}ms`)); }, timeoutMs);
1113
- }),
1114
- ]);
1115
- logDecision({ event: "mesh_event", at, mesh_event: event });
1116
- return true;
1117
- }
1118
- catch (err) {
1119
- const message = err instanceof Error ? err.message : String(err);
1120
- logDecision({ event: "mesh_event_failed", at, mesh_event: event, error: message });
1121
- process.stderr.write(`hq lanes watcher: mesh_event_failed ${event}: ${message}\n`);
1122
- return false;
1123
- }
1124
- finally {
1125
- if (timer)
1126
- clearTimeout(timer);
1127
- }
1128
- }
1129
- function readProgressIntervalMs(hqRoot, lane) {
1130
- try {
1131
- const config = loadLanesConfig(hqRoot);
1132
- if (lane)
1133
- return providerProgressEventMinIntervalMs(config.providers[lane.provider]);
1134
- }
1135
- catch (err) {
1136
- process.stderr.write(`hq lanes watcher: lanes config unreadable, using default progress interval: ${err instanceof Error ? err.message : String(err)}\n`);
1137
- }
1138
- return providerProgressEventMinIntervalMs({ max_running: 1, max_queued: 1, accounts: {} });
1139
- }
1140
- function readLaneSoft(hqRoot, laneId) {
1141
- try {
1142
- return readLane(hqRoot, laneId);
1143
- }
1144
- catch (err) {
1145
- process.stderr.write(`hq lanes watcher: lane read failed for ${laneId}: ${err instanceof Error ? err.message : String(err)}\n`);
1146
- return null;
1147
- }
1148
- }
1149
- /** Question ids an ask envelope raised, as `raiseEnvelopeQuestions` mints them. */
1150
- export function envelopeQuestionIds(laneId, envelopeRef, envelope, questionIndexes) {
1151
- return (envelope.questions ?? []).map((_q, i) => envelopeQuestionId(laneId, envelopeRef, questionIndexes?.[i] ?? i));
1152
- }
1153
- function defaultSleep(ms) {
1154
- return new Promise((resolve) => {
1155
- setTimeout(resolve, ms);
1156
- });
1157
- }
1158
- const WATCHER_LOOP_OWNER_FILE = "watcher-loop.pid";
1159
- function claimWatcherLoop(hqRoot, laneId, deps) {
1160
- const runDir = laneRunDir(hqRoot, laneId);
1161
- const ownerPath = path.join(runDir, WATCHER_LOOP_OWNER_FILE);
1162
- const isAlive = deps.isAlive ?? isPidAlive;
1163
- const readStarttime = deps.readStarttime ?? readProcStarttime;
1164
- const owner = withLaneHireLocks(hqRoot, [laneId], () => {
1165
- fs.mkdirSync(runDir, { recursive: true });
1166
- const existing = readPidRecord(ownerPath);
1167
- if (existing !== null && probePidRecord(existing, isAlive, readStarttime).alive) {
1168
- return null;
1169
- }
1170
- if (existing !== null)
1171
- fs.unlinkSync(ownerPath);
1172
- writePidRecord(ownerPath, {
1173
- pid: process.pid,
1174
- starttime: readStarttime(process.pid) ?? readProcStarttime(process.pid) ?? undefined,
1175
- });
1176
- const stat = fs.statSync(ownerPath);
1177
- return { dev: stat.dev, ino: stat.ino };
1178
- });
1179
- if (owner === null)
1180
- return null;
1181
- return () => {
1182
- withLaneHireLocks(hqRoot, [laneId], () => {
1183
- try {
1184
- const current = fs.statSync(ownerPath);
1185
- if (current.dev === owner.dev && current.ino === owner.ino)
1186
- fs.unlinkSync(ownerPath);
1187
- }
1188
- catch (err) {
1189
- if (err.code !== "ENOENT")
1190
- throw err;
1191
- }
1192
- });
1193
- };
1194
- }
1195
- async function maybeContinueAfterMissingEnvelopeRepair(hqRoot, lane, envelope, envelopeRef, at, deps, logDecision) {
1196
- const repair = lane.envelope_repair;
1197
- const missingRepair = repair?.attempted === true &&
1198
- repair.succeeded === true &&
1199
- repair.envelope_ref === envelopeRef &&
1200
- repair.first_error.startsWith("Missing expected envelope file:");
1201
- if (!missingRepair || envelope === null || envelopeRef === undefined) {
1202
- if (envelope?.decision === "blocked")
1203
- logDecision({ event: "envelope_repair_continue", at, outcome: "skipped", reason: "not_a_successful_missing_repair", missing_repair: missingRepair, envelope_ref: envelopeRef, repair_ref: repair?.envelope_ref, first_error: repair?.first_error, succeeded: repair?.succeeded });
1204
- return lane;
1205
- }
1206
- const incompleteDone = envelope.decision === "done" && envelope.story_complete === false;
1207
- const repairInstructionBlock = envelope.decision === "blocked" &&
1208
- (envelope.questions?.length ?? 0) === 0 &&
1209
- /(?:not to resume|do not resume|don't resume)(?: the)? task/i.test(envelope.blocked_reason ?? "");
1210
- if (!incompleteDone && !repairInstructionBlock) {
1211
- if (envelope.decision === "blocked")
1212
- logDecision({ event: "envelope_repair_continue", at, outcome: "skipped", reason: "blocked_reason_not_repair_instruction", blocked_reason: envelope.blocked_reason });
1213
- return lane;
1214
- }
1215
- if (lane.last_resume?.text === ENVELOPE_REPAIR_CONTINUE_TEXT) {
1216
- logDecision({ event: "envelope_repair_continue", at, outcome: "skipped", reason: "continue_already_used" });
1217
- return lane;
1218
- }
1219
- let pendingQuestion = false;
1220
- try {
1221
- for (const id of listQuestionIds(hqRoot)) {
1222
- const question = readQuestion(hqRoot, id);
1223
- if (question.lane_id === lane.lane_id && question.status === "pending") {
1224
- pendingQuestion = true;
1225
- break;
1226
- }
1227
- }
1228
- }
1229
- catch (error) {
1230
- logDecision({ event: "envelope_repair_continue", at, outcome: "skipped", reason: "question_check_failed", error: error instanceof Error ? error.message : String(error) });
1231
- return lane;
1232
- }
1233
- if (pendingQuestion) {
1234
- logDecision({ event: "envelope_repair_continue", at, outcome: "skipped", reason: "pending_question" });
1235
- return lane;
1236
- }
1237
- const readFlag = deps.readEnvelopeRepairContinueFlag ?? readLanesRegistryFlag;
1238
- let enabled = false;
1239
- try {
1240
- const resolution = resolveLaneCompany(hqRoot, lane);
1241
- const company = resolution.company ?? undefined;
1242
- enabled = await readFlag(LANE_ENVELOPE_REPAIR_CONTINUE_FLAG, {
1243
- company,
1244
- ...(company ? { companyUidSource: laneCompanyUidSource(resolution.source) } : {}),
1245
- });
1246
- }
1247
- catch (error) {
1248
- logDecision({ event: "envelope_repair_continue", at, outcome: "skipped", reason: "flag_read_failed", error: error instanceof Error ? error.message : String(error) });
1249
- return lane;
1250
- }
1251
- if (!enabled)
1252
- return lane;
1253
- const queued = retryUpdateLane(hqRoot, lane.lane_id, "watcher", (current) => {
1254
- if (current.version !== lane.version ||
1255
- (current.state !== "done" && current.state !== "blocked") ||
1256
- current.last_envelope?.ref !== envelopeRef ||
1257
- current.envelope_repair?.attempted !== true ||
1258
- current.envelope_repair.succeeded !== true ||
1259
- current.envelope_repair.envelope_ref !== envelopeRef ||
1260
- current.envelope_repair.first_error !== repair.first_error ||
1261
- current.last_resume?.text === ENVELOPE_REPAIR_CONTINUE_TEXT)
1262
- return current;
1263
- const result = queueLaneTerminalResume(current, at, ENVELOPE_REPAIR_CONTINUE_TEXT, { allowBlockedResume: true });
1264
- if (!result.resumeQueued || result.lane.pending_resume?.session_id === undefined)
1265
- return current;
1266
- return {
1267
- ...result.lane,
1268
- status_gate_history: appendCappedHistory(current.status_gate_history ?? [], {
1269
- event: "envelope_repair_continued",
1270
- at,
1271
- envelope_ref: envelopeRef,
1272
- session_id: result.lane.pending_resume.session_id,
1273
- }),
1274
- };
1275
- });
1276
- if (queued.state === "queued" && queued.pending_resume?.text === ENVELOPE_REPAIR_CONTINUE_TEXT) {
1277
- logDecision({ event: "envelope_repair_continue", at, outcome: "queued", envelope_ref: envelopeRef, session_id: queued.pending_resume.session_id });
1278
- }
1279
- return queued;
1280
- }
1281
- /** Detached and synchronous classifiers share one process-identity claim. */
1282
- export async function runWatcherLoop(hqRoot, laneId, deps = {}) {
1283
- const release = claimWatcherLoop(hqRoot, laneId, deps);
1284
- if (release === null)
1285
- return;
1286
- try {
1287
- await runWatcherLoopOwned(hqRoot, laneId, deps);
1288
- }
1289
- finally {
1290
- release();
1291
- }
1292
- }
1293
- async function runWatcherLoopOwned(hqRoot, laneId, deps) {
1294
- const sleep = deps.sleep ?? defaultSleep;
1295
- const now = deps.now ?? (() => Date.now());
1296
- const isAlive = deps.isAlive ?? isPidAlive;
1297
- const readStarttime = deps.readStarttime ?? readProcStarttime;
1298
- const pollMs = deps.pollMs ?? WATCHER_POLL_MS;
1299
- const silenceMs = deps.silenceMs ?? SILENCE_MS;
1300
- const runDir = laneRunDir(hqRoot, laneId);
1301
- const outPath = deps.watcherOutPath ?? watcherOutLogPath(hqRoot, laneId);
1302
- const outMax = deps.watcherOutMaxBytes ?? WATCHER_OUT_MAX_BYTES;
1303
- const workerPidPath = path.join(runDir, "worker.pid");
1304
- const manifest = readSpawnManifest(runDir);
1305
- const minEnvelopeName = manifest.envelope_path !== undefined
1306
- ? path.basename(manifest.envelope_path)
1307
- : undefined;
1308
- const logFiles = [
1309
- path.join(runDir, "logs", "worker.out"),
1310
- path.join(runDir, "logs", "worker.err"),
1311
- path.join(runDir, "logs", "last-message.txt"),
1312
- ];
1313
- // Progress only. A tool call is not partial output: a worker that called
1314
- // tools and exited with no envelope and no output is still `failed`.
1315
- const activityFiles = [toolActivityPath(hqRoot, laneId)];
1316
- const progressFiles = [...logFiles, ...activityFiles];
1317
- // Mesh seam (spec §8). Non-interactive: nobody is at this process's tty.
1318
- const mesh = deps.mesh === undefined ? createLaneMesh({ interactive: false }) : deps.mesh;
1319
- const storyStatusSuppressions = new Set();
1320
- const meshRequestTimeoutMs = deps.meshRequestTimeoutMs ?? 10_000;
1321
- const initialLane = readLaneSoft(hqRoot, laneId);
1322
- if (mesh && initialLane) {
1323
- // Every armed watcher refreshes the server descriptor. This migrates old
1324
- // shared project threads and picks up account/model changes after resume.
1325
- const company = initialLane.mesh_company ?? initialLane.company ?? undefined;
1326
- if (company &&
1327
- (mesh.ensureLaneThread || !initialLane.thread_id || initialLane.thread_id.startsWith("proj-"))) {
1328
- let timer;
1329
- try {
1330
- const threadId = await Promise.race([
1331
- mesh.ensureLaneThread
1332
- ? mesh.ensureLaneThread(company, initialLane)
1333
- : mesh.ensureProjectThread(company, initialLane.project_id),
1334
- new Promise((_resolve, reject) => {
1335
- timer = setTimeout(() => reject(new Error(`mesh thread ensure timed out after ${meshRequestTimeoutMs}ms`)), meshRequestTimeoutMs);
1336
- }),
1337
- ]);
1338
- const updated = initialLane.thread_id === threadId
1339
- ? initialLane
1340
- : retryUpdateLane(hqRoot, laneId, "spawn", (current) => current.thread_id === threadId ? current : { ...current, thread_id: threadId });
1341
- if (mesh.ensureLaneThread && updated.version !== initialLane.version) {
1342
- await mesh.ensureLaneThread(company, updated);
1343
- }
1344
- }
1345
- catch (err) {
1346
- const message = err instanceof Error ? err.message : String(err);
1347
- if (company && initialLane.story_id &&
1348
- err instanceof LanesError && err.error === "story_not_on_board") {
1349
- storyStatusSuppressions.add(laneStoryStatusSuppressionKey(company, initialLane.project_id, initialLane.story_id));
1350
- }
1351
- process.stderr.write(`hq lanes watcher: mesh thread ensure failed for ${laneId}: ${message}\n`);
1352
- writeWatcherDecision(outPath, {
1353
- event: "mesh_event_failed",
1354
- at: new Date(now()).toISOString(),
1355
- mesh_event: "ensure_lane_thread",
1356
- error: message,
1357
- }, outMax);
1358
- }
1359
- finally {
1360
- if (timer)
1361
- clearTimeout(timer);
1362
- }
1363
- }
1364
- }
1365
- const progressIntervalMs = deps.progressEventMinIntervalMs ?? readProgressIntervalMs(hqRoot, readLaneSoft(hqRoot, laneId));
1366
- const spawnRepair = deps.spawnRepair ?? spawnEnvelopeRepair;
1367
- const retryAccount = deps.retryAccount ?? ((root, lane, reason) => retryLaneOnAlternateAccount(root, lane, reason, "watcher", {
1368
- ...deps.retrySpawnDeps,
1369
- admissionHost: (deps.resolveAdmissionHost ?? resolveProcessAdmissionHost)(),
1370
- }));
1371
- let lastSignalMs = now();
1372
- let lastSeenMtime = 0;
1373
- let lastAlive = null;
1374
- let lastEnvelopeRef = null;
1375
- let lastInvalidRef = null;
1376
- let lastProgressEmitMs = (() => {
1377
- const stamp = readLaneSoft(hqRoot, laneId)?.last_progress_event_at;
1378
- return stamp ? Date.parse(stamp) || null : null;
1379
- })();
1380
- for (const file of progressFiles) {
1381
- const mtime = fileMtimeMs(file);
1382
- if (mtime !== null && mtime > lastSeenMtime)
1383
- lastSeenMtime = mtime;
1384
- }
1385
- const logDecision = (record) => {
1386
- writeWatcherDecision(outPath, record, outMax);
1387
- };
1388
- while (true) {
1389
- const worker = readPidRecord(workerPidPath);
1390
- const probe = worker === null
1391
- ? missingPidProbe()
1392
- : probePidRecord(worker, isAlive, readStarttime);
1393
- const processAlive = probe.alive;
1394
- if (lastAlive !== false && !processAlive) {
1395
- logDecision({
1396
- event: "liveness_transition",
1397
- at: new Date(now()).toISOString(),
1398
- pid: probe.pid,
1399
- recorded_starttime: probe.recorded_starttime,
1400
- live_starttime: probe.live_starttime,
1401
- starttime_error: probe.starttime_error,
1402
- decided_by: probe.decided_by,
1403
- });
1404
- }
1405
- lastAlive = processAlive;
1406
- let progressed = false;
1407
- let newestMtime = lastSeenMtime;
1408
- let newestFile = null;
1409
- for (const file of progressFiles) {
1410
- const mtime = fileMtimeMs(file);
1411
- if (mtime !== null && mtime > newestMtime) {
1412
- newestMtime = mtime;
1413
- newestFile = file;
1414
- progressed = true;
1415
- }
1416
- }
1417
- const latestFile = readLatestEnvelopeFile(hqRoot, laneId, minEnvelopeName);
1418
- const missingExpected = !processAlive && latestFile === null
1419
- ? missingExpectedEnvelopeFile(hqRoot, laneId, manifest.envelope_path)
1420
- : null;
1421
- let latest = latestFile && latestFile.envelope
1422
- ? { envelope: latestFile.envelope, ref: latestFile.ref }
1423
- : null;
1424
- let envelope = latest?.envelope ?? null;
1425
- if (latest && latest.ref !== lastEnvelopeRef) {
1426
- logDecision({
1427
- event: "envelope_observed",
1428
- at: new Date(now()).toISOString(),
1429
- filename: path.posix.basename(latest.ref),
1430
- decision: latest.envelope.decision,
1431
- });
1432
- lastEnvelopeRef = latest.ref;
1433
- }
1434
- if (latestFile && latestFile.envelope === null && latestFile.ref !== lastInvalidRef) {
1435
- logDecision({
1436
- event: "envelope_invalid",
1437
- at: new Date(now()).toISOString(),
1438
- filename: path.posix.basename(latestFile.ref),
1439
- error: latestFile.error,
1440
- });
1441
- lastInvalidRef = latestFile.ref;
1442
- }
1443
- const hasPartialOutput = logFiles.some((file) => fileNonEmpty(file));
1444
- let quota = null;
1445
- let quotaLane = null;
1446
- let providerRejection = null;
1447
- if (!processAlive && !envelope) {
1448
- try {
1449
- quotaLane = readLane(hqRoot, laneId);
1450
- const workerOutOffset = readSpawnManifest(runDir).worker_out_offset ?? 0;
1451
- const routed = routeProviderFailure(readProviderRejection(runDir, quotaLane.provider, workerOutOffset), () => readQuotaSignal(runDir, quotaLane.model, new Date(now()), workerOutOffset), quotaLane.model, new Date(now()));
1452
- // A reset-less 429 still holds the account: the configured default
1453
- // hold becomes its reset, recorded as such.
1454
- quota = routed.quota
1455
- ? applyDefaultQuotaHold(routed.quota, providerQuotaDefaultHoldMs(loadLanesConfig(hqRoot).providers[quotaLane.provider]), new Date(now()))
1456
- : null;
1457
- providerRejection = routed.rejection;
1458
- }
1459
- catch (err) {
1460
- process.stderr.write(`hq lanes watcher: quota read failed for ${laneId}: ${err instanceof Error ? err.message : String(err)}\n`);
1461
- }
1462
- }
1463
- // Spec §4: the process exited and its envelope file does not parse, or
1464
- // this run never wrote its expected slot. Exactly one repair turn. A provider
1465
- // rejection skips the repair: the provider refused the turn, so a
1466
- // second turn on the same model and account would be refused the same
1467
- // way. A quota signal skips it too: a repair turn on an exhausted account
1468
- // fails the same way, and would end the lane envelope_invalid without
1469
- // ever recording the hold. The quota result applies immediately instead.
1470
- let invalidEnvelope = null;
1471
- let envelopeValidationErrors;
1472
- let questionIndexes;
1473
- let recoveredAsk = false;
1474
- const repairCandidate = latestFile ?? missingExpected;
1475
- if (!processAlive &&
1476
- !envelope &&
1477
- !providerRejection &&
1478
- !quota &&
1479
- repairCandidate &&
1480
- repairCandidate.envelope === null) {
1481
- const lane = repairCandidate.missing ? readLaneSoft(hqRoot, laneId) : null;
1482
- const missingRepairAllowed = !repairCandidate.missing ||
1483
- (lane !== null && envelopeRepairMode(lane.provider) === "resume");
1484
- if (missingRepairAllowed) {
1485
- const repair = decideEnvelopeRepair(hqRoot, laneId, repairCandidate, now(), spawnRepair, logDecision);
1486
- if (repair.action === "spawned") {
1487
- lastSignalMs = now();
1488
- lastAlive = null;
1489
- if (progressed)
1490
- lastSeenMtime = newestMtime;
1491
- await sleep(pollMs);
1492
- continue;
1493
- }
1494
- if (!repairCandidate.missing) {
1495
- const validationErrors = repair.errors.filter((error) => !error.startsWith("repair_spawn_failed:"));
1496
- let recovery = null;
1497
- try {
1498
- recovery = recoverAskEnvelope(repairCandidate.text, validationErrors);
1499
- }
1500
- catch (err) {
1501
- const message = err instanceof Error ? err.message : String(err);
1502
- process.stderr.write(`hq lanes watcher: invalid ask fallback could not parse ${repairCandidate.path} for ${laneId}: ${message}\n`);
1503
- logDecision({
1504
- event: "envelope_repair",
1505
- at: new Date(now()).toISOString(),
1506
- outcome: "ask_fallback_skipped",
1507
- reason: "invalid_json",
1508
- error: message,
1509
- validation_errors: validationErrors,
1510
- });
1511
- }
1512
- if (recovery !== null && (recovery.envelope.questions?.length ?? 0) > 0) {
1513
- const errors = [...new Set([...validationErrors, ...recovery.questionErrors])];
1514
- envelopeValidationErrors = errors;
1515
- questionIndexes = recovery.questionIndexes;
1516
- latest = { envelope: recovery.envelope, ref: repairCandidate.ref };
1517
- envelope = recovery.envelope;
1518
- recoveredAsk = true;
1519
- const message = `hq lanes watcher: routing invalid ask envelope for ${laneId} to awaiting_input ` +
1520
- `with ${recovery.envelope.questions?.length ?? 0} validated question(s); errors: ${errors.join("; ")}`;
1521
- process.stderr.write(`${message}\n`);
1522
- logDecision({
1523
- event: "envelope_repair",
1524
- at: new Date(now()).toISOString(),
1525
- outcome: "ask_fallback_routed",
1526
- state: "awaiting_input",
1527
- questions: recovery.envelope.questions?.length ?? 0,
1528
- validation_errors: errors,
1529
- });
1530
- }
1531
- else {
1532
- const errors = recovery === null
1533
- ? repair.errors
1534
- : [...new Set([...repair.errors, ...recovery.questionErrors])];
1535
- invalidEnvelope = { errors };
1536
- if (recovery !== null) {
1537
- const message = `hq lanes watcher: invalid ask envelope for ${laneId} remains failed; ` +
1538
- `0 of ${recovery.sourceQuestionCount} questions passed validation`;
1539
- process.stderr.write(`${message}\n`);
1540
- logDecision({
1541
- event: "envelope_repair",
1542
- at: new Date(now()).toISOString(),
1543
- outcome: "ask_fallback_skipped",
1544
- reason: "no_valid_questions",
1545
- questions: 0,
1546
- validation_errors: errors,
1547
- });
1548
- }
1549
- }
1550
- }
1551
- }
1552
- }
1553
- if (processAlive === false &&
1554
- envelope &&
1555
- latestFile !== null &&
1556
- latestFile.envelope !== null &&
1557
- !recoveredAsk) {
1558
- markRepairSucceeded(hqRoot, laneId, latestFile.ref);
1559
- }
1560
- const tick = tickWatcher({
1561
- nowMs: now(),
1562
- processAlive,
1563
- progressed,
1564
- lastSignalMs,
1565
- envelope,
1566
- hasPartialOutput,
1567
- silenceMs,
1568
- quota,
1569
- invalidEnvelope,
1570
- providerRejection,
1571
- });
1572
- if (processAlive) {
1573
- maybeHeartbeatLane(hqRoot, laneId, now());
1574
- }
1575
- if (tick.emit) {
1576
- parseWatcherSignalKind(tick.emit.kind);
1577
- appendWatcherSignal(hqRoot, laneId, tick.emit);
1578
- if (tick.emit.kind === "silence") {
1579
- const reason = stalledReason(silenceMs);
1580
- logDecision({
1581
- event: "silence_deadline",
1582
- at: tick.emit.at,
1583
- last_activity_at: new Date(lastSignalMs).toISOString(),
1584
- last_tool_call_at: readToolActivity(hqRoot, laneId)?.at ?? null,
1585
- deadline_at: new Date(lastSignalMs + silenceMs).toISOString(),
1586
- silence_ms: silenceMs,
1587
- stalled_reason: reason,
1588
- });
1589
- try {
1590
- markLaneStalled(hqRoot, laneId, tick.emit.at, reason);
1591
- }
1592
- catch (err) {
1593
- process.stderr.write(`hq lanes watcher: stalled write failed for ${laneId}: ${err instanceof Error ? err.message : String(err)}\n`);
1594
- }
1595
- }
1596
- if (tick.emit.kind === "progress") {
1597
- const progressEmitAt = tick.emit.at;
1598
- try {
1599
- clearLaneStalled(hqRoot, laneId);
1600
- }
1601
- catch (err) {
1602
- process.stderr.write(`hq lanes watcher: stalled clear failed for ${laneId}: ${err instanceof Error ? err.message : String(err)}\n`);
1603
- }
1604
- // Spec §8 progress row. Only a tick that saw new tool activity or
1605
- // new output gets here (tickWatcher emits progress on `progressed`
1606
- // alone), and the throttle bounds the rate. Silence never reaches
1607
- // this branch.
1608
- if (mesh &&
1609
- progressEventDue({
1610
- lastEmitMs: lastProgressEmitMs,
1611
- nowMs: progressEmitAt ? Date.parse(progressEmitAt) : now(),
1612
- minIntervalMs: progressIntervalMs,
1613
- })) {
1614
- const lane = readLaneSoft(hqRoot, laneId);
1615
- if (lane) {
1616
- const detail = newestFile && activityFiles.includes(newestFile)
1617
- ? `tool call at ${readToolActivity(hqRoot, laneId)?.at ?? tick.emit.at}`
1618
- : envelope
1619
- ? "envelope written"
1620
- : "new output";
1621
- const sent = await emitMeshSoft("lane_progress", logDecision, progressEmitAt, (signal) => emitLaneProgressEvent(mesh, lane, detail, signal), meshRequestTimeoutMs);
1622
- if (sent) {
1623
- lastProgressEmitMs = Date.parse(progressEmitAt);
1624
- try {
1625
- retryUpdateLane(hqRoot, laneId, "watcher", (current) => ({
1626
- ...current,
1627
- last_progress_event_at: progressEmitAt,
1628
- }));
1629
- }
1630
- catch (err) {
1631
- process.stderr.write(`hq lanes watcher: progress timestamp write failed for ${laneId}: ${err instanceof Error ? err.message : String(err)}\n`);
1632
- }
1633
- }
1634
- }
1635
- }
1636
- }
1637
- if (tick.emit.kind === "terminal" && tick.emit.classification) {
1638
- const classification = tick.emit.classification;
1639
- logDecision({
1640
- event: "classification",
1641
- at: tick.emit.at,
1642
- envelope_present: envelope !== null,
1643
- has_partial_output: hasPartialOutput,
1644
- state: classification.state,
1645
- reason: classification.reason,
1646
- ...(invalidEnvelope ? { envelope_errors: invalidEnvelope.errors } : {}),
1647
- ...(providerRejection
1648
- ? {
1649
- provider_status: providerRejection.status,
1650
- provider_message: providerRejection.message,
1651
- retryable: providerRejection.retryable,
1652
- }
1653
- : {}),
1654
- });
1655
- if (quota &&
1656
- quotaLane?.account &&
1657
- (classification.reason === "account_quota_exhausted" ||
1658
- classification.reason === "account_model_unavailable")) {
1659
- try {
1660
- recordAccountQuota(hqRoot, quotaLane.provider, quotaLane.account, quota);
1661
- }
1662
- catch (err) {
1663
- process.stderr.write(`hq lanes watcher: quota record failed for ${laneId}: ${err instanceof Error ? err.message : String(err)}\n`);
1664
- }
1665
- }
1666
- const accountRetryReason = quota
1667
- ? "usage_limit"
1668
- : isProviderLoginFailure(providerRejection)
1669
- ? "account_unavailable"
1670
- : null;
1671
- if (accountRetryReason && quotaLane?.account) {
1672
- try {
1673
- const retry = await retryAccount(hqRoot, quotaLane, accountRetryReason);
1674
- logDecision({
1675
- event: "account_failover",
1676
- at: tick.emit.at,
1677
- from: quotaLane.account,
1678
- to: retry.account ?? null,
1679
- reason: accountRetryReason,
1680
- state: retry.state,
1681
- });
1682
- return;
1683
- }
1684
- catch (err) {
1685
- const message = err instanceof Error ? err.message : String(err);
1686
- process.stderr.write(`hq lanes watcher: account failover failed for ${laneId}: ${message}\n`);
1687
- logDecision({ event: "account_failover_failed", at: tick.emit.at, reason: accountRetryReason, error: message });
1688
- if (readLane(hqRoot, laneId).state !== "running")
1689
- return;
1690
- }
1691
- }
1692
- const terminalLane = readLane(hqRoot, laneId);
1693
- let activeQuestionCompany;
1694
- if (envelope?.decision === "ask" && (envelope.questions?.length ?? 0) > 0) {
1695
- try {
1696
- activeQuestionCompany = await resolveQuestionCompanyWithFallback(hqRoot, terminalLane, deps.resolveQuestionActiveCompany);
1697
- }
1698
- catch (err) {
1699
- if (questionRecordRefusalCode(err) !== "question_company_unavailable")
1700
- throw err;
1701
- // applyTerminalToLaneWithResult repeats the synchronous lane and
1702
- // project checks, then terminalizes this ask with the named refusal.
1703
- }
1704
- }
1705
- const terminalWrite = applyTerminalToLaneWithResult(hqRoot, laneId, classification, {
1706
- envelope,
1707
- envelopeRef: latest?.ref,
1708
- envelopeValidationErrors,
1709
- questionIndexes,
1710
- activeCompany: activeQuestionCompany,
1711
- at: tick.emit.at,
1712
- quota,
1713
- providerRejection,
1714
- });
1715
- let updated = terminalWrite.record;
1716
- const effectiveEnvelope = terminalWrite.envelope ?? envelope;
1717
- const effectiveClassification = terminalWrite.classification;
1718
- logDecision({
1719
- event: "terminal_write",
1720
- at: tick.emit.at,
1721
- state: updated.state,
1722
- version: updated.version,
1723
- });
1724
- // Spec §8 terminal rows: done → lane_done + story review; blocked →
1725
- // lane_blocked; ask → lane_ask with the queue ids. After the state
1726
- // write, so a mesh failure can never leave the lane unclassified.
1727
- if (mesh && terminalWrite.changed) {
1728
- const envelopeState = effectiveEnvelope?.decision === "ask"
1729
- ? "awaiting_input"
1730
- : effectiveEnvelope?.decision === "blocked"
1731
- ? "blocked"
1732
- : "done";
1733
- if (effectiveEnvelope && latest && updated.state === envelopeState) {
1734
- const questionIds = effectiveEnvelope.decision === "ask"
1735
- ? envelopeQuestionIds(laneId, latest.ref, effectiveEnvelope, questionIndexes)
1736
- : undefined;
1737
- await emitMeshSoft(`lane_${effectiveEnvelope.decision}`, logDecision, tick.emit.at, (signal) => emitLaneDecisionEvents(mesh, updated, effectiveEnvelope, {
1738
- questionIds,
1739
- signal,
1740
- storyStatusSuppressions,
1741
- }), meshRequestTimeoutMs);
1742
- }
1743
- else if (updated.state === "failed" || updated.state === "interrupted" ||
1744
- updated.state === "cancelled" || updated.state === "killed") {
1745
- await emitMeshSoft(`lane_${updated.state}`, logDecision, tick.emit.at, (signal) => emitLaneTerminalStateEvent(mesh, updated, updated.state, updated.terminal_reason ?? effectiveClassification.reason, signal), meshRequestTimeoutMs);
1746
- }
1747
- }
1748
- if (terminalWrite.changed) {
1749
- updated = await settleManagerStatusGate(hqRoot, updated, manifest.turn_id, tick.emit.at, deps, logDecision);
1750
- updated = await settleBlockerFreshness(hqRoot, updated, manifest.turn_id, tick.emit.at, deps, mesh, logDecision);
1751
- updated = await settleKrFreshness(hqRoot, updated, manifest.turn_id, tick.emit.at, deps, logDecision);
1752
- }
1753
- const managerStatusFollowupQueued = manifest.turn_id !== undefined &&
1754
- updated.status_gate_history?.some((entry) => "turn_id" in entry && entry.turn_id === manifest.turn_id &&
1755
- ((entry.event === "status_missed" && entry.resume_queued === true) ||
1756
- (entry.event === "blocker_stale" && entry.resume_queued === true) ||
1757
- (entry.event === "kr_stalled" && entry.resume_queued === true))) === true;
1758
- if (terminalWrite.changed && !managerStatusFollowupQueued) {
1759
- updated = await maybeContinueAfterMissingEnvelopeRepair(hqRoot, updated, effectiveEnvelope ?? null, latest?.ref, tick.emit.at, deps, logDecision);
1760
- }
1761
- if (terminalWrite.changed && deps.recoverQueuedMessages && !managerStatusFollowupQueued && updated.state !== "queued") {
1762
- try {
1763
- if (dropboxInboxHasMessages(hqRoot, laneId)) {
1764
- await deps.recoverQueuedMessages(updated);
1765
- logDecision({
1766
- event: "message_recovery",
1767
- at: tick.emit.at,
1768
- state: updated.state,
1769
- });
1770
- }
1771
- }
1772
- catch (err) {
1773
- const message = err instanceof Error ? err.message : String(err);
1774
- process.stderr.write(`hq lanes watcher: queued message recovery failed for ${laneId}: ${message}\n`);
1775
- logDecision({
1776
- event: "message_recovery_failed",
1777
- at: tick.emit.at,
1778
- state: updated.state,
1779
- error: message,
1780
- });
1781
- }
1782
- }
1783
- const terminalEnvelopeNextCheckMs = effectiveEnvelope?.next_check_at === undefined
1784
- ? undefined
1785
- : Date.parse(effectiveEnvelope.next_check_at);
1786
- const hasFutureTerminalNextCheck = terminalEnvelopeNextCheckMs !== undefined &&
1787
- Number.isFinite(terminalEnvelopeNextCheckMs) &&
1788
- terminalEnvelopeNextCheckMs > Date.parse(tick.emit.at);
1789
- if (terminalWrite.changed &&
1790
- updated.keep_alive === true &&
1791
- effectiveEnvelope?.decision === "done" &&
1792
- effectiveEnvelope.story_complete === false &&
1793
- !hasFutureTerminalNextCheck &&
1794
- updated.state === "done" &&
1795
- deps.scheduleTerminalKeepAlive) {
1796
- try {
1797
- const current = readLane(hqRoot, laneId);
1798
- if (current.state === "done" && current.version === updated.version && current.keep_alive === true) {
1799
- const resolution = resolveLaneCompany(hqRoot, current);
1800
- const company = resolution.company;
1801
- if (company) {
1802
- const readFlag = deps.readTerminalKeepAliveFlag ?? readLanesRegistryFlag;
1803
- const flagOptions = { company, companyUidSource: laneCompanyUidSource(resolution.source) };
1804
- const [triggerEnabled, keepAliveEnabled, immediateFirstResumeEnabled] = await Promise.all([
1805
- readFlag(LEAD_LANE_KEEP_ALIVE_TERMINAL_TRIGGER_FLAG, flagOptions),
1806
- readFlag(LEAD_LANE_KEEP_ALIVE_FLAG, flagOptions),
1807
- readFlag(LEAD_LANE_KEEP_ALIVE_IMMEDIATE_FIRST_RESUME_FLAG, flagOptions),
1808
- ]);
1809
- if (triggerEnabled && keepAliveEnabled && immediateFirstResumeEnabled) {
1810
- const terminalAtMs = Date.parse(tick.emit.at);
1811
- const dueAt = new Date(terminalAtMs + LEAD_LANE_KEEP_ALIVE_FIRST_RESUME_SETTLE_MS).toISOString();
1812
- logDecision({ event: "keep_alive_terminal_trigger_scheduled", at: tick.emit.at, due_at: dueAt, version: current.version });
1813
- await deps.scheduleTerminalKeepAlive({
1814
- laneId,
1815
- version: current.version,
1816
- terminalAt: tick.emit.at,
1817
- dueAt,
1818
- });
1819
- }
1820
- }
1821
- }
1822
- }
1823
- catch (err) {
1824
- const message = err instanceof Error ? err.message : String(err);
1825
- process.stderr.write(`hq lanes watcher: terminal keep-alive trigger failed for ${laneId}: ${message}\n`);
1826
- logDecision({ event: "keep_alive_terminal_trigger_failed", at: tick.emit.at, error: message });
1827
- }
1828
- }
1829
- }
1830
- }
1831
- lastSignalMs = tick.nextLastSignalMs;
1832
- if (progressed)
1833
- lastSeenMtime = newestMtime;
1834
- if (tick.done)
1835
- return;
1836
- await sleep(pollMs);
1837
- }
1838
- }
1839
- /**
1840
- * Spec §4 repair decision for an exited worker whose expected envelope is
1841
- * invalid or missing. First failure on a resumable provider with a recorded
1842
- * session id: record `envelope_repair` on the lane and spawn the repair turn.
1843
- * A provider with no session resume gets the same single attempt as a fresh
1844
- * turn for invalid files. Anything else (already attempted, no session id on a
1845
- * resumable provider, non-running lane, spawn failure): give up with every
1846
- * error collected. The caller preserves the normal interrupted classification
1847
- * for a missing file and uses `envelope_invalid` only for an existing invalid
1848
- * file.
1849
- */
1850
- export function decideEnvelopeRepair(hqRoot, laneId, latest, nowMs, spawnRepair, logDecision) {
1851
- const at = new Date(nowMs).toISOString();
1852
- const error = latest.error ?? "unparseable envelope";
1853
- const lane = readLaneSoft(hqRoot, laneId);
1854
- if (!lane)
1855
- return { action: "give_up", errors: [error] };
1856
- if (lane.state !== "running") {
1857
- logDecision({ event: "envelope_repair", at, outcome: "skipped", skipped_reason: "lane_not_running", error });
1858
- return { action: "give_up", errors: [error] };
1859
- }
1860
- const runDir = laneRunDir(hqRoot, laneId);
1861
- const manifest = readSpawnManifest(runDir);
1862
- const prior = lane.envelope_repair;
1863
- // A resumed worker can write its next envelope before spawn.json points to
1864
- // that slot. Use the newest of the manifest's expected slot and the actual
1865
- // latest file so an older manifest or repair record cannot spend its budget.
1866
- const expectedRef = missingExpectedEnvelopeFile(hqRoot, laneId, manifest.envelope_path)?.ref;
1867
- const repairRef = expectedRef !== undefined && expectedRef > latest.ref ? expectedRef : latest.ref;
1868
- const priorAppliesToSlot = prior?.envelope_ref === undefined || prior.envelope_ref === repairRef;
1869
- if (prior && prior.attempted && priorAppliesToSlot) {
1870
- // The repair turn ran and its output does not parse either.
1871
- if (prior.attempted) {
1872
- const errors = [prior.first_error, error];
1873
- try {
1874
- retryUpdateLane(hqRoot, laneId, "watcher", (current) => ({
1875
- ...current,
1876
- envelope_repair: { ...prior, succeeded: false, second_error: error },
1877
- }));
1878
- }
1879
- catch (err) {
1880
- process.stderr.write(`hq lanes watcher: envelope_repair write failed for ${laneId}: ${err instanceof Error ? err.message : String(err)}\n`);
1881
- }
1882
- logDecision({ event: "envelope_repair", at, outcome: "second_failure", errors });
1883
- return { action: "give_up", errors };
1884
- }
1885
- return { action: "give_up", errors: [prior.first_error] };
1886
- }
1887
- // `resume` (claude, codex) continues the recorded session; `fresh_turn`
1888
- // (grok) runs the repair prompt as a new single turn on the same account.
1889
- const mode = envelopeRepairMode(lane.provider);
1890
- let skipped;
1891
- let sessionId = null;
1892
- if (mode === "resume") {
1893
- const result = readWorkerRunResult(runDir, lane.provider, manifest.worker_out_offset ?? 0);
1894
- sessionId = result?.session_id ??
1895
- [manifest.resume?.session_id, lane.provider_session_id, lane.last_resume?.session_id].find((candidate) => typeof candidate === "string" && candidate.trim().length > 0) ?? null;
1896
- if (sessionId === null)
1897
- skipped = result?.session_id_absent ?? "no_result_json";
1898
- }
1899
- const base = {
1900
- first_error: error,
1901
- envelope_ref: repairRef,
1902
- at,
1903
- };
1904
- if (skipped !== undefined) {
1905
- writeRepairRecord(hqRoot, laneId, { ...base, attempted: false, succeeded: false, skipped_reason: skipped });
1906
- logDecision({ event: "envelope_repair", at, outcome: "skipped", skipped_reason: skipped, error });
1907
- return { action: "give_up", errors: [error] };
1908
- }
1909
- writeRepairRecord(hqRoot, laneId, { ...base, mode, attempted: true, succeeded: false });
1910
- try {
1911
- const pid = spawnRepair(hqRoot, lane, {
1912
- session_id: sessionId,
1913
- envelopePath: latest.path,
1914
- error,
1915
- rawText: latest.text,
1916
- missing: latest.missing,
1917
- onProfileWarning: (fields) => {
1918
- logDecision({
1919
- event: "envelope_repair",
1920
- at,
1921
- outcome: "profile_unknown_meta_fields_ignored",
1922
- fields: [...fields],
1923
- });
1924
- },
1925
- });
1926
- logDecision({ event: "envelope_repair", at, outcome: "spawned", mode, pid, session_id: sessionId, error });
1927
- return { action: "spawned" };
1928
- }
1929
- catch (err) {
1930
- const message = err instanceof Error ? err.message : String(err);
1931
- process.stderr.write(`hq lanes watcher: envelope repair spawn failed for ${laneId}: ${message}\n`);
1932
- writeRepairRecord(hqRoot, laneId, {
1933
- ...base,
1934
- mode,
1935
- attempted: true,
1936
- succeeded: false,
1937
- second_error: `repair_spawn_failed: ${message}`,
1938
- });
1939
- logDecision({ event: "envelope_repair", at, outcome: "spawn_failed", error: message });
1940
- return { action: "give_up", errors: [error, `repair_spawn_failed: ${message}`] };
1941
- }
1942
- }
1943
- function writeRepairRecord(hqRoot, laneId, record) {
1944
- retryUpdateLane(hqRoot, laneId, "watcher", (current) => ({ ...current, envelope_repair: record }));
1945
- }
1946
- /** The repair run wrote a parseable envelope: close the record as succeeded. */
1947
- function markRepairSucceeded(hqRoot, laneId, _envelopeRef) {
1948
- try {
1949
- retryUpdateLane(hqRoot, laneId, "watcher", (current) => {
1950
- const prior = current.envelope_repair;
1951
- if (!prior || !prior.attempted || prior.succeeded) {
1952
- return current;
1953
- }
1954
- return { ...current, envelope_repair: { ...prior, succeeded: true, second_error: undefined } };
1955
- });
1956
- }
1957
- catch (err) {
1958
- process.stderr.write(`hq lanes watcher: envelope_repair success write failed for ${laneId}: ${err instanceof Error ? err.message : String(err)}\n`);
1959
- }
1960
- }
1961
- /** Exported so tests can prove the watcher reads the live record, not spawn env. */
1962
- export function laneIdentityFromRecord(hqRoot, laneId) {
1963
- const lane = readLane(hqRoot, laneId);
1964
- return {
1965
- lane_id: lane.lane_id,
1966
- company: lane.company,
1967
- project_id: lane.project_id,
1968
- story_id: lane.story_id,
1969
- senior: lane.senior,
1970
- };
1971
- }
1972
- //# sourceMappingURL=watcher.js.map