@indigoai-us/hq-cli 5.314.0 → 5.315.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 (1178) hide show
  1. package/CHANGELOG.md +4311 -1
  2. package/README.md +113 -0
  3. package/assets/bot-workers/setup/context/USER-GUIDE.md +404 -0
  4. package/assets/bot-workers/setup/context/quick-reference.md +199 -0
  5. package/assets/bot-workers/setup/skills/agents-and-team.md +167 -0
  6. package/assets/bot-workers/setup/skills/explain-hq.md +35 -0
  7. package/assets/bot-workers/setup/skills/first-company.md +74 -0
  8. package/assets/bot-workers/setup/skills/joining-a-team.md +125 -0
  9. package/assets/bot-workers/setup/skills/pricing.md +92 -0
  10. package/assets/bot-workers/setup/skills/standing-help.md +81 -0
  11. package/assets/bot-workers/setup/skills/your-business.md +281 -0
  12. package/assets/bot-workers/setup/worker.yaml +791 -0
  13. package/assets/lanes-hooks/hq-lanes-drain.json +15 -0
  14. package/assets/lanes-hooks/hq-lanes-drain.mjs +275 -0
  15. package/assets/lanes-hooks/hq-lanes-drain.sh +21 -0
  16. package/assets/lanes-reconcile/hq-lanes-reconcile.service +11 -0
  17. package/assets/lanes-reconcile/hq-lanes-reconcile.timer +12 -0
  18. package/assets/scaffold/.claude/hooks/validate-policy-frontmatter.sh +485 -0
  19. package/assets/scaffold/core/scripts/audit-log.sh +384 -0
  20. package/assets/scaffold/core/scripts/checkpoint-stop-gate.sh +281 -43
  21. package/assets/scaffold/core/scripts/clean-worktree-reconcile-handoff.sh +171 -0
  22. package/assets/scaffold/core/scripts/eval-trigger.sh +193 -0
  23. package/assets/scaffold/core/scripts/git-pack-extension-check.sh +164 -0
  24. package/assets/scaffold/core/scripts/handoff-finalize.sh +688 -0
  25. package/assets/scaffold/core/scripts/handoff-open-steps.sh +81 -0
  26. package/assets/scaffold/core/scripts/handoff-post.sh +252 -0
  27. package/assets/scaffold/core/scripts/hook-lib.sh +345 -50
  28. package/assets/scaffold/core/scripts/hq-delegate-bundle.sh +307 -0
  29. package/assets/scaffold/core/scripts/hq-delegate-grant.sh +252 -0
  30. package/assets/scaffold/core/scripts/hq-delegate-pickup.sh +99 -0
  31. package/assets/scaffold/core/scripts/hq-delegate-publish.sh +91 -0
  32. package/assets/scaffold/core/scripts/hq-delegate-repo.sh +158 -0
  33. package/assets/scaffold/core/scripts/hq-delegate-resolve.sh +145 -0
  34. package/assets/scaffold/core/scripts/hq-delegate-secrets.sh +129 -0
  35. package/assets/scaffold/core/scripts/hq-delegate-send.sh +259 -0
  36. package/assets/scaffold/core/scripts/hq-delegate-transfer.sh +175 -0
  37. package/assets/scaffold/core/scripts/hq-delegate-verify.sh +238 -0
  38. package/assets/scaffold/core/scripts/hq-dm-bind.sh +585 -0
  39. package/assets/scaffold/core/scripts/hq-job-notify.sh +389 -0
  40. package/assets/scaffold/core/scripts/hq-job-probe.sh +835 -0
  41. package/assets/scaffold/core/scripts/hq-job-remediate.sh +359 -0
  42. package/assets/scaffold/core/scripts/hq-job-run.sh +1025 -0
  43. package/assets/scaffold/core/scripts/hq-pin.sh +118 -0
  44. package/assets/scaffold/core/scripts/hq-session.sh +184 -23
  45. package/assets/scaffold/core/scripts/jobs-schedule-parse.sh +310 -0
  46. package/assets/scaffold/core/scripts/jobs-validate.sh +451 -0
  47. package/assets/scaffold/core/scripts/knowledge-prefs.sh +55 -0
  48. package/assets/scaffold/core/scripts/lib/portable.sh +211 -0
  49. package/assets/scaffold/core/scripts/lib/secret-patterns.sh +58 -0
  50. package/assets/scaffold/core/scripts/lib/session-id.sh +3 -2
  51. package/assets/scaffold/core/scripts/lib/session-scope-capability.sh +1 -1
  52. package/assets/scaffold/core/scripts/lib/work-mesh-enqueue.sh +2 -1
  53. package/assets/scaffold/core/scripts/lib/work-mesh-live-hook.sh +378 -0
  54. package/assets/scaffold/core/scripts/lib/work-mesh-live-rebind.sh +141 -0
  55. package/assets/scaffold/core/scripts/migrate-policy-triggers.sh +378 -0
  56. package/assets/scaffold/core/scripts/ontology-audience-grant.sh +81 -0
  57. package/assets/scaffold/core/scripts/ontology-brief.mjs +93 -0
  58. package/assets/scaffold/core/scripts/ontology-candidate.sh +100 -0
  59. package/assets/scaffold/core/scripts/ontology-garden.mjs +238 -0
  60. package/assets/scaffold/core/scripts/ontology-source-worklist.sh +79 -0
  61. package/assets/scaffold/core/scripts/outpost-jobs-reconcile.sh +834 -0
  62. package/assets/scaffold/core/scripts/policy-age-report.sh +156 -0
  63. package/assets/scaffold/core/scripts/policy-retire.sh +199 -0
  64. package/assets/scaffold/core/scripts/qmd-reindex-after-sync.sh +10 -87
  65. package/assets/scaffold/core/scripts/qmd-reindex-bg.sh +40 -0
  66. package/assets/scaffold/core/scripts/read-policy-frontmatter.sh +32 -0
  67. package/assets/scaffold/core/scripts/rebuild-company-knowledge-index.sh +36 -3
  68. package/assets/scaffold/core/scripts/rebuild-projects-index.sh +99 -12
  69. package/assets/scaffold/core/scripts/refresh-vault-access.sh +188 -0
  70. package/assets/scaffold/core/scripts/register-project.sh +262 -0
  71. package/assets/scaffold/core/scripts/resolve-company.sh +199 -0
  72. package/assets/scaffold/core/scripts/resume-thread-lock.sh +285 -0
  73. package/assets/scaffold/core/scripts/source-yaml-validate.sh +36 -0
  74. package/assets/scaffold/core/scripts/token-usage-report.sh +81 -20
  75. package/assets/scaffold/core/scripts/verify-story-deliverables.sh +148 -0
  76. package/assets/scaffold/core/scripts/work-mesh-live-bind-trusted.sh +152 -0
  77. package/assets/scaffold/core/scripts/work-mesh-live-rebind.sh +59 -0
  78. package/assets/scaffold/core/scripts/worktree-gc.sh +362 -0
  79. package/contracts/preflight/v1/fixtures.json +87 -0
  80. package/contracts/preflight/v1/schema.json +58 -0
  81. package/dist/bin/hq-auth-refresh.d.ts +2 -0
  82. package/dist/bin/hq-auth-refresh.js +12 -6
  83. package/dist/command-catalog.generated.d.ts +10753 -0
  84. package/dist/command-catalog.generated.js +13859 -0
  85. package/dist/command-registration-plan.d.ts +474 -0
  86. package/dist/command-registration-plan.js +136 -0
  87. package/dist/commands/__fixtures__/access-vault.d.ts +2 -0
  88. package/dist/commands/__fixtures__/access-vault.js +1 -1
  89. package/dist/commands/_patterns.d.ts +16 -0
  90. package/dist/commands/_patterns.js +20 -3
  91. package/dist/commands/access.d.ts +2 -1
  92. package/dist/commands/access.js +58 -49
  93. package/dist/commands/agent-enroll.d.ts +146 -0
  94. package/dist/commands/agent-enroll.js +401 -0
  95. package/dist/commands/agent-inbox.d.ts +9 -0
  96. package/dist/commands/agent-inbox.js +102 -0
  97. package/dist/commands/agent-kit.d.ts +87 -0
  98. package/dist/commands/agent-kit.js +480 -0
  99. package/dist/commands/agent-mcp.d.ts +24 -0
  100. package/dist/commands/agent-mcp.js +127 -0
  101. package/dist/commands/agent-probe.d.ts +77 -0
  102. package/dist/commands/agent-probe.js +335 -0
  103. package/dist/commands/agent.d.ts +13 -0
  104. package/dist/commands/agent.js +40 -0
  105. package/dist/commands/agents.d.ts +106 -4
  106. package/dist/commands/agents.js +924 -45
  107. package/dist/commands/auth.d.ts +1 -0
  108. package/dist/commands/auth.js +189 -19
  109. package/dist/commands/billing-sponsor.d.ts +83 -0
  110. package/dist/commands/billing-sponsor.js +344 -0
  111. package/dist/commands/billing.d.ts +3 -0
  112. package/dist/commands/billing.js +6 -1
  113. package/dist/commands/bot-companies.d.ts +40 -0
  114. package/dist/commands/bot-companies.js +64 -0
  115. package/dist/commands/bot-continuity.d.ts +28 -0
  116. package/dist/commands/bot-continuity.js +68 -0
  117. package/dist/commands/bot-jobs.d.ts +127 -0
  118. package/dist/commands/bot-jobs.js +454 -0
  119. package/dist/commands/bot.d.ts +278 -0
  120. package/dist/commands/bot.js +1982 -0
  121. package/dist/commands/channels.js +56 -1
  122. package/dist/commands/cloud-demote.js +3 -2
  123. package/dist/commands/cloud-provision.d.ts +14 -0
  124. package/dist/commands/cloud-provision.js +232 -58
  125. package/dist/commands/cloud-retire.d.ts +51 -0
  126. package/dist/commands/cloud-retire.js +154 -0
  127. package/dist/commands/cloud.d.ts +49 -15
  128. package/dist/commands/cloud.js +357 -122
  129. package/dist/commands/company-rename-flag.d.ts +4 -0
  130. package/dist/commands/company-rename-flag.js +7 -0
  131. package/dist/commands/company-rename.d.ts +4 -0
  132. package/dist/commands/company-rename.js +90 -0
  133. package/dist/commands/company-transfer.d.ts +4 -28
  134. package/dist/commands/company-transfer.js +5 -49
  135. package/dist/commands/company.js +68 -3
  136. package/dist/commands/core-audit-log-native.d.ts +9 -0
  137. package/dist/commands/core-audit-log-native.js +257 -0
  138. package/dist/commands/core-checkpoint-gate-setting.d.ts +59 -0
  139. package/dist/commands/core-checkpoint-gate-setting.js +163 -0
  140. package/dist/commands/core-checkpoint-stop-gate-native.d.ts +34 -0
  141. package/dist/commands/core-checkpoint-stop-gate-native.js +725 -0
  142. package/dist/commands/core-checkpoint.d.ts +19 -9
  143. package/dist/commands/core-checkpoint.js +301 -37
  144. package/dist/commands/core-command-catalog.d.ts +34 -0
  145. package/dist/commands/core-command-catalog.js +62 -0
  146. package/dist/commands/core-company-index-scope-flag.d.ts +3 -0
  147. package/dist/commands/core-company-index-scope-flag.js +6 -0
  148. package/dist/commands/core-delegate-w1b.d.ts +10 -0
  149. package/dist/commands/core-delegate-w1b.js +1219 -0
  150. package/dist/commands/core-delegate.d.ts +46 -0
  151. package/dist/commands/core-delegate.js +1040 -0
  152. package/dist/commands/core-dm-bind-native.d.ts +32 -0
  153. package/dist/commands/core-dm-bind-native.js +668 -0
  154. package/dist/commands/core-eval-trigger-native.d.ts +4 -0
  155. package/dist/commands/core-eval-trigger-native.js +12 -0
  156. package/dist/commands/core-git-pack-extension-check-native.d.ts +22 -0
  157. package/dist/commands/core-git-pack-extension-check-native.js +190 -0
  158. package/dist/commands/core-handoff-fast.d.ts +18 -0
  159. package/dist/commands/core-handoff-fast.js +104 -0
  160. package/dist/commands/core-handoff-open-steps.d.ts +21 -0
  161. package/dist/commands/core-handoff-open-steps.js +264 -0
  162. package/dist/commands/core-handoff.d.ts +24 -0
  163. package/dist/commands/core-handoff.js +1144 -0
  164. package/dist/commands/core-hq-session-native.d.ts +39 -0
  165. package/dist/commands/core-hq-session-native.js +579 -0
  166. package/dist/commands/core-job-native-utils.d.ts +6 -0
  167. package/dist/commands/core-job-native-utils.js +80 -0
  168. package/dist/commands/core-job-native.d.ts +5 -0
  169. package/dist/commands/core-job-native.js +16 -0
  170. package/dist/commands/core-job-notify-native.d.ts +36 -0
  171. package/dist/commands/core-job-notify-native.js +359 -0
  172. package/dist/commands/core-job-probe-native.d.ts +45 -0
  173. package/dist/commands/core-job-probe-native.js +564 -0
  174. package/dist/commands/core-job-remediate-native.d.ts +26 -0
  175. package/dist/commands/core-job-remediate-native.js +374 -0
  176. package/dist/commands/core-job-remote-launcher.d.ts +7 -0
  177. package/dist/commands/core-job-remote-launcher.js +51 -0
  178. package/dist/commands/core-job-run-native.d.ts +47 -0
  179. package/dist/commands/core-job-run-native.js +1215 -0
  180. package/dist/commands/core-jobs-native.d.ts +25 -0
  181. package/dist/commands/core-jobs-native.js +1339 -0
  182. package/dist/commands/core-knowledge-prefs.d.ts +11 -0
  183. package/dist/commands/core-knowledge-prefs.js +137 -0
  184. package/dist/commands/core-migrate-policy-triggers-native.d.ts +21 -0
  185. package/dist/commands/core-migrate-policy-triggers-native.js +374 -0
  186. package/dist/commands/core-native-handoff-flag.d.ts +4 -0
  187. package/dist/commands/core-native-handoff-flag.js +7 -0
  188. package/dist/commands/core-native-hook-helper-commands.d.ts +4 -0
  189. package/dist/commands/core-native-hook-helper-commands.js +56 -0
  190. package/dist/commands/core-native-hook-helpers-flag.d.ts +4 -0
  191. package/dist/commands/core-native-hook-helpers-flag.js +7 -0
  192. package/dist/commands/core-native-jobs-flag.d.ts +4 -0
  193. package/dist/commands/core-native-jobs-flag.js +7 -0
  194. package/dist/commands/core-native-policy-flag.d.ts +9 -0
  195. package/dist/commands/core-native-policy-flag.js +12 -0
  196. package/dist/commands/core-native-session-flag.d.ts +4 -0
  197. package/dist/commands/core-native-session-flag.js +7 -0
  198. package/dist/commands/core-native-utilities-flag.d.ts +4 -0
  199. package/dist/commands/core-native-utilities-flag.js +7 -0
  200. package/dist/commands/core-native-utilities.d.ts +29 -0
  201. package/dist/commands/core-native-utilities.js +54 -0
  202. package/dist/commands/core-native-worker-skills-flag.d.ts +4 -0
  203. package/dist/commands/core-native-worker-skills-flag.js +7 -0
  204. package/dist/commands/core-ontology-native.d.ts +17 -0
  205. package/dist/commands/core-ontology-native.js +916 -0
  206. package/dist/commands/core-ontology.d.ts +66 -0
  207. package/dist/commands/core-ontology.js +430 -0
  208. package/dist/commands/core-pin-native.d.ts +14 -0
  209. package/dist/commands/core-pin-native.js +236 -0
  210. package/dist/commands/core-policy-frontmatter.d.ts +8 -0
  211. package/dist/commands/core-policy-frontmatter.js +52 -0
  212. package/dist/commands/core-policy.d.ts +14 -0
  213. package/dist/commands/core-policy.js +1018 -0
  214. package/dist/commands/core-refresh-vault-access-native.d.ts +20 -0
  215. package/dist/commands/core-refresh-vault-access-native.js +229 -0
  216. package/dist/commands/core-register-project-native.d.ts +30 -0
  217. package/dist/commands/core-register-project-native.js +347 -0
  218. package/dist/commands/core-resolve-company-command.d.ts +4 -0
  219. package/dist/commands/core-resolve-company-command.js +42 -0
  220. package/dist/commands/core-resolve-company-native.d.ts +28 -0
  221. package/dist/commands/core-resolve-company-native.js +408 -0
  222. package/dist/commands/core-work-mesh-bind-trusted-native.d.ts +32 -0
  223. package/dist/commands/core-work-mesh-bind-trusted-native.js +190 -0
  224. package/dist/commands/core-work-mesh-live-rebind-native.d.ts +18 -0
  225. package/dist/commands/core-work-mesh-live-rebind-native.js +262 -0
  226. package/dist/commands/core-worker-lint-native.d.ts +4 -0
  227. package/dist/commands/core-worker-lint-native.js +160 -0
  228. package/dist/commands/core-worker-share-native.d.ts +4 -0
  229. package/dist/commands/core-worker-share-native.js +260 -0
  230. package/dist/commands/core-worker-skills-command.d.ts +8 -0
  231. package/dist/commands/core-worker-skills-command.js +33 -0
  232. package/dist/commands/core-worker-skills-runtime.d.ts +33 -0
  233. package/dist/commands/core-worker-skills-runtime.js +86 -0
  234. package/dist/commands/core.d.ts +4 -0
  235. package/dist/commands/core.js +277 -80
  236. package/dist/commands/crm.js +52 -3
  237. package/dist/commands/daemon.d.ts +63 -0
  238. package/dist/commands/daemon.js +877 -0
  239. package/dist/commands/db-provision.js +4 -4
  240. package/dist/commands/db-sql.js +7 -21
  241. package/dist/commands/deploy-comments.d.ts +3 -0
  242. package/dist/commands/deploy-comments.js +162 -0
  243. package/dist/commands/dm.d.ts +119 -12
  244. package/dist/commands/dm.js +388 -38
  245. package/dist/commands/doctor.d.ts +12 -0
  246. package/dist/commands/doctor.js +158 -12
  247. package/dist/commands/feedback.d.ts +6 -0
  248. package/dist/commands/feedback.js +86 -37
  249. package/dist/commands/files-browse.d.ts +32 -12
  250. package/dist/commands/files-browse.js +176 -60
  251. package/dist/commands/files.d.ts +17 -0
  252. package/dist/commands/files.js +300 -47
  253. package/dist/commands/group-grants.js +3 -2
  254. package/dist/commands/groups.js +6 -5
  255. package/dist/commands/index-cmd.d.ts +19 -1
  256. package/dist/commands/index-cmd.js +74 -7
  257. package/dist/commands/integrations-api.d.ts +15 -10
  258. package/dist/commands/integrations-api.js +27 -22
  259. package/dist/commands/integrations-connect.d.ts +51 -13
  260. package/dist/commands/integrations-connect.js +86 -71
  261. package/dist/commands/integrations-core.d.ts +6 -6
  262. package/dist/commands/integrations-core.js +25 -11
  263. package/dist/commands/integrations-import.d.ts +1 -1
  264. package/dist/commands/integrations-import.js +43 -24
  265. package/dist/commands/integrations-manage.js +20 -13
  266. package/dist/commands/integrations.d.ts +8 -0
  267. package/dist/commands/integrations.js +94 -7
  268. package/dist/commands/lanes-accounts.d.ts +28 -0
  269. package/dist/commands/lanes-accounts.js +595 -0
  270. package/dist/commands/lanes-autopilot.d.ts +11 -0
  271. package/dist/commands/lanes-autopilot.js +336 -0
  272. package/dist/commands/lanes-checks.d.ts +51 -0
  273. package/dist/commands/lanes-checks.js +941 -0
  274. package/dist/commands/lanes-hold.d.ts +43 -0
  275. package/dist/commands/lanes-hold.js +655 -0
  276. package/dist/commands/lanes-keep-alive-audit.d.ts +10 -0
  277. package/dist/commands/lanes-keep-alive-audit.js +19 -0
  278. package/dist/commands/lanes-kpis.d.ts +11 -0
  279. package/dist/commands/lanes-kpis.js +34 -0
  280. package/dist/commands/lanes-message.d.ts +9 -0
  281. package/dist/commands/lanes-message.js +946 -0
  282. package/dist/commands/lanes-move.d.ts +12 -0
  283. package/dist/commands/lanes-move.js +397 -0
  284. package/dist/commands/lanes-questions.d.ts +36 -0
  285. package/dist/commands/lanes-questions.js +1005 -0
  286. package/dist/commands/lanes-report.d.ts +11 -0
  287. package/dist/commands/lanes-report.js +333 -0
  288. package/dist/commands/lanes-resume.d.ts +6 -0
  289. package/dist/commands/lanes-resume.js +564 -0
  290. package/dist/commands/lanes-review.d.ts +10 -0
  291. package/dist/commands/lanes-review.js +56 -0
  292. package/dist/commands/lanes-shared.d.ts +449 -0
  293. package/dist/commands/lanes-shared.js +170 -0
  294. package/dist/commands/lanes-stories.d.ts +15 -0
  295. package/dist/commands/lanes-stories.js +347 -0
  296. package/dist/commands/lanes-watch.d.ts +7 -0
  297. package/dist/commands/lanes-watch.js +216 -0
  298. package/dist/commands/lanes.d.ts +149 -0
  299. package/dist/commands/lanes.js +8983 -0
  300. package/dist/commands/login.js +49 -6
  301. package/dist/commands/mcp-registration.d.ts +32 -25
  302. package/dist/commands/mcp-registration.js +256 -23
  303. package/dist/commands/mcp-status.js +1 -0
  304. package/dist/commands/meetings.js +55 -34
  305. package/dist/commands/members.js +5 -1
  306. package/dist/commands/mesh.d.ts +11 -0
  307. package/dist/commands/mesh.js +1086 -76
  308. package/dist/commands/monitor.d.ts +58 -0
  309. package/dist/commands/monitor.js +980 -0
  310. package/dist/commands/onboard-bot-membership.d.ts +32 -0
  311. package/dist/commands/onboard-bot-membership.js +40 -0
  312. package/dist/commands/onboard-create-identity.d.ts +26 -0
  313. package/dist/commands/onboard-create-identity.js +23 -0
  314. package/dist/commands/onboard-identity-guard.d.ts +1 -1
  315. package/dist/commands/onboard.js +24 -5
  316. package/dist/commands/outpost-pruner.d.ts +3 -0
  317. package/dist/commands/outpost-pruner.js +125 -0
  318. package/dist/commands/pack-install.js +3 -1
  319. package/dist/commands/packs.js +11 -1
  320. package/dist/commands/people.d.ts +4 -0
  321. package/dist/commands/people.js +37 -3
  322. package/dist/commands/personal-connector-settings-flag.d.ts +4 -0
  323. package/dist/commands/personal-connector-settings-flag.js +7 -0
  324. package/dist/commands/personal-targeted-push-flag.d.ts +4 -0
  325. package/dist/commands/personal-targeted-push-flag.js +7 -0
  326. package/dist/commands/personal-targeted-push-paths.d.ts +3 -0
  327. package/dist/commands/personal-targeted-push-paths.js +67 -0
  328. package/dist/commands/publish.d.ts +8 -1
  329. package/dist/commands/publish.js +17 -4
  330. package/dist/commands/reindex.js +56 -6
  331. package/dist/commands/report.d.ts +19 -0
  332. package/dist/commands/report.js +537 -0
  333. package/dist/commands/rescue.d.ts +4 -0
  334. package/dist/commands/rescue.js +27 -17
  335. package/dist/commands/run-feature-telemetry.d.ts +3 -0
  336. package/dist/commands/run-feature-telemetry.js +6 -0
  337. package/dist/commands/run.js +18 -4
  338. package/dist/commands/safe-extract.d.ts +11 -2
  339. package/dist/commands/safe-extract.js +36 -8
  340. package/dist/commands/secrets.d.ts +20 -2
  341. package/dist/commands/secrets.js +175 -71
  342. package/dist/commands/skill.d.ts +35 -4
  343. package/dist/commands/skill.js +357 -18
  344. package/dist/commands/staff/reset-test-account.d.ts +110 -0
  345. package/dist/commands/staff/reset-test-account.js +268 -0
  346. package/dist/commands/staff/test-account.d.ts +51 -0
  347. package/dist/commands/staff/test-account.js +196 -0
  348. package/dist/commands/sync-mode.d.ts +11 -0
  349. package/dist/commands/sync-mode.js +30 -0
  350. package/dist/commands/sync-narrow.js +36 -5
  351. package/dist/commands/team-sync.js +71 -10
  352. package/dist/commands/update.js +6 -0
  353. package/dist/commands/vault-retention-flag.d.ts +3 -0
  354. package/dist/commands/vault-retention-flag.js +9 -0
  355. package/dist/commands/vault-retention.d.ts +11 -0
  356. package/dist/commands/vault-retention.js +69 -0
  357. package/dist/commands/version.d.ts +10 -0
  358. package/dist/commands/version.js +11 -0
  359. package/dist/commands/whoami.d.ts +22 -0
  360. package/dist/commands/whoami.js +137 -4
  361. package/dist/commands/workers.d.ts +2 -14
  362. package/dist/commands/workers.js +7 -10
  363. package/dist/fast-core.d.ts +6 -7
  364. package/dist/fast-core.js +87 -24
  365. package/dist/fast-scaffold.d.ts +86 -0
  366. package/dist/fast-scaffold.js +364 -0
  367. package/dist/index.d.ts +3 -4
  368. package/dist/index.js +59 -9
  369. package/dist/lanes-drain-hook.d.ts +14 -0
  370. package/dist/lanes-drain-hook.js +203 -0
  371. package/dist/lazy-commands.d.ts +20 -44
  372. package/dist/lazy-commands.js +60 -58
  373. package/dist/lib/agent-kit/adopt-identity.d.ts +27 -0
  374. package/dist/lib/agent-kit/adopt-identity.js +60 -0
  375. package/dist/lib/agent-kit/attachment-download.d.ts +24 -0
  376. package/dist/lib/agent-kit/attachment-download.js +47 -0
  377. package/dist/lib/agent-kit/creds.d.ts +106 -0
  378. package/dist/lib/agent-kit/creds.js +163 -0
  379. package/dist/lib/agent-kit/fallback.d.ts +78 -0
  380. package/dist/lib/agent-kit/fallback.js +210 -0
  381. package/dist/lib/agent-kit/inbox-state.d.ts +83 -0
  382. package/dist/lib/agent-kit/inbox-state.js +159 -0
  383. package/dist/lib/agent-kit/kit-config.d.ts +56 -0
  384. package/dist/lib/agent-kit/kit-config.js +65 -0
  385. package/dist/lib/agent-kit/log.d.ts +16 -0
  386. package/dist/lib/agent-kit/log.js +46 -0
  387. package/dist/lib/agent-kit/mcp/attachments.d.ts +126 -0
  388. package/dist/lib/agent-kit/mcp/attachments.js +222 -0
  389. package/dist/lib/agent-kit/mcp/jsonrpc.d.ts +75 -0
  390. package/dist/lib/agent-kit/mcp/jsonrpc.js +164 -0
  391. package/dist/lib/agent-kit/mcp/tools.d.ts +64 -0
  392. package/dist/lib/agent-kit/mcp/tools.js +397 -0
  393. package/dist/lib/agent-kit/paths.d.ts +65 -0
  394. package/dist/lib/agent-kit/paths.js +118 -0
  395. package/dist/lib/agent-kit/private-file.d.ts +29 -0
  396. package/dist/lib/agent-kit/private-file.js +91 -0
  397. package/dist/lib/agent-kit/run/heartbeat.d.ts +72 -0
  398. package/dist/lib/agent-kit/run/heartbeat.js +128 -0
  399. package/dist/lib/agent-kit/run/inbox.d.ts +76 -0
  400. package/dist/lib/agent-kit/run/inbox.js +205 -0
  401. package/dist/lib/agent-kit/run/supervisor.d.ts +35 -0
  402. package/dist/lib/agent-kit/run/supervisor.js +85 -0
  403. package/dist/lib/agent-kit/run/sync.d.ts +33 -0
  404. package/dist/lib/agent-kit/run/sync.js +58 -0
  405. package/dist/lib/agent-kit/services.d.ts +31 -0
  406. package/dist/lib/agent-kit/services.js +55 -0
  407. package/dist/lib/agent-kit/skills.d.ts +18 -0
  408. package/dist/lib/agent-kit/skills.js +151 -0
  409. package/dist/lib/agent-kit/wake.d.ts +83 -0
  410. package/dist/lib/agent-kit/wake.js +243 -0
  411. package/dist/lib/agents/model-catalog.d.ts +62 -0
  412. package/dist/lib/agents/model-catalog.js +275 -0
  413. package/dist/lib/auth-login-provider-state.d.ts +8 -0
  414. package/dist/lib/auth-login-provider-state.js +63 -0
  415. package/dist/lib/aws-sdk-node-warning-output.d.ts +12 -0
  416. package/dist/lib/aws-sdk-node-warning-output.js +22 -0
  417. package/dist/lib/billing/free-month.d.ts +18 -0
  418. package/dist/lib/billing/free-month.js +31 -0
  419. package/dist/lib/billing/plan-limit-refusals.d.ts +69 -0
  420. package/dist/lib/billing/plan-limit-refusals.js +187 -0
  421. package/dist/lib/billing/plan-limit-upgrade-url.d.ts +11 -0
  422. package/dist/lib/billing/plan-limit-upgrade-url.js +66 -0
  423. package/dist/lib/billing/plan-lock.d.ts +143 -0
  424. package/dist/lib/billing/plan-lock.js +439 -0
  425. package/dist/lib/bot/api.d.ts +349 -0
  426. package/dist/lib/bot/api.js +316 -0
  427. package/dist/lib/bot/attachments.d.ts +45 -0
  428. package/dist/lib/bot/attachments.js +89 -0
  429. package/dist/lib/bot/cli-update.d.ts +138 -0
  430. package/dist/lib/bot/cli-update.js +278 -0
  431. package/dist/lib/bot/company-bind.d.ts +27 -0
  432. package/dist/lib/bot/company-bind.js +62 -0
  433. package/dist/lib/bot/config.d.ts +153 -0
  434. package/dist/lib/bot/config.js +233 -0
  435. package/dist/lib/bot/continuity-download.d.ts +28 -0
  436. package/dist/lib/bot/continuity-download.js +75 -0
  437. package/dist/lib/bot/continuity-install.d.ts +14 -0
  438. package/dist/lib/bot/continuity-install.js +101 -0
  439. package/dist/lib/bot/continuity.d.ts +67 -0
  440. package/dist/lib/bot/continuity.js +301 -0
  441. package/dist/lib/bot/creds.d.ts +24 -0
  442. package/dist/lib/bot/creds.js +51 -0
  443. package/dist/lib/bot/daemon.d.ts +173 -0
  444. package/dist/lib/bot/daemon.js +552 -0
  445. package/dist/lib/bot/inbox-poll-backoff-flag.d.ts +24 -0
  446. package/dist/lib/bot/inbox-poll-backoff-flag.js +135 -0
  447. package/dist/lib/bot/inbox-state.d.ts +18 -0
  448. package/dist/lib/bot/inbox-state.js +51 -0
  449. package/dist/lib/bot/index.d.ts +23 -0
  450. package/dist/lib/bot/index.js +23 -0
  451. package/dist/lib/bot/inflight.d.ts +119 -0
  452. package/dist/lib/bot/inflight.js +83 -0
  453. package/dist/lib/bot/job-completions.d.ts +89 -0
  454. package/dist/lib/bot/job-completions.js +132 -0
  455. package/dist/lib/bot/job-run.d.ts +109 -0
  456. package/dist/lib/bot/job-run.js +246 -0
  457. package/dist/lib/bot/local-config.d.ts +61 -0
  458. package/dist/lib/bot/local-config.js +145 -0
  459. package/dist/lib/bot/local-jobs.d.ts +89 -0
  460. package/dist/lib/bot/local-jobs.js +459 -0
  461. package/dist/lib/bot/local-name.d.ts +54 -0
  462. package/dist/lib/bot/local-name.js +114 -0
  463. package/dist/lib/bot/log.d.ts +13 -0
  464. package/dist/lib/bot/log.js +59 -0
  465. package/dist/lib/bot/owner-context.d.ts +79 -0
  466. package/dist/lib/bot/owner-context.js +175 -0
  467. package/dist/lib/bot/paths.d.ts +76 -0
  468. package/dist/lib/bot/paths.js +131 -0
  469. package/dist/lib/bot/progress.d.ts +132 -0
  470. package/dist/lib/bot/progress.js +289 -0
  471. package/dist/lib/bot/promote.d.ts +16 -0
  472. package/dist/lib/bot/promote.js +106 -0
  473. package/dist/lib/bot/promotion-hold.d.ts +24 -0
  474. package/dist/lib/bot/promotion-hold.js +103 -0
  475. package/dist/lib/bot/promotion-receipt.d.ts +9 -0
  476. package/dist/lib/bot/promotion-receipt.js +56 -0
  477. package/dist/lib/bot/promotion-upload.d.ts +16 -0
  478. package/dist/lib/bot/promotion-upload.js +80 -0
  479. package/dist/lib/bot/prompt.d.ts +136 -0
  480. package/dist/lib/bot/prompt.js +433 -0
  481. package/dist/lib/bot/room-policy.d.ts +63 -0
  482. package/dist/lib/bot/room-policy.js +91 -0
  483. package/dist/lib/bot/run.d.ts +217 -0
  484. package/dist/lib/bot/run.js +1869 -0
  485. package/dist/lib/bot/runnable.d.ts +51 -0
  486. package/dist/lib/bot/runnable.js +65 -0
  487. package/dist/lib/bot/runtime/claude.d.ts +50 -0
  488. package/dist/lib/bot/runtime/claude.js +170 -0
  489. package/dist/lib/bot/runtime/codex.d.ts +28 -0
  490. package/dist/lib/bot/runtime/codex.js +153 -0
  491. package/dist/lib/bot/runtime/grok-acp.d.ts +40 -0
  492. package/dist/lib/bot/runtime/grok-acp.js +265 -0
  493. package/dist/lib/bot/runtime/grok.d.ts +41 -0
  494. package/dist/lib/bot/runtime/grok.js +169 -0
  495. package/dist/lib/bot/runtime/index.d.ts +36 -0
  496. package/dist/lib/bot/runtime/index.js +417 -0
  497. package/dist/lib/bot/runtime/messages-stream.d.ts +56 -0
  498. package/dist/lib/bot/runtime/messages-stream.js +194 -0
  499. package/dist/lib/bot/runtime/sanitize.d.ts +18 -0
  500. package/dist/lib/bot/runtime/sanitize.js +28 -0
  501. package/dist/lib/bot/runtime/types.d.ts +159 -0
  502. package/dist/lib/bot/runtime/types.js +51 -0
  503. package/dist/lib/bot/runtime/windows.d.ts +10 -0
  504. package/dist/lib/bot/runtime/windows.js +53 -0
  505. package/dist/lib/bot/runtime-sign-in.d.ts +24 -0
  506. package/dist/lib/bot/runtime-sign-in.js +31 -0
  507. package/dist/lib/bot/scaffold.d.ts +38 -0
  508. package/dist/lib/bot/scaffold.js +94 -0
  509. package/dist/lib/bot/self-heal.d.ts +52 -0
  510. package/dist/lib/bot/self-heal.js +79 -0
  511. package/dist/lib/bot/self-process.d.ts +19 -0
  512. package/dist/lib/bot/self-process.js +35 -0
  513. package/dist/lib/bot/session.d.ts +19 -0
  514. package/dist/lib/bot/session.js +39 -0
  515. package/dist/lib/bot/setup-explain.d.ts +64 -0
  516. package/dist/lib/bot/setup-explain.js +141 -0
  517. package/dist/lib/bot/split.d.ts +32 -0
  518. package/dist/lib/bot/split.js +241 -0
  519. package/dist/lib/bot/status.d.ts +57 -0
  520. package/dist/lib/bot/status.js +66 -0
  521. package/dist/lib/bot/worker-source.d.ts +66 -0
  522. package/dist/lib/bot/worker-source.js +283 -0
  523. package/dist/lib/checkpoint-ontology/aliases.d.ts +17 -0
  524. package/dist/lib/checkpoint-ontology/aliases.js +44 -0
  525. package/dist/lib/checkpoint-ontology/apply.d.ts +110 -0
  526. package/dist/lib/checkpoint-ontology/apply.js +777 -0
  527. package/dist/lib/checkpoint-ontology/company-brief.d.ts +18 -0
  528. package/dist/lib/checkpoint-ontology/company-brief.js +337 -0
  529. package/dist/lib/checkpoint-ontology/company.d.ts +44 -0
  530. package/dist/lib/checkpoint-ontology/company.js +118 -0
  531. package/dist/lib/checkpoint-ontology/drop-aliases.d.ts +41 -0
  532. package/dist/lib/checkpoint-ontology/drop-aliases.js +76 -0
  533. package/dist/lib/checkpoint-ontology/entity-file.d.ts +109 -0
  534. package/dist/lib/checkpoint-ontology/entity-file.js +371 -0
  535. package/dist/lib/checkpoint-ontology/identity.d.ts +38 -0
  536. package/dist/lib/checkpoint-ontology/identity.js +95 -0
  537. package/dist/lib/checkpoint-ontology/merge-copies.d.ts +199 -0
  538. package/dist/lib/checkpoint-ontology/merge-copies.js +1086 -0
  539. package/dist/lib/checkpoint-ontology/multi-writer.d.ts +101 -0
  540. package/dist/lib/checkpoint-ontology/multi-writer.js +394 -0
  541. package/dist/lib/checkpoint-ontology/plan.d.ts +193 -0
  542. package/dist/lib/checkpoint-ontology/plan.js +504 -0
  543. package/dist/lib/checkpoint-ontology/queued-touches.d.ts +29 -0
  544. package/dist/lib/checkpoint-ontology/queued-touches.js +193 -0
  545. package/dist/lib/checkpoint-ontology/sync-client.d.ts +38 -0
  546. package/dist/lib/checkpoint-ontology/sync-client.js +84 -0
  547. package/dist/lib/checkpoint-ontology/tree.d.ts +55 -0
  548. package/dist/lib/checkpoint-ontology/tree.js +198 -0
  549. package/dist/lib/company-errors-sdk-warning-flag.d.ts +5 -0
  550. package/dist/lib/company-errors-sdk-warning-flag.js +8 -0
  551. package/dist/lib/company-skill-wrapper.d.ts +1 -0
  552. package/dist/lib/company-skill-wrapper.js +121 -29
  553. package/dist/lib/core-utils/codex-skill-bridge.d.ts +2 -1
  554. package/dist/lib/core-utils/hook-timeout-debug-context-flag.d.ts +20 -0
  555. package/dist/lib/core-utils/hook-timeout-debug-context-flag.js +81 -0
  556. package/dist/lib/core-utils/jq-json-serializer.d.ts +5 -0
  557. package/dist/lib/core-utils/jq-json-serializer.js +10 -0
  558. package/dist/lib/core-utils/qmd-reindex-after-sync.d.ts +14 -1
  559. package/dist/lib/core-utils/qmd-reindex-after-sync.js +101 -17
  560. package/dist/lib/core-utils/secret-patterns.d.ts +43 -0
  561. package/dist/lib/core-utils/secret-patterns.js +34 -0
  562. package/dist/lib/core-utils/sentry-report.d.ts +114 -0
  563. package/dist/lib/core-utils/sentry-report.js +1055 -0
  564. package/dist/lib/core-utils/soft-timeout.js +1 -1
  565. package/dist/lib/core-utils/timeout-guard-native.d.ts +7 -0
  566. package/dist/lib/core-utils/timeout-guard-native.js +40 -0
  567. package/dist/lib/core-utils/timeout-guard.d.ts +3 -3
  568. package/dist/lib/core-utils/timeout-guard.js +28 -13
  569. package/dist/lib/core-utils/token-usage-report.js +17 -3
  570. package/dist/lib/core-utils/worktree-resume.d.ts +20 -0
  571. package/dist/lib/core-utils/worktree-resume.js +1198 -0
  572. package/dist/lib/daemon/catalog.d.ts +134 -0
  573. package/dist/lib/daemon/catalog.js +358 -0
  574. package/dist/lib/daemon/config.d.ts +35 -0
  575. package/dist/lib/daemon/config.js +108 -0
  576. package/dist/lib/daemon/flag.d.ts +25 -0
  577. package/dist/lib/daemon/flag.js +59 -0
  578. package/dist/lib/daemon/handoff.d.ts +56 -0
  579. package/dist/lib/daemon/handoff.js +161 -0
  580. package/dist/lib/daemon/hq-cloud.d.ts +79 -0
  581. package/dist/lib/daemon/hq-cloud.js +183 -0
  582. package/dist/lib/daemon/install.d.ts +85 -0
  583. package/dist/lib/daemon/install.js +320 -0
  584. package/dist/lib/daemon/legacy-sync-env.d.ts +10 -0
  585. package/dist/lib/daemon/legacy-sync-env.js +58 -0
  586. package/dist/lib/daemon/legacy.d.ts +45 -0
  587. package/dist/lib/daemon/legacy.js +133 -0
  588. package/dist/lib/daemon/lock.d.ts +47 -0
  589. package/dist/lib/daemon/lock.js +138 -0
  590. package/dist/lib/daemon/machine-type.d.ts +50 -0
  591. package/dist/lib/daemon/machine-type.js +159 -0
  592. package/dist/lib/daemon/migrate.d.ts +77 -0
  593. package/dist/lib/daemon/migrate.js +265 -0
  594. package/dist/lib/daemon/paths.d.ts +24 -0
  595. package/dist/lib/daemon/paths.js +43 -0
  596. package/dist/lib/daemon/protocol-tail.d.ts +33 -0
  597. package/dist/lib/daemon/protocol-tail.js +131 -0
  598. package/dist/lib/daemon/remote-control.d.ts +74 -0
  599. package/dist/lib/daemon/remote-control.js +153 -0
  600. package/dist/lib/daemon/requests.d.ts +28 -0
  601. package/dist/lib/daemon/requests.js +65 -0
  602. package/dist/lib/daemon/run.d.ts +79 -0
  603. package/dist/lib/daemon/run.js +755 -0
  604. package/dist/lib/daemon/succession.d.ts +118 -0
  605. package/dist/lib/daemon/succession.js +263 -0
  606. package/dist/lib/daemon/supervisor.d.ts +132 -0
  607. package/dist/lib/daemon/supervisor.js +836 -0
  608. package/dist/lib/daemon/sync-runner.d.ts +58 -0
  609. package/dist/lib/daemon/sync-runner.js +277 -0
  610. package/dist/lib/daemon/tools.d.ts +52 -0
  611. package/dist/lib/daemon/tools.js +95 -0
  612. package/dist/lib/daemon/updater.d.ts +57 -0
  613. package/dist/lib/daemon/updater.js +163 -0
  614. package/dist/lib/db/control-plane.js +6 -0
  615. package/dist/lib/db/local.d.ts +0 -5
  616. package/dist/lib/db/local.js +1 -1
  617. package/dist/lib/db/migrate.d.ts +0 -12
  618. package/dist/lib/db/migrate.js +5 -5
  619. package/dist/lib/db/remote-sql.d.ts +2 -2
  620. package/dist/lib/db/remote-sql.js +3 -3
  621. package/dist/lib/db/sql.d.ts +0 -10
  622. package/dist/lib/db/sql.js +4 -8
  623. package/dist/lib/deploy-api.d.ts +5 -0
  624. package/dist/lib/deploy-api.js +21 -0
  625. package/dist/lib/deploy-apps.d.ts +13 -0
  626. package/dist/lib/deploy-apps.js +29 -0
  627. package/dist/lib/doctor/__testing__/fake-hq-tree.d.ts +1 -1
  628. package/dist/lib/doctor/__testing__/fake-hq-tree.js +1 -1
  629. package/dist/lib/doctor/__testing__/run-doctor.d.ts +8 -0
  630. package/dist/lib/doctor/__testing__/run-doctor.js +52 -0
  631. package/dist/lib/doctor/checks/bots.d.ts +13 -0
  632. package/dist/lib/doctor/checks/bots.js +189 -0
  633. package/dist/lib/doctor/checks/claude-wiring.js +70 -1
  634. package/dist/lib/doctor/checks/codex-wiring.d.ts +0 -4
  635. package/dist/lib/doctor/checks/codex-wiring.js +3 -35
  636. package/dist/lib/doctor/checks/grok-wiring.js +1 -34
  637. package/dist/lib/doctor/checks/integrations.js +11 -0
  638. package/dist/lib/doctor/checks/runtime-health.d.ts +4 -17
  639. package/dist/lib/doctor/checks/runtime-health.js +20 -7
  640. package/dist/lib/doctor/checks/scaffold-cli-floor.d.ts +6 -0
  641. package/dist/lib/doctor/checks/scaffold-cli-floor.js +73 -0
  642. package/dist/lib/doctor/checks/sync-health.d.ts +21 -0
  643. package/dist/lib/doctor/checks/sync-health.js +72 -2
  644. package/dist/lib/doctor/checks/sync-runtime.d.ts +11 -0
  645. package/dist/lib/doctor/checks/sync-runtime.js +216 -0
  646. package/dist/lib/doctor/checks/work-context.js +20 -6
  647. package/dist/lib/doctor/client-health-flag-token.d.ts +15 -0
  648. package/dist/lib/doctor/client-health-flag-token.js +66 -0
  649. package/dist/lib/doctor/client-health-reason-codes-flag.d.ts +27 -0
  650. package/dist/lib/doctor/client-health-reason-codes-flag.js +106 -0
  651. package/dist/lib/doctor/compat.d.ts +0 -16
  652. package/dist/lib/doctor/compat.js +4 -3
  653. package/dist/lib/doctor/deep/effects.js +1 -3
  654. package/dist/lib/doctor/deep/executor.d.ts +4 -10
  655. package/dist/lib/doctor/deep/executor.js +1 -1
  656. package/dist/lib/doctor/deep/parity.d.ts +2 -29
  657. package/dist/lib/doctor/deep/parity.js +7 -7
  658. package/dist/lib/doctor/deep/sandbox.d.ts +7 -25
  659. package/dist/lib/doctor/deep/sandbox.js +5 -7
  660. package/dist/lib/doctor/fix/apply.d.ts +79 -8
  661. package/dist/lib/doctor/fix/apply.js +292 -80
  662. package/dist/lib/doctor/fix/json-output.d.ts +28 -0
  663. package/dist/lib/doctor/fix/json-output.js +33 -0
  664. package/dist/lib/doctor/fix/refresh-sync-outcome.d.ts +12 -0
  665. package/dist/lib/doctor/fix/refresh-sync-outcome.js +25 -0
  666. package/dist/lib/doctor/fix/remediation.d.ts +14 -6
  667. package/dist/lib/doctor/fix/remediation.js +49 -9
  668. package/dist/lib/doctor/fixtures/schema.js +1 -3
  669. package/dist/lib/doctor/json-output.d.ts +17 -1
  670. package/dist/lib/doctor/json-output.js +7 -2
  671. package/dist/lib/doctor/platform.d.ts +0 -26
  672. package/dist/lib/doctor/platform.js +5 -5
  673. package/dist/lib/doctor/registry.d.ts +14 -0
  674. package/dist/lib/doctor/registry.js +71 -0
  675. package/dist/lib/doctor/report.js +1 -1
  676. package/dist/lib/doctor/shared.d.ts +8 -0
  677. package/dist/lib/doctor/shared.js +38 -0
  678. package/dist/lib/doctor/stray-gate-entries.d.ts +35 -0
  679. package/dist/lib/doctor/stray-gate-entries.js +83 -0
  680. package/dist/lib/doctor/types.d.ts +5 -0
  681. package/dist/lib/doctor/types.js +20 -0
  682. package/dist/lib/first-sync-next-step.d.ts +34 -0
  683. package/dist/lib/first-sync-next-step.js +179 -0
  684. package/dist/lib/flag-registry-endpoint.d.ts +5 -0
  685. package/dist/lib/flag-registry-endpoint.js +9 -0
  686. package/dist/lib/flag-registry-worker-source.generated.d.ts +2 -0
  687. package/dist/lib/flag-registry-worker-source.generated.js +3 -0
  688. package/dist/lib/flag-registry-worker.js +12 -1
  689. package/dist/lib/flag-registry.d.ts +26 -6
  690. package/dist/lib/flag-registry.js +133 -16
  691. package/dist/lib/flag-snapshot-file.d.ts +20 -0
  692. package/dist/lib/flag-snapshot-file.js +91 -0
  693. package/dist/lib/heartbeat-identity.d.ts +30 -0
  694. package/dist/lib/heartbeat-identity.js +76 -0
  695. package/dist/lib/index-render/companies.d.ts +4 -1
  696. package/dist/lib/index-render/companies.js +66 -3
  697. package/dist/lib/index-render/company-knowledge.js +80 -17
  698. package/dist/lib/index-render/index.d.ts +1 -0
  699. package/dist/lib/index-render/index.js +2 -1
  700. package/dist/lib/index-render/projects.js +82 -5
  701. package/dist/lib/index-render/shared.d.ts +13 -1
  702. package/dist/lib/index-render/shared.js +41 -2
  703. package/dist/lib/lanes/account-home.d.ts +8 -0
  704. package/dist/lib/lanes/account-home.js +10 -0
  705. package/dist/lib/lanes/accounts.d.ts +117 -0
  706. package/dist/lib/lanes/accounts.js +366 -0
  707. package/dist/lib/lanes/admission-host.d.ts +22 -0
  708. package/dist/lib/lanes/admission-host.js +37 -0
  709. package/dist/lib/lanes/admission.d.ts +26 -0
  710. package/dist/lib/lanes/admission.js +210 -0
  711. package/dist/lib/lanes/approval-gate.d.ts +8 -0
  712. package/dist/lib/lanes/approval-gate.js +90 -0
  713. package/dist/lib/lanes/autopilot-metrics.d.ts +99 -0
  714. package/dist/lib/lanes/autopilot-metrics.js +301 -0
  715. package/dist/lib/lanes/autopilot-registry.d.ts +62 -0
  716. package/dist/lib/lanes/autopilot-registry.js +192 -0
  717. package/dist/lib/lanes/autopilot.d.ts +133 -0
  718. package/dist/lib/lanes/autopilot.js +1222 -0
  719. package/dist/lib/lanes/blocker-freshness.d.ts +31 -0
  720. package/dist/lib/lanes/blocker-freshness.js +168 -0
  721. package/dist/lib/lanes/checked-company-path.d.ts +3 -0
  722. package/dist/lib/lanes/checked-company-path.js +39 -0
  723. package/dist/lib/lanes/claude-balance.d.ts +97 -0
  724. package/dist/lib/lanes/claude-balance.js +319 -0
  725. package/dist/lib/lanes/compaction.d.ts +110 -0
  726. package/dist/lib/lanes/compaction.js +293 -0
  727. package/dist/lib/lanes/config.d.ts +94 -0
  728. package/dist/lib/lanes/config.js +606 -0
  729. package/dist/lib/lanes/constants.d.ts +3 -0
  730. package/dist/lib/lanes/constants.js +3 -0
  731. package/dist/lib/lanes/delivery-core.d.ts +15 -0
  732. package/dist/lib/lanes/delivery-core.js +21 -0
  733. package/dist/lib/lanes/delivery.d.ts +180 -0
  734. package/dist/lib/lanes/delivery.js +443 -0
  735. package/dist/lib/lanes/disk-guard.d.ts +66 -0
  736. package/dist/lib/lanes/disk-guard.js +172 -0
  737. package/dist/lib/lanes/dropbox.d.ts +129 -0
  738. package/dist/lib/lanes/dropbox.js +601 -0
  739. package/dist/lib/lanes/effort.d.ts +51 -0
  740. package/dist/lib/lanes/effort.js +113 -0
  741. package/dist/lib/lanes/envelope-repair-dispatch.d.ts +26 -0
  742. package/dist/lib/lanes/envelope-repair-dispatch.js +74 -0
  743. package/dist/lib/lanes/errors.d.ts +39 -0
  744. package/dist/lib/lanes/errors.js +72 -0
  745. package/dist/lib/lanes/flag-keys.d.ts +22 -0
  746. package/dist/lib/lanes/flag-keys.js +22 -0
  747. package/dist/lib/lanes/grants.d.ts +30 -0
  748. package/dist/lib/lanes/grants.js +171 -0
  749. package/dist/lib/lanes/hire-grant-dispatch.d.ts +29 -0
  750. package/dist/lib/lanes/hire-grant-dispatch.js +315 -0
  751. package/dist/lib/lanes/hooks-install.d.ts +82 -0
  752. package/dist/lib/lanes/hooks-install.js +479 -0
  753. package/dist/lib/lanes/host-capacity.d.ts +69 -0
  754. package/dist/lib/lanes/host-capacity.js +254 -0
  755. package/dist/lib/lanes/hq-root.d.ts +19 -0
  756. package/dist/lib/lanes/hq-root.js +28 -0
  757. package/dist/lib/lanes/index.d.ts +76 -0
  758. package/dist/lib/lanes/index.js +42 -0
  759. package/dist/lib/lanes/keep-alive-audit.d.ts +46 -0
  760. package/dist/lib/lanes/keep-alive-audit.js +370 -0
  761. package/dist/lib/lanes/keep-alive.d.ts +68 -0
  762. package/dist/lib/lanes/keep-alive.js +343 -0
  763. package/dist/lib/lanes/kr-freshness.d.ts +76 -0
  764. package/dist/lib/lanes/kr-freshness.js +413 -0
  765. package/dist/lib/lanes/lane-company.d.ts +10 -0
  766. package/dist/lib/lanes/lane-company.js +41 -0
  767. package/dist/lib/lanes/liveness.d.ts +108 -0
  768. package/dist/lib/lanes/liveness.js +396 -0
  769. package/dist/lib/lanes/machine-identity.d.ts +34 -0
  770. package/dist/lib/lanes/machine-identity.js +92 -0
  771. package/dist/lib/lanes/manager-status-gate.d.ts +17 -0
  772. package/dist/lib/lanes/manager-status-gate.js +133 -0
  773. package/dist/lib/lanes/merge-command.d.ts +15 -0
  774. package/dist/lib/lanes/merge-command.js +629 -0
  775. package/dist/lib/lanes/mesh-events.d.ts +127 -0
  776. package/dist/lib/lanes/mesh-events.js +564 -0
  777. package/dist/lib/lanes/message-replay.d.ts +21 -0
  778. package/dist/lib/lanes/message-replay.js +122 -0
  779. package/dist/lib/lanes/models.d.ts +86 -0
  780. package/dist/lib/lanes/models.js +234 -0
  781. package/dist/lib/lanes/monitor.d.ts +48 -0
  782. package/dist/lib/lanes/monitor.js +428 -0
  783. package/dist/lib/lanes/move-account.d.ts +56 -0
  784. package/dist/lib/lanes/move-account.js +193 -0
  785. package/dist/lib/lanes/orphans.d.ts +25 -0
  786. package/dist/lib/lanes/orphans.js +102 -0
  787. package/dist/lib/lanes/outpost-dispatch.d.ts +147 -0
  788. package/dist/lib/lanes/outpost-dispatch.js +271 -0
  789. package/dist/lib/lanes/outpost-hire-cache.d.ts +22 -0
  790. package/dist/lib/lanes/outpost-hire-cache.js +153 -0
  791. package/dist/lib/lanes/outpost-identity.d.ts +33 -0
  792. package/dist/lib/lanes/outpost-identity.js +59 -0
  793. package/dist/lib/lanes/outpost-profile-repin.d.ts +17 -0
  794. package/dist/lib/lanes/outpost-profile-repin.js +84 -0
  795. package/dist/lib/lanes/outpost-pruner-install.d.ts +37 -0
  796. package/dist/lib/lanes/outpost-pruner-install.js +238 -0
  797. package/dist/lib/lanes/outpost-registry-worker-approval.d.ts +18 -0
  798. package/dist/lib/lanes/outpost-registry-worker-approval.js +109 -0
  799. package/dist/lib/lanes/outpost-snapshot-memo.d.ts +6 -0
  800. package/dist/lib/lanes/outpost-snapshot-memo.js +14 -0
  801. package/dist/lib/lanes/outpost-worktree-pruner-flag.d.ts +19 -0
  802. package/dist/lib/lanes/outpost-worktree-pruner-flag.js +86 -0
  803. package/dist/lib/lanes/outpost-worktree-pruner.d.ts +62 -0
  804. package/dist/lib/lanes/outpost-worktree-pruner.js +1201 -0
  805. package/dist/lib/lanes/profile.d.ts +69 -0
  806. package/dist/lib/lanes/profile.js +552 -0
  807. package/dist/lib/lanes/provider-rejection.d.ts +86 -0
  808. package/dist/lib/lanes/provider-rejection.js +286 -0
  809. package/dist/lib/lanes/questions.d.ts +90 -0
  810. package/dist/lib/lanes/questions.js +384 -0
  811. package/dist/lib/lanes/quota.d.ts +134 -0
  812. package/dist/lib/lanes/quota.js +471 -0
  813. package/dist/lib/lanes/reconcile-install.d.ts +90 -0
  814. package/dist/lib/lanes/reconcile-install.js +257 -0
  815. package/dist/lib/lanes/reconcile.d.ts +161 -0
  816. package/dist/lib/lanes/reconcile.js +3343 -0
  817. package/dist/lib/lanes/registry-flag.d.ts +35 -0
  818. package/dist/lib/lanes/registry-flag.js +164 -0
  819. package/dist/lib/lanes/registry-persona.d.ts +20 -0
  820. package/dist/lib/lanes/registry-persona.js +329 -0
  821. package/dist/lib/lanes/registry.d.ts +122 -0
  822. package/dist/lib/lanes/registry.js +570 -0
  823. package/dist/lib/lanes/reviews.d.ts +38 -0
  824. package/dist/lib/lanes/reviews.js +395 -0
  825. package/dist/lib/lanes/runaway-tool-guard.d.ts +38 -0
  826. package/dist/lib/lanes/runaway-tool-guard.js +284 -0
  827. package/dist/lib/lanes/session-relink.d.ts +25 -0
  828. package/dist/lib/lanes/session-relink.js +216 -0
  829. package/dist/lib/lanes/spawn.d.ts +355 -0
  830. package/dist/lib/lanes/spawn.js +2668 -0
  831. package/dist/lib/lanes/ssm-command-context.d.ts +12 -0
  832. package/dist/lib/lanes/ssm-command-context.js +52 -0
  833. package/dist/lib/lanes/store.d.ts +91 -0
  834. package/dist/lib/lanes/store.js +1822 -0
  835. package/dist/lib/lanes/stories.d.ts +23 -0
  836. package/dist/lib/lanes/stories.js +92 -0
  837. package/dist/lib/lanes/story-ledger.d.ts +80 -0
  838. package/dist/lib/lanes/story-ledger.js +815 -0
  839. package/dist/lib/lanes/story-switch.d.ts +21 -0
  840. package/dist/lib/lanes/story-switch.js +75 -0
  841. package/dist/lib/lanes/text-scan.d.ts +11 -0
  842. package/dist/lib/lanes/text-scan.js +103 -0
  843. package/dist/lib/lanes/throttle.d.ts +116 -0
  844. package/dist/lib/lanes/throttle.js +437 -0
  845. package/dist/lib/lanes/timestamp.d.ts +3 -0
  846. package/dist/lib/lanes/timestamp.js +26 -0
  847. package/dist/lib/lanes/tracker-checks.d.ts +77 -0
  848. package/dist/lib/lanes/tracker-checks.js +134 -0
  849. package/dist/lib/lanes/tracker-report-state.d.ts +10 -0
  850. package/dist/lib/lanes/tracker-report-state.js +124 -0
  851. package/dist/lib/lanes/tracker-report.d.ts +203 -0
  852. package/dist/lib/lanes/tracker-report.js +522 -0
  853. package/dist/lib/lanes/tracker-store.d.ts +18 -0
  854. package/dist/lib/lanes/tracker-store.js +106 -0
  855. package/dist/lib/lanes/types.d.ts +1030 -0
  856. package/dist/lib/lanes/types.js +418 -0
  857. package/dist/lib/lanes/wait.d.ts +39 -0
  858. package/dist/lib/lanes/wait.js +159 -0
  859. package/dist/lib/lanes/watch.d.ts +39 -0
  860. package/dist/lib/lanes/watch.js +249 -0
  861. package/dist/lib/lanes/watcher-main.d.ts +11 -0
  862. package/dist/lib/lanes/watcher-main.js +108 -0
  863. package/dist/lib/lanes/watcher.d.ts +287 -0
  864. package/dist/lib/lanes/watcher.js +1972 -0
  865. package/dist/lib/mesh/api.d.ts +103 -10
  866. package/dist/lib/mesh/api.js +334 -64
  867. package/dist/lib/mesh/client.d.ts +3 -2
  868. package/dist/lib/mesh/client.js +26 -7
  869. package/dist/lib/mesh/denial-codes.d.ts +5 -0
  870. package/dist/lib/mesh/denial-codes.js +14 -0
  871. package/dist/lib/mesh/live/backfill-held.d.ts +67 -16
  872. package/dist/lib/mesh/live/backfill-held.js +415 -61
  873. package/dist/lib/mesh/live/backoff.d.ts +2 -2
  874. package/dist/lib/mesh/live/backoff.js +16 -3
  875. package/dist/lib/mesh/live/daemon/board-refresh.d.ts +7 -1
  876. package/dist/lib/mesh/live/daemon/board-refresh.js +78 -30
  877. package/dist/lib/mesh/live/daemon/config.d.ts +36 -0
  878. package/dist/lib/mesh/live/daemon/config.js +120 -0
  879. package/dist/lib/mesh/live/daemon/credentials.d.ts +64 -10
  880. package/dist/lib/mesh/live/daemon/credentials.js +270 -20
  881. package/dist/lib/mesh/live/daemon/doctor.d.ts +53 -0
  882. package/dist/lib/mesh/live/daemon/doctor.js +190 -6
  883. package/dist/lib/mesh/live/daemon/index.d.ts +13 -10
  884. package/dist/lib/mesh/live/daemon/index.js +7 -6
  885. package/dist/lib/mesh/live/daemon/install.d.ts +255 -1
  886. package/dist/lib/mesh/live/daemon/install.js +811 -13
  887. package/dist/lib/mesh/live/daemon/legacy-listen.d.ts +43 -0
  888. package/dist/lib/mesh/live/daemon/legacy-listen.js +89 -0
  889. package/dist/lib/mesh/live/daemon/live-cache.d.ts +26 -0
  890. package/dist/lib/mesh/live/daemon/live-cache.js +116 -0
  891. package/dist/lib/mesh/live/daemon/mqtt-events.d.ts +7 -0
  892. package/dist/lib/mesh/live/daemon/mqtt-events.js +2 -0
  893. package/dist/lib/mesh/live/daemon/mqtt-events.test-d.d.ts +2 -0
  894. package/dist/lib/mesh/live/daemon/mqtt-events.test-d.js +10 -0
  895. package/dist/lib/mesh/live/daemon/paths.d.ts +2 -0
  896. package/dist/lib/mesh/live/daemon/paths.js +2 -0
  897. package/dist/lib/mesh/live/daemon/presence.d.ts +24 -5
  898. package/dist/lib/mesh/live/daemon/presence.js +79 -10
  899. package/dist/lib/mesh/live/daemon/run.d.ts +48 -2
  900. package/dist/lib/mesh/live/daemon/run.js +485 -33
  901. package/dist/lib/mesh/live/daemon/state.d.ts +19 -2
  902. package/dist/lib/mesh/live/daemon/state.js +34 -2
  903. package/dist/lib/mesh/live/daemon/transcript-watch.d.ts +45 -9
  904. package/dist/lib/mesh/live/daemon/transcript-watch.js +227 -31
  905. package/dist/lib/mesh/live/daemon/version-drift.d.ts +5 -0
  906. package/dist/lib/mesh/live/daemon/version-drift.js +47 -0
  907. package/dist/lib/mesh/live/daemon/work-subscribe.d.ts +32 -0
  908. package/dist/lib/mesh/live/daemon/work-subscribe.js +262 -0
  909. package/dist/lib/mesh/live/emit-client.d.ts +8 -0
  910. package/dist/lib/mesh/live/emit-client.js +23 -8
  911. package/dist/lib/mesh/live/emit-evidence.d.ts +19 -0
  912. package/dist/lib/mesh/live/emit-evidence.js +20 -2
  913. package/dist/lib/mesh/live/emit.d.ts +9 -0
  914. package/dist/lib/mesh/live/emit.js +28 -2
  915. package/dist/lib/mesh/live/enqueue.d.ts +5 -0
  916. package/dist/lib/mesh/live/enqueue.js +19 -0
  917. package/dist/lib/mesh/live/flush.d.ts +17 -5
  918. package/dist/lib/mesh/live/flush.js +391 -38
  919. package/dist/lib/mesh/live/format-spool-line.d.ts +5 -2
  920. package/dist/lib/mesh/live/format-spool-line.js +10 -0
  921. package/dist/lib/mesh/live/paths.d.ts +2 -0
  922. package/dist/lib/mesh/live/paths.js +4 -0
  923. package/dist/lib/mesh/live/report-summary.d.ts +45 -0
  924. package/dist/lib/mesh/live/report-summary.js +234 -0
  925. package/dist/lib/mesh/live/session-event.schema.json +24 -1
  926. package/dist/lib/mesh/live/session-events-client.d.ts +2 -0
  927. package/dist/lib/mesh/live/session-events-client.js +26 -0
  928. package/dist/lib/mesh/live/session-seq.d.ts +4 -0
  929. package/dist/lib/mesh/live/session-seq.js +33 -0
  930. package/dist/lib/mesh/live/spool.d.ts +19 -0
  931. package/dist/lib/mesh/live/spool.js +269 -3
  932. package/dist/lib/mesh/live/validate-session-event.d.ts +1 -1
  933. package/dist/lib/mesh/live/validate-session-event.js +1 -1
  934. package/dist/lib/mesh/project-board.d.ts +65 -0
  935. package/dist/lib/mesh/project-board.js +181 -0
  936. package/dist/lib/mesh/story-status.d.ts +22 -0
  937. package/dist/lib/mesh/story-status.js +49 -0
  938. package/dist/lib/monitor.d.ts +149 -0
  939. package/dist/lib/monitor.js +519 -0
  940. package/dist/lib/node-binary.d.ts +50 -0
  941. package/dist/lib/node-binary.js +133 -0
  942. package/dist/lib/notify-recipient.d.ts +7 -0
  943. package/dist/lib/notify-recipient.js +11 -0
  944. package/dist/lib/onboarding/checkpoint.d.ts +13 -0
  945. package/dist/lib/onboarding/checkpoint.js +44 -0
  946. package/dist/lib/onboarding/cli/onboard.d.ts +53 -0
  947. package/dist/lib/onboarding/cli/onboard.js +135 -0
  948. package/dist/lib/onboarding/cli/prompts.d.ts +28 -0
  949. package/dist/lib/onboarding/cli/prompts.js +83 -0
  950. package/dist/lib/onboarding/errors.d.ts +34 -0
  951. package/dist/lib/onboarding/errors.js +59 -0
  952. package/dist/lib/onboarding/index.d.ts +13 -0
  953. package/dist/lib/onboarding/index.js +13 -0
  954. package/dist/lib/onboarding/orchestrator.d.ts +47 -0
  955. package/dist/lib/onboarding/orchestrator.js +569 -0
  956. package/dist/lib/onboarding/types.d.ts +79 -0
  957. package/dist/lib/onboarding/types.js +8 -0
  958. package/dist/lib/plan-limit-nag.d.ts +102 -6
  959. package/dist/lib/plan-limit-nag.js +348 -43
  960. package/dist/lib/policy-validator.d.ts +7 -0
  961. package/dist/lib/policy-validator.js +187 -0
  962. package/dist/lib/process-flag-company-context.d.ts +8 -0
  963. package/dist/lib/process-flag-company-context.js +67 -0
  964. package/dist/lib/report-publish.d.ts +175 -0
  965. package/dist/lib/report-publish.js +421 -0
  966. package/dist/lib/report-run.d.ts +62 -0
  967. package/dist/lib/report-run.js +123 -0
  968. package/dist/lib/report-snapshot.d.ts +12 -0
  969. package/dist/lib/report-snapshot.js +135 -0
  970. package/dist/lib/report-templates.d.ts +9 -0
  971. package/dist/lib/report-templates.js +21 -0
  972. package/dist/lib/scaffold-cli-floor.d.ts +8 -0
  973. package/dist/lib/scaffold-cli-floor.js +50 -0
  974. package/dist/lib/scan-packages/index.d.ts +2 -0
  975. package/dist/lib/scan-packages/index.js +168 -6
  976. package/dist/lib/search-index/background.d.ts +8 -1
  977. package/dist/lib/search-index/background.js +55 -200
  978. package/dist/lib/search-index/collection-path-repair-flag.d.ts +4 -0
  979. package/dist/lib/search-index/collection-path-repair-flag.js +7 -0
  980. package/dist/lib/search-index/embed-lock.d.ts +34 -0
  981. package/dist/lib/search-index/embed-lock.js +295 -0
  982. package/dist/lib/search-index/index.d.ts +12 -0
  983. package/dist/lib/search-index/index.js +153 -7
  984. package/dist/lib/search-index/load-gate.d.ts +57 -0
  985. package/dist/lib/search-index/load-gate.js +270 -0
  986. package/dist/lib/search-index/max-doc-bytes.d.ts +219 -0
  987. package/dist/lib/search-index/max-doc-bytes.js +463 -0
  988. package/dist/lib/search-index/qmd-exit-diagnostics.d.ts +5 -0
  989. package/dist/lib/search-index/qmd-exit-diagnostics.js +40 -0
  990. package/dist/lib/search-index/reindex-single-flight-flag.d.ts +5 -0
  991. package/dist/lib/search-index/reindex-single-flight-flag.js +8 -0
  992. package/dist/lib/service-manager/index.d.ts +42 -0
  993. package/dist/lib/service-manager/index.js +105 -0
  994. package/dist/lib/service-manager/launchd.d.ts +81 -0
  995. package/dist/lib/service-manager/launchd.js +212 -0
  996. package/dist/lib/service-manager/systemd.d.ts +19 -0
  997. package/dist/lib/service-manager/systemd.js +72 -0
  998. package/dist/lib/service-manager/types.d.ts +34 -0
  999. package/dist/lib/service-manager/types.js +26 -0
  1000. package/dist/lib/test-utils/isolated-flag-company-context.d.ts +3 -0
  1001. package/dist/lib/test-utils/isolated-flag-company-context.js +18 -0
  1002. package/dist/lib/work-context/bind-best.d.ts +66 -0
  1003. package/dist/lib/work-context/bind-best.js +344 -0
  1004. package/dist/lib/work-context/bind-calling-session.d.ts +26 -0
  1005. package/dist/lib/work-context/bind-calling-session.js +63 -0
  1006. package/dist/lib/work-context/company-rebind.d.ts +23 -0
  1007. package/dist/lib/work-context/company-rebind.js +59 -0
  1008. package/dist/lib/work-context/company.d.ts +22 -20
  1009. package/dist/lib/work-context/company.js +124 -40
  1010. package/dist/lib/work-context/config.d.ts +58 -11
  1011. package/dist/lib/work-context/config.js +334 -83
  1012. package/dist/lib/work-context/contract.d.ts +13 -0
  1013. package/dist/lib/work-context/contract.schema.json +3 -1
  1014. package/dist/lib/work-context/default-company.d.ts +43 -0
  1015. package/dist/lib/work-context/default-company.js +83 -0
  1016. package/dist/lib/work-context/outbox-quarantine-status-flag.d.ts +4 -0
  1017. package/dist/lib/work-context/outbox-quarantine-status-flag.js +7 -0
  1018. package/dist/lib/work-context/outbox.d.ts +27 -5
  1019. package/dist/lib/work-context/outbox.js +135 -6
  1020. package/dist/lib/work-context/prd-sync.d.ts +56 -0
  1021. package/dist/lib/work-context/prd-sync.js +197 -0
  1022. package/dist/lib/work-context/preflight-contract.d.ts +28 -0
  1023. package/dist/lib/work-context/preflight-contract.js +85 -0
  1024. package/dist/lib/work-context/prompt-rebind.d.ts +25 -0
  1025. package/dist/lib/work-context/prompt-rebind.js +85 -0
  1026. package/dist/lib/work-context/reconcile.d.ts +15 -0
  1027. package/dist/lib/work-context/reconcile.js +405 -29
  1028. package/dist/lib/work-context/state.d.ts +93 -10
  1029. package/dist/lib/work-context/state.js +342 -29
  1030. package/dist/lib/work-context/windows-acl.d.ts +123 -0
  1031. package/dist/lib/work-context/windows-acl.js +425 -0
  1032. package/dist/lib/workers-registry/index.js +62 -8
  1033. package/dist/lib/workers-registry/read.d.ts +15 -0
  1034. package/dist/lib/workers-registry/read.js +17 -0
  1035. package/dist/main.d.ts +32 -0
  1036. package/dist/main.js +273 -73
  1037. package/dist/native-fast-route.d.ts +7 -0
  1038. package/dist/native-fast-route.js +45 -0
  1039. package/dist/node-network-compat-core.d.ts +12 -0
  1040. package/dist/node-network-compat-core.js +41 -0
  1041. package/dist/node-network-compat-fast.d.ts +7 -0
  1042. package/dist/node-network-compat-fast.js +23 -0
  1043. package/dist/node-network-compat.d.ts +2 -30
  1044. package/dist/node-network-compat.js +4 -51
  1045. package/dist/node-preflight.d.ts +7 -1
  1046. package/dist/node-preflight.js +5 -5
  1047. package/dist/register-all.d.ts +4 -29
  1048. package/dist/register-all.js +4 -233
  1049. package/dist/run/discover-schemas.d.ts +2 -1
  1050. package/dist/run/env-graph-guard.d.ts +2 -2
  1051. package/dist/run/env-graph-guard.js +5 -2
  1052. package/dist/run/hq-plugin.d.ts +4 -0
  1053. package/dist/run/hq-plugin.js +36 -8
  1054. package/dist/secrets-env-fast-path.d.ts +5 -0
  1055. package/dist/secrets-env-fast-path.js +16 -0
  1056. package/dist/secrets-env-fast-route.d.ts +18 -0
  1057. package/dist/secrets-env-fast-route.js +54 -0
  1058. package/dist/sentry-before-send.js +80 -0
  1059. package/dist/sentry.d.ts +16 -4
  1060. package/dist/sentry.js +179 -18
  1061. package/dist/startup-registration.d.ts +26 -2
  1062. package/dist/startup-registration.js +116 -15
  1063. package/dist/utils/checkpoint-stamp-write-error.d.ts +28 -0
  1064. package/dist/utils/checkpoint-stamp-write-error.js +99 -0
  1065. package/dist/utils/cli-network-lifecycle.d.ts +4 -0
  1066. package/dist/utils/cli-network-lifecycle.js +11 -0
  1067. package/dist/utils/cli-telemetry.d.ts +75 -1
  1068. package/dist/utils/cli-telemetry.js +433 -7
  1069. package/dist/utils/client-health.d.ts +0 -4
  1070. package/dist/utils/client-health.js +2 -2
  1071. package/dist/utils/cognito-refresh-sentry.d.ts +3 -0
  1072. package/dist/utils/cognito-refresh-sentry.js +49 -0
  1073. package/dist/utils/cognito-session.d.ts +71 -0
  1074. package/dist/utils/cognito-session.js +481 -27
  1075. package/dist/utils/console-origin.d.ts +9 -0
  1076. package/dist/utils/console-origin.js +28 -0
  1077. package/dist/utils/contribution-table.d.ts +1 -1
  1078. package/dist/utils/core-eval-trigger.d.ts +4 -0
  1079. package/dist/utils/core-eval-trigger.js +88 -0
  1080. package/dist/utils/environmental-error.d.ts +18 -0
  1081. package/dist/utils/environmental-error.js +240 -7
  1082. package/dist/utils/exclusive-lock.d.ts +32 -0
  1083. package/dist/utils/exclusive-lock.js +75 -0
  1084. package/dist/utils/expected-cli-error.d.ts +2 -0
  1085. package/dist/utils/expected-cli-error.js +4 -0
  1086. package/dist/utils/fast-stream-errors.d.ts +12 -0
  1087. package/dist/utils/fast-stream-errors.js +18 -0
  1088. package/dist/utils/feedback-diagnostics.d.ts +2 -1
  1089. package/dist/utils/feedback-log-bundle.d.ts +51 -26
  1090. package/dist/utils/feedback-log-bundle.js +211 -31
  1091. package/dist/utils/feedback-logs.d.ts +18 -47
  1092. package/dist/utils/feedback-logs.js +50 -21
  1093. package/dist/utils/feedback-screenshots.d.ts +0 -1
  1094. package/dist/utils/feedback-screenshots.js +1 -1
  1095. package/dist/utils/files-browse-acl.d.ts +5 -0
  1096. package/dist/utils/files-browse-acl.js +11 -0
  1097. package/dist/utils/hq-core-yaml.d.ts +10 -0
  1098. package/dist/utils/hq-core-yaml.js +40 -0
  1099. package/dist/utils/hq-root-resolver.d.ts +13 -0
  1100. package/dist/utils/hq-root-resolver.js +103 -0
  1101. package/dist/utils/hq-roots.d.ts +25 -2
  1102. package/dist/utils/hq-roots.js +67 -7
  1103. package/dist/utils/incomplete-install-error.d.ts +87 -19
  1104. package/dist/utils/incomplete-install-error.js +319 -68
  1105. package/dist/utils/install-tree-torn.d.ts +260 -24
  1106. package/dist/utils/install-tree-torn.js +998 -51
  1107. package/dist/utils/large-file-guard.d.ts +0 -10
  1108. package/dist/utils/large-file-guard.js +1 -1
  1109. package/dist/utils/local-files-overview.d.ts +4 -8
  1110. package/dist/utils/local-files-overview.js +48 -7
  1111. package/dist/utils/login-provider.d.ts +7 -0
  1112. package/dist/utils/login-provider.js +34 -0
  1113. package/dist/utils/pack-contributions.d.ts +2 -14
  1114. package/dist/utils/pack-contributions.js +7 -44
  1115. package/dist/utils/package-root-diagnostics.d.ts +1 -1
  1116. package/dist/utils/people.d.ts +7 -11
  1117. package/dist/utils/people.js +5 -20
  1118. package/dist/utils/plan-gate-error.d.ts +52 -10
  1119. package/dist/utils/plan-gate-error.js +364 -41
  1120. package/dist/utils/qmd-model-download-error.d.ts +0 -8
  1121. package/dist/utils/qmd-model-download-error.js +1 -1
  1122. package/dist/utils/qmd-query-document-error.d.ts +0 -6
  1123. package/dist/utils/qmd-query-document-error.js +1 -1
  1124. package/dist/utils/redact-error-text.d.ts +0 -2
  1125. package/dist/utils/redact-error-text.js +3 -2
  1126. package/dist/utils/redact-url.d.ts +14 -0
  1127. package/dist/utils/redact-url.js +218 -0
  1128. package/dist/utils/run-bundled-script.d.ts +6 -0
  1129. package/dist/utils/run-bundled-script.js +117 -4
  1130. package/dist/utils/sandbox-runner-client.d.ts +2 -1
  1131. package/dist/utils/scaffold-fast-import-guard.d.ts +2 -0
  1132. package/dist/utils/scaffold-fast-import-guard.js +40 -0
  1133. package/dist/utils/scaffold-packlist-guard.d.ts +7 -0
  1134. package/dist/utils/scaffold-packlist-guard.js +23 -0
  1135. package/dist/utils/scaffold-sibling-references.d.ts +22 -0
  1136. package/dist/utils/scaffold-sibling-references.js +156 -0
  1137. package/dist/utils/secret-load-availability.d.ts +8 -0
  1138. package/dist/utils/secret-load-availability.js +54 -0
  1139. package/dist/utils/secrets-cache.d.ts +7 -3
  1140. package/dist/utils/secrets-cache.js +162 -14
  1141. package/dist/utils/self-update.d.ts +34 -1
  1142. package/dist/utils/self-update.js +660 -42
  1143. package/dist/utils/sentry-fingerprint.d.ts +23 -1
  1144. package/dist/utils/sentry-fingerprint.js +223 -31
  1145. package/dist/utils/staged-install.d.ts +34 -0
  1146. package/dist/utils/staged-install.js +346 -0
  1147. package/dist/utils/staged-npm-install.d.ts +16 -0
  1148. package/dist/utils/staged-npm-install.js +264 -0
  1149. package/dist/utils/sync-log-sources.d.ts +15 -0
  1150. package/dist/utils/sync-log-sources.js +36 -0
  1151. package/dist/utils/table-width.d.ts +7 -0
  1152. package/dist/utils/table-width.js +15 -0
  1153. package/dist/utils/team-upgrade.d.ts +1 -1
  1154. package/dist/utils/team-upgrade.js +4 -3
  1155. package/dist/utils/update-command-supervisor.cjs +247 -0
  1156. package/dist/utils/upload-author.d.ts +15 -0
  1157. package/dist/utils/upload-author.js +39 -0
  1158. package/dist/utils/vault-api.d.ts +21 -1
  1159. package/dist/utils/vault-api.js +251 -84
  1160. package/dist/utils/version-check.d.ts +11 -1
  1161. package/dist/utils/version-check.js +32 -3
  1162. package/dist/utils/version-gate.d.ts +101 -17
  1163. package/dist/utils/version-gate.js +645 -70
  1164. package/dist/utils/version-report.d.ts +27 -0
  1165. package/dist/utils/version-report.js +105 -0
  1166. package/dist/utils/windows-spawn.d.ts +6 -0
  1167. package/dist/utils/windows-spawn.js +37 -0
  1168. package/dist/version-request.d.ts +14 -0
  1169. package/dist/version-request.js +36 -0
  1170. package/package.json +20 -8
  1171. package/scripts/mesh-daemon-if-stale.mjs +20 -0
  1172. package/templates/reports/blank.md +3 -0
  1173. package/templates/reports/daily-digest.md +11 -0
  1174. package/templates/runbooks/update-report.md +21 -0
  1175. package/dist/commands/scaffold-fast.d.ts +0 -41
  1176. package/dist/commands/scaffold-fast.js +0 -57
  1177. package/dist/lib/work-context/index.d.ts +0 -25
  1178. package/dist/lib/work-context/index.js +0 -21
