@indigoai-us/hq-cli 5.313.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 (1174) hide show
  1. package/CHANGELOG.md +1 -4300
  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 -357
  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 -68
  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 -277
  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 -87
  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 -20
  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 +7 -26
  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 -53
  187. package/dist/lib/mesh/live/daemon/doctor.js +6 -190
  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 -13
  236. package/dist/lib/work-context/contract.schema.json +1 -3
  237. package/dist/lib/work-context/index.d.ts +25 -0
  238. package/dist/lib/work-context/index.js +21 -0
  239. package/dist/lib/work-context/outbox.d.ts +5 -27
  240. package/dist/lib/work-context/outbox.js +6 -135
  241. package/dist/lib/work-context/reconcile.d.ts +0 -15
  242. package/dist/lib/work-context/reconcile.js +29 -405
  243. package/dist/lib/work-context/state.d.ts +10 -93
  244. package/dist/lib/work-context/state.js +29 -342
  245. package/dist/lib/workers-registry/index.js +8 -62
  246. package/dist/main.d.ts +0 -32
  247. package/dist/main.js +73 -273
  248. package/dist/node-network-compat.d.ts +30 -2
  249. package/dist/node-network-compat.js +51 -4
  250. package/dist/node-preflight.d.ts +1 -7
  251. package/dist/node-preflight.js +5 -5
  252. package/dist/register-all.d.ts +29 -4
  253. package/dist/register-all.js +233 -4
  254. package/dist/run/discover-schemas.d.ts +1 -2
  255. package/dist/run/env-graph-guard.d.ts +2 -2
  256. package/dist/run/env-graph-guard.js +2 -5
  257. package/dist/run/hq-plugin.d.ts +0 -4
  258. package/dist/run/hq-plugin.js +8 -36
  259. package/dist/sentry-before-send.js +0 -80
  260. package/dist/sentry.d.ts +2 -8
  261. package/dist/sentry.js +13 -117
  262. package/dist/startup-registration.d.ts +2 -26
  263. package/dist/startup-registration.js +15 -116
  264. package/dist/utils/cli-telemetry.d.ts +1 -74
  265. package/dist/utils/cli-telemetry.js +7 -434
  266. package/dist/utils/client-health.d.ts +4 -0
  267. package/dist/utils/client-health.js +2 -2
  268. package/dist/utils/cognito-session.d.ts +0 -71
  269. package/dist/utils/cognito-session.js +27 -481
  270. package/dist/utils/contribution-table.d.ts +1 -1
  271. package/dist/utils/environmental-error.d.ts +0 -18
  272. package/dist/utils/environmental-error.js +7 -240
  273. package/dist/utils/expected-cli-error.d.ts +0 -2
  274. package/dist/utils/expected-cli-error.js +0 -4
  275. package/dist/utils/feedback-diagnostics.d.ts +1 -2
  276. package/dist/utils/feedback-log-bundle.d.ts +26 -51
  277. package/dist/utils/feedback-log-bundle.js +31 -211
  278. package/dist/utils/feedback-logs.d.ts +47 -18
  279. package/dist/utils/feedback-logs.js +21 -50
  280. package/dist/utils/feedback-screenshots.d.ts +1 -0
  281. package/dist/utils/feedback-screenshots.js +1 -1
  282. package/dist/utils/hq-roots.d.ts +2 -25
  283. package/dist/utils/hq-roots.js +7 -67
  284. package/dist/utils/incomplete-install-error.d.ts +19 -87
  285. package/dist/utils/incomplete-install-error.js +68 -319
  286. package/dist/utils/install-tree-torn.d.ts +24 -260
  287. package/dist/utils/install-tree-torn.js +51 -998
  288. package/dist/utils/large-file-guard.d.ts +10 -0
  289. package/dist/utils/large-file-guard.js +1 -1
  290. package/dist/utils/local-files-overview.d.ts +8 -4
  291. package/dist/utils/local-files-overview.js +7 -48
  292. package/dist/utils/login-provider.d.ts +0 -7
  293. package/dist/utils/login-provider.js +0 -34
  294. package/dist/utils/pack-contributions.d.ts +14 -2
  295. package/dist/utils/pack-contributions.js +44 -7
  296. package/dist/utils/package-root-diagnostics.d.ts +1 -1
  297. package/dist/utils/people.d.ts +11 -7
  298. package/dist/utils/people.js +20 -5
  299. package/dist/utils/plan-gate-error.d.ts +10 -52
  300. package/dist/utils/plan-gate-error.js +41 -364
  301. package/dist/utils/qmd-model-download-error.d.ts +8 -0
  302. package/dist/utils/qmd-model-download-error.js +1 -1
  303. package/dist/utils/qmd-query-document-error.d.ts +6 -0
  304. package/dist/utils/qmd-query-document-error.js +1 -1
  305. package/dist/utils/redact-error-text.d.ts +2 -0
  306. package/dist/utils/redact-error-text.js +2 -3
  307. package/dist/utils/run-bundled-script.d.ts +0 -6
  308. package/dist/utils/run-bundled-script.js +4 -117
  309. package/dist/utils/sandbox-runner-client.d.ts +1 -2
  310. package/dist/utils/secrets-cache.d.ts +3 -7
  311. package/dist/utils/secrets-cache.js +14 -162
  312. package/dist/utils/self-update.d.ts +1 -34
  313. package/dist/utils/self-update.js +42 -660
  314. package/dist/utils/sentry-fingerprint.d.ts +1 -23
  315. package/dist/utils/sentry-fingerprint.js +31 -223
  316. package/dist/utils/team-upgrade.d.ts +1 -1
  317. package/dist/utils/team-upgrade.js +3 -4
  318. package/dist/utils/vault-api.d.ts +1 -21
  319. package/dist/utils/vault-api.js +84 -251
  320. package/dist/utils/version-check.d.ts +1 -11
  321. package/dist/utils/version-check.js +3 -32
  322. package/dist/utils/version-gate.d.ts +17 -101
  323. package/dist/utils/version-gate.js +70 -645
  324. package/dist/utils/windows-spawn.d.ts +0 -6
  325. package/dist/utils/windows-spawn.js +0 -37
  326. package/package.json +8 -20
  327. package/README.md +0 -113
  328. package/assets/bot-workers/setup/context/USER-GUIDE.md +0 -404
  329. package/assets/bot-workers/setup/context/quick-reference.md +0 -199
  330. package/assets/bot-workers/setup/skills/agents-and-team.md +0 -167
  331. package/assets/bot-workers/setup/skills/explain-hq.md +0 -35
  332. package/assets/bot-workers/setup/skills/first-company.md +0 -74
  333. package/assets/bot-workers/setup/skills/joining-a-team.md +0 -125
  334. package/assets/bot-workers/setup/skills/pricing.md +0 -92
  335. package/assets/bot-workers/setup/skills/standing-help.md +0 -81
  336. package/assets/bot-workers/setup/skills/your-business.md +0 -281
  337. package/assets/bot-workers/setup/worker.yaml +0 -791
  338. package/assets/lanes-hooks/hq-lanes-drain.json +0 -15
  339. package/assets/lanes-hooks/hq-lanes-drain.mjs +0 -275
  340. package/assets/lanes-hooks/hq-lanes-drain.sh +0 -21
  341. package/assets/lanes-reconcile/hq-lanes-reconcile.service +0 -11
  342. package/assets/lanes-reconcile/hq-lanes-reconcile.timer +0 -12
  343. package/assets/scaffold/.claude/hooks/validate-policy-frontmatter.sh +0 -485
  344. package/assets/scaffold/core/scripts/audit-log.sh +0 -384
  345. package/assets/scaffold/core/scripts/clean-worktree-reconcile-handoff.sh +0 -171
  346. package/assets/scaffold/core/scripts/eval-trigger.sh +0 -193
  347. package/assets/scaffold/core/scripts/git-pack-extension-check.sh +0 -164
  348. package/assets/scaffold/core/scripts/handoff-finalize.sh +0 -688
  349. package/assets/scaffold/core/scripts/handoff-open-steps.sh +0 -81
  350. package/assets/scaffold/core/scripts/handoff-post.sh +0 -252
  351. package/assets/scaffold/core/scripts/hq-delegate-bundle.sh +0 -307
  352. package/assets/scaffold/core/scripts/hq-delegate-grant.sh +0 -252
  353. package/assets/scaffold/core/scripts/hq-delegate-pickup.sh +0 -99
  354. package/assets/scaffold/core/scripts/hq-delegate-publish.sh +0 -91
  355. package/assets/scaffold/core/scripts/hq-delegate-repo.sh +0 -158
  356. package/assets/scaffold/core/scripts/hq-delegate-resolve.sh +0 -145
  357. package/assets/scaffold/core/scripts/hq-delegate-secrets.sh +0 -129
  358. package/assets/scaffold/core/scripts/hq-delegate-send.sh +0 -259
  359. package/assets/scaffold/core/scripts/hq-delegate-transfer.sh +0 -175
  360. package/assets/scaffold/core/scripts/hq-delegate-verify.sh +0 -238
  361. package/assets/scaffold/core/scripts/hq-dm-bind.sh +0 -585
  362. package/assets/scaffold/core/scripts/hq-job-notify.sh +0 -389
  363. package/assets/scaffold/core/scripts/hq-job-probe.sh +0 -835
  364. package/assets/scaffold/core/scripts/hq-job-remediate.sh +0 -359
  365. package/assets/scaffold/core/scripts/hq-job-run.sh +0 -1025
  366. package/assets/scaffold/core/scripts/hq-pin.sh +0 -118
  367. package/assets/scaffold/core/scripts/jobs-schedule-parse.sh +0 -310
  368. package/assets/scaffold/core/scripts/jobs-validate.sh +0 -451
  369. package/assets/scaffold/core/scripts/knowledge-prefs.sh +0 -55
  370. package/assets/scaffold/core/scripts/lib/portable.sh +0 -211
  371. package/assets/scaffold/core/scripts/lib/secret-patterns.sh +0 -58
  372. package/assets/scaffold/core/scripts/lib/work-mesh-live-hook.sh +0 -378
  373. package/assets/scaffold/core/scripts/lib/work-mesh-live-rebind.sh +0 -141
  374. package/assets/scaffold/core/scripts/migrate-policy-triggers.sh +0 -373
  375. package/assets/scaffold/core/scripts/ontology-audience-grant.sh +0 -81
  376. package/assets/scaffold/core/scripts/ontology-brief.mjs +0 -93
  377. package/assets/scaffold/core/scripts/ontology-candidate.sh +0 -100
  378. package/assets/scaffold/core/scripts/ontology-garden.mjs +0 -238
  379. package/assets/scaffold/core/scripts/ontology-source-worklist.sh +0 -79
  380. package/assets/scaffold/core/scripts/outpost-jobs-reconcile.sh +0 -834
  381. package/assets/scaffold/core/scripts/policy-age-report.sh +0 -156
  382. package/assets/scaffold/core/scripts/policy-retire.sh +0 -199
  383. package/assets/scaffold/core/scripts/qmd-reindex-bg.sh +0 -40
  384. package/assets/scaffold/core/scripts/read-policy-frontmatter.sh +0 -32
  385. package/assets/scaffold/core/scripts/refresh-vault-access.sh +0 -188
  386. package/assets/scaffold/core/scripts/register-project.sh +0 -262
  387. package/assets/scaffold/core/scripts/resolve-company.sh +0 -199
  388. package/assets/scaffold/core/scripts/resume-thread-lock.sh +0 -285
  389. package/assets/scaffold/core/scripts/source-yaml-validate.sh +0 -36
  390. package/assets/scaffold/core/scripts/verify-story-deliverables.sh +0 -148
  391. package/assets/scaffold/core/scripts/work-mesh-live-bind-trusted.sh +0 -152
  392. package/assets/scaffold/core/scripts/work-mesh-live-rebind.sh +0 -59
  393. package/assets/scaffold/core/scripts/worktree-gc.sh +0 -362
  394. package/contracts/preflight/v1/fixtures.json +0 -87
  395. package/contracts/preflight/v1/schema.json +0 -58
  396. package/dist/command-catalog.generated.d.ts +0 -10735
  397. package/dist/command-catalog.generated.js +0 -13836
  398. package/dist/command-registration-plan.d.ts +0 -474
  399. package/dist/command-registration-plan.js +0 -136
  400. package/dist/commands/agent-enroll.d.ts +0 -146
  401. package/dist/commands/agent-enroll.js +0 -401
  402. package/dist/commands/agent-inbox.d.ts +0 -9
  403. package/dist/commands/agent-inbox.js +0 -102
  404. package/dist/commands/agent-kit.d.ts +0 -87
  405. package/dist/commands/agent-kit.js +0 -480
  406. package/dist/commands/agent-mcp.d.ts +0 -24
  407. package/dist/commands/agent-mcp.js +0 -127
  408. package/dist/commands/agent-probe.d.ts +0 -77
  409. package/dist/commands/agent-probe.js +0 -335
  410. package/dist/commands/agent.d.ts +0 -13
  411. package/dist/commands/agent.js +0 -40
  412. package/dist/commands/billing-sponsor.d.ts +0 -83
  413. package/dist/commands/billing-sponsor.js +0 -344
  414. package/dist/commands/bot-companies.d.ts +0 -40
  415. package/dist/commands/bot-companies.js +0 -64
  416. package/dist/commands/bot-continuity.d.ts +0 -28
  417. package/dist/commands/bot-continuity.js +0 -68
  418. package/dist/commands/bot-jobs.d.ts +0 -127
  419. package/dist/commands/bot-jobs.js +0 -454
  420. package/dist/commands/bot.d.ts +0 -278
  421. package/dist/commands/bot.js +0 -1982
  422. package/dist/commands/cloud-retire.d.ts +0 -51
  423. package/dist/commands/cloud-retire.js +0 -154
  424. package/dist/commands/company-rename-flag.d.ts +0 -4
  425. package/dist/commands/company-rename-flag.js +0 -7
  426. package/dist/commands/company-rename.d.ts +0 -4
  427. package/dist/commands/company-rename.js +0 -90
  428. package/dist/commands/core-audit-log-native.d.ts +0 -9
  429. package/dist/commands/core-audit-log-native.js +0 -257
  430. package/dist/commands/core-checkpoint-gate-setting.d.ts +0 -59
  431. package/dist/commands/core-checkpoint-gate-setting.js +0 -163
  432. package/dist/commands/core-checkpoint-stop-gate-native.d.ts +0 -34
  433. package/dist/commands/core-checkpoint-stop-gate-native.js +0 -725
  434. package/dist/commands/core-command-catalog.d.ts +0 -34
  435. package/dist/commands/core-command-catalog.js +0 -62
  436. package/dist/commands/core-company-index-scope-flag.d.ts +0 -3
  437. package/dist/commands/core-company-index-scope-flag.js +0 -6
  438. package/dist/commands/core-delegate-w1b.d.ts +0 -10
  439. package/dist/commands/core-delegate-w1b.js +0 -1219
  440. package/dist/commands/core-delegate.d.ts +0 -46
  441. package/dist/commands/core-delegate.js +0 -1040
  442. package/dist/commands/core-dm-bind-native.d.ts +0 -32
  443. package/dist/commands/core-dm-bind-native.js +0 -668
  444. package/dist/commands/core-eval-trigger-native.d.ts +0 -4
  445. package/dist/commands/core-eval-trigger-native.js +0 -12
  446. package/dist/commands/core-git-pack-extension-check-native.d.ts +0 -22
  447. package/dist/commands/core-git-pack-extension-check-native.js +0 -190
  448. package/dist/commands/core-handoff-fast.d.ts +0 -18
  449. package/dist/commands/core-handoff-fast.js +0 -104
  450. package/dist/commands/core-handoff-open-steps.d.ts +0 -21
  451. package/dist/commands/core-handoff-open-steps.js +0 -264
  452. package/dist/commands/core-handoff.d.ts +0 -24
  453. package/dist/commands/core-handoff.js +0 -1144
  454. package/dist/commands/core-hq-session-native.d.ts +0 -39
  455. package/dist/commands/core-hq-session-native.js +0 -579
  456. package/dist/commands/core-job-native-utils.d.ts +0 -6
  457. package/dist/commands/core-job-native-utils.js +0 -80
  458. package/dist/commands/core-job-native.d.ts +0 -5
  459. package/dist/commands/core-job-native.js +0 -16
  460. package/dist/commands/core-job-notify-native.d.ts +0 -36
  461. package/dist/commands/core-job-notify-native.js +0 -359
  462. package/dist/commands/core-job-probe-native.d.ts +0 -45
  463. package/dist/commands/core-job-probe-native.js +0 -564
  464. package/dist/commands/core-job-remediate-native.d.ts +0 -26
  465. package/dist/commands/core-job-remediate-native.js +0 -374
  466. package/dist/commands/core-job-remote-launcher.d.ts +0 -7
  467. package/dist/commands/core-job-remote-launcher.js +0 -51
  468. package/dist/commands/core-job-run-native.d.ts +0 -47
  469. package/dist/commands/core-job-run-native.js +0 -1215
  470. package/dist/commands/core-jobs-native.d.ts +0 -25
  471. package/dist/commands/core-jobs-native.js +0 -1339
  472. package/dist/commands/core-knowledge-prefs.d.ts +0 -11
  473. package/dist/commands/core-knowledge-prefs.js +0 -137
  474. package/dist/commands/core-migrate-policy-triggers-native.d.ts +0 -21
  475. package/dist/commands/core-migrate-policy-triggers-native.js +0 -378
  476. package/dist/commands/core-native-handoff-flag.d.ts +0 -4
  477. package/dist/commands/core-native-handoff-flag.js +0 -7
  478. package/dist/commands/core-native-hook-helper-commands.d.ts +0 -4
  479. package/dist/commands/core-native-hook-helper-commands.js +0 -56
  480. package/dist/commands/core-native-hook-helpers-flag.d.ts +0 -4
  481. package/dist/commands/core-native-hook-helpers-flag.js +0 -7
  482. package/dist/commands/core-native-jobs-flag.d.ts +0 -4
  483. package/dist/commands/core-native-jobs-flag.js +0 -7
  484. package/dist/commands/core-native-policy-flag.d.ts +0 -9
  485. package/dist/commands/core-native-policy-flag.js +0 -12
  486. package/dist/commands/core-native-session-flag.d.ts +0 -4
  487. package/dist/commands/core-native-session-flag.js +0 -7
  488. package/dist/commands/core-native-utilities-flag.d.ts +0 -4
  489. package/dist/commands/core-native-utilities-flag.js +0 -7
  490. package/dist/commands/core-native-utilities.d.ts +0 -29
  491. package/dist/commands/core-native-utilities.js +0 -54
  492. package/dist/commands/core-native-worker-skills-flag.d.ts +0 -4
  493. package/dist/commands/core-native-worker-skills-flag.js +0 -7
  494. package/dist/commands/core-ontology-native.d.ts +0 -17
  495. package/dist/commands/core-ontology-native.js +0 -916
  496. package/dist/commands/core-ontology.d.ts +0 -66
  497. package/dist/commands/core-ontology.js +0 -430
  498. package/dist/commands/core-pin-native.d.ts +0 -14
  499. package/dist/commands/core-pin-native.js +0 -236
  500. package/dist/commands/core-policy-frontmatter.d.ts +0 -8
  501. package/dist/commands/core-policy-frontmatter.js +0 -52
  502. package/dist/commands/core-policy.d.ts +0 -14
  503. package/dist/commands/core-policy.js +0 -1018
  504. package/dist/commands/core-refresh-vault-access-native.d.ts +0 -20
  505. package/dist/commands/core-refresh-vault-access-native.js +0 -229
  506. package/dist/commands/core-register-project-native.d.ts +0 -30
  507. package/dist/commands/core-register-project-native.js +0 -347
  508. package/dist/commands/core-resolve-company-command.d.ts +0 -4
  509. package/dist/commands/core-resolve-company-command.js +0 -42
  510. package/dist/commands/core-resolve-company-native.d.ts +0 -28
  511. package/dist/commands/core-resolve-company-native.js +0 -408
  512. package/dist/commands/core-work-mesh-bind-trusted-native.d.ts +0 -32
  513. package/dist/commands/core-work-mesh-bind-trusted-native.js +0 -190
  514. package/dist/commands/core-work-mesh-live-rebind-native.d.ts +0 -18
  515. package/dist/commands/core-work-mesh-live-rebind-native.js +0 -262
  516. package/dist/commands/core-worker-lint-native.d.ts +0 -4
  517. package/dist/commands/core-worker-lint-native.js +0 -160
  518. package/dist/commands/core-worker-share-native.d.ts +0 -4
  519. package/dist/commands/core-worker-share-native.js +0 -260
  520. package/dist/commands/core-worker-skills-command.d.ts +0 -8
  521. package/dist/commands/core-worker-skills-command.js +0 -33
  522. package/dist/commands/core-worker-skills-runtime.d.ts +0 -33
  523. package/dist/commands/core-worker-skills-runtime.js +0 -86
  524. package/dist/commands/daemon.d.ts +0 -63
  525. package/dist/commands/daemon.js +0 -877
  526. package/dist/commands/deploy-comments.d.ts +0 -3
  527. package/dist/commands/deploy-comments.js +0 -162
  528. package/dist/commands/lanes-accounts.d.ts +0 -28
  529. package/dist/commands/lanes-accounts.js +0 -595
  530. package/dist/commands/lanes-autopilot.d.ts +0 -11
  531. package/dist/commands/lanes-autopilot.js +0 -336
  532. package/dist/commands/lanes-checks.d.ts +0 -51
  533. package/dist/commands/lanes-checks.js +0 -941
  534. package/dist/commands/lanes-hold.d.ts +0 -43
  535. package/dist/commands/lanes-hold.js +0 -655
  536. package/dist/commands/lanes-kpis.d.ts +0 -11
  537. package/dist/commands/lanes-kpis.js +0 -34
  538. package/dist/commands/lanes-message.d.ts +0 -9
  539. package/dist/commands/lanes-message.js +0 -937
  540. package/dist/commands/lanes-move.d.ts +0 -12
  541. package/dist/commands/lanes-move.js +0 -397
  542. package/dist/commands/lanes-questions.d.ts +0 -36
  543. package/dist/commands/lanes-questions.js +0 -1005
  544. package/dist/commands/lanes-report.d.ts +0 -11
  545. package/dist/commands/lanes-report.js +0 -333
  546. package/dist/commands/lanes-resume.d.ts +0 -6
  547. package/dist/commands/lanes-resume.js +0 -564
  548. package/dist/commands/lanes-review.d.ts +0 -10
  549. package/dist/commands/lanes-review.js +0 -56
  550. package/dist/commands/lanes-shared.d.ts +0 -448
  551. package/dist/commands/lanes-shared.js +0 -170
  552. package/dist/commands/lanes-stories.d.ts +0 -15
  553. package/dist/commands/lanes-stories.js +0 -347
  554. package/dist/commands/lanes-watch.d.ts +0 -7
  555. package/dist/commands/lanes-watch.js +0 -216
  556. package/dist/commands/lanes.d.ts +0 -149
  557. package/dist/commands/lanes.js +0 -8973
  558. package/dist/commands/monitor.d.ts +0 -58
  559. package/dist/commands/monitor.js +0 -980
  560. package/dist/commands/onboard-bot-membership.d.ts +0 -32
  561. package/dist/commands/onboard-bot-membership.js +0 -40
  562. package/dist/commands/onboard-create-identity.d.ts +0 -26
  563. package/dist/commands/onboard-create-identity.js +0 -23
  564. package/dist/commands/outpost-pruner.d.ts +0 -3
  565. package/dist/commands/outpost-pruner.js +0 -125
  566. package/dist/commands/personal-connector-settings-flag.d.ts +0 -4
  567. package/dist/commands/personal-connector-settings-flag.js +0 -7
  568. package/dist/commands/personal-targeted-push-flag.d.ts +0 -4
  569. package/dist/commands/personal-targeted-push-flag.js +0 -7
  570. package/dist/commands/personal-targeted-push-paths.d.ts +0 -3
  571. package/dist/commands/personal-targeted-push-paths.js +0 -67
  572. package/dist/commands/report.d.ts +0 -19
  573. package/dist/commands/report.js +0 -537
  574. package/dist/commands/run-feature-telemetry.d.ts +0 -3
  575. package/dist/commands/run-feature-telemetry.js +0 -6
  576. package/dist/commands/staff/reset-test-account.d.ts +0 -110
  577. package/dist/commands/staff/reset-test-account.js +0 -268
  578. package/dist/commands/staff/test-account.d.ts +0 -51
  579. package/dist/commands/staff/test-account.js +0 -196
  580. package/dist/commands/vault-retention-flag.d.ts +0 -3
  581. package/dist/commands/vault-retention-flag.js +0 -9
  582. package/dist/commands/vault-retention.d.ts +0 -11
  583. package/dist/commands/vault-retention.js +0 -69
  584. package/dist/commands/version.d.ts +0 -10
  585. package/dist/commands/version.js +0 -11
  586. package/dist/fast-scaffold.d.ts +0 -86
  587. package/dist/fast-scaffold.js +0 -364
  588. package/dist/lanes-drain-hook.d.ts +0 -14
  589. package/dist/lanes-drain-hook.js +0 -203
  590. package/dist/lib/agent-kit/adopt-identity.d.ts +0 -27
  591. package/dist/lib/agent-kit/adopt-identity.js +0 -60
  592. package/dist/lib/agent-kit/attachment-download.d.ts +0 -24
  593. package/dist/lib/agent-kit/attachment-download.js +0 -47
  594. package/dist/lib/agent-kit/creds.d.ts +0 -106
  595. package/dist/lib/agent-kit/creds.js +0 -163
  596. package/dist/lib/agent-kit/fallback.d.ts +0 -78
  597. package/dist/lib/agent-kit/fallback.js +0 -210
  598. package/dist/lib/agent-kit/inbox-state.d.ts +0 -83
  599. package/dist/lib/agent-kit/inbox-state.js +0 -159
  600. package/dist/lib/agent-kit/kit-config.d.ts +0 -56
  601. package/dist/lib/agent-kit/kit-config.js +0 -65
  602. package/dist/lib/agent-kit/log.d.ts +0 -16
  603. package/dist/lib/agent-kit/log.js +0 -46
  604. package/dist/lib/agent-kit/mcp/attachments.d.ts +0 -126
  605. package/dist/lib/agent-kit/mcp/attachments.js +0 -222
  606. package/dist/lib/agent-kit/mcp/jsonrpc.d.ts +0 -75
  607. package/dist/lib/agent-kit/mcp/jsonrpc.js +0 -164
  608. package/dist/lib/agent-kit/mcp/tools.d.ts +0 -64
  609. package/dist/lib/agent-kit/mcp/tools.js +0 -397
  610. package/dist/lib/agent-kit/paths.d.ts +0 -65
  611. package/dist/lib/agent-kit/paths.js +0 -118
  612. package/dist/lib/agent-kit/private-file.d.ts +0 -29
  613. package/dist/lib/agent-kit/private-file.js +0 -91
  614. package/dist/lib/agent-kit/run/heartbeat.d.ts +0 -72
  615. package/dist/lib/agent-kit/run/heartbeat.js +0 -128
  616. package/dist/lib/agent-kit/run/inbox.d.ts +0 -76
  617. package/dist/lib/agent-kit/run/inbox.js +0 -205
  618. package/dist/lib/agent-kit/run/supervisor.d.ts +0 -35
  619. package/dist/lib/agent-kit/run/supervisor.js +0 -85
  620. package/dist/lib/agent-kit/run/sync.d.ts +0 -33
  621. package/dist/lib/agent-kit/run/sync.js +0 -58
  622. package/dist/lib/agent-kit/services.d.ts +0 -31
  623. package/dist/lib/agent-kit/services.js +0 -55
  624. package/dist/lib/agent-kit/skills.d.ts +0 -18
  625. package/dist/lib/agent-kit/skills.js +0 -151
  626. package/dist/lib/agent-kit/wake.d.ts +0 -83
  627. package/dist/lib/agent-kit/wake.js +0 -243
  628. package/dist/lib/agents/model-catalog.d.ts +0 -62
  629. package/dist/lib/agents/model-catalog.js +0 -275
  630. package/dist/lib/auth-login-provider-state.d.ts +0 -8
  631. package/dist/lib/auth-login-provider-state.js +0 -63
  632. package/dist/lib/aws-sdk-node-warning-output.d.ts +0 -12
  633. package/dist/lib/aws-sdk-node-warning-output.js +0 -22
  634. package/dist/lib/billing/free-month.d.ts +0 -18
  635. package/dist/lib/billing/free-month.js +0 -31
  636. package/dist/lib/billing/plan-limit-refusals.d.ts +0 -69
  637. package/dist/lib/billing/plan-limit-refusals.js +0 -187
  638. package/dist/lib/billing/plan-limit-upgrade-url.d.ts +0 -11
  639. package/dist/lib/billing/plan-limit-upgrade-url.js +0 -66
  640. package/dist/lib/billing/plan-lock.d.ts +0 -143
  641. package/dist/lib/billing/plan-lock.js +0 -439
  642. package/dist/lib/bot/api.d.ts +0 -349
  643. package/dist/lib/bot/api.js +0 -316
  644. package/dist/lib/bot/attachments.d.ts +0 -45
  645. package/dist/lib/bot/attachments.js +0 -89
  646. package/dist/lib/bot/cli-update.d.ts +0 -138
  647. package/dist/lib/bot/cli-update.js +0 -278
  648. package/dist/lib/bot/company-bind.d.ts +0 -27
  649. package/dist/lib/bot/company-bind.js +0 -62
  650. package/dist/lib/bot/config.d.ts +0 -153
  651. package/dist/lib/bot/config.js +0 -233
  652. package/dist/lib/bot/continuity-download.d.ts +0 -28
  653. package/dist/lib/bot/continuity-download.js +0 -75
  654. package/dist/lib/bot/continuity-install.d.ts +0 -14
  655. package/dist/lib/bot/continuity-install.js +0 -101
  656. package/dist/lib/bot/continuity.d.ts +0 -67
  657. package/dist/lib/bot/continuity.js +0 -301
  658. package/dist/lib/bot/creds.d.ts +0 -24
  659. package/dist/lib/bot/creds.js +0 -51
  660. package/dist/lib/bot/daemon.d.ts +0 -173
  661. package/dist/lib/bot/daemon.js +0 -552
  662. package/dist/lib/bot/inbox-poll-backoff-flag.d.ts +0 -24
  663. package/dist/lib/bot/inbox-poll-backoff-flag.js +0 -135
  664. package/dist/lib/bot/inbox-state.d.ts +0 -18
  665. package/dist/lib/bot/inbox-state.js +0 -51
  666. package/dist/lib/bot/index.d.ts +0 -23
  667. package/dist/lib/bot/index.js +0 -23
  668. package/dist/lib/bot/inflight.d.ts +0 -119
  669. package/dist/lib/bot/inflight.js +0 -83
  670. package/dist/lib/bot/job-completions.d.ts +0 -89
  671. package/dist/lib/bot/job-completions.js +0 -132
  672. package/dist/lib/bot/job-run.d.ts +0 -109
  673. package/dist/lib/bot/job-run.js +0 -246
  674. package/dist/lib/bot/local-config.d.ts +0 -61
  675. package/dist/lib/bot/local-config.js +0 -145
  676. package/dist/lib/bot/local-jobs.d.ts +0 -89
  677. package/dist/lib/bot/local-jobs.js +0 -459
  678. package/dist/lib/bot/local-name.d.ts +0 -54
  679. package/dist/lib/bot/local-name.js +0 -114
  680. package/dist/lib/bot/log.d.ts +0 -13
  681. package/dist/lib/bot/log.js +0 -59
  682. package/dist/lib/bot/owner-context.d.ts +0 -79
  683. package/dist/lib/bot/owner-context.js +0 -175
  684. package/dist/lib/bot/paths.d.ts +0 -76
  685. package/dist/lib/bot/paths.js +0 -131
  686. package/dist/lib/bot/progress.d.ts +0 -132
  687. package/dist/lib/bot/progress.js +0 -289
  688. package/dist/lib/bot/promote.d.ts +0 -16
  689. package/dist/lib/bot/promote.js +0 -106
  690. package/dist/lib/bot/promotion-hold.d.ts +0 -24
  691. package/dist/lib/bot/promotion-hold.js +0 -103
  692. package/dist/lib/bot/promotion-receipt.d.ts +0 -9
  693. package/dist/lib/bot/promotion-receipt.js +0 -56
  694. package/dist/lib/bot/promotion-upload.d.ts +0 -16
  695. package/dist/lib/bot/promotion-upload.js +0 -80
  696. package/dist/lib/bot/prompt.d.ts +0 -136
  697. package/dist/lib/bot/prompt.js +0 -433
  698. package/dist/lib/bot/room-policy.d.ts +0 -63
  699. package/dist/lib/bot/room-policy.js +0 -91
  700. package/dist/lib/bot/run.d.ts +0 -217
  701. package/dist/lib/bot/run.js +0 -1869
  702. package/dist/lib/bot/runnable.d.ts +0 -51
  703. package/dist/lib/bot/runnable.js +0 -65
  704. package/dist/lib/bot/runtime/claude.d.ts +0 -50
  705. package/dist/lib/bot/runtime/claude.js +0 -170
  706. package/dist/lib/bot/runtime/codex.d.ts +0 -28
  707. package/dist/lib/bot/runtime/codex.js +0 -153
  708. package/dist/lib/bot/runtime/grok-acp.d.ts +0 -40
  709. package/dist/lib/bot/runtime/grok-acp.js +0 -265
  710. package/dist/lib/bot/runtime/grok.d.ts +0 -41
  711. package/dist/lib/bot/runtime/grok.js +0 -169
  712. package/dist/lib/bot/runtime/index.d.ts +0 -36
  713. package/dist/lib/bot/runtime/index.js +0 -417
  714. package/dist/lib/bot/runtime/messages-stream.d.ts +0 -56
  715. package/dist/lib/bot/runtime/messages-stream.js +0 -194
  716. package/dist/lib/bot/runtime/sanitize.d.ts +0 -18
  717. package/dist/lib/bot/runtime/sanitize.js +0 -28
  718. package/dist/lib/bot/runtime/types.d.ts +0 -159
  719. package/dist/lib/bot/runtime/types.js +0 -51
  720. package/dist/lib/bot/runtime/windows.d.ts +0 -10
  721. package/dist/lib/bot/runtime/windows.js +0 -53
  722. package/dist/lib/bot/runtime-sign-in.d.ts +0 -24
  723. package/dist/lib/bot/runtime-sign-in.js +0 -31
  724. package/dist/lib/bot/scaffold.d.ts +0 -38
  725. package/dist/lib/bot/scaffold.js +0 -94
  726. package/dist/lib/bot/self-heal.d.ts +0 -52
  727. package/dist/lib/bot/self-heal.js +0 -79
  728. package/dist/lib/bot/self-process.d.ts +0 -19
  729. package/dist/lib/bot/self-process.js +0 -35
  730. package/dist/lib/bot/session.d.ts +0 -19
  731. package/dist/lib/bot/session.js +0 -39
  732. package/dist/lib/bot/setup-explain.d.ts +0 -64
  733. package/dist/lib/bot/setup-explain.js +0 -141
  734. package/dist/lib/bot/split.d.ts +0 -32
  735. package/dist/lib/bot/split.js +0 -241
  736. package/dist/lib/bot/status.d.ts +0 -57
  737. package/dist/lib/bot/status.js +0 -66
  738. package/dist/lib/bot/worker-source.d.ts +0 -66
  739. package/dist/lib/bot/worker-source.js +0 -283
  740. package/dist/lib/checkpoint-ontology/aliases.d.ts +0 -17
  741. package/dist/lib/checkpoint-ontology/aliases.js +0 -44
  742. package/dist/lib/checkpoint-ontology/apply.d.ts +0 -110
  743. package/dist/lib/checkpoint-ontology/apply.js +0 -777
  744. package/dist/lib/checkpoint-ontology/company-brief.d.ts +0 -18
  745. package/dist/lib/checkpoint-ontology/company-brief.js +0 -337
  746. package/dist/lib/checkpoint-ontology/company.d.ts +0 -44
  747. package/dist/lib/checkpoint-ontology/company.js +0 -118
  748. package/dist/lib/checkpoint-ontology/drop-aliases.d.ts +0 -41
  749. package/dist/lib/checkpoint-ontology/drop-aliases.js +0 -76
  750. package/dist/lib/checkpoint-ontology/entity-file.d.ts +0 -109
  751. package/dist/lib/checkpoint-ontology/entity-file.js +0 -371
  752. package/dist/lib/checkpoint-ontology/identity.d.ts +0 -38
  753. package/dist/lib/checkpoint-ontology/identity.js +0 -95
  754. package/dist/lib/checkpoint-ontology/merge-copies.d.ts +0 -199
  755. package/dist/lib/checkpoint-ontology/merge-copies.js +0 -1086
  756. package/dist/lib/checkpoint-ontology/multi-writer.d.ts +0 -101
  757. package/dist/lib/checkpoint-ontology/multi-writer.js +0 -394
  758. package/dist/lib/checkpoint-ontology/plan.d.ts +0 -193
  759. package/dist/lib/checkpoint-ontology/plan.js +0 -504
  760. package/dist/lib/checkpoint-ontology/queued-touches.d.ts +0 -29
  761. package/dist/lib/checkpoint-ontology/queued-touches.js +0 -193
  762. package/dist/lib/checkpoint-ontology/sync-client.d.ts +0 -38
  763. package/dist/lib/checkpoint-ontology/sync-client.js +0 -84
  764. package/dist/lib/checkpoint-ontology/tree.d.ts +0 -55
  765. package/dist/lib/checkpoint-ontology/tree.js +0 -198
  766. package/dist/lib/company-errors-sdk-warning-flag.d.ts +0 -5
  767. package/dist/lib/company-errors-sdk-warning-flag.js +0 -8
  768. package/dist/lib/core-utils/hook-timeout-debug-context-flag.d.ts +0 -20
  769. package/dist/lib/core-utils/hook-timeout-debug-context-flag.js +0 -81
  770. package/dist/lib/core-utils/jq-json-serializer.d.ts +0 -5
  771. package/dist/lib/core-utils/jq-json-serializer.js +0 -10
  772. package/dist/lib/core-utils/secret-patterns.d.ts +0 -43
  773. package/dist/lib/core-utils/secret-patterns.js +0 -34
  774. package/dist/lib/core-utils/sentry-report.d.ts +0 -114
  775. package/dist/lib/core-utils/sentry-report.js +0 -1034
  776. package/dist/lib/core-utils/timeout-guard-native.d.ts +0 -7
  777. package/dist/lib/core-utils/timeout-guard-native.js +0 -40
  778. package/dist/lib/core-utils/worktree-resume.d.ts +0 -20
  779. package/dist/lib/core-utils/worktree-resume.js +0 -1198
  780. package/dist/lib/daemon/catalog.d.ts +0 -134
  781. package/dist/lib/daemon/catalog.js +0 -358
  782. package/dist/lib/daemon/config.d.ts +0 -35
  783. package/dist/lib/daemon/config.js +0 -108
  784. package/dist/lib/daemon/flag.d.ts +0 -25
  785. package/dist/lib/daemon/flag.js +0 -59
  786. package/dist/lib/daemon/handoff.d.ts +0 -56
  787. package/dist/lib/daemon/handoff.js +0 -161
  788. package/dist/lib/daemon/hq-cloud.d.ts +0 -79
  789. package/dist/lib/daemon/hq-cloud.js +0 -183
  790. package/dist/lib/daemon/install.d.ts +0 -85
  791. package/dist/lib/daemon/install.js +0 -320
  792. package/dist/lib/daemon/legacy-sync-env.d.ts +0 -10
  793. package/dist/lib/daemon/legacy-sync-env.js +0 -58
  794. package/dist/lib/daemon/legacy.d.ts +0 -45
  795. package/dist/lib/daemon/legacy.js +0 -133
  796. package/dist/lib/daemon/lock.d.ts +0 -47
  797. package/dist/lib/daemon/lock.js +0 -138
  798. package/dist/lib/daemon/machine-type.d.ts +0 -50
  799. package/dist/lib/daemon/machine-type.js +0 -159
  800. package/dist/lib/daemon/migrate.d.ts +0 -77
  801. package/dist/lib/daemon/migrate.js +0 -265
  802. package/dist/lib/daemon/paths.d.ts +0 -24
  803. package/dist/lib/daemon/paths.js +0 -43
  804. package/dist/lib/daemon/protocol-tail.d.ts +0 -33
  805. package/dist/lib/daemon/protocol-tail.js +0 -131
  806. package/dist/lib/daemon/remote-control.d.ts +0 -74
  807. package/dist/lib/daemon/remote-control.js +0 -153
  808. package/dist/lib/daemon/requests.d.ts +0 -28
  809. package/dist/lib/daemon/requests.js +0 -65
  810. package/dist/lib/daemon/run.d.ts +0 -79
  811. package/dist/lib/daemon/run.js +0 -755
  812. package/dist/lib/daemon/succession.d.ts +0 -118
  813. package/dist/lib/daemon/succession.js +0 -263
  814. package/dist/lib/daemon/supervisor.d.ts +0 -132
  815. package/dist/lib/daemon/supervisor.js +0 -836
  816. package/dist/lib/daemon/sync-runner.d.ts +0 -58
  817. package/dist/lib/daemon/sync-runner.js +0 -277
  818. package/dist/lib/daemon/tools.d.ts +0 -52
  819. package/dist/lib/daemon/tools.js +0 -95
  820. package/dist/lib/daemon/updater.d.ts +0 -57
  821. package/dist/lib/daemon/updater.js +0 -163
  822. package/dist/lib/deploy-api.d.ts +0 -5
  823. package/dist/lib/deploy-api.js +0 -21
  824. package/dist/lib/deploy-apps.d.ts +0 -13
  825. package/dist/lib/deploy-apps.js +0 -29
  826. package/dist/lib/doctor/__testing__/run-doctor.d.ts +0 -8
  827. package/dist/lib/doctor/__testing__/run-doctor.js +0 -52
  828. package/dist/lib/doctor/checks/bots.d.ts +0 -13
  829. package/dist/lib/doctor/checks/bots.js +0 -189
  830. package/dist/lib/doctor/checks/scaffold-cli-floor.d.ts +0 -6
  831. package/dist/lib/doctor/checks/scaffold-cli-floor.js +0 -73
  832. package/dist/lib/doctor/checks/sync-runtime.d.ts +0 -11
  833. package/dist/lib/doctor/checks/sync-runtime.js +0 -216
  834. package/dist/lib/doctor/client-health-flag-token.d.ts +0 -15
  835. package/dist/lib/doctor/client-health-flag-token.js +0 -66
  836. package/dist/lib/doctor/client-health-reason-codes-flag.d.ts +0 -27
  837. package/dist/lib/doctor/client-health-reason-codes-flag.js +0 -106
  838. package/dist/lib/doctor/fix/json-output.d.ts +0 -28
  839. package/dist/lib/doctor/fix/json-output.js +0 -33
  840. package/dist/lib/doctor/fix/refresh-sync-outcome.d.ts +0 -12
  841. package/dist/lib/doctor/fix/refresh-sync-outcome.js +0 -25
  842. package/dist/lib/doctor/shared.d.ts +0 -8
  843. package/dist/lib/doctor/shared.js +0 -38
  844. package/dist/lib/doctor/stray-gate-entries.d.ts +0 -35
  845. package/dist/lib/doctor/stray-gate-entries.js +0 -83
  846. package/dist/lib/first-sync-next-step.d.ts +0 -37
  847. package/dist/lib/first-sync-next-step.js +0 -189
  848. package/dist/lib/flag-registry-endpoint.d.ts +0 -5
  849. package/dist/lib/flag-registry-endpoint.js +0 -9
  850. package/dist/lib/flag-registry-worker-source.generated.d.ts +0 -2
  851. package/dist/lib/flag-registry-worker-source.generated.js +0 -3
  852. package/dist/lib/flag-snapshot-file.d.ts +0 -20
  853. package/dist/lib/flag-snapshot-file.js +0 -91
  854. package/dist/lib/heartbeat-identity.d.ts +0 -30
  855. package/dist/lib/heartbeat-identity.js +0 -76
  856. package/dist/lib/lanes/account-home.d.ts +0 -8
  857. package/dist/lib/lanes/account-home.js +0 -10
  858. package/dist/lib/lanes/accounts.d.ts +0 -117
  859. package/dist/lib/lanes/accounts.js +0 -366
  860. package/dist/lib/lanes/admission-host.d.ts +0 -22
  861. package/dist/lib/lanes/admission-host.js +0 -37
  862. package/dist/lib/lanes/admission.d.ts +0 -26
  863. package/dist/lib/lanes/admission.js +0 -210
  864. package/dist/lib/lanes/approval-gate.d.ts +0 -8
  865. package/dist/lib/lanes/approval-gate.js +0 -90
  866. package/dist/lib/lanes/autopilot-metrics.d.ts +0 -99
  867. package/dist/lib/lanes/autopilot-metrics.js +0 -301
  868. package/dist/lib/lanes/autopilot-registry.d.ts +0 -62
  869. package/dist/lib/lanes/autopilot-registry.js +0 -192
  870. package/dist/lib/lanes/autopilot.d.ts +0 -120
  871. package/dist/lib/lanes/autopilot.js +0 -1061
  872. package/dist/lib/lanes/blocker-freshness.d.ts +0 -31
  873. package/dist/lib/lanes/blocker-freshness.js +0 -168
  874. package/dist/lib/lanes/checked-company-path.d.ts +0 -3
  875. package/dist/lib/lanes/checked-company-path.js +0 -39
  876. package/dist/lib/lanes/claude-balance.d.ts +0 -97
  877. package/dist/lib/lanes/claude-balance.js +0 -319
  878. package/dist/lib/lanes/compaction.d.ts +0 -110
  879. package/dist/lib/lanes/compaction.js +0 -293
  880. package/dist/lib/lanes/config.d.ts +0 -94
  881. package/dist/lib/lanes/config.js +0 -606
  882. package/dist/lib/lanes/constants.d.ts +0 -3
  883. package/dist/lib/lanes/constants.js +0 -3
  884. package/dist/lib/lanes/delivery-core.d.ts +0 -15
  885. package/dist/lib/lanes/delivery-core.js +0 -21
  886. package/dist/lib/lanes/delivery.d.ts +0 -180
  887. package/dist/lib/lanes/delivery.js +0 -443
  888. package/dist/lib/lanes/disk-guard.d.ts +0 -66
  889. package/dist/lib/lanes/disk-guard.js +0 -172
  890. package/dist/lib/lanes/dropbox.d.ts +0 -129
  891. package/dist/lib/lanes/dropbox.js +0 -601
  892. package/dist/lib/lanes/effort.d.ts +0 -51
  893. package/dist/lib/lanes/effort.js +0 -113
  894. package/dist/lib/lanes/envelope-repair-dispatch.d.ts +0 -26
  895. package/dist/lib/lanes/envelope-repair-dispatch.js +0 -74
  896. package/dist/lib/lanes/errors.d.ts +0 -39
  897. package/dist/lib/lanes/errors.js +0 -72
  898. package/dist/lib/lanes/flag-keys.d.ts +0 -15
  899. package/dist/lib/lanes/flag-keys.js +0 -15
  900. package/dist/lib/lanes/grants.d.ts +0 -30
  901. package/dist/lib/lanes/grants.js +0 -171
  902. package/dist/lib/lanes/hire-grant-dispatch.d.ts +0 -29
  903. package/dist/lib/lanes/hire-grant-dispatch.js +0 -315
  904. package/dist/lib/lanes/hooks-install.d.ts +0 -82
  905. package/dist/lib/lanes/hooks-install.js +0 -479
  906. package/dist/lib/lanes/host-capacity.d.ts +0 -69
  907. package/dist/lib/lanes/host-capacity.js +0 -254
  908. package/dist/lib/lanes/hq-root.d.ts +0 -19
  909. package/dist/lib/lanes/hq-root.js +0 -28
  910. package/dist/lib/lanes/index.d.ts +0 -76
  911. package/dist/lib/lanes/index.js +0 -42
  912. package/dist/lib/lanes/keep-alive.d.ts +0 -68
  913. package/dist/lib/lanes/keep-alive.js +0 -343
  914. package/dist/lib/lanes/kr-freshness.d.ts +0 -76
  915. package/dist/lib/lanes/kr-freshness.js +0 -413
  916. package/dist/lib/lanes/lane-company.d.ts +0 -10
  917. package/dist/lib/lanes/lane-company.js +0 -41
  918. package/dist/lib/lanes/liveness.d.ts +0 -108
  919. package/dist/lib/lanes/liveness.js +0 -396
  920. package/dist/lib/lanes/machine-identity.d.ts +0 -34
  921. package/dist/lib/lanes/machine-identity.js +0 -92
  922. package/dist/lib/lanes/manager-status-gate.d.ts +0 -17
  923. package/dist/lib/lanes/manager-status-gate.js +0 -133
  924. package/dist/lib/lanes/merge-command.d.ts +0 -15
  925. package/dist/lib/lanes/merge-command.js +0 -629
  926. package/dist/lib/lanes/mesh-events.d.ts +0 -127
  927. package/dist/lib/lanes/mesh-events.js +0 -564
  928. package/dist/lib/lanes/message-replay.d.ts +0 -21
  929. package/dist/lib/lanes/message-replay.js +0 -122
  930. package/dist/lib/lanes/models.d.ts +0 -86
  931. package/dist/lib/lanes/models.js +0 -234
  932. package/dist/lib/lanes/monitor.d.ts +0 -48
  933. package/dist/lib/lanes/monitor.js +0 -428
  934. package/dist/lib/lanes/move-account.d.ts +0 -56
  935. package/dist/lib/lanes/move-account.js +0 -193
  936. package/dist/lib/lanes/orphans.d.ts +0 -25
  937. package/dist/lib/lanes/orphans.js +0 -102
  938. package/dist/lib/lanes/outpost-dispatch.d.ts +0 -147
  939. package/dist/lib/lanes/outpost-dispatch.js +0 -271
  940. package/dist/lib/lanes/outpost-hire-cache.d.ts +0 -22
  941. package/dist/lib/lanes/outpost-hire-cache.js +0 -153
  942. package/dist/lib/lanes/outpost-identity.d.ts +0 -33
  943. package/dist/lib/lanes/outpost-identity.js +0 -59
  944. package/dist/lib/lanes/outpost-profile-repin.d.ts +0 -17
  945. package/dist/lib/lanes/outpost-profile-repin.js +0 -84
  946. package/dist/lib/lanes/outpost-pruner-install.d.ts +0 -37
  947. package/dist/lib/lanes/outpost-pruner-install.js +0 -238
  948. package/dist/lib/lanes/outpost-registry-worker-approval.d.ts +0 -18
  949. package/dist/lib/lanes/outpost-registry-worker-approval.js +0 -109
  950. package/dist/lib/lanes/outpost-snapshot-memo.d.ts +0 -6
  951. package/dist/lib/lanes/outpost-snapshot-memo.js +0 -14
  952. package/dist/lib/lanes/outpost-worktree-pruner-flag.d.ts +0 -19
  953. package/dist/lib/lanes/outpost-worktree-pruner-flag.js +0 -86
  954. package/dist/lib/lanes/outpost-worktree-pruner.d.ts +0 -62
  955. package/dist/lib/lanes/outpost-worktree-pruner.js +0 -1201
  956. package/dist/lib/lanes/profile.d.ts +0 -69
  957. package/dist/lib/lanes/profile.js +0 -552
  958. package/dist/lib/lanes/provider-rejection.d.ts +0 -86
  959. package/dist/lib/lanes/provider-rejection.js +0 -286
  960. package/dist/lib/lanes/questions.d.ts +0 -90
  961. package/dist/lib/lanes/questions.js +0 -384
  962. package/dist/lib/lanes/quota.d.ts +0 -134
  963. package/dist/lib/lanes/quota.js +0 -471
  964. package/dist/lib/lanes/reconcile-install.d.ts +0 -90
  965. package/dist/lib/lanes/reconcile-install.js +0 -257
  966. package/dist/lib/lanes/reconcile.d.ts +0 -161
  967. package/dist/lib/lanes/reconcile.js +0 -3324
  968. package/dist/lib/lanes/registry-flag.d.ts +0 -35
  969. package/dist/lib/lanes/registry-flag.js +0 -164
  970. package/dist/lib/lanes/registry-persona.d.ts +0 -20
  971. package/dist/lib/lanes/registry-persona.js +0 -329
  972. package/dist/lib/lanes/registry.d.ts +0 -122
  973. package/dist/lib/lanes/registry.js +0 -570
  974. package/dist/lib/lanes/reviews.d.ts +0 -38
  975. package/dist/lib/lanes/reviews.js +0 -395
  976. package/dist/lib/lanes/runaway-tool-guard.d.ts +0 -38
  977. package/dist/lib/lanes/runaway-tool-guard.js +0 -284
  978. package/dist/lib/lanes/session-relink.d.ts +0 -25
  979. package/dist/lib/lanes/session-relink.js +0 -216
  980. package/dist/lib/lanes/spawn.d.ts +0 -355
  981. package/dist/lib/lanes/spawn.js +0 -2668
  982. package/dist/lib/lanes/ssm-command-context.d.ts +0 -12
  983. package/dist/lib/lanes/ssm-command-context.js +0 -52
  984. package/dist/lib/lanes/store.d.ts +0 -91
  985. package/dist/lib/lanes/store.js +0 -1822
  986. package/dist/lib/lanes/stories.d.ts +0 -23
  987. package/dist/lib/lanes/stories.js +0 -92
  988. package/dist/lib/lanes/story-ledger.d.ts +0 -80
  989. package/dist/lib/lanes/story-ledger.js +0 -815
  990. package/dist/lib/lanes/story-switch.d.ts +0 -21
  991. package/dist/lib/lanes/story-switch.js +0 -75
  992. package/dist/lib/lanes/text-scan.d.ts +0 -11
  993. package/dist/lib/lanes/text-scan.js +0 -103
  994. package/dist/lib/lanes/throttle.d.ts +0 -116
  995. package/dist/lib/lanes/throttle.js +0 -437
  996. package/dist/lib/lanes/timestamp.d.ts +0 -3
  997. package/dist/lib/lanes/timestamp.js +0 -26
  998. package/dist/lib/lanes/tracker-checks.d.ts +0 -77
  999. package/dist/lib/lanes/tracker-checks.js +0 -134
  1000. package/dist/lib/lanes/tracker-report-state.d.ts +0 -10
  1001. package/dist/lib/lanes/tracker-report-state.js +0 -124
  1002. package/dist/lib/lanes/tracker-report.d.ts +0 -203
  1003. package/dist/lib/lanes/tracker-report.js +0 -522
  1004. package/dist/lib/lanes/tracker-store.d.ts +0 -18
  1005. package/dist/lib/lanes/tracker-store.js +0 -106
  1006. package/dist/lib/lanes/types.d.ts +0 -1030
  1007. package/dist/lib/lanes/types.js +0 -418
  1008. package/dist/lib/lanes/wait.d.ts +0 -39
  1009. package/dist/lib/lanes/wait.js +0 -159
  1010. package/dist/lib/lanes/watch.d.ts +0 -39
  1011. package/dist/lib/lanes/watch.js +0 -249
  1012. package/dist/lib/lanes/watcher-main.d.ts +0 -11
  1013. package/dist/lib/lanes/watcher-main.js +0 -108
  1014. package/dist/lib/lanes/watcher.d.ts +0 -287
  1015. package/dist/lib/lanes/watcher.js +0 -1972
  1016. package/dist/lib/mesh/denial-codes.d.ts +0 -5
  1017. package/dist/lib/mesh/denial-codes.js +0 -14
  1018. package/dist/lib/mesh/live/daemon/config.d.ts +0 -36
  1019. package/dist/lib/mesh/live/daemon/config.js +0 -120
  1020. package/dist/lib/mesh/live/daemon/legacy-listen.d.ts +0 -43
  1021. package/dist/lib/mesh/live/daemon/legacy-listen.js +0 -89
  1022. package/dist/lib/mesh/live/daemon/live-cache.d.ts +0 -26
  1023. package/dist/lib/mesh/live/daemon/live-cache.js +0 -116
  1024. package/dist/lib/mesh/live/daemon/mqtt-events.d.ts +0 -7
  1025. package/dist/lib/mesh/live/daemon/mqtt-events.js +0 -2
  1026. package/dist/lib/mesh/live/daemon/mqtt-events.test-d.d.ts +0 -2
  1027. package/dist/lib/mesh/live/daemon/mqtt-events.test-d.js +0 -10
  1028. package/dist/lib/mesh/live/daemon/version-drift.d.ts +0 -5
  1029. package/dist/lib/mesh/live/daemon/version-drift.js +0 -47
  1030. package/dist/lib/mesh/live/daemon/work-subscribe.d.ts +0 -32
  1031. package/dist/lib/mesh/live/daemon/work-subscribe.js +0 -262
  1032. package/dist/lib/mesh/live/report-summary.d.ts +0 -45
  1033. package/dist/lib/mesh/live/report-summary.js +0 -234
  1034. package/dist/lib/mesh/live/session-seq.d.ts +0 -4
  1035. package/dist/lib/mesh/live/session-seq.js +0 -33
  1036. package/dist/lib/mesh/project-board.d.ts +0 -65
  1037. package/dist/lib/mesh/project-board.js +0 -181
  1038. package/dist/lib/mesh/story-status.d.ts +0 -22
  1039. package/dist/lib/mesh/story-status.js +0 -49
  1040. package/dist/lib/monitor.d.ts +0 -149
  1041. package/dist/lib/monitor.js +0 -519
  1042. package/dist/lib/node-binary.d.ts +0 -50
  1043. package/dist/lib/node-binary.js +0 -133
  1044. package/dist/lib/notify-recipient.d.ts +0 -7
  1045. package/dist/lib/notify-recipient.js +0 -11
  1046. package/dist/lib/onboarding/checkpoint.d.ts +0 -13
  1047. package/dist/lib/onboarding/checkpoint.js +0 -44
  1048. package/dist/lib/onboarding/cli/onboard.d.ts +0 -53
  1049. package/dist/lib/onboarding/cli/onboard.js +0 -135
  1050. package/dist/lib/onboarding/cli/prompts.d.ts +0 -28
  1051. package/dist/lib/onboarding/cli/prompts.js +0 -83
  1052. package/dist/lib/onboarding/errors.d.ts +0 -34
  1053. package/dist/lib/onboarding/errors.js +0 -59
  1054. package/dist/lib/onboarding/index.d.ts +0 -13
  1055. package/dist/lib/onboarding/index.js +0 -13
  1056. package/dist/lib/onboarding/orchestrator.d.ts +0 -47
  1057. package/dist/lib/onboarding/orchestrator.js +0 -569
  1058. package/dist/lib/onboarding/types.d.ts +0 -79
  1059. package/dist/lib/onboarding/types.js +0 -8
  1060. package/dist/lib/policy-validator.d.ts +0 -7
  1061. package/dist/lib/policy-validator.js +0 -187
  1062. package/dist/lib/process-flag-company-context.d.ts +0 -8
  1063. package/dist/lib/process-flag-company-context.js +0 -67
  1064. package/dist/lib/report-publish.d.ts +0 -175
  1065. package/dist/lib/report-publish.js +0 -421
  1066. package/dist/lib/report-run.d.ts +0 -62
  1067. package/dist/lib/report-run.js +0 -123
  1068. package/dist/lib/report-snapshot.d.ts +0 -12
  1069. package/dist/lib/report-snapshot.js +0 -135
  1070. package/dist/lib/report-templates.d.ts +0 -9
  1071. package/dist/lib/report-templates.js +0 -21
  1072. package/dist/lib/scaffold-cli-floor.d.ts +0 -8
  1073. package/dist/lib/scaffold-cli-floor.js +0 -50
  1074. package/dist/lib/search-index/collection-path-repair-flag.d.ts +0 -4
  1075. package/dist/lib/search-index/collection-path-repair-flag.js +0 -7
  1076. package/dist/lib/search-index/embed-lock.d.ts +0 -34
  1077. package/dist/lib/search-index/embed-lock.js +0 -295
  1078. package/dist/lib/search-index/load-gate.d.ts +0 -57
  1079. package/dist/lib/search-index/load-gate.js +0 -270
  1080. package/dist/lib/search-index/max-doc-bytes.d.ts +0 -219
  1081. package/dist/lib/search-index/max-doc-bytes.js +0 -463
  1082. package/dist/lib/search-index/qmd-exit-diagnostics.d.ts +0 -5
  1083. package/dist/lib/search-index/qmd-exit-diagnostics.js +0 -40
  1084. package/dist/lib/search-index/reindex-single-flight-flag.d.ts +0 -5
  1085. package/dist/lib/search-index/reindex-single-flight-flag.js +0 -8
  1086. package/dist/lib/service-manager/index.d.ts +0 -42
  1087. package/dist/lib/service-manager/index.js +0 -105
  1088. package/dist/lib/service-manager/launchd.d.ts +0 -81
  1089. package/dist/lib/service-manager/launchd.js +0 -212
  1090. package/dist/lib/service-manager/systemd.d.ts +0 -19
  1091. package/dist/lib/service-manager/systemd.js +0 -72
  1092. package/dist/lib/service-manager/types.d.ts +0 -34
  1093. package/dist/lib/service-manager/types.js +0 -26
  1094. package/dist/lib/test-utils/isolated-flag-company-context.d.ts +0 -3
  1095. package/dist/lib/test-utils/isolated-flag-company-context.js +0 -18
  1096. package/dist/lib/work-context/bind-best.d.ts +0 -66
  1097. package/dist/lib/work-context/bind-best.js +0 -344
  1098. package/dist/lib/work-context/bind-calling-session.d.ts +0 -26
  1099. package/dist/lib/work-context/bind-calling-session.js +0 -63
  1100. package/dist/lib/work-context/company-rebind.d.ts +0 -23
  1101. package/dist/lib/work-context/company-rebind.js +0 -59
  1102. package/dist/lib/work-context/default-company.d.ts +0 -43
  1103. package/dist/lib/work-context/default-company.js +0 -83
  1104. package/dist/lib/work-context/outbox-quarantine-status-flag.d.ts +0 -4
  1105. package/dist/lib/work-context/outbox-quarantine-status-flag.js +0 -7
  1106. package/dist/lib/work-context/prd-sync.d.ts +0 -56
  1107. package/dist/lib/work-context/prd-sync.js +0 -197
  1108. package/dist/lib/work-context/preflight-contract.d.ts +0 -28
  1109. package/dist/lib/work-context/preflight-contract.js +0 -85
  1110. package/dist/lib/work-context/prompt-rebind.d.ts +0 -25
  1111. package/dist/lib/work-context/prompt-rebind.js +0 -85
  1112. package/dist/lib/work-context/windows-acl.d.ts +0 -123
  1113. package/dist/lib/work-context/windows-acl.js +0 -425
  1114. package/dist/lib/workers-registry/read.d.ts +0 -15
  1115. package/dist/lib/workers-registry/read.js +0 -17
  1116. package/dist/native-fast-route.d.ts +0 -7
  1117. package/dist/native-fast-route.js +0 -45
  1118. package/dist/node-network-compat-core.d.ts +0 -12
  1119. package/dist/node-network-compat-core.js +0 -41
  1120. package/dist/node-network-compat-fast.d.ts +0 -7
  1121. package/dist/node-network-compat-fast.js +0 -23
  1122. package/dist/secrets-env-fast-path.d.ts +0 -5
  1123. package/dist/secrets-env-fast-path.js +0 -16
  1124. package/dist/secrets-env-fast-route.d.ts +0 -18
  1125. package/dist/secrets-env-fast-route.js +0 -54
  1126. package/dist/utils/checkpoint-stamp-write-error.d.ts +0 -28
  1127. package/dist/utils/checkpoint-stamp-write-error.js +0 -99
  1128. package/dist/utils/cli-network-lifecycle.d.ts +0 -4
  1129. package/dist/utils/cli-network-lifecycle.js +0 -11
  1130. package/dist/utils/cognito-refresh-sentry.d.ts +0 -3
  1131. package/dist/utils/cognito-refresh-sentry.js +0 -49
  1132. package/dist/utils/console-origin.d.ts +0 -9
  1133. package/dist/utils/console-origin.js +0 -28
  1134. package/dist/utils/core-eval-trigger.d.ts +0 -4
  1135. package/dist/utils/core-eval-trigger.js +0 -88
  1136. package/dist/utils/exclusive-lock.d.ts +0 -32
  1137. package/dist/utils/exclusive-lock.js +0 -75
  1138. package/dist/utils/fast-stream-errors.d.ts +0 -12
  1139. package/dist/utils/fast-stream-errors.js +0 -18
  1140. package/dist/utils/files-browse-acl.d.ts +0 -5
  1141. package/dist/utils/files-browse-acl.js +0 -11
  1142. package/dist/utils/hq-core-yaml.d.ts +0 -10
  1143. package/dist/utils/hq-core-yaml.js +0 -40
  1144. package/dist/utils/hq-root-resolver.d.ts +0 -13
  1145. package/dist/utils/hq-root-resolver.js +0 -103
  1146. package/dist/utils/redact-url.d.ts +0 -14
  1147. package/dist/utils/redact-url.js +0 -218
  1148. package/dist/utils/scaffold-fast-import-guard.d.ts +0 -2
  1149. package/dist/utils/scaffold-fast-import-guard.js +0 -40
  1150. package/dist/utils/scaffold-packlist-guard.d.ts +0 -7
  1151. package/dist/utils/scaffold-packlist-guard.js +0 -23
  1152. package/dist/utils/scaffold-sibling-references.d.ts +0 -22
  1153. package/dist/utils/scaffold-sibling-references.js +0 -156
  1154. package/dist/utils/secret-load-availability.d.ts +0 -8
  1155. package/dist/utils/secret-load-availability.js +0 -54
  1156. package/dist/utils/staged-install.d.ts +0 -34
  1157. package/dist/utils/staged-install.js +0 -346
  1158. package/dist/utils/staged-npm-install.d.ts +0 -16
  1159. package/dist/utils/staged-npm-install.js +0 -264
  1160. package/dist/utils/sync-log-sources.d.ts +0 -15
  1161. package/dist/utils/sync-log-sources.js +0 -36
  1162. package/dist/utils/table-width.d.ts +0 -7
  1163. package/dist/utils/table-width.js +0 -15
  1164. package/dist/utils/update-command-supervisor.cjs +0 -247
  1165. package/dist/utils/upload-author.d.ts +0 -15
  1166. package/dist/utils/upload-author.js +0 -39
  1167. package/dist/utils/version-report.d.ts +0 -27
  1168. package/dist/utils/version-report.js +0 -105
  1169. package/dist/version-request.d.ts +0 -14
  1170. package/dist/version-request.js +0 -36
  1171. package/scripts/mesh-daemon-if-stale.mjs +0 -20
  1172. package/templates/reports/blank.md +0 -3
  1173. package/templates/reports/daily-digest.md +0 -11
  1174. 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