@@ -0,0 +1,1222 @@
1
+ import { createHash } from "node:crypto";
2
+ import * as fs from "node:fs";
3
+ import * as path from "node:path";
4
+ import { laneRunsOnHost } from "./admission.js";
5
+ import { isControllerAliasOutpostId } from "./admission-host.js";
6
+ import { LEAD_REGISTRY_REL, validateOutpostLeadRegistry } from "./autopilot-registry.js";
7
+ import { appendDropboxMessage } from "./dropbox.js";
8
+ import { LanesError } from "./errors.js";
9
+ import { LANE_AUTOPILOT_MISSED_DEADLINE_ESCALATION_FLAG, LANE_AUTOPILOT_NUDGE_DEDUPE_FLAG, LEAD_AUTOPILOT_KPI_STALENESS_BATCH_FLAG, LEAD_AUTOPILOT_KPI_STALENESS_FLAG, LEAD_AUTOPILOT_PER_LEAD_ERRORS_FLAG as PER_LEAD_ERRORS_FLAG, } from "./flag-keys.js";
10
+ import { resolveLaneCompany } from "./lane-company.js";
11
+ import { readLanesRegistryFlag } from "./registry-flag.js";
12
+ import { readAllLanes } from "./store.js";
13
+ export const LEAD_AUTOPILOT_FLAG = "lanes.lead-autopilot";
14
+ export const LEAD_AUTOPILOT_DEFAULT_ENABLED = false;
15
+ export const LEAD_AUTOPILOT_MISSED_DEADLINE_ESCALATION_FLAG = LANE_AUTOPILOT_MISSED_DEADLINE_ESCALATION_FLAG;
16
+ export const LEAD_AUTOPILOT_MISSED_DEADLINE_ESCALATION_DEFAULT_ENABLED = false;
17
+ export const LEAD_AUTOPILOT_MISSED_DEADLINE_ESCALATION_DELAY_MS = 60 * 60_000;
18
+ export const LEAD_AUTOPILOT_NUDGE_DEDUPE_FLAG = LANE_AUTOPILOT_NUDGE_DEDUPE_FLAG;
19
+ export const LEAD_AUTOPILOT_NUDGE_DEDUPE_DEFAULT_ENABLED = false;
20
+ export const LEAD_AUTOPILOT_NUDGE_REDELIVERY_DELAY_MS = 30 * 60_000;
21
+ export const LEAD_AUTOPILOT_NUDGE_STATE_RETENTION_MS = 24 * 60 * 60_000;
22
+ const LEAD_AUTOPILOT_DELIVERED_ID_RETENTION_MS = 7 * 24 * 60 * 60_000;
23
+ export const LEAD_AUTOPILOT_REVIEW_DELAY_MS = 15 * 60_000;
24
+ export const LEAD_AUTOPILOT_FILL_DELAY_MS = 15 * 60_000;
25
+ export const LEAD_AUTOPILOT_PROMPT_LOOP = "personal/knowledge/team-lead-operating-loop.md";
26
+ export const LEAD_AUTOPILOT_KPI_STALE_AFTER_MINUTES = 55;
27
+ export const LEAD_AUTOPILOT_PER_LEAD_ERRORS_FLAG = PER_LEAD_ERRORS_FLAG;
28
+ export const LEAD_AUTOPILOT_PER_LEAD_ERRORS_DEFAULT_ENABLED = false;
29
+ const LIVE_STATES = new Set(["running", "queued", "awaiting_input", "blocked"]);
30
+ const OPEN_STORY_STATES = new Set(["todo", "queued", "in_progress", "review", "blocked"]);
31
+ function isOpenProjectStory(story) {
32
+ return story.passes !== true && OPEN_STORY_STATES.has(story.status);
33
+ }
34
+ function isRecord(value) {
35
+ return value !== null && typeof value === "object" && !Array.isArray(value);
36
+ }
37
+ function readJsonFile(filePath, code) {
38
+ let text;
39
+ try {
40
+ const stat = fs.lstatSync(filePath);
41
+ if (!stat.isFile() || stat.isSymbolicLink())
42
+ throw new Error("expected a regular file");
43
+ text = fs.readFileSync(filePath, "utf8");
44
+ }
45
+ catch (error) {
46
+ throw new LanesError(code, `Cannot read ${filePath}: ${error instanceof Error ? error.message : String(error)}`, { path: filePath });
47
+ }
48
+ try {
49
+ return JSON.parse(text);
50
+ }
51
+ catch (error) {
52
+ throw new LanesError(code, `Cannot parse ${filePath}: ${error instanceof Error ? error.message : String(error)}`, { path: filePath });
53
+ }
54
+ }
55
+ function parseRegistry(hqRoot, outpostId, now) {
56
+ const file = path.join(hqRoot, LEAD_REGISTRY_REL);
57
+ let stat;
58
+ try {
59
+ stat = fs.lstatSync(file);
60
+ }
61
+ catch (error) {
62
+ if (error.code === "ENOENT") {
63
+ // An Outpost without a delivered registry reports it; it does not fail reconcile.
64
+ // The primary delivers nothing when it has no registry or every company is flagged off.
65
+ if (outpostId !== null && !isControllerAliasOutpostId(outpostId, { kind: "outpost", id: outpostId }))
66
+ return null;
67
+ return [];
68
+ }
69
+ throw new LanesError("lead_autopilot_registry_invalid", `Cannot inspect ${file}: ${error instanceof Error ? error.message : String(error)}`, { path: file });
70
+ }
71
+ if (!stat.isFile() || stat.isSymbolicLink()) {
72
+ throw new LanesError("lead_autopilot_registry_invalid", `Invalid lead registry ${file}: expected a regular file`, { path: file });
73
+ }
74
+ const raw = readJsonFile(file, "lead_autopilot_registry_invalid");
75
+ if (outpostId !== null && !isControllerAliasOutpostId(outpostId, { kind: "outpost", id: outpostId }))
76
+ return validateOutpostLeadRegistry({ registry: raw, outpostId, now }).juniors;
77
+ if (isRecord(raw) && raw.juniors === undefined && Array.isArray(raw.retired))
78
+ return [];
79
+ if (!isRecord(raw) || !Array.isArray(raw.juniors)) {
80
+ throw new LanesError("lead_autopilot_registry_invalid", `Invalid lead registry ${file}: juniors must be an array`, { path: file });
81
+ }
82
+ const rows = [];
83
+ for (const [index, value] of raw.juniors.entries()) {
84
+ if (!isRecord(value) || ["team", "lane", "host", "status", "prd"].some((key) => typeof value[key] !== "string" || !value[key].trim())) {
85
+ throw new LanesError("lead_autopilot_registry_invalid", `Invalid lead registry ${file}: juniors[${index}] must name team, lane, host, status, and prd`, { path: file, index });
86
+ }
87
+ rows.push(value);
88
+ }
89
+ return rows;
90
+ }
91
+ function registeredFilePath(hqRoot, relativePath, errorCode) {
92
+ const root = path.resolve(hqRoot);
93
+ const file = path.resolve(root, relativePath);
94
+ if (file === root || !file.startsWith(`${root}${path.sep}`)) {
95
+ throw new LanesError(errorCode, `Registered path escapes HQ root: ${relativePath}`, { path: relativePath });
96
+ }
97
+ try {
98
+ const realRoot = fs.realpathSync(root);
99
+ const realFile = fs.realpathSync(file);
100
+ if (realFile === realRoot || !realFile.startsWith(`${realRoot}${path.sep}`)) {
101
+ throw new LanesError(errorCode, `Registered path resolves outside HQ root: ${relativePath}`, { path: relativePath });
102
+ }
103
+ }
104
+ catch (error) {
105
+ if (error instanceof LanesError)
106
+ throw error;
107
+ throw new LanesError(errorCode, `Cannot resolve registered path ${relativePath}: ${error instanceof Error ? error.message : String(error)}`, { path: relativePath });
108
+ }
109
+ return file;
110
+ }
111
+ function projectStories(hqRoot, relativePath, companySlug, projectId) {
112
+ if (companySlug !== undefined) {
113
+ const expected = path.join("companies", companySlug, "projects", projectId, "prd.json");
114
+ if (path.normalize(relativePath) !== expected) {
115
+ throw new LanesError("lead_autopilot_tenant_mismatch", `Project registry path does not match lead ${companySlug}/${projectId}`, { path: relativePath, company: companySlug, project_id: projectId });
116
+ }
117
+ }
118
+ const file = registeredFilePath(hqRoot, relativePath, "lead_autopilot_project_path_invalid");
119
+ const raw = readJsonFile(file, "lead_autopilot_project_invalid");
120
+ const rows = isRecord(raw) ? raw.userStories ?? raw.stories : undefined;
121
+ if (!Array.isArray(rows)) {
122
+ throw new LanesError("lead_autopilot_project_invalid", `Invalid project ${file}: userStories or stories must be an array`, { path: file });
123
+ }
124
+ return rows.map((story, index) => {
125
+ const rawStatus = isRecord(story) ? story.status ?? story.state : undefined;
126
+ const status = isRecord(story) && story.passes === true ? "done" : rawStatus;
127
+ if (!isRecord(story) || typeof story.id !== "string" || typeof status !== "string") {
128
+ throw new LanesError("lead_autopilot_project_invalid", `Invalid project ${file}: stories[${index}] needs string id and status/state`, { path: file, index });
129
+ }
130
+ const sourceRef = isRecord(story.source) ? story.source.ref : undefined;
131
+ const rawBrief = story.brief_path ?? story.brief_file ?? sourceRef;
132
+ if (story.lanes !== undefined && (!Array.isArray(story.lanes) || story.lanes.some((lane) => typeof lane === "string" ? !lane.trim() : !isRecord(lane) || typeof lane.lane_id !== "string" || !lane.lane_id.trim()))) {
133
+ throw new LanesError("lead_autopilot_project_invalid", `Invalid project ${file}: stories[${index}] lanes must contain lane IDs or lane_id objects`, { path: file, index });
134
+ }
135
+ if (story.updated_at !== undefined && (typeof story.updated_at !== "string" || !Number.isFinite(Date.parse(story.updated_at)))) {
136
+ throw new LanesError("lead_autopilot_project_invalid", `Invalid project ${file}: stories[${index}] updated_at must be a valid timestamp`, { path: file, index });
137
+ }
138
+ if (story.lane !== undefined && story.lane !== null && typeof story.lane !== "string") {
139
+ throw new LanesError("lead_autopilot_project_invalid", `Invalid project ${file}: stories[${index}] lane must be a string`, { path: file, index });
140
+ }
141
+ if (story.external_blocker !== undefined && (typeof story.external_blocker !== "string" || !story.external_blocker.trim())) {
142
+ throw new LanesError("lead_autopilot_project_invalid", `Invalid project ${file}: stories[${index}] external_blocker must be a non-empty string`, { path: file, index });
143
+ }
144
+ if (rawBrief !== undefined && (typeof rawBrief !== "string" || !rawBrief.trim())) {
145
+ throw new LanesError("lead_autopilot_project_invalid", `Invalid project ${file}: stories[${index}] brief path must be a non-empty string`, { path: file, index });
146
+ }
147
+ if (typeof rawBrief === "string" && companySlug !== undefined) {
148
+ const normalizedBrief = path.normalize(rawBrief);
149
+ if (normalizedBrief.startsWith(`companies${path.sep}`) && !normalizedBrief.startsWith(path.join("companies", companySlug) + path.sep)) {
150
+ throw new LanesError("lead_autopilot_tenant_mismatch", `Story brief path does not match lead ${companySlug}/${projectId}`, { path: rawBrief, company: companySlug, project_id: projectId });
151
+ }
152
+ }
153
+ let briefPath;
154
+ if (typeof rawBrief === "string") {
155
+ briefPath = registeredFilePath(hqRoot, rawBrief, "lead_autopilot_story_brief_path_invalid");
156
+ try {
157
+ const briefStat = fs.lstatSync(briefPath);
158
+ if (!briefStat.isFile() || briefStat.isSymbolicLink())
159
+ throw new Error("expected a regular file");
160
+ }
161
+ catch (error) {
162
+ throw new LanesError("lead_autopilot_story_brief_invalid", `Cannot read story brief ${rawBrief}: ${error instanceof Error ? error.message : String(error)}`, { path: rawBrief, story_id: story.id });
163
+ }
164
+ }
165
+ return {
166
+ id: story.id,
167
+ status,
168
+ ...(story.passes === true ? { passes: true } : {}),
169
+ ...(briefPath ? { briefPath } : {}),
170
+ ...storyLaneIds(story),
171
+ ...(typeof story.updated_at === "string" ? { updatedAt: story.updated_at } : {}),
172
+ ...(typeof story.external_blocker === "string" ? { externalBlocker: story.external_blocker } : {}),
173
+ deadlineFields: story,
174
+ };
175
+ });
176
+ }
177
+ const DEADLINE_FIELDS = ["deadline", "due_at", "unblock_by", "unblock_at", "eta"];
178
+ const CLOSED_COMMITMENT_STATES = new Set(["done", "resolved", "closed", "cancelled", "canceled", "dropped", "complete", "completed"]);
179
+ const COMMITMENT_SECTIONS = ["open_blockers", "waiting", "open_decisions", "decisions", "slot_requests", "blockers"];
180
+ function hasDeadlineField(value) {
181
+ return DEADLINE_FIELDS.some((field) => value[field] !== undefined && value[field] !== null && value[field] !== "");
182
+ }
183
+ function commitmentDue(value, context) {
184
+ const dates = [];
185
+ const errors = [];
186
+ for (const field of DEADLINE_FIELDS) {
187
+ const raw = value[field];
188
+ if (raw === undefined || raw === null || raw === "")
189
+ continue;
190
+ if (typeof raw !== "string" || !/^\d{4}-\d\d-\d\dT\d\d:\d\d(?::\d\d(?:\.\d{1,9})?)?(?:Z|[+-]\d\d:\d\d)$/.test(raw) || !Number.isFinite(Date.parse(raw))) {
191
+ // `eta` is also used as free-text planning context in manager and story
192
+ // records. It is a deadline only when it is already a valid ISO instant.
193
+ if (field === "eta")
194
+ continue;
195
+ errors.push({ field, reason: `${context}.${field} must be a valid date-time` });
196
+ continue;
197
+ }
198
+ dates.push({ field, iso: new Date(Date.parse(raw)).toISOString() });
199
+ }
200
+ if (errors.length > 0)
201
+ return { due: null, errors };
202
+ if (dates.length === 0)
203
+ return { due: null, errors };
204
+ if (new Set(dates.map((date) => date.iso)).size > 1) {
205
+ return { due: null, errors: [{ field: "deadline_fields", reason: `${context} has conflicting deadline fields` }] };
206
+ }
207
+ return { due: dates[0].iso, errors };
208
+ }
209
+ function isResolvedCommitment(value, status) {
210
+ return value.passes === true || value.resolved === true || value.open === false ||
211
+ value.resolved_at !== undefined && value.resolved_at !== null ||
212
+ value.completed_at !== undefined && value.completed_at !== null ||
213
+ (typeof status === "string" && CLOSED_COMMITMENT_STATES.has(status.toLowerCase()));
214
+ }
215
+ function optionalLabel(value, fields, fallback) {
216
+ for (const field of fields) {
217
+ const candidate = value[field];
218
+ if (typeof candidate === "string" && candidate.trim())
219
+ return candidate.trim();
220
+ }
221
+ return fallback;
222
+ }
223
+ function deadlineCommitments(status, stories, leadLane) {
224
+ const commitments = [];
225
+ const errors = [];
226
+ for (const section of COMMITMENT_SECTIONS) {
227
+ const rows = status[section];
228
+ if (rows === undefined)
229
+ continue;
230
+ if (!Array.isArray(rows)) {
231
+ errors.push({ lead_lane: leadLane, item_ref: `manager:${section}`, field: section, reason: `Manager status ${section} must be an array` });
232
+ continue;
233
+ }
234
+ rows.forEach((row, index) => {
235
+ if (!isRecord(row) || !hasDeadlineField(row))
236
+ return;
237
+ const itemRef = `manager:${section}[${index}]`;
238
+ const dueResult = commitmentDue(row, `Manager status ${section}[${index}]`);
239
+ errors.push(...dueResult.errors.map((error) => ({ lead_lane: leadLane, item_ref: itemRef, ...error })));
240
+ if (dueResult.errors.length > 0 || !dueResult.due)
241
+ return;
242
+ const id = row.id;
243
+ if (typeof id !== "string" || !id.trim()) {
244
+ errors.push({ lead_lane: leadLane, item_ref: itemRef, field: "id", reason: `Manager status ${section}[${index}] with a deadline needs a non-empty id` });
245
+ return;
246
+ }
247
+ const owner = optionalLabel(row, ["owner", "unblock_owner", "waiting_on", "assigned_to"], "unassigned");
248
+ const state = typeof row.status === "string" ? row.status : typeof row.state === "string" ? row.state : undefined;
249
+ commitments.push({
250
+ key: `manager:${section}:${id}`,
251
+ item: id,
252
+ owner,
253
+ due: dueResult.due,
254
+ description: optionalLabel(row, ["what", "question", "request", "title", "line"], id),
255
+ resolved: isResolvedCommitment(row, state),
256
+ });
257
+ });
258
+ }
259
+ for (const story of stories) {
260
+ const raw = story.deadlineFields;
261
+ if (!raw || !hasDeadlineField(raw))
262
+ continue;
263
+ const dueResult = commitmentDue(raw, `Project story ${story.id}`);
264
+ errors.push(...dueResult.errors.map((error) => ({ lead_lane: leadLane, item_ref: `story:${story.id}`, ...error })));
265
+ if (dueResult.errors.length > 0 || !dueResult.due)
266
+ continue;
267
+ const state = typeof raw.status === "string" ? raw.status : typeof raw.state === "string" ? raw.state : story.status;
268
+ commitments.push({
269
+ key: `story:${story.id}`,
270
+ item: story.id,
271
+ owner: optionalLabel(raw, ["owner", "assigned_to"], "lead"),
272
+ due: dueResult.due,
273
+ description: optionalLabel(raw, ["title", "name", "what"], story.id),
274
+ resolved: isResolvedCommitment(raw, state),
275
+ });
276
+ }
277
+ return { commitments: commitments.sort((a, b) => a.key.localeCompare(b.key)), errors };
278
+ }
279
+ function readStatus(hqRoot, relativePath, companySlug) {
280
+ if (path.isAbsolute(relativePath)) {
281
+ throw new LanesError("lead_autopilot_status_path_invalid", `Registered status path must be relative to the HQ root: ${relativePath}`, { path: relativePath });
282
+ }
283
+ const root = path.resolve(hqRoot);
284
+ const file = registeredFilePath(root, relativePath, "lead_autopilot_status_path_invalid");
285
+ const assertCompanyBoundary = (candidate) => {
286
+ const relative = path.relative(root, candidate).split(path.sep);
287
+ if (relative[0] === "companies" && relative[1] !== companySlug) {
288
+ throw new LanesError("lead_autopilot_tenant_mismatch", `Manager status path does not match lead company ${companySlug}`, { path: relativePath, company: companySlug });
289
+ }
290
+ };
291
+ assertCompanyBoundary(path.resolve(root, relativePath));
292
+ assertCompanyBoundary(fs.realpathSync(file));
293
+ const status = readJsonFile(file, "lead_autopilot_status_invalid");
294
+ if (!isRecord(status))
295
+ throw new LanesError("lead_autopilot_status_invalid", `Invalid manager status ${file}: expected an object`, { path: file });
296
+ return status;
297
+ }
298
+ function parseOkrReports(status) {
299
+ const raw = status.okr_reports;
300
+ if (raw === undefined)
301
+ return [];
302
+ if (!Array.isArray(raw)) {
303
+ throw new LanesError("lead_autopilot_okr_reports_invalid", "Manager status okr_reports must be an array");
304
+ }
305
+ return raw.map((value, index) => {
306
+ if (!isRecord(value) || typeof value.at !== "string" || !Number.isFinite(Date.parse(value.at)) || !Array.isArray(value.kpis) || !Array.isArray(value.okrs)) {
307
+ throw new LanesError("lead_autopilot_okr_reports_invalid", `Manager status okr_reports[${index}] must include at, kpis, and okrs`);
308
+ }
309
+ const parseLines = (rows, kind) => rows.map((row, lineIndex) => {
310
+ if (!isRecord(row) || typeof row.id !== "string" || !row.id.trim()) {
311
+ throw new LanesError("lead_autopilot_okr_reports_invalid", `Manager status okr_reports[${index}].${kind.toLowerCase()}s[${lineIndex}] needs an id`);
312
+ }
313
+ const text = typeof row.line === "string" ? row.line : typeof row.name === "string" ? row.name : typeof row.objective === "string" ? row.objective : "";
314
+ if (!text.trim()) {
315
+ throw new LanesError("lead_autopilot_okr_reports_invalid", `Manager status okr_reports[${index}].${kind.toLowerCase()}s[${lineIndex}] needs a line, name, or objective`);
316
+ }
317
+ if ((row.value !== undefined && (typeof row.value !== "number" || !Number.isFinite(row.value))) ||
318
+ (row.moved !== undefined && (typeof row.moved !== "number" || !Number.isFinite(row.moved)))) {
319
+ throw new LanesError("lead_autopilot_okr_reports_invalid", `Manager status okr_reports[${index}].${kind.toLowerCase()}s[${lineIndex}] has invalid numeric progress`);
320
+ }
321
+ return { id: row.id, line: text, ...(typeof row.value === "number" ? { value: row.value } : {}), ...(typeof row.moved === "number" ? { moved: row.moved } : {}) };
322
+ });
323
+ return { at: value.at, kpis: parseLines(value.kpis, "KPI"), okrs: parseLines(value.okrs, "OKR") };
324
+ }).sort((a, b) => a.at.localeCompare(b.at));
325
+ }
326
+ // A story's current `lane` counts alongside its `lanes` history, so `lanes: []` with `lane: X` is assigned to X.
327
+ function storyLaneIds(story) {
328
+ const history = Array.isArray(story.lanes)
329
+ ? story.lanes.map((lane) => typeof lane === "string" ? lane : lane.lane_id)
330
+ : undefined;
331
+ const current = typeof story.lane === "string" && story.lane.trim() ? story.lane : undefined;
332
+ if (history)
333
+ return { laneIds: current && !history.includes(current) ? [...history, current] : history };
334
+ if (current)
335
+ return { laneIds: [current] };
336
+ return story.lane === "" ? { laneIds: [] } : {};
337
+ }
338
+ function statusBlockers(status) {
339
+ const raw = status.blockers;
340
+ if (raw === undefined)
341
+ return [];
342
+ if (!Array.isArray(raw))
343
+ throw new LanesError("lead_autopilot_status_invalid", "Manager status blockers must be an array");
344
+ return raw.map((value, index) => {
345
+ if (!isRecord(value) || typeof value.id !== "string" || !value.id.trim()) {
346
+ throw new LanesError("lead_autopilot_status_invalid", `Manager status blockers[${index}] needs a non-empty id`);
347
+ }
348
+ return value;
349
+ });
350
+ }
351
+ function managerKpiFreshness(status, now) {
352
+ const rawKpis = status.kpis;
353
+ if (rawKpis === undefined)
354
+ return [];
355
+ if (!Array.isArray(rawKpis)) {
356
+ return [{
357
+ name: "kpis",
358
+ measuredAt: null,
359
+ ageMinutes: null,
360
+ stale: false,
361
+ staleAfterMinutes: LEAD_AUTOPILOT_KPI_STALE_AFTER_MINUTES,
362
+ fingerprint: "",
363
+ error: "invalid_kpi",
364
+ }];
365
+ }
366
+ return rawKpis.map((value, index) => {
367
+ const invalid = () => {
368
+ let name = `KPI ${index + 1}`;
369
+ if (isRecord(value)) {
370
+ const rawName = typeof value.name === "string" ? value.name : value.id;
371
+ if (typeof rawName === "string" && rawName.trim())
372
+ name = rawName.trim();
373
+ }
374
+ return {
375
+ name,
376
+ measuredAt: null,
377
+ ageMinutes: null,
378
+ stale: false,
379
+ staleAfterMinutes: LEAD_AUTOPILOT_KPI_STALE_AFTER_MINUTES,
380
+ fingerprint: "",
381
+ ...(isRecord(value) && typeof value.status === "string" ? { status: value.status } : {}),
382
+ error: "invalid_kpi",
383
+ };
384
+ };
385
+ if (!isRecord(value)) {
386
+ return invalid();
387
+ }
388
+ const rawName = typeof value.name === "string" ? value.name : value.id;
389
+ if (typeof rawName !== "string" || !rawName.trim()) {
390
+ return invalid();
391
+ }
392
+ const staleAfterMinutes = value.stale_after_minutes === undefined
393
+ ? LEAD_AUTOPILOT_KPI_STALE_AFTER_MINUTES
394
+ : value.stale_after_minutes;
395
+ if (typeof staleAfterMinutes !== "number" || !Number.isSafeInteger(staleAfterMinutes) || staleAfterMinutes < 1 || staleAfterMinutes > 525_600) {
396
+ return invalid();
397
+ }
398
+ const measuredAt = typeof value.measured_at === "string" && Number.isFinite(Date.parse(value.measured_at))
399
+ ? new Date(Date.parse(value.measured_at)).toISOString()
400
+ : null;
401
+ const elapsedMs = measuredAt === null ? null : Math.max(0, now.getTime() - Date.parse(measuredAt));
402
+ const ageMinutes = elapsedMs === null ? null : Math.floor(elapsedMs / 60_000);
403
+ const terminalStatus = typeof value.status === "string" && ["superseded", "retired", "dropped"].includes(value.status.toLowerCase());
404
+ const stale = !terminalStatus && (elapsedMs === null || elapsedMs > staleAfterMinutes * 60_000);
405
+ const fingerprint = `stale-kpi:${createHash("sha256").update(JSON.stringify([rawName.trim(), measuredAt, value.value ?? null])).digest("hex")}`;
406
+ return {
407
+ name: rawName.trim(),
408
+ measuredAt,
409
+ ageMinutes,
410
+ stale,
411
+ staleAfterMinutes,
412
+ fingerprint,
413
+ ...(typeof value.status === "string" ? { status: value.status } : {}),
414
+ };
415
+ });
416
+ }
417
+ function leastMoved(lines, priorLines = []) {
418
+ const priorById = new Map(priorLines.map((line) => [line.id, line]));
419
+ return [...lines].sort((a, b) => {
420
+ const moved = (line) => line.moved !== undefined ? Math.abs(line.moved) :
421
+ line.value !== undefined && priorById.get(line.id)?.value !== undefined ? Math.abs(line.value - priorById.get(line.id).value) : 0;
422
+ return moved(a) - moved(b) || a.id.localeCompare(b.id);
423
+ })[0];
424
+ }
425
+ export function planLeadAutopilotWakes(input) {
426
+ const { lead, children, stories, now } = input;
427
+ if (input.keepAliveResumed)
428
+ return [];
429
+ const status = input.managerStatus ?? {};
430
+ const reports = parseOkrReports(status);
431
+ const blockers = statusBlockers(status);
432
+ const byStory = new Map(stories.map((story) => [story.id, story]));
433
+ const wakes = [];
434
+ if (input.kpiStalenessEnabled) {
435
+ const staleKpis = managerKpiFreshness(status, now).filter((kpi) => kpi.stale);
436
+ if (input.kpiStalenessBatchEnabled && staleKpis.length > 0) {
437
+ const byOldest = [...staleKpis].sort((a, b) => (b.ageMinutes ?? Number.MAX_SAFE_INTEGER) - (a.ageMinutes ?? Number.MAX_SAFE_INTEGER) ||
438
+ a.name.localeCompare(b.name));
439
+ const identity = staleKpis
440
+ .map(({ name, measuredAt }) => [name, measuredAt])
441
+ .sort(([nameA, measuredAtA], [nameB, measuredAtB]) => nameA.localeCompare(nameB) || String(measuredAtA).localeCompare(String(measuredAtB)));
442
+ const fingerprint = `stale-kpi-batch:${createHash("sha256").update(JSON.stringify(identity)).digest("hex")}`;
443
+ const details = byOldest.map((kpi) => `- ${kpi.name}: age ${kpi.ageMinutes === null ? "unknown" : kpi.ageMinutes} minutes (stale after ${kpi.staleAfterMinutes} minutes)`).join("\n");
444
+ wakes.push({
445
+ condition: "stale_kpi",
446
+ lead_lane: lead.lane_id,
447
+ story_id: "kpi-staleness",
448
+ kpi_id: "batch",
449
+ fingerprint,
450
+ prompt: `Re-measure these stale KPIs, oldest first:\n${details}\nUpdate measured_at in manager-status.json. Follow ${LEAD_AUTOPILOT_PROMPT_LOOP}.`,
451
+ });
452
+ }
453
+ else {
454
+ for (const kpi of staleKpis) {
455
+ const age = kpi.ageMinutes === null
456
+ ? "its measurement age is unknown"
457
+ : `its latest measurement is ${kpi.ageMinutes} minutes old`;
458
+ wakes.push({
459
+ condition: "stale_kpi",
460
+ lead_lane: lead.lane_id,
461
+ story_id: "kpi-staleness",
462
+ kpi_id: kpi.name,
463
+ fingerprint: kpi.fingerprint,
464
+ prompt: `Re-measure KPI ${kpi.name}: ${age} (stale after ${kpi.staleAfterMinutes} minutes). Update measured_at in manager-status.json. Follow ${LEAD_AUTOPILOT_PROMPT_LOOP}.`,
465
+ });
466
+ }
467
+ }
468
+ }
469
+ const finishedReviews = children.flatMap((child) => {
470
+ if (!["done", "blocked", "failed", "interrupted"].includes(child.state))
471
+ return [];
472
+ const story = byStory.get(child.story_id);
473
+ if (!story || !isOpenProjectStory(story))
474
+ return [];
475
+ const finishedAt = child.ended_at ?? child.updated_at;
476
+ const finishedMs = Date.parse(finishedAt);
477
+ if (!Number.isFinite(finishedMs) || now.getTime() - finishedMs < LEAD_AUTOPILOT_REVIEW_DELAY_MS)
478
+ return [];
479
+ return [{ laneId: child.lane_id, story, finishedAt }];
480
+ });
481
+ const knownChildIds = new Set(children.map((child) => child.lane_id));
482
+ const missingReviews = stories.flatMap((story) => {
483
+ if (!isOpenProjectStory(story) || !story.updatedAt || !story.laneIds)
484
+ return [];
485
+ const finishedMs = Date.parse(story.updatedAt);
486
+ if (!Number.isFinite(finishedMs) || now.getTime() - finishedMs < LEAD_AUTOPILOT_REVIEW_DELAY_MS)
487
+ return [];
488
+ // The lead's own lane is never a finished worker of itself.
489
+ return story.laneIds.filter((laneId) => laneId !== lead.lane_id && !knownChildIds.has(laneId))
490
+ .map((laneId) => ({ laneId, story, finishedAt: story.updatedAt }));
491
+ });
492
+ const overdueReviews = [...finishedReviews, ...missingReviews].sort((a, b) => a.laneId.localeCompare(b.laneId));
493
+ if (overdueReviews.length > 0) {
494
+ const fingerprint = `review:${overdueReviews.map(({ laneId, story, finishedAt }) => `${laneId}:${story.id}:${story.status}:${finishedAt}`).join(",")}`;
495
+ const reviewList = overdueReviews.map(({ laneId, story }) => `lane ${laneId} (story ${story.id}, status ${story.status})`).join("; ");
496
+ wakes.push({
497
+ condition: "review_finished_worker",
498
+ lead_lane: lead.lane_id,
499
+ story_id: overdueReviews.map(({ story }) => story.id).join(","),
500
+ ...(overdueReviews.length === 1 ? { worker_lane: overdueReviews[0].laneId } : {}),
501
+ fingerprint,
502
+ prompt: `Review finished worker ${overdueReviews.length === 1 ? "lane" : "lanes"}: ${reviewList}. Follow ${LEAD_AUTOPILOT_PROMPT_LOOP}.`,
503
+ });
504
+ }
505
+ const liveChildren = children.filter((child) => LIVE_STATES.has(child.state));
506
+ const liveCount = liveChildren.length;
507
+ const assigned = new Set(liveChildren.flatMap((child) => [child.story_id, ...(child.stories ?? []).map((story) => story.story_id)]));
508
+ const readyStory = stories.find((story) => story.status === "todo" && !story.passes && !assigned.has(story.id));
509
+ if (readyStory && liveCount < (lead.hire_grant ?? 0)) {
510
+ const fingerprint = `fill:${readyStory.id}:${liveCount}:${lead.hire_grant ?? 0}`;
511
+ wakes.push({
512
+ condition: "fill_grant",
513
+ lead_lane: lead.lane_id,
514
+ story_id: readyStory.id,
515
+ fingerprint,
516
+ prompt: `Start a worker for ready story ${readyStory.id}. You have ${liveCount} live workers against a grant of ${lead.hire_grant ?? 0}. Follow ${LEAD_AUTOPILOT_PROMPT_LOOP}.`,
517
+ });
518
+ }
519
+ const hasFreeSlots = liveCount < (lead.hire_grant ?? 0);
520
+ if (hasFreeSlots && !readyStory) {
521
+ const latest = reports.at(-1);
522
+ const previous = reports.at(-2);
523
+ const kpiLine = latest ? leastMoved(latest.kpis, previous?.kpis) : undefined;
524
+ const okrLine = latest ? leastMoved(latest.okrs, previous?.okrs) : undefined;
525
+ const kpiText = kpiLine?.line ?? "no KPI line in the latest OKR report";
526
+ const okrText = okrLine?.line ?? "no OKR line in the latest OKR report";
527
+ const fingerprint = `plan:${latest?.at ?? "no-report"}:${kpiLine?.id ?? "no-kpi"}:${okrLine?.id ?? "no-okr"}:${stories.map((story) => `${story.id}:${story.status}`).sort().join(",")}`;
528
+ wakes.push({ condition: "plan_free_slots", lead_lane: lead.lane_id, story_id: "planning", fingerprint,
529
+ prompt: `You have ${liveCount} live workers against a grant of ${lead.hire_grant ?? 0} and no ready stories. Plan work against the least-moved KPI line: ${kpiText}; and OKR line: ${okrText}. Follow ${LEAD_AUTOPILOT_PROMPT_LOOP}.` });
530
+ }
531
+ if (reports.length >= 2) {
532
+ const latest = reports.at(-1);
533
+ const prior = new Map(reports.at(-2).kpis.filter((line) => line.value !== undefined).map((line) => [line.id, line]));
534
+ const flat = latest.kpis.filter((line) => line.value !== undefined && prior.get(line.id)?.value === line.value);
535
+ if (flat.length > 0) {
536
+ const line = flat.map((item) => `${item.line} (${item.value})`).join("; ");
537
+ const fingerprint = `flat-kpi:${latest.at}:${flat.map((item) => `${item.id}:${item.value}`).join(",")}`;
538
+ wakes.push({ condition: "flat_kpi", lead_lane: lead.lane_id, story_id: flat.map((item) => item.id).join(","), fingerprint,
539
+ prompt: `KPI line(s) remained flat across the two latest OKR reports: ${line}. Re-plan the affected line(s). Follow ${LEAD_AUTOPILOT_PROMPT_LOOP}.` });
540
+ }
541
+ }
542
+ const staleBlockers = blockers.filter((blocker) => {
543
+ const blockerStatus = blocker.status ?? blocker.state;
544
+ const resolved = blockerStatus === "resolved" || blocker.resolved_at !== undefined && blocker.resolved_at !== null;
545
+ const owner = typeof blocker.unblock_owner === "string" ? blocker.unblock_owner : blocker.owner;
546
+ const due = blocker.unblock_by ?? blocker.unblock_at ?? blocker.due_at;
547
+ const ownerMissing = typeof owner !== "string" || !owner.trim();
548
+ const dueMissing = typeof due !== "string" || !Number.isFinite(Date.parse(due));
549
+ return resolved || ownerMissing || dueMissing;
550
+ });
551
+ if (staleBlockers.length > 0) {
552
+ const labels = staleBlockers.map((blocker) => `${String(blocker.id)}${typeof blocker.what === "string" ? ` (${blocker.what})` : ""}`).join("; ");
553
+ const fingerprint = `blockers:${staleBlockers.map((blocker) => `${String(blocker.id)}:${String(blocker.status ?? blocker.state ?? "")}:${String(blocker.resolved_at ?? "")}:${String(blocker.unblock_owner ?? blocker.owner ?? "")}:${String(blocker.unblock_by ?? blocker.unblock_at ?? blocker.due_at ?? "")}`).join(",")}`;
554
+ wakes.push({ condition: "blocker_record_needs_update", lead_lane: lead.lane_id, story_id: staleBlockers.map((blocker) => String(blocker.id)).join(","), fingerprint,
555
+ prompt: `Fix blocker records still listed as resolved or missing an unblock owner/time: ${labels}. Move resolved blockers out of blockers, and give every open blocker an owner and time. Follow ${LEAD_AUTOPILOT_PROMPT_LOOP}.` });
556
+ }
557
+ if (stories.length > 0 && stories.every((story) => story.passes === true || story.status === "done" || story.status === "dropped" ||
558
+ ((story.status === "parked" || story.status === "blocked") && Boolean(story.externalBlocker)))) {
559
+ const fingerprint = `project-close:${stories.map((story) => `${story.id}:${story.status}:${story.externalBlocker ?? ""}`).sort().join(",")}`;
560
+ wakes.push({ condition: "project_ready_to_close", lead_lane: lead.lane_id, story_id: stories.map((story) => story.id).join(","), fingerprint,
561
+ prompt: `Every story is done, dropped, or parked on a named external blocker. Write the final report and mark the project complete. Follow ${LEAD_AUTOPILOT_PROMPT_LOOP}.` });
562
+ }
563
+ const staleLedger = stories.flatMap((story) => {
564
+ if (story.status !== "in_progress" || !story.updatedAt || !story.laneIds)
565
+ return [];
566
+ const updated = Date.parse(story.updatedAt);
567
+ if (!Number.isFinite(updated) || now.getTime() - updated <= 30 * 60_000)
568
+ return [];
569
+ return story.laneIds.flatMap((laneId) => {
570
+ const worker = children.find((child) => child.lane_id === laneId && child.state === "running" &&
571
+ (child.story_id === story.id || (child.stories ?? []).some((carried) => carried.story_id === story.id)));
572
+ return worker ? [{ story, worker }] : [];
573
+ });
574
+ }).sort((a, b) => a.story.id.localeCompare(b.story.id) || a.worker.lane_id.localeCompare(b.worker.lane_id));
575
+ if (staleLedger.length > 0) {
576
+ const labels = staleLedger.map(({ story, worker }) => `${story.id} (lane ${worker.lane_id}, ledger updated ${story.updatedAt})`).join("; ");
577
+ const fingerprint = `stale-ledger:${staleLedger.map(({ story, worker }) => `${story.id}:${worker.lane_id}:${story.updatedAt}`).join(",")}`;
578
+ wakes.push({ condition: "stale_worker_ledger", lead_lane: lead.lane_id, story_id: staleLedger.map(({ story }) => story.id).join(","), worker_lane: staleLedger.length === 1 ? staleLedger[0].worker.lane_id : undefined, fingerprint,
579
+ prompt: `A running worker has made no ledger update in over 30 minutes: ${labels}. Check the worker and update the story ledger. Follow ${LEAD_AUTOPILOT_PROMPT_LOOP}.` });
580
+ }
581
+ const withoutLiveLane = stories.flatMap((story) => {
582
+ if (story.status !== "in_progress")
583
+ return [];
584
+ const laneIds = story.laneIds ?? [];
585
+ // A story assigned to the lead itself is worked by the lead, which is the lane being woken.
586
+ if (laneIds.includes(lead.lane_id))
587
+ return [];
588
+ const live = laneIds.filter((laneId) => children.some((child) => child.lane_id === laneId && LIVE_STATES.has(child.state)));
589
+ if (live.length > 0)
590
+ return [];
591
+ const detail = laneIds.length === 0 ? "empty lane assignment" : `no live lane among ${laneIds.join(", ")}`;
592
+ return [{ story, laneIds, detail }];
593
+ }).sort((a, b) => a.story.id.localeCompare(b.story.id));
594
+ if (withoutLiveLane.length > 0) {
595
+ const labels = withoutLiveLane.map(({ story, detail }) => `${story.id} (${detail})`).join("; ");
596
+ const fingerprint = `missing-worker:${withoutLiveLane.map(({ story, detail }) => `${story.id}:${story.updatedAt ?? ""}:${detail}`).join(",")}`;
597
+ wakes.push({ condition: "story_without_live_lane", lead_lane: lead.lane_id, story_id: withoutLiveLane.map(({ story }) => story.id).join(","), fingerprint,
598
+ prompt: `In-progress story has no live worker lane: ${labels}. Relaunch a worker or set the story to waiting/blocked with its wake. Follow ${LEAD_AUTOPILOT_PROMPT_LOOP}.` });
599
+ }
600
+ return wakes;
601
+ }
602
+ function readState(file) {
603
+ if (!fs.existsSync(file))
604
+ return { schema_version: "hq-lanes-autopilot-state.v1", sent: {}, deadline_misses: {} };
605
+ const value = readJsonFile(file, "lead_autopilot_state_invalid");
606
+ if (!isRecord(value) || value.schema_version !== "hq-lanes-autopilot-state.v1" || !isRecord(value.sent) ||
607
+ (value.delivered_ids !== undefined && !isRecord(value.delivered_ids)) ||
608
+ (value.deadline_misses !== undefined && !isRecord(value.deadline_misses)) ||
609
+ (value.per_lead_error_notices !== undefined && (!isRecord(value.per_lead_error_notices) || Object.values(value.per_lead_error_notices).some((id) => typeof id !== "string")))) {
610
+ throw new LanesError("lead_autopilot_state_invalid", `Invalid autopilot state ${file}`, { path: file });
611
+ }
612
+ for (const [key, row] of Object.entries(value.sent)) {
613
+ if (!isRecord(row) || typeof row.fingerprint !== "string" || typeof row.at !== "string" ||
614
+ (row.status_updated_at !== undefined && typeof row.status_updated_at !== "string") ||
615
+ (row.acted !== undefined && typeof row.acted !== "boolean") ||
616
+ (row.auto_started !== undefined && typeof row.auto_started !== "boolean") ||
617
+ (row.worker_lane !== undefined && typeof row.worker_lane !== "string") ||
618
+ (row.wake_count !== undefined && (!Number.isSafeInteger(row.wake_count) || row.wake_count < 1)) ||
619
+ (row.last_wake_at !== undefined && typeof row.last_wake_at !== "string") ||
620
+ (row.escalated_at !== undefined && typeof row.escalated_at !== "string") ||
621
+ (row.inactive_since !== undefined && (typeof row.inactive_since !== "string" || !Number.isFinite(Date.parse(row.inactive_since))))) {
622
+ throw new LanesError("lead_autopilot_state_invalid", `Invalid autopilot state entry ${key}`, { path: file, key });
623
+ }
624
+ }
625
+ for (const [key, row] of Object.entries(value.deadline_misses ?? {})) {
626
+ if (!isRecord(row) || typeof row.item !== "string" || typeof row.owner !== "string" ||
627
+ typeof row.due_at !== "string" || !Number.isFinite(Date.parse(row.due_at)) ||
628
+ !Number.isSafeInteger(row.miss_count) || row.miss_count < 1 ||
629
+ typeof row.first_missed_at !== "string" || !Number.isFinite(Date.parse(row.first_missed_at)) ||
630
+ typeof row.currently_missed !== "boolean" ||
631
+ (row.escalated_at !== undefined && (typeof row.escalated_at !== "string" || !Number.isFinite(Date.parse(row.escalated_at))))) {
632
+ throw new LanesError("lead_autopilot_state_invalid", `Invalid missed-deadline state entry ${key}`, { path: file, key });
633
+ }
634
+ }
635
+ for (const [messageId, deliveredAt] of Object.entries(value.delivered_ids ?? {})) {
636
+ if (!messageId.trim() || typeof deliveredAt !== "string" || !Number.isFinite(Date.parse(deliveredAt))) {
637
+ throw new LanesError("lead_autopilot_state_invalid", `Invalid delivered message id ${messageId}`, { path: file, message_id: messageId });
638
+ }
639
+ }
640
+ return {
641
+ ...value,
642
+ per_lead_error_notices: (value.per_lead_error_notices ?? {}),
643
+ };
644
+ }
645
+ function appendAutopilotMessage(input) {
646
+ if (input.dedupeEnabled && input.state.delivered_ids?.[input.message.message_id])
647
+ return false;
648
+ appendDropboxMessage(input.hqRoot, input.leadLane, input.message);
649
+ if (input.dedupeEnabled) {
650
+ input.state.delivered_ids ??= {};
651
+ input.state.delivered_ids[input.message.message_id] = input.message.at;
652
+ }
653
+ return true;
654
+ }
655
+ function removeDeliveredIdsForFingerprint(state, fingerprint) {
656
+ const prefix = `lead-autopilot:${fingerprint}`;
657
+ let removed = false;
658
+ for (const messageId of Object.keys(state.delivered_ids ?? {})) {
659
+ if (messageId.startsWith(prefix)) {
660
+ delete state.delivered_ids[messageId];
661
+ removed = true;
662
+ }
663
+ }
664
+ return removed;
665
+ }
666
+ function pruneDeliveredIds(state, now) {
667
+ let pruned = false;
668
+ for (const [messageId, deliveredAt] of Object.entries(state.delivered_ids ?? {})) {
669
+ if (now.getTime() - Date.parse(deliveredAt) > LEAD_AUTOPILOT_DELIVERED_ID_RETENTION_MS) {
670
+ delete state.delivered_ids[messageId];
671
+ pruned = true;
672
+ }
673
+ }
674
+ return pruned;
675
+ }
676
+ function writeState(file, state) {
677
+ fs.mkdirSync(path.dirname(file), { recursive: true });
678
+ const temp = `${file}.${process.pid}.tmp`;
679
+ fs.writeFileSync(temp, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 });
680
+ fs.renameSync(temp, file);
681
+ }
682
+ function recordOperatorEscalation(hqRoot, record) {
683
+ const file = path.join(hqRoot, "workspace", "lane-briefs", "ops-board-state.json");
684
+ let state = {};
685
+ if (fs.existsSync(file)) {
686
+ const value = readJsonFile(file, "lead_autopilot_escalation_record_invalid");
687
+ if (!isRecord(value))
688
+ throw new LanesError("lead_autopilot_escalation_record_invalid", `Invalid operator board state ${file}`);
689
+ state = value;
690
+ }
691
+ const current = state.autopilot_escalations;
692
+ if (current !== undefined && (!Array.isArray(current) || current.some((item) => !isRecord(item)))) {
693
+ throw new LanesError("lead_autopilot_escalation_record_invalid", `Invalid autopilot escalations in ${file}`);
694
+ }
695
+ const rows = (current ?? []);
696
+ if (rows.some((item) => item.lead_lane === record.lead_lane && item.fingerprint === record.fingerprint))
697
+ return;
698
+ const next = { ...state, autopilot_escalations: [...rows, record] };
699
+ fs.mkdirSync(path.dirname(file), { recursive: true });
700
+ const temp = `${file}.${process.pid}.tmp`;
701
+ fs.writeFileSync(temp, `${JSON.stringify(next, null, 2)}\n`, { mode: 0o600 });
702
+ fs.renameSync(temp, file);
703
+ }
704
+ async function runLeadAutopilotPassUnlocked(input) {
705
+ const { hqRoot, host, now } = input;
706
+ const effectiveOutpostId = input.outpostId !== null && isControllerAliasOutpostId(input.outpostId, { kind: "outpost", id: input.outpostId }) ? null : input.outpostId;
707
+ const result = { ok: true, host, evaluated: 0, sent: [], started: [], escalated: [], skipped: [] };
708
+ const registered = parseRegistry(hqRoot, input.outpostId, now);
709
+ if (registered === null)
710
+ result.registry = "missing";
711
+ const leads = registered ?? [];
712
+ const lanes = readAllLanes(hqRoot);
713
+ const byId = new Map(lanes.map((lane) => [lane.lane_id, lane]));
714
+ const stateFile = path.join(hqRoot, "workspace", "lane-briefs", "autopilot-state.json");
715
+ const state = readState(stateFile);
716
+ for (const registered of leads) {
717
+ const lead = byId.get(registered.lane) ?? lanes.find((candidate) => candidate.lane_id.startsWith(`${registered.lane}_`));
718
+ if (!lead) {
719
+ result.skipped.push({ lead_lane: registered.lane, reason: "lead_lane_missing" });
720
+ continue;
721
+ }
722
+ const company = resolveLaneCompany(hqRoot, lead).company;
723
+ if (!company) {
724
+ result.skipped.push({ lead_lane: lead.lane_id, reason: "lead_company_unresolved" });
725
+ continue;
726
+ }
727
+ const registeredLocalHost = registered.host === "local" || registered.host === input.hostname;
728
+ const hostMatchesRegistry = registeredLocalHost
729
+ ? lead.host.kind === "local"
730
+ : lead.host.kind === "outpost" && lead.host.id === registered.host && input.outpostId === registered.host;
731
+ if (!hostMatchesRegistry ||
732
+ !laneRunsOnHost(lead, { hostname: input.hostname, outpostId: effectiveOutpostId })) {
733
+ result.skipped.push({ lead_lane: lead.lane_id, reason: "lead_host_mismatch" });
734
+ continue;
735
+ }
736
+ let stateChanged = false;
737
+ let perLeadErrorsEnabled = false;
738
+ let currentInputPath = registered.status;
739
+ try {
740
+ const readFlag = input.readFlag ?? readLanesRegistryFlag;
741
+ const enabled = await readFlag(LEAD_AUTOPILOT_FLAG, { company });
742
+ if (!enabled) {
743
+ result.skipped.push({ lead_lane: lead.lane_id, reason: "flag_off" });
744
+ continue;
745
+ }
746
+ perLeadErrorsEnabled = await readFlag(PER_LEAD_ERRORS_FLAG, { company });
747
+ currentInputPath = registered.status;
748
+ const status = readStatus(hqRoot, registered.status, company.slug);
749
+ const kpiStalenessEnabled = await (input.readFlag ?? readLanesRegistryFlag)(LEAD_AUTOPILOT_KPI_STALENESS_FLAG, { company });
750
+ const kpiStalenessBatchEnabled = kpiStalenessEnabled && await (input.readFlag ?? readLanesRegistryFlag)(LEAD_AUTOPILOT_KPI_STALENESS_BATCH_FLAG, { company });
751
+ if (kpiStalenessEnabled) {
752
+ result.kpi_status ??= [];
753
+ result.kpi_status.push(...managerKpiFreshness(status, now).map((kpi) => ({
754
+ lead_lane: lead.lane_id,
755
+ team: registered.team,
756
+ kpi: kpi.name,
757
+ age_minutes: kpi.ageMinutes,
758
+ stale: kpi.stale,
759
+ stale_after_minutes: kpi.staleAfterMinutes,
760
+ ...(kpi.status === undefined ? {} : { status: kpi.status }),
761
+ ...(kpi.error === undefined ? {} : { error: kpi.error }),
762
+ })));
763
+ }
764
+ const statusUpdatedAt = typeof status.updated_at === "string" && Number.isFinite(Date.parse(status.updated_at))
765
+ ? new Date(Date.parse(status.updated_at)).toISOString()
766
+ : undefined;
767
+ currentInputPath = registered.prd;
768
+ const stories = projectStories(hqRoot, registered.prd, company.slug, lead.project_id);
769
+ const children = lanes.filter((lane) => lane.senior.kind === "lane" && lane.senior.id === lead.lane_id);
770
+ const deadlineEscalationEnabled = await (input.readDeadlineFlag ?? readFlag)(LEAD_AUTOPILOT_MISSED_DEADLINE_ESCALATION_FLAG, { company });
771
+ const nudgeDedupeEnabled = await (input.readNudgeDedupeFlag ?? readFlag)(LEAD_AUTOPILOT_NUDGE_DEDUPE_FLAG, { company });
772
+ if (nudgeDedupeEnabled && pruneDeliveredIds(state, now))
773
+ stateChanged = true;
774
+ currentInputPath = registered.status;
775
+ const planned = planLeadAutopilotWakes({
776
+ lead,
777
+ children,
778
+ stories,
779
+ now,
780
+ managerStatus: status,
781
+ kpiStalenessEnabled,
782
+ kpiStalenessBatchEnabled,
783
+ keepAliveResumed: input.keepAliveResumedLeads?.has(lead.lane_id) === true,
784
+ });
785
+ const stateKey = (wake) => `${lead.lane_id}:${wake.condition}${wake.condition === "stale_kpi" ? `:${wake.kpi_id}` : ""}`;
786
+ const activeKeys = new Set(planned.map(stateKey));
787
+ const suppressedKeys = new Set();
788
+ for (const key of Object.keys(state.sent)) {
789
+ if (!key.startsWith(`${lead.lane_id}:`))
790
+ continue;
791
+ const entry = state.sent[key];
792
+ const isActive = activeKeys.has(key);
793
+ if (!nudgeDedupeEnabled) {
794
+ if (!isActive) {
795
+ delete state.sent[key];
796
+ stateChanged = true;
797
+ }
798
+ continue;
799
+ }
800
+ if (!isActive && entry.inactive_since === undefined) {
801
+ state.sent[key] = { ...entry, inactive_since: now.toISOString() };
802
+ stateChanged = true;
803
+ continue;
804
+ }
805
+ if (isActive && entry.inactive_since !== undefined) {
806
+ const inactiveAt = Date.parse(entry.inactive_since);
807
+ if (now.getTime() - inactiveAt < LEAD_AUTOPILOT_NUDGE_STATE_RETENTION_MS) {
808
+ suppressedKeys.add(key);
809
+ }
810
+ else {
811
+ delete state.sent[key];
812
+ if (removeDeliveredIdsForFingerprint(state, entry.fingerprint))
813
+ stateChanged = true;
814
+ stateChanged = true;
815
+ }
816
+ }
817
+ else if (!isActive) {
818
+ const inactiveSince = entry.inactive_since ?? now.toISOString();
819
+ if (now.getTime() - Date.parse(inactiveSince) >= LEAD_AUTOPILOT_NUDGE_STATE_RETENTION_MS) {
820
+ delete state.sent[key];
821
+ if (removeDeliveredIdsForFingerprint(state, entry.fingerprint))
822
+ stateChanged = true;
823
+ stateChanged = true;
824
+ }
825
+ else if (entry.inactive_since === undefined) {
826
+ state.sent[key] = { ...entry, inactive_since: inactiveSince };
827
+ stateChanged = true;
828
+ }
829
+ }
830
+ }
831
+ for (const wake of planned) {
832
+ const key = stateKey(wake);
833
+ if (suppressedKeys.has(key))
834
+ continue;
835
+ const prior = state.sent[key];
836
+ if (nudgeDedupeEnabled && prior && prior.fingerprint !== wake.fingerprint && !prior.acted) {
837
+ const leadActedSincePrior = statusUpdatedAt !== undefined && prior.status_updated_at !== undefined &&
838
+ Date.parse(statusUpdatedAt) > Date.parse(prior.status_updated_at);
839
+ if (!leadActedSincePrior) {
840
+ const lastWakeAt = Date.parse(prior.last_wake_at ?? prior.at);
841
+ if (!Number.isFinite(lastWakeAt)) {
842
+ throw new LanesError("lead_autopilot_state_invalid", `Invalid wake time for ${lead.lane_id}`, { lead_lane: lead.lane_id, story_id: wake.story_id });
843
+ }
844
+ if (now.getTime() - lastWakeAt < LEAD_AUTOPILOT_NUDGE_REDELIVERY_DELAY_MS)
845
+ continue;
846
+ }
847
+ }
848
+ if (prior?.fingerprint === wake.fingerprint) {
849
+ if (input.dryRun)
850
+ continue;
851
+ let current = prior;
852
+ const lastWakeAt = Date.parse(prior.last_wake_at ?? prior.at);
853
+ if (!Number.isFinite(lastWakeAt)) {
854
+ throw new LanesError("lead_autopilot_state_invalid", `Invalid wake time for ${lead.lane_id}`, { lead_lane: lead.lane_id, story_id: wake.story_id });
855
+ }
856
+ if (statusUpdatedAt === undefined || prior.status_updated_at === undefined) {
857
+ throw new LanesError("lead_autopilot_status_activity_unverifiable", `Cannot verify whether lead ${lead.lane_id} acted after its autopilot wake`, { lead_lane: lead.lane_id, story_id: wake.story_id });
858
+ }
859
+ if (!prior.acted && Date.parse(statusUpdatedAt) > Date.parse(prior.status_updated_at)) {
860
+ current = { ...prior, acted: true };
861
+ state.sent[key] = current;
862
+ stateChanged = true;
863
+ }
864
+ if (wake.condition === "fill_grant" && input.startWorker && !current.acted && !current.auto_started) {
865
+ const firstWakeAt = Date.parse(current.at);
866
+ if (!Number.isFinite(firstWakeAt)) {
867
+ throw new LanesError("lead_autopilot_state_invalid", `Invalid fill-grant wake time for ${lead.lane_id}`, { lead_lane: lead.lane_id, story_id: wake.story_id });
868
+ }
869
+ if (now.getTime() - firstWakeAt >= LEAD_AUTOPILOT_FILL_DELAY_MS) {
870
+ const story = stories.find((candidate) => candidate.id === wake.story_id && candidate.status === "todo");
871
+ if (!story?.briefPath) {
872
+ throw new LanesError("lead_autopilot_story_brief_missing", `Cannot auto-start story ${wake.story_id}: its project record has no valid brief path`, { lead_lane: lead.lane_id, story_id: wake.story_id, project_id: lead.project_id });
873
+ }
874
+ if (lead.state !== "running" && lead.state !== "queued") {
875
+ current = { ...current, acted: true };
876
+ state.sent[key] = current;
877
+ stateChanged = true;
878
+ result.skipped.push({ lead_lane: lead.lane_id, reason: "auto_start_lead_not_active" });
879
+ }
880
+ else {
881
+ const started = await input.startWorker({ lead, story });
882
+ current = { ...current, auto_started: true, worker_lane: started.lane_id };
883
+ state.sent[key] = current;
884
+ stateChanged = true;
885
+ result.started.push({ lead_lane: lead.lane_id, story_id: story.id, worker_lane: started.lane_id });
886
+ }
887
+ }
888
+ }
889
+ // Stale KPIs get one notice per measurement fingerprint, not the
890
+ // repeated wake/escalation cadence used by other conditions.
891
+ if (wake.condition === "stale_kpi")
892
+ continue;
893
+ const redeliveryDelay = nudgeDedupeEnabled ? LEAD_AUTOPILOT_NUDGE_REDELIVERY_DELAY_MS : LEAD_AUTOPILOT_FILL_DELAY_MS;
894
+ if (!current.acted && !current.auto_started && current.escalated_at === undefined && now.getTime() - lastWakeAt >= redeliveryDelay) {
895
+ const wakeCount = current.wake_count ?? 1;
896
+ if (wakeCount < 2) {
897
+ const delivered = appendAutopilotMessage({ hqRoot, leadLane: lead.lane_id, state, dedupeEnabled: nudgeDedupeEnabled, message: {
898
+ at: now.toISOString(),
899
+ message_id: `lead-autopilot:${wake.fingerprint}:wake-2`,
900
+ kind: "system_notice",
901
+ text: wake.prompt,
902
+ } });
903
+ current = { ...current, wake_count: 2, last_wake_at: now.toISOString() };
904
+ state.sent[key] = current;
905
+ stateChanged = true;
906
+ if (delivered)
907
+ result.sent.push(wake);
908
+ }
909
+ else {
910
+ const escalation = { team: registered.team, lead_lane: lead.lane_id, condition: wake.condition, story_id: wake.story_id, at: now.toISOString(), fingerprint: wake.fingerprint };
911
+ recordOperatorEscalation(hqRoot, escalation);
912
+ current = { ...current, escalated_at: now.toISOString() };
913
+ state.sent[key] = current;
914
+ stateChanged = true;
915
+ result.escalated.push(escalation);
916
+ }
917
+ }
918
+ continue;
919
+ }
920
+ if (!input.dryRun) {
921
+ const delivered = appendAutopilotMessage({ hqRoot, leadLane: lead.lane_id, state, dedupeEnabled: nudgeDedupeEnabled, message: {
922
+ at: now.toISOString(),
923
+ message_id: `lead-autopilot:${wake.fingerprint}`,
924
+ kind: "system_notice",
925
+ text: wake.prompt,
926
+ } });
927
+ state.sent[key] = {
928
+ fingerprint: wake.fingerprint,
929
+ at: now.toISOString(),
930
+ ...(statusUpdatedAt ? { status_updated_at: statusUpdatedAt } : {}),
931
+ wake_count: 1,
932
+ last_wake_at: now.toISOString(),
933
+ };
934
+ stateChanged = true;
935
+ if (!delivered)
936
+ continue;
937
+ }
938
+ result.sent.push(wake);
939
+ }
940
+ // Planned wakes have already been delivered. Persist their dedupe state
941
+ // before deadline parsing/recording so an unexpected deadline failure
942
+ // cannot make those wakes repeat on the next pass.
943
+ if (!input.dryRun && stateChanged) {
944
+ writeState(stateFile, state);
945
+ stateChanged = false;
946
+ }
947
+ if (deadlineEscalationEnabled) {
948
+ result.missed_deadlines ??= [];
949
+ const parsedCommitments = deadlineCommitments(status, stories, lead.lane_id);
950
+ if (parsedCommitments.errors.length > 0) {
951
+ result.deadline_errors ??= [];
952
+ result.deadline_errors.push(...parsedCommitments.errors);
953
+ }
954
+ const commitments = parsedCommitments.commitments;
955
+ const currentCommitmentKeys = new Set(commitments.map((item) => `${lead.lane_id}:${item.key}`));
956
+ const deadlineState = state.deadline_misses ?? (state.deadline_misses = {});
957
+ for (const key of Object.keys(deadlineState)) {
958
+ if (key.startsWith(`${lead.lane_id}:`) && !currentCommitmentKeys.has(key)) {
959
+ delete deadlineState[key];
960
+ stateChanged = true;
961
+ }
962
+ }
963
+ const escalationDelay = input.missedDeadlineEscalationDelayMs ?? LEAD_AUTOPILOT_MISSED_DEADLINE_ESCALATION_DELAY_MS;
964
+ if (!Number.isFinite(escalationDelay) || escalationDelay < 0) {
965
+ throw new LanesError("lead_autopilot_deadline_config_invalid", "Missed-deadline escalation delay must be a non-negative number");
966
+ }
967
+ for (const commitment of commitments) {
968
+ const key = `${lead.lane_id}:${commitment.key}`;
969
+ const prior = deadlineState[key];
970
+ if (commitment.resolved) {
971
+ if (prior) {
972
+ delete deadlineState[key];
973
+ stateChanged = true;
974
+ }
975
+ continue;
976
+ }
977
+ const isMissed = now.getTime() > Date.parse(commitment.due);
978
+ if (!isMissed) {
979
+ if (prior && (prior.due_at !== commitment.due || prior.owner !== commitment.owner || prior.currently_missed)) {
980
+ deadlineState[key] = { ...prior, due_at: commitment.due, owner: commitment.owner, currently_missed: false };
981
+ stateChanged = true;
982
+ }
983
+ continue;
984
+ }
985
+ if (!prior || prior.miss_count === 0) {
986
+ const firstMiss = {
987
+ item: commitment.item,
988
+ owner: commitment.owner,
989
+ due_at: commitment.due,
990
+ miss_count: 1,
991
+ first_missed_at: now.toISOString(),
992
+ currently_missed: true,
993
+ };
994
+ if (!input.dryRun) {
995
+ const fingerprint = `missed-deadline:${commitment.key}:${commitment.owner}:${commitment.due}`;
996
+ const wake = {
997
+ condition: "missed_deadline",
998
+ lead_lane: lead.lane_id,
999
+ story_id: commitment.item,
1000
+ fingerprint,
1001
+ prompt: `Deadline missed for ${commitment.item} (${commitment.description}), owner ${commitment.owner}, due ${commitment.due}. Deliver it or re-date with a reason. Follow ${LEAD_AUTOPILOT_PROMPT_LOOP}.`,
1002
+ };
1003
+ const delivered = appendAutopilotMessage({ hqRoot, leadLane: lead.lane_id, state, dedupeEnabled: nudgeDedupeEnabled, message: {
1004
+ at: now.toISOString(),
1005
+ message_id: `lead-autopilot:${fingerprint}`,
1006
+ kind: "system_notice",
1007
+ text: wake.prompt,
1008
+ } });
1009
+ stateChanged = true;
1010
+ if (delivered)
1011
+ result.sent.push(wake);
1012
+ deadlineState[key] = firstMiss;
1013
+ }
1014
+ else {
1015
+ deadlineState[key] = firstMiss;
1016
+ }
1017
+ }
1018
+ else {
1019
+ const dueChanged = prior.due_at !== commitment.due || prior.owner !== commitment.owner;
1020
+ const reMissed = !prior.currently_missed;
1021
+ const firstMissAt = Date.parse(prior.first_missed_at);
1022
+ if (!Number.isFinite(firstMissAt)) {
1023
+ throw new LanesError("lead_autopilot_state_invalid", `Invalid first missed-deadline time for ${commitment.item}`, { lead_lane: lead.lane_id, item: commitment.item });
1024
+ }
1025
+ const stillLateAgain = now.getTime() - firstMissAt >= escalationDelay;
1026
+ const secondMiss = !prior.escalated_at && (dueChanged || reMissed || stillLateAgain);
1027
+ const next = {
1028
+ ...prior,
1029
+ item: commitment.item,
1030
+ owner: commitment.owner,
1031
+ due_at: commitment.due,
1032
+ miss_count: secondMiss ? prior.miss_count + 1 : prior.miss_count,
1033
+ currently_missed: true,
1034
+ ...(secondMiss ? { escalated_at: now.toISOString() } : {}),
1035
+ };
1036
+ if (secondMiss) {
1037
+ const fingerprint = `missed-deadline:${commitment.key}:${commitment.owner}:${commitment.due}:miss-${next.miss_count}`;
1038
+ const escalation = {
1039
+ team: registered.team,
1040
+ lead_lane: lead.lane_id,
1041
+ condition: "missed_deadline",
1042
+ story_id: commitment.item,
1043
+ at: now.toISOString(),
1044
+ fingerprint,
1045
+ owner: commitment.owner,
1046
+ due: commitment.due,
1047
+ miss_count: next.miss_count,
1048
+ };
1049
+ if (!input.dryRun)
1050
+ recordOperatorEscalation(hqRoot, escalation);
1051
+ if (!input.dryRun)
1052
+ stateChanged = true;
1053
+ result.escalated.push(escalation);
1054
+ }
1055
+ if (!input.dryRun && JSON.stringify(prior) !== JSON.stringify(next))
1056
+ stateChanged = true;
1057
+ deadlineState[key] = next;
1058
+ }
1059
+ const current = deadlineState[key] ?? prior;
1060
+ result.missed_deadlines.push({ lead_lane: lead.lane_id, item: commitment.item, owner: commitment.owner, due: commitment.due, miss_count: current?.miss_count ?? 1 });
1061
+ }
1062
+ }
1063
+ if (!input.dryRun && stateChanged)
1064
+ writeState(stateFile, state);
1065
+ result.evaluated += 1;
1066
+ }
1067
+ catch (error) {
1068
+ if (!input.dryRun && stateChanged)
1069
+ writeState(stateFile, state);
1070
+ if (perLeadErrorsEnabled && error instanceof LanesError && LEAD_AUTOPILOT_PER_LEAD_ERROR_CODES.has(error.error)) {
1071
+ const errorPath = typeof error.details.path === "string" ? error.details.path : currentInputPath;
1072
+ const messageId = `lead-autopilot-error:${error.error}:${createHash("sha256").update(`${error.error}\0${errorPath}`).digest("hex")}`;
1073
+ result.skipped.push({ lane_id: lead.lane_id, error: error.error, path: errorPath, message: error.message });
1074
+ const noticeKey = `${lead.lane_id}:${error.error}:${errorPath}`;
1075
+ if (!input.dryRun && state.per_lead_error_notices?.[noticeKey] !== messageId) {
1076
+ appendDropboxMessage(hqRoot, lead.lane_id, {
1077
+ at: now.toISOString(),
1078
+ message_id: messageId,
1079
+ kind: "system_notice",
1080
+ text: `Lead autopilot skipped this lead because ${error.error}: ${error.message}. Fix the registry row for lane ${registered.lane} (team ${registered.team}) in ${LEAD_REGISTRY_REL} (registered path: ${errorPath}).`,
1081
+ });
1082
+ state.per_lead_error_notices ??= {};
1083
+ state.per_lead_error_notices[noticeKey] = messageId;
1084
+ writeState(stateFile, state);
1085
+ }
1086
+ continue;
1087
+ }
1088
+ if (!(error instanceof LanesError) || LEAD_AUTOPILOT_PASS_FATAL_ERRORS.has(error.error))
1089
+ throw error;
1090
+ result.skipped.push({ lead_lane: lead.lane_id, reason: error.error });
1091
+ }
1092
+ }
1093
+ return result;
1094
+ }
1095
+ // Tenant-boundary and path-safety failures stop the whole pass; other per-lead
1096
+ // data errors skip only that lead.
1097
+ const LEAD_AUTOPILOT_PASS_FATAL_ERRORS = new Set([
1098
+ "lead_autopilot_tenant_mismatch",
1099
+ "lead_autopilot_status_path_invalid",
1100
+ "lead_autopilot_escalation_record_invalid",
1101
+ ]);
1102
+ const LEAD_AUTOPILOT_PER_LEAD_ERROR_CODES = new Set([
1103
+ "lead_autopilot_tenant_mismatch",
1104
+ "lead_autopilot_project_path_invalid",
1105
+ "lead_autopilot_project_invalid",
1106
+ "lead_autopilot_story_brief_path_invalid",
1107
+ "lead_autopilot_story_brief_invalid",
1108
+ "lead_autopilot_status_path_invalid",
1109
+ "lead_autopilot_status_invalid",
1110
+ ]);
1111
+ const LEAD_AUTOPILOT_STALE_LOCK_MAX_AGE_MS = 60 * 60_000;
1112
+ function processStartIdentity(pid) {
1113
+ try {
1114
+ const stat = fs.readFileSync(`/proc/${pid}/stat`, "utf8");
1115
+ const fields = stat.slice(stat.lastIndexOf(")") + 2).trim().split(/\s+/);
1116
+ return fields[19] ?? null;
1117
+ }
1118
+ catch {
1119
+ return null;
1120
+ }
1121
+ }
1122
+ function reclaimStaleLock(lockPath) {
1123
+ let before;
1124
+ let text;
1125
+ let after;
1126
+ try {
1127
+ before = fs.lstatSync(lockPath);
1128
+ text = fs.readFileSync(lockPath, "utf8");
1129
+ after = fs.lstatSync(lockPath);
1130
+ }
1131
+ catch (error) {
1132
+ if (error.code === "ENOENT")
1133
+ return true;
1134
+ return false;
1135
+ }
1136
+ if (!before.isFile() || before.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino)
1137
+ return false;
1138
+ const [pidText, createdAt, recordedStartIdentity] = text.split("\n");
1139
+ const pid = Number(pidText);
1140
+ if (!Number.isSafeInteger(pid) || pid < 1)
1141
+ return false;
1142
+ let dead = false;
1143
+ try {
1144
+ process.kill(pid, 0);
1145
+ const currentStartIdentity = processStartIdentity(pid);
1146
+ if (recordedStartIdentity && currentStartIdentity) {
1147
+ if (recordedStartIdentity !== currentStartIdentity)
1148
+ dead = true;
1149
+ else
1150
+ return false;
1151
+ }
1152
+ else {
1153
+ const createdMs = Date.parse(createdAt ?? "");
1154
+ if (!Number.isFinite(createdMs) || Date.now() - createdMs < LEAD_AUTOPILOT_STALE_LOCK_MAX_AGE_MS)
1155
+ return false;
1156
+ dead = true;
1157
+ }
1158
+ }
1159
+ catch (error) {
1160
+ if (error.code !== "ESRCH")
1161
+ return false;
1162
+ dead = true;
1163
+ }
1164
+ if (!dead)
1165
+ return false;
1166
+ try {
1167
+ const current = fs.lstatSync(lockPath);
1168
+ if (current.dev !== before.dev || current.ino !== before.ino)
1169
+ return false;
1170
+ fs.unlinkSync(lockPath);
1171
+ return true;
1172
+ }
1173
+ catch (error) {
1174
+ if (error.code === "ENOENT")
1175
+ return true;
1176
+ return false;
1177
+ }
1178
+ }
1179
+ export async function runLeadAutopilotPass(input) {
1180
+ if (input.dryRun)
1181
+ return runLeadAutopilotPassUnlocked(input);
1182
+ const lockPath = path.join(input.hqRoot, "workspace", "lane-briefs", "autopilot.lock");
1183
+ fs.mkdirSync(path.dirname(lockPath), { recursive: true });
1184
+ let lockFd;
1185
+ for (let attempt = 0; attempt < 2; attempt += 1) {
1186
+ try {
1187
+ lockFd = fs.openSync(lockPath, "wx", 0o600);
1188
+ fs.writeFileSync(lockFd, `${process.pid}\n${input.now.toISOString()}\n${processStartIdentity(process.pid) ?? ""}\n`, "utf8");
1189
+ break;
1190
+ }
1191
+ catch (error) {
1192
+ if (error.code === "EEXIST" && attempt === 0 && reclaimStaleLock(lockPath))
1193
+ continue;
1194
+ if (error.code === "EEXIST") {
1195
+ throw new LanesError("lead_autopilot_lock_busy", `Another autopilot pass owns ${lockPath}`, { path: lockPath });
1196
+ }
1197
+ throw new LanesError("lead_autopilot_lock_failed", `Cannot lock autopilot state: ${error instanceof Error ? error.message : String(error)}`, { path: lockPath });
1198
+ }
1199
+ }
1200
+ if (lockFd === undefined)
1201
+ throw new LanesError("lead_autopilot_lock_busy", `Another autopilot pass owns ${lockPath}`, { path: lockPath });
1202
+ try {
1203
+ return await runLeadAutopilotPassUnlocked(input);
1204
+ }
1205
+ finally {
1206
+ try {
1207
+ fs.closeSync(lockFd);
1208
+ }
1209
+ catch (error) {
1210
+ process.stderr.write(`hq lanes autopilot: lock close failed: ${error instanceof Error ? error.message : String(error)}\n`);
1211
+ }
1212
+ try {
1213
+ fs.unlinkSync(lockPath);
1214
+ }
1215
+ catch (error) {
1216
+ if (error.code !== "ENOENT") {
1217
+ process.stderr.write(`hq lanes autopilot: lock removal failed: ${error instanceof Error ? error.message : String(error)}\n`);
1218
+ }
1219
+ }
1220
+ }
1221
+ }
1222
+ //# sourceMappingURL=autopilot.js.map