@joshuafolkken/kit 1.1229.0 → 1.1370.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 (939) hide show
  1. package/.claude/agents/investigator.md +1 -0
  2. package/.claude/settings.json +4 -0
  3. package/.claude/skills/dependency-update/SKILL.md +5 -3
  4. package/.claude/skills/epic-commands/SKILL.md +82 -113
  5. package/.claude/skills/epic-commands/epic-bundle.md +38 -63
  6. package/.claude/skills/epic-commands/execution-waves.md +30 -51
  7. package/.claude/skills/verify-ui/SKILL.md +13 -20
  8. package/.claude/skills/workflow-commands/SKILL.md +10 -10
  9. package/.claude/skills/workflow-commands/background-commands.md +4 -4
  10. package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
  11. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
  12. package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
  13. package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
  14. package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
  15. package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
  16. package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
  17. package/.claude/skills/workflow-commands/backlogrun.md +50 -61
  18. package/.claude/skills/workflow-commands/chain-rule.md +36 -40
  19. package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
  20. package/.claude/skills/workflow-commands/followup.md +24 -20
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
  22. package/.claude/skills/workflow-commands/fullrun.md +10 -10
  23. package/.claude/skills/workflow-commands/halfrun.md +9 -8
  24. package/.claude/skills/workflow-commands/into-target.md +12 -18
  25. package/.claude/skills/workflow-commands/issue-comments.md +11 -26
  26. package/.claude/skills/workflow-commands/kickoff.md +27 -16
  27. package/.claude/skills/workflow-commands/latest-gate.md +18 -29
  28. package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
  29. package/.claude/skills/workflow-commands/observation-filing.md +37 -28
  30. package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
  31. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
  32. package/.claude/skills/workflow-commands/prerequisite.md +23 -15
  33. package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
  34. package/.claude/skills/workflow-commands/prrun.md +3 -3
  35. package/.claude/skills/workflow-commands/retrospective.md +13 -18
  36. package/.claude/skills/workflow-commands/split-assessment.md +6 -4
  37. package/.claude/skills/workflow-commands/target-repository.md +25 -28
  38. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
  39. package/.gitattributes +2 -1
  40. package/.github/workflows/ci.yml +14 -0
  41. package/.github/workflows/publish.yml +2 -0
  42. package/.vscode/tasks.json +14 -0
  43. package/CLAUDE.md +10 -61
  44. package/README.md +38 -57
  45. package/SECURITY.md +1 -1
  46. package/dist/CLAUDE.md +10 -61
  47. package/dist/commands/document-section-cli.js +42 -10
  48. package/dist/config-merge/index.js +11 -2
  49. package/dist/hooks/audit-provision.js +2 -2
  50. package/dist/hooks/batch-guard.js +7 -7
  51. package/dist/hooks/{chunk-FIVDHQGT.js → chunk-43G45XJF.js} +18 -20
  52. package/dist/hooks/{chunk-JUDKDCDP.js → chunk-4TW4MQUL.js} +284 -362
  53. package/dist/hooks/{chunk-5VMKCCC4.js → chunk-76RK6E3H.js} +13 -11
  54. package/dist/hooks/{chunk-RNWHN5BP.js → chunk-DZWZ3DKY.js} +4 -4
  55. package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
  56. package/dist/hooks/{chunk-VC3PZPZO.js → chunk-GG72ANKI.js} +1 -1
  57. package/dist/hooks/{chunk-6HJJXRBX.js → chunk-KPM4YIIX.js} +8 -44
  58. package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
  59. package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
  60. package/dist/hooks/{chunk-TQNPDZNH.js → chunk-NZBHG6FW.js} +7 -5
  61. package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
  62. package/dist/hooks/{chunk-F56MFS4B.js → chunk-R6CRQEAL.js} +4 -4
  63. package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
  64. package/dist/hooks/{chunk-55HHG5PX.js → chunk-TLJYAGZK.js} +799 -903
  65. package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
  66. package/dist/hooks/codex-hook-adapter.js +26 -21
  67. package/dist/hooks/duplicate-read-guard.js +8 -8
  68. package/dist/hooks/format-edited.js +4 -4
  69. package/dist/hooks/inputs.json +213 -197
  70. package/dist/hooks/investigation-guard.js +8 -8
  71. package/dist/hooks/pretool-guard.js +15 -15
  72. package/dist/hooks/session-lang.js +406 -8
  73. package/dist/hooks/stop-guard.js +122 -201
  74. package/dist/josh.js +540 -137
  75. package/dist/version/index.js +15 -13
  76. package/eslint/base.js +43 -5
  77. package/eslint/rules/english-only-prose.js +3 -3
  78. package/eslint/rules/import.js +12 -0
  79. package/eslint/rules/namespace-object-export.js +2 -2
  80. package/package.json +16 -10
  81. package/pnpm-workspace.yaml +2 -4
  82. package/prompts/coding-standards.md +14 -48
  83. package/prompts/collaboration-workflow/file-edits.md +1 -1
  84. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  85. package/prompts/collaboration-workflow/issue-template.md +4 -10
  86. package/prompts/collaboration-workflow/operating-rules.md +7 -8
  87. package/prompts/collaboration-workflow/output-bounds.md +1 -1
  88. package/prompts/collaboration-workflow/overview.md +1 -1
  89. package/prompts/collaboration-workflow/plan-comment.md +2 -1
  90. package/prompts/collaboration-workflow/principles.md +21 -3
  91. package/prompts/collaboration-workflow/report-format.md +16 -29
  92. package/prompts/collaboration-workflow/residency.md +1 -1
  93. package/prompts/collaboration-workflow/rule-delivery.md +7 -95
  94. package/prompts/collaboration-workflow/shell-body.md +3 -23
  95. package/prompts/collaboration-workflow/turn-batching.md +4 -13
  96. package/prompts/collaboration-workflow/wip-cap.md +5 -11
  97. package/prompts/refactoring.md +1 -1
  98. package/prompts/review-rubric.md +3 -22
  99. package/prompts/review.md +15 -38
  100. package/prompts/testing-guide.md +2 -4
  101. package/scripts/adopt/adopt-logic.ts +5 -5
  102. package/scripts/adopt/adopt-toolkits.ts +4 -5
  103. package/scripts/adopt/adopt.ts +2 -3
  104. package/scripts/agent/agent-argv.ts +7 -7
  105. package/scripts/agent/agent-diagnostics.ts +2 -2
  106. package/scripts/agent/agent-exit-record.ts +1 -1
  107. package/scripts/agent/agent-headless.ts +1 -1
  108. package/scripts/agent/agent-launch-environment.ts +6 -1
  109. package/scripts/agent/agent-role-profile.ts +49 -22
  110. package/scripts/agent/agent-session-role.ts +32 -0
  111. package/scripts/agent/api-outage.ts +1 -1
  112. package/scripts/agent/claude-agent-argv.ts +4 -4
  113. package/scripts/agent/claude-result-event.ts +4 -4
  114. package/scripts/agent/codex-hooks.ts +2 -2
  115. package/scripts/agent/interactive-ask.ts +3 -6
  116. package/scripts/auto-ok/auto-ok-cli.ts +46 -60
  117. package/scripts/backlog/backlog-arrival-added.ts +34 -0
  118. package/scripts/backlog/backlog-arrival.ts +54 -17
  119. package/scripts/backlog/backlog-budget-cli.ts +34 -6
  120. package/scripts/backlog/backlog-budget.ts +17 -24
  121. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  122. package/scripts/backlog/backlog-drive-args.ts +5 -4
  123. package/scripts/backlog/backlog-drive-cli.ts +14 -10
  124. package/scripts/backlog/backlog-drive-epic.ts +85 -0
  125. package/scripts/backlog/backlog-drive-launch.ts +1 -1
  126. package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
  127. package/scripts/backlog/backlog-drive-named.ts +39 -9
  128. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  129. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  130. package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
  131. package/scripts/backlog/backlog-drive.ts +43 -28
  132. package/scripts/backlog/backlog-idle.ts +88 -0
  133. package/scripts/backlog/backlog-named.ts +11 -15
  134. package/scripts/backlog/backlog-next.ts +26 -30
  135. package/scripts/backlog/backlog-offer-cli.ts +28 -23
  136. package/scripts/backlog/backlog-offer.ts +7 -7
  137. package/scripts/backlog/backlog-overlap.ts +178 -0
  138. package/scripts/backlog/backlog-plan-cli.ts +14 -90
  139. package/scripts/backlog/backlog-plan-read.ts +111 -0
  140. package/scripts/backlog/backlog-plan.ts +11 -10
  141. package/scripts/backlog/backlog-pool.ts +13 -14
  142. package/scripts/backlog/backlog-rank.ts +11 -11
  143. package/scripts/backlog/backlog-ready.ts +15 -10
  144. package/scripts/backlog/backlog-scope.ts +14 -15
  145. package/scripts/backlog/backlog-stalled-cli.ts +2 -2
  146. package/scripts/backlog/backlog-stalled-detect.ts +4 -4
  147. package/scripts/backlog/backlog-stalled.ts +5 -6
  148. package/scripts/backlog/backlog-waves.ts +4 -4
  149. package/scripts/backlog/backlogrun-args.ts +74 -0
  150. package/scripts/backlog/backlogrun-cli.ts +113 -0
  151. package/scripts/backlog/backlogrun-launch.ts +178 -0
  152. package/scripts/behavior/behavior-assertion.ts +6 -8
  153. package/scripts/behavior/behavior-cli.ts +1 -1
  154. package/scripts/behavior/behavior-rules.ts +3 -3
  155. package/scripts/build/build-claude-md.ts +4 -4
  156. package/scripts/build/build-codex-hooks.ts +2 -2
  157. package/scripts/build/build-commands.ts +1 -1
  158. package/scripts/build/build-hooks.ts +5 -5
  159. package/scripts/build/build.ts +1 -1
  160. package/scripts/build/hook-bundle-stamp.ts +109 -7
  161. package/scripts/build/local-bin.ts +2 -2
  162. package/scripts/cases/cases-cli.ts +1 -1
  163. package/scripts/cases/cases-logic.ts +2 -2
  164. package/scripts/ci/composite-actions.ts +1 -2
  165. package/scripts/ci/pr-classification.ts +2 -2
  166. package/scripts/claude/workflow-destination.ts +1 -1
  167. package/scripts/clone/clone-aggregate.ts +1 -1
  168. package/scripts/clone/clone-fingerprint.ts +1 -1
  169. package/scripts/clone/clone-scan-cli.ts +1 -1
  170. package/scripts/clone/clone-scan.ts +1 -1
  171. package/scripts/config-merge/index.ts +1 -1
  172. package/scripts/config-merge/json-format.ts +1 -3
  173. package/scripts/config-merge/patch-json-array.ts +90 -0
  174. package/scripts/config-merge/patch-json-key.ts +6 -3
  175. package/scripts/config-merge/patch-json-list.ts +1 -1
  176. package/scripts/cost-runtime/codex-usage.ts +1 -1
  177. package/scripts/cost-runtime/context-cut-payback.ts +4 -5
  178. package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
  179. package/scripts/cost-runtime/cost-attribute.ts +3 -3
  180. package/scripts/cost-runtime/cost-blocks.ts +3 -4
  181. package/scripts/cost-runtime/cost-cli.ts +14 -11
  182. package/scripts/cost-runtime/cost-corpus.ts +11 -11
  183. package/scripts/cost-runtime/cost-pricing.ts +4 -4
  184. package/scripts/cost-runtime/cost-tokens.ts +1 -2
  185. package/scripts/cost-runtime/cost-transcript.ts +29 -29
  186. package/scripts/cost-runtime/cost-usage.ts +6 -7
  187. package/scripts/cost-runtime/cost-verdict.ts +10 -11
  188. package/scripts/cost-runtime/own-session.ts +1 -1
  189. package/scripts/cost-runtime/transcript-cwd.ts +2 -2
  190. package/scripts/delegation/delegation-cli.ts +4 -4
  191. package/scripts/delegation/delegation-policy.ts +13 -15
  192. package/scripts/delegation/duplicate-read-guard.ts +9 -10
  193. package/scripts/delegation/fanout-cli.ts +1 -1
  194. package/scripts/delegation/fanout.ts +1 -1
  195. package/scripts/delegation/investigation-guard.ts +18 -22
  196. package/scripts/delegation/investigation-reads.ts +48 -238
  197. package/scripts/discovery/repo-discovery.ts +1 -1
  198. package/scripts/discovery/repo-map-logic.ts +1 -2
  199. package/scripts/discovery/repo-origin.ts +3 -3
  200. package/scripts/discovery/repo-party-cli.ts +2 -2
  201. package/scripts/discovery/repo-party.ts +2 -2
  202. package/scripts/doctor/doctor-consumer.ts +1 -1
  203. package/scripts/doctor/doctor-io.ts +6 -7
  204. package/scripts/doctor/doctor-logic.ts +1 -1
  205. package/scripts/doctor/doctor-ports.ts +1 -1
  206. package/scripts/doctor/doctor.ts +8 -9
  207. package/scripts/document/backlogrun-parent-read-set.ts +5 -6
  208. package/scripts/document/bash-output-cap.ts +5 -7
  209. package/scripts/document/capped-print-part.ts +1 -1
  210. package/scripts/document/capped-print.ts +1 -1
  211. package/scripts/document/document-byte-budget.ts +33 -64
  212. package/scripts/document/document-byte-check.ts +4 -4
  213. package/scripts/document/document-reachability.ts +7 -8
  214. package/scripts/document/document-read-cli.ts +2 -2
  215. package/scripts/document/document-scan.ts +26 -2
  216. package/scripts/document/document-section-cli.ts +6 -8
  217. package/scripts/document/document-section.ts +8 -12
  218. package/scripts/document/edit-files-cli.ts +3 -4
  219. package/scripts/document/entry-read-budget.ts +8 -70
  220. package/scripts/document/entry-read-set.ts +51 -34
  221. package/scripts/document/lane-child-read-set.ts +9 -9
  222. package/scripts/document/read-files-cli.ts +1 -2
  223. package/scripts/document/read-set-cli.ts +16 -19
  224. package/scripts/document/read-set-cost.ts +4 -4
  225. package/scripts/document/read-set-point-of-use.ts +28 -38
  226. package/scripts/document/read-set-pricing.ts +1 -1
  227. package/scripts/document/read-set-trim.ts +3 -3
  228. package/scripts/document/resident-budget.ts +8 -10
  229. package/scripts/epic/epic-add-body.ts +15 -18
  230. package/scripts/epic/epic-add-plan.ts +26 -28
  231. package/scripts/epic/epic-add.ts +32 -25
  232. package/scripts/epic/epic-audit-checks.ts +27 -37
  233. package/scripts/epic/epic-audit-cli.ts +21 -22
  234. package/scripts/epic/epic-audit-orphans.ts +16 -17
  235. package/scripts/epic/epic-audit-rationale.ts +10 -15
  236. package/scripts/epic/epic-audit-report.ts +2 -5
  237. package/scripts/epic/epic-audit.ts +18 -14
  238. package/scripts/epic/epic-body.ts +10 -10
  239. package/scripts/epic/epic-bundle-cli.ts +36 -34
  240. package/scripts/epic/epic-bundle-evidence.ts +5 -5
  241. package/scripts/epic/epic-bundle-gaps.ts +6 -9
  242. package/scripts/epic/epic-bundle-poll.ts +1 -1
  243. package/scripts/epic/epic-bundle-referenced.ts +11 -14
  244. package/scripts/epic/epic-bundle.ts +19 -20
  245. package/scripts/epic/epic-busy.ts +44 -21
  246. package/scripts/epic/epic-candidate-confirm.ts +15 -18
  247. package/scripts/epic/epic-chains.ts +18 -23
  248. package/scripts/epic/epic-classify.ts +11 -12
  249. package/scripts/epic/epic-cli-argv.ts +5 -6
  250. package/scripts/epic/epic-cli-remove.ts +9 -4
  251. package/scripts/epic/epic-cli.ts +38 -26
  252. package/scripts/epic/epic-close-comment.ts +14 -15
  253. package/scripts/epic/epic-close.ts +25 -29
  254. package/scripts/epic/epic-cross-repo.ts +18 -21
  255. package/scripts/epic/epic-decision.ts +14 -18
  256. package/scripts/epic/epic-fetch.ts +25 -31
  257. package/scripts/epic/epic-graph.ts +15 -17
  258. package/scripts/epic/epic-index.ts +14 -16
  259. package/scripts/epic/epic-issue.ts +9 -11
  260. package/scripts/epic/epic-label-age.ts +74 -0
  261. package/scripts/epic/epic-lane-offer.ts +35 -24
  262. package/scripts/epic/epic-nested.ts +1 -1
  263. package/scripts/epic/epic-next-read.ts +8 -8
  264. package/scripts/epic/epic-next-views.ts +12 -12
  265. package/scripts/epic/epic-next.ts +29 -33
  266. package/scripts/epic/epic-outside-blocker.ts +11 -10
  267. package/scripts/epic/epic-parse.ts +22 -24
  268. package/scripts/epic/epic-promote.ts +3 -2
  269. package/scripts/epic/epic-rank.ts +1 -1
  270. package/scripts/epic/epic-read.ts +10 -8
  271. package/scripts/epic/epic-reconcile.ts +8 -6
  272. package/scripts/epic/epic-reference.ts +5 -4
  273. package/scripts/epic/epic-relation-recheck.ts +10 -11
  274. package/scripts/epic/epic-relations.ts +9 -8
  275. package/scripts/epic/epic-remove-plan.ts +4 -5
  276. package/scripts/epic/epic-remove.ts +7 -5
  277. package/scripts/epic/epic-report.ts +18 -20
  278. package/scripts/epic/epic-run.ts +6 -5
  279. package/scripts/epic/epic-sections.ts +2 -2
  280. package/scripts/epic/epic-shape.ts +3 -3
  281. package/scripts/epic/epic-solo-stale.ts +3 -2
  282. package/scripts/epic/epic-solo.ts +8 -8
  283. package/scripts/epic/epic-triage.ts +5 -4
  284. package/scripts/epic/epic-validate.ts +8 -7
  285. package/scripts/epic/epic.ts +5 -5
  286. package/scripts/exports/unused-members-cli.ts +1 -1
  287. package/scripts/followup/followup-issue-number.ts +1 -2
  288. package/scripts/followup/git-followup-cleanup.ts +6 -7
  289. package/scripts/followup/git-followup-finish.ts +11 -13
  290. package/scripts/followup/git-followup-flush.ts +11 -7
  291. package/scripts/followup/git-followup-issue-close.ts +16 -13
  292. package/scripts/followup/git-followup-label.ts +9 -6
  293. package/scripts/followup/git-followup-merged.ts +1 -1
  294. package/scripts/followup/git-followup-pending.ts +7 -9
  295. package/scripts/followup/git-followup-stages.ts +28 -17
  296. package/scripts/followup/git-followup-workflow.ts +19 -21
  297. package/scripts/followup/git-pr-followup-checks.ts +13 -20
  298. package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
  299. package/scripts/followup/git-pr-followup.ts +18 -17
  300. package/scripts/gate/core-admission.ts +162 -0
  301. package/scripts/gate/core-budget.ts +134 -91
  302. package/scripts/gate/gate-ledger.ts +114 -0
  303. package/scripts/gate/gate-log.ts +7 -9
  304. package/scripts/gate/gate-plan.ts +103 -35
  305. package/scripts/gate/gate-report.ts +39 -21
  306. package/scripts/gate/gate-skip.ts +11 -13
  307. package/scripts/gate/gate-steps.ts +5 -1
  308. package/scripts/gate/gate-tree.ts +3 -4
  309. package/scripts/gate/hook-gate-reuse.ts +9 -9
  310. package/scripts/gate/machine-capacity.ts +313 -0
  311. package/scripts/gate/pre-commit-type-check.ts +4 -4
  312. package/scripts/gate/project-checks.ts +12 -4
  313. package/scripts/gate/scoped-green.ts +11 -18
  314. package/scripts/gate/type-check-command.ts +2 -2
  315. package/scripts/gate/type-check-step.ts +4 -4
  316. package/scripts/gate/verification-gate.ts +60 -53
  317. package/scripts/gh/gh-spawn.ts +2 -2
  318. package/scripts/gh/git-ai-review-scan.ts +3 -2
  319. package/scripts/gh/git-gh-api-path.ts +10 -11
  320. package/scripts/gh/git-gh-exec.ts +43 -48
  321. package/scripts/gh/git-gh-failure.ts +6 -9
  322. package/scripts/gh/git-gh-helpers.ts +1 -1
  323. package/scripts/gh/git-gh-issue-list.ts +15 -19
  324. package/scripts/gh/git-gh-issue-read.ts +43 -60
  325. package/scripts/gh/git-gh-issue-rest.ts +14 -15
  326. package/scripts/gh/git-gh-issue-write.ts +52 -40
  327. package/scripts/gh/git-gh-issue.ts +23 -24
  328. package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
  329. package/scripts/gh/git-gh-pr-read.ts +46 -50
  330. package/scripts/gh/git-gh-pr-rest.ts +23 -26
  331. package/scripts/gh/git-gh-pr-review.ts +2 -2
  332. package/scripts/gh/git-gh-pr-rollup.ts +4 -4
  333. package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
  334. package/scripts/gh/git-gh-pr.ts +16 -16
  335. package/scripts/gh/git-gh-reachability.ts +11 -12
  336. package/scripts/gh/git-gh-repo.ts +2 -3
  337. package/scripts/gh/git-gh-rest-state.ts +1 -1
  338. package/scripts/gh/git-pr-ai-review.ts +6 -5
  339. package/scripts/gh/git-pr-checks-eval.ts +28 -30
  340. package/scripts/gh/git-pr-checks-parse.ts +14 -16
  341. package/scripts/gh/git-pr-checks-watch.ts +17 -17
  342. package/scripts/gh/git-pr-checks.ts +20 -23
  343. package/scripts/gh/git-pr-coderabbit.ts +8 -6
  344. package/scripts/gh/git-pr-confirmation.ts +5 -5
  345. package/scripts/gh/git-pr-managed-config.ts +7 -9
  346. package/scripts/gh/git-pr-messages.ts +1 -1
  347. package/scripts/gh/git-pr.ts +15 -16
  348. package/scripts/gh/github-issue-url.ts +8 -9
  349. package/scripts/git/base-tree.ts +66 -0
  350. package/scripts/git/change-base.ts +42 -2
  351. package/scripts/git/changed-file-scope.ts +5 -5
  352. package/scripts/git/changed-paths.ts +1 -2
  353. package/scripts/git/constants.ts +2 -2
  354. package/scripts/git/git-branch.ts +1 -1
  355. package/scripts/git/git-closes-keyword.ts +3 -3
  356. package/scripts/git/git-command.ts +53 -41
  357. package/scripts/git/git-common-directory.ts +3 -3
  358. package/scripts/git/git-diff-reads.ts +14 -15
  359. package/scripts/git/git-error.ts +1 -1
  360. package/scripts/git/git-execa-error.ts +1 -2
  361. package/scripts/git/git-issue.ts +10 -8
  362. package/scripts/git/git-location-environment.ts +3 -4
  363. package/scripts/git/git-ls-remote.ts +6 -8
  364. package/scripts/git/git-pre-push-hook.ts +11 -10
  365. package/scripts/git/git-preflight.ts +5 -5
  366. package/scripts/git/git-push-transport.ts +2 -2
  367. package/scripts/git/git-remote-branch.ts +1 -2
  368. package/scripts/git/git-schemas.ts +16 -23
  369. package/scripts/git/git-spawn-sync.ts +1 -1
  370. package/scripts/git/git-spawn.ts +37 -14
  371. package/scripts/git/git-ssh-keepalive.ts +12 -5
  372. package/scripts/git/git-staging.ts +7 -8
  373. package/scripts/git/git-workflow.ts +1 -1
  374. package/scripts/git/git-worktree.ts +35 -27
  375. package/scripts/git/gone-branch.ts +2 -2
  376. package/scripts/git/listing-cutoff.ts +1 -2
  377. package/scripts/git/lockfile-sync.ts +65 -0
  378. package/scripts/git/main-merge-guard.ts +1 -2
  379. package/scripts/git/main-merge.ts +7 -7
  380. package/scripts/git/main-sync.ts +23 -8
  381. package/scripts/git/parse-json-array.ts +18 -23
  382. package/scripts/git/repository-lock.ts +34 -2
  383. package/scripts/git/stash/git-stash.ts +4 -5
  384. package/scripts/git/stash/stash-orphans.ts +5 -3
  385. package/scripts/git/stash/stash-pop-args.ts +1 -1
  386. package/scripts/git/stash/stash-pop-cli.ts +3 -3
  387. package/scripts/git/stash/stash-sweep-lock.ts +2 -2
  388. package/scripts/hooks/batch-guard.ts +11 -13
  389. package/scripts/hooks/check-commit-message.ts +12 -9
  390. package/scripts/hooks/codex-hook-adapter.ts +16 -10
  391. package/scripts/hooks/edited-cspell.ts +3 -4
  392. package/scripts/hooks/format-edited-cli.ts +1 -1
  393. package/scripts/hooks/format-edited-file.ts +11 -17
  394. package/scripts/hooks/format-rewrite-notice.ts +19 -17
  395. package/scripts/hooks/pre-push-unit.ts +10 -14
  396. package/scripts/hooks/pretool-guard-cli.ts +4 -4
  397. package/scripts/hooks/pretool-guard.ts +93 -18
  398. package/scripts/hooks/reserved-run.ts +2 -2
  399. package/scripts/hooks/step-zero-notice.ts +1 -1
  400. package/scripts/hooks/stop-guard.ts +21 -10
  401. package/scripts/init/basic-path-migration.ts +2 -2
  402. package/scripts/init/claude-kit-only-settings.ts +2 -2
  403. package/scripts/init/claude-plugin-config.ts +2 -2
  404. package/scripts/init/distributed-paths.ts +4 -4
  405. package/scripts/init/hook-command-rewrite.ts +3 -3
  406. package/scripts/init/hook-launch.ts +5 -5
  407. package/scripts/init/init-actions.ts +13 -0
  408. package/scripts/init/init-ai-copy.ts +11 -11
  409. package/scripts/init/init-bootstrap.ts +3 -3
  410. package/scripts/init/init-copy-content.ts +4 -4
  411. package/scripts/init/init-logic-json-merge.ts +7 -9
  412. package/scripts/init/init-logic-migrate.ts +1 -1
  413. package/scripts/init/init-logic-templates.ts +1 -1
  414. package/scripts/init/init-logic-workspace.ts +4 -4
  415. package/scripts/init/init-logic-yaml-merge.ts +2 -2
  416. package/scripts/init/init-logic.ts +19 -22
  417. package/scripts/init/init.ts +12 -8
  418. package/scripts/init/kit-base-preset.ts +1 -1
  419. package/scripts/init/kit-setup-state.ts +1 -1
  420. package/scripts/init/kit-written-paths.ts +1 -2
  421. package/scripts/init/package-manager-pin.ts +35 -0
  422. package/scripts/init/project-profile-cli.ts +1 -1
  423. package/scripts/init/project-profile.ts +3 -3
  424. package/scripts/init/session-language-environment.ts +1 -1
  425. package/scripts/init/start-exec.ts +3 -4
  426. package/scripts/init/start-plan.ts +2 -2
  427. package/scripts/init/start-setup-pr.ts +3 -2
  428. package/scripts/init/start-steps.ts +2 -2
  429. package/scripts/init/tsconfig-preset-migration.ts +1 -1
  430. package/scripts/init/vscode-tasks.ts +62 -0
  431. package/scripts/issue/baseline-measure.ts +2 -2
  432. package/scripts/issue/behavior-change-lint.ts +2 -2
  433. package/scripts/issue/defect-rate-cli.ts +6 -7
  434. package/scripts/issue/defect-rate.ts +37 -27
  435. package/scripts/issue/git-next-issues.ts +9 -8
  436. package/scripts/issue/issue-auto-ok.ts +49 -11
  437. package/scripts/issue/issue-backlinks-cli.ts +5 -5
  438. package/scripts/issue/issue-backlinks.ts +6 -6
  439. package/scripts/issue/issue-cite-cli.ts +20 -18
  440. package/scripts/issue/issue-cite.ts +18 -8
  441. package/scripts/issue/issue-closing-pr.ts +4 -4
  442. package/scripts/issue/issue-comment-cli.ts +6 -4
  443. package/scripts/issue/issue-file-cli.ts +75 -15
  444. package/scripts/issue/issue-file-fold.ts +155 -0
  445. package/scripts/issue/issue-file.ts +14 -6
  446. package/scripts/issue/issue-fold-cli.ts +14 -9
  447. package/scripts/issue/issue-fold.ts +23 -8
  448. package/scripts/issue/issue-labels.ts +46 -37
  449. package/scripts/issue/issue-lint-cli.ts +2 -2
  450. package/scripts/issue/issue-lint.ts +1 -1
  451. package/scripts/issue/issue-merged.ts +10 -4
  452. package/scripts/issue/issue-number-shape.ts +27 -0
  453. package/scripts/issue/issue-rank.ts +1 -1
  454. package/scripts/issue/issue-read-cli.ts +4 -5
  455. package/scripts/issue/issue-read.ts +4 -5
  456. package/scripts/issue/issue-reference.ts +5 -5
  457. package/scripts/issue/issue-release-cli.ts +165 -0
  458. package/scripts/issue/issue-release.ts +58 -0
  459. package/scripts/issue/issue-report-failures.ts +7 -4
  460. package/scripts/issue/issue-scout-cli.ts +11 -11
  461. package/scripts/issue/issue-scout-closed.ts +4 -4
  462. package/scripts/issue/issue-scout.ts +4 -5
  463. package/scripts/issue/issue-state-cli.ts +17 -10
  464. package/scripts/issue/issue-state.ts +12 -13
  465. package/scripts/issue/issue-wip.ts +7 -7
  466. package/scripts/issue/markdown-section.ts +3 -3
  467. package/scripts/issue/measure-rerun-cli.ts +10 -9
  468. package/scripts/issue/reproduction-measure.ts +3 -3
  469. package/scripts/issue/session-cite.ts +56 -0
  470. package/scripts/josh/agent-session-environment.ts +10 -8
  471. package/scripts/josh/cli-body.ts +2 -2
  472. package/scripts/josh/command-suggest.ts +1 -1
  473. package/scripts/josh/file-map-stamp.ts +20 -23
  474. package/scripts/josh/hook-decision.ts +24 -28
  475. package/scripts/josh/josh-command-map.ts +4 -1
  476. package/scripts/josh/josh-command-types.ts +32 -34
  477. package/scripts/josh/josh-commands-ai.ts +6 -6
  478. package/scripts/josh/josh-commands-backlog.ts +15 -3
  479. package/scripts/josh/josh-commands-clone.ts +1 -1
  480. package/scripts/josh/josh-commands-development.ts +33 -4
  481. package/scripts/josh/josh-commands-document.ts +3 -3
  482. package/scripts/josh/josh-commands-guard.ts +3 -3
  483. package/scripts/josh/josh-commands-issue.ts +11 -5
  484. package/scripts/josh/josh-commands-lane.ts +16 -5
  485. package/scripts/josh/josh-commands-lint.ts +1 -1
  486. package/scripts/josh/josh-commands-maintenance.ts +2 -2
  487. package/scripts/josh/josh-commands-run.ts +20 -6
  488. package/scripts/josh/josh-commands-split.ts +1 -2
  489. package/scripts/josh/josh-commands-versioning.ts +5 -5
  490. package/scripts/josh/josh-commands-workflow.ts +30 -22
  491. package/scripts/josh/josh-environment-file.ts +1 -1
  492. package/scripts/josh/josh-in-process.ts +3 -3
  493. package/scripts/josh/josh-logic.ts +10 -10
  494. package/scripts/josh/josh-run.ts +3 -3
  495. package/scripts/josh/josh-verdict.ts +9 -12
  496. package/scripts/josh/josh.ts +3 -3
  497. package/scripts/josh/kit-only.ts +2 -2
  498. package/scripts/josh/path-decision.ts +3 -3
  499. package/scripts/josh/platform-temporary.ts +7 -5
  500. package/scripts/josh/process-identity.ts +24 -6
  501. package/scripts/josh/process-owner.ts +4 -4
  502. package/scripts/josh/session-language-cli.ts +53 -11
  503. package/scripts/josh/session-language.ts +1 -1
  504. package/scripts/josh/stamp-file.ts +48 -29
  505. package/scripts/josh/stamp-record.ts +57 -0
  506. package/scripts/lane/lane-await.ts +35 -11
  507. package/scripts/lane/lane-cache.ts +6 -6
  508. package/scripts/lane/lane-capacity.ts +32 -17
  509. package/scripts/lane/lane-child-invocation.ts +17 -15
  510. package/scripts/lane/lane-child-marker.ts +12 -12
  511. package/scripts/lane/lane-cli.ts +20 -13
  512. package/scripts/lane/lane-close.ts +6 -6
  513. package/scripts/lane/lane-dispatch.ts +61 -72
  514. package/scripts/lane/lane-environment.ts +5 -5
  515. package/scripts/lane/lane-guard-policy.ts +7 -21
  516. package/scripts/lane/lane-handoff.ts +2 -2
  517. package/scripts/lane/lane-install.ts +9 -10
  518. package/scripts/lane/lane-launch-cli.ts +13 -8
  519. package/scripts/lane/lane-ledger.ts +73 -11
  520. package/scripts/lane/lane-leftover.ts +44 -30
  521. package/scripts/lane/lane-limit-cli.ts +160 -0
  522. package/scripts/lane/lane-limit-override.ts +74 -0
  523. package/scripts/lane/lane-load.ts +19 -68
  524. package/scripts/lane/lane-measure-cli.ts +15 -25
  525. package/scripts/lane/lane-occupancy.ts +6 -4
  526. package/scripts/lane/lane-open.ts +25 -24
  527. package/scripts/lane/lane-output.ts +4 -3
  528. package/scripts/lane/lane-paths.ts +22 -8
  529. package/scripts/lane/lane-phase.ts +33 -0
  530. package/scripts/lane/lane-reap.ts +2 -2
  531. package/scripts/lane/lane-registry.ts +27 -15
  532. package/scripts/lane/lane-relaunch.ts +9 -9
  533. package/scripts/lane/lane-report.ts +5 -4
  534. package/scripts/lane/lane-resume.ts +2 -2
  535. package/scripts/lane/lane-sampler.ts +55 -0
  536. package/scripts/lane/lane-seed.ts +7 -7
  537. package/scripts/lane/lane-stage-stats.ts +135 -0
  538. package/scripts/lane/lane-start-point.ts +8 -11
  539. package/scripts/lane/lane-stats.ts +60 -15
  540. package/scripts/lane/lane-stray.ts +140 -0
  541. package/scripts/lane/lane-vacant.ts +1 -1
  542. package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
  543. package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
  544. package/scripts/lane/openai-review-broker.ts +2 -4
  545. package/scripts/lib/ancestor-directories.ts +1 -1
  546. package/scripts/lib/bounded-pool.ts +2 -2
  547. package/scripts/lib/buffered-process.ts +4 -6
  548. package/scripts/lib/caddy-logs.sh +0 -0
  549. package/scripts/lib/cli-flags.ts +39 -6
  550. package/scripts/lib/error-message.ts +1 -1
  551. package/scripts/lib/json-value.ts +17 -3
  552. package/scripts/lib/poll.ts +1 -1
  553. package/scripts/lib/status-icons.ts +3 -3
  554. package/scripts/lib/timed-fetch.ts +1 -1
  555. package/scripts/lib/timeouts.ts +1 -1
  556. package/scripts/lines/bytes-command.ts +3 -4
  557. package/scripts/lines/effective-limit.ts +25 -12
  558. package/scripts/lines/line-budget.ts +47 -55
  559. package/scripts/lines/line-targets.ts +6 -2
  560. package/scripts/lines/lines-command.ts +3 -3
  561. package/scripts/lint/cspell-cached.ts +1 -1
  562. package/scripts/lint/cycle-recheck.ts +122 -0
  563. package/scripts/lint/format.ts +1 -2
  564. package/scripts/lint/lint-parallel.ts +34 -19
  565. package/scripts/lint/lint-related-scope.ts +25 -15
  566. package/scripts/lint/lint-related.ts +6 -7
  567. package/scripts/managed-marker/index.ts +1 -1
  568. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  569. package/scripts/notify/git-notify.ts +9 -7
  570. package/scripts/notify/telegram-notify.ts +53 -37
  571. package/scripts/notify/telegram-test-logic.ts +3 -3
  572. package/scripts/notify/telegram-test.ts +45 -30
  573. package/scripts/observations/observation-ledger-home.ts +14 -8
  574. package/scripts/observations/observation-ledger-line.ts +3 -2
  575. package/scripts/observations/observation-ledger-migrate.ts +3 -4
  576. package/scripts/observations/observation-ledger-prepare.ts +4 -4
  577. package/scripts/observations/observation-ledger.ts +14 -15
  578. package/scripts/observations/observation-record-cli.ts +83 -0
  579. package/scripts/observations/observation-record.ts +91 -0
  580. package/scripts/observations/observations-flush-cli.ts +1 -1
  581. package/scripts/observations/observations-flush-landing.ts +7 -6
  582. package/scripts/observations/observations-flush.ts +26 -27
  583. package/scripts/overrides/overrides-check.ts +18 -8
  584. package/scripts/package/package-scout-cli.ts +1 -1
  585. package/scripts/package/package-scout-format.ts +2 -2
  586. package/scripts/package/package-scout.ts +1 -1
  587. package/scripts/propagate/propagate-git-failure.ts +1 -1
  588. package/scripts/propagate/propagate-git.ts +7 -7
  589. package/scripts/propagate/propagate-plan.ts +2 -2
  590. package/scripts/propagate/propagate-publish.ts +2 -3
  591. package/scripts/propagate/propagate-run.ts +5 -7
  592. package/scripts/propagate/propagate-select.ts +1 -1
  593. package/scripts/propagate/propagate-steps.ts +19 -20
  594. package/scripts/propagate/propagate-targets.ts +6 -10
  595. package/scripts/propagate/propagate.ts +5 -5
  596. package/scripts/refactor/import-graph.ts +1 -1
  597. package/scripts/refactor/refactor-lint.ts +4 -10
  598. package/scripts/refactor/refactor-scan-cli.ts +1 -1
  599. package/scripts/refactor/refactor-scan.ts +2 -2
  600. package/scripts/refactor/refactor-targets.ts +1 -1
  601. package/scripts/release/github-release-cli.ts +25 -3
  602. package/scripts/release/github-release-environment.ts +1 -0
  603. package/scripts/release/github-release-runs.ts +115 -0
  604. package/scripts/release/github-release.ts +13 -67
  605. package/scripts/release/release-cli.ts +21 -4
  606. package/scripts/release/release-history.ts +6 -10
  607. package/scripts/release/release-plan.ts +3 -3
  608. package/scripts/release/release-progress.ts +3 -4
  609. package/scripts/release/release-publish.ts +8 -9
  610. package/scripts/release/release-scope-cli.ts +8 -10
  611. package/scripts/release/release-tag.ts +6 -8
  612. package/scripts/release/release-worktree.ts +5 -5
  613. package/scripts/repo/auto-merge-setting-logic.ts +7 -9
  614. package/scripts/repo/auto-merge-setting.ts +1 -1
  615. package/scripts/repo/repo-setting.ts +4 -4
  616. package/scripts/repo/repository-labels.ts +1 -1
  617. package/scripts/repo/required-checks-logic.ts +3 -3
  618. package/scripts/repo/required-checks-report.ts +1 -1
  619. package/scripts/repo/ruleset-check-cli.ts +1 -1
  620. package/scripts/repo/ruleset-check.ts +1 -1
  621. package/scripts/report/report-format-reference.ts +26 -0
  622. package/scripts/report/report-lint-cli.ts +2 -2
  623. package/scripts/report/report-lint.ts +16 -2
  624. package/scripts/review/disposition-cli.ts +2 -2
  625. package/scripts/review/disposition-logic.ts +1 -1
  626. package/scripts/review/live-evidence.ts +9 -6
  627. package/scripts/review/review-attest-cli.ts +1 -2
  628. package/scripts/review/review-attest.ts +3 -3
  629. package/scripts/review/review-brief-cli.ts +19 -20
  630. package/scripts/review/review-brief.ts +29 -32
  631. package/scripts/review/review-checkout.ts +2 -2
  632. package/scripts/review/review-diff-parts.ts +3 -5
  633. package/scripts/review/review-diff-write.ts +1 -1
  634. package/scripts/review/review-finding-ledger.ts +7 -4
  635. package/scripts/review/review-findings-cli.ts +2 -2
  636. package/scripts/review/review-level.ts +4 -7
  637. package/scripts/review/review-record-cli.ts +73 -16
  638. package/scripts/review/review-record.ts +5 -4
  639. package/scripts/review/review-round2-cli.ts +2 -3
  640. package/scripts/review/review-round2.ts +13 -21
  641. package/scripts/review/review-stamps.ts +9 -71
  642. package/scripts/review/review-tree.ts +4 -5
  643. package/scripts/rules/bash-triggers.ts +4 -4
  644. package/scripts/rules/decision-oracle-batch.ts +5 -6
  645. package/scripts/rules/decision-oracle-stage.ts +1 -1
  646. package/scripts/rules/decision-oracle-tokens.ts +1 -2
  647. package/scripts/rules/decision-oracle.ts +2 -2
  648. package/scripts/rules/delivered-rules.ts +61 -406
  649. package/scripts/rules/destructive-command.ts +2 -2
  650. package/scripts/rules/direct-filing.ts +4 -4
  651. package/scripts/rules/direct-pr-create.ts +2 -2
  652. package/scripts/rules/early-heartbeat.ts +15 -19
  653. package/scripts/rules/file-body.ts +5 -6
  654. package/scripts/rules/filing-cap.ts +6 -7
  655. package/scripts/rules/filing-offer.ts +1 -1
  656. package/scripts/rules/firing-point.ts +6 -6
  657. package/scripts/rules/gh-api.ts +2 -2
  658. package/scripts/rules/git-argv.ts +3 -3
  659. package/scripts/rules/git-force.ts +2 -2
  660. package/scripts/rules/hook-context-line.ts +31 -0
  661. package/scripts/rules/implementation-cut-verdict.ts +5 -8
  662. package/scripts/rules/implementation-cut.ts +35 -32
  663. package/scripts/rules/index-guard.ts +2 -2
  664. package/scripts/rules/issue-citation.ts +7 -7
  665. package/scripts/rules/issue-comments.ts +21 -13
  666. package/scripts/rules/josh-git-bare.ts +2 -2
  667. package/scripts/rules/lane-background.ts +14 -16
  668. package/scripts/rules/lane-carry-conflict.ts +41 -5
  669. package/scripts/rules/lane-interactive-ask.ts +6 -9
  670. package/scripts/rules/lane-park.ts +12 -16
  671. package/scripts/rules/lane-split-park.ts +1 -2
  672. package/scripts/rules/lane-switch-main.ts +10 -13
  673. package/scripts/rules/last-prompt.ts +1 -1
  674. package/scripts/rules/oracle-consulted.ts +5 -5
  675. package/scripts/rules/oracle-firing.ts +6 -9
  676. package/scripts/rules/oracle-list-cli.ts +2 -2
  677. package/scripts/rules/permission-guards.ts +2 -2
  678. package/scripts/rules/piped-verification.ts +79 -9
  679. package/scripts/rules/poll-loop.ts +9 -11
  680. package/scripts/rules/pre-gate-cut.ts +33 -30
  681. package/scripts/rules/prior-comment-read.ts +3 -3
  682. package/scripts/rules/protected-files.ts +25 -13
  683. package/scripts/rules/raw-field-body.ts +3 -4
  684. package/scripts/rules/reply-language.ts +1 -1
  685. package/scripts/rules/rule-body-guard.ts +10 -12
  686. package/scripts/rules/rule-guard.ts +1 -1
  687. package/scripts/rules/rule-list.ts +51 -0
  688. package/scripts/rules/rule-registry-rows.ts +282 -0
  689. package/scripts/rules/rule-registry.ts +109 -0
  690. package/scripts/rules/rule-value-cache.ts +2 -2
  691. package/scripts/rules/rule-value-cli.ts +6 -4
  692. package/scripts/rules/rule-value.ts +61 -22
  693. package/scripts/rules/run-tail-rule.ts +11 -15
  694. package/scripts/rules/shell-body-trigger.ts +7 -7
  695. package/scripts/rules/shell-segments.ts +2 -4
  696. package/scripts/rules/stop-rules.ts +54 -41
  697. package/scripts/rules/tail-commands.ts +1 -1
  698. package/scripts/rules/test-declared-commit.ts +2 -2
  699. package/scripts/rules/third-party-write.ts +3 -3
  700. package/scripts/rules/worktree-guard.ts +12 -5
  701. package/scripts/run/add/run-add-cli.ts +165 -0
  702. package/scripts/run/add/run-add.ts +124 -0
  703. package/scripts/run/board/run-board-cli.ts +207 -0
  704. package/scripts/run/board/run-board-closed.ts +95 -0
  705. package/scripts/run/board/run-board-every.ts +60 -0
  706. package/scripts/run/board/run-board-fetch.ts +38 -0
  707. package/scripts/run/board/run-board-fit.ts +219 -0
  708. package/scripts/run/board/run-board-github.ts +162 -0
  709. package/scripts/run/board/run-board-header.ts +275 -0
  710. package/scripts/run/board/run-board-kind.ts +35 -0
  711. package/scripts/run/board/run-board-labels.ts +299 -0
  712. package/scripts/run/board/run-board-layout.ts +222 -0
  713. package/scripts/run/board/run-board-link.ts +31 -0
  714. package/scripts/run/board/run-board-machine.ts +198 -0
  715. package/scripts/run/board/run-board-notes.ts +103 -0
  716. package/scripts/run/board/run-board-phase.ts +136 -0
  717. package/scripts/run/board/run-board-plan.ts +129 -0
  718. package/scripts/run/board/run-board-read.ts +62 -0
  719. package/scripts/run/board/run-board-render-legend.ts +82 -0
  720. package/scripts/run/board/run-board-render-notes.ts +77 -0
  721. package/scripts/run/board/run-board-render-slot.ts +50 -0
  722. package/scripts/run/board/run-board-render.ts +407 -0
  723. package/scripts/run/board/run-board-scope.ts +17 -0
  724. package/scripts/run/board/run-board-screen.ts +43 -0
  725. package/scripts/run/board/run-board-span.ts +66 -0
  726. package/scripts/run/board/run-board-spin.ts +115 -0
  727. package/scripts/run/board/run-board-state.ts +113 -0
  728. package/scripts/run/board/run-board-status.ts +279 -0
  729. package/scripts/run/board/run-board-tick.ts +210 -0
  730. package/scripts/run/board/run-board-track.ts +22 -0
  731. package/scripts/run/board/run-board-usage-read.ts +255 -0
  732. package/scripts/run/board/run-board-usage-rusage.ts +124 -0
  733. package/scripts/run/board/run-board-usage-text.ts +80 -0
  734. package/scripts/run/board/run-board-usage.ts +165 -0
  735. package/scripts/run/carry/run-carry-added.ts +62 -0
  736. package/scripts/run/carry/run-carry-args.ts +25 -22
  737. package/scripts/run/carry/run-carry-change.ts +1 -1
  738. package/scripts/run/carry/run-carry-cli.ts +71 -48
  739. package/scripts/run/carry/run-carry-conversation.ts +6 -7
  740. package/scripts/run/carry/run-carry-ended.ts +85 -0
  741. package/scripts/run/carry/run-carry-reclaim.ts +1 -1
  742. package/scripts/run/carry/run-carry-stash.ts +3 -2
  743. package/scripts/run/carry/run-carry-streak.ts +8 -10
  744. package/scripts/run/carry/run-carry.ts +85 -89
  745. package/scripts/run/cut/run-cut-args.ts +7 -7
  746. package/scripts/run/cut/run-cut-cli.ts +68 -37
  747. package/scripts/run/cut/run-cut-handoff.ts +15 -15
  748. package/scripts/run/cut/run-cut-report.ts +37 -16
  749. package/scripts/run/cut/run-cut.ts +63 -77
  750. package/scripts/run/detached-launch.ts +35 -50
  751. package/scripts/run/entry/run-entry-cli.ts +48 -27
  752. package/scripts/run/entry/run-entry-stop.ts +7 -9
  753. package/scripts/run/entry/run-entry.ts +5 -6
  754. package/scripts/run/event/run-event-cli.ts +5 -6
  755. package/scripts/run/event/run-event-filed.ts +69 -0
  756. package/scripts/run/event/run-event-follow.ts +3 -3
  757. package/scripts/run/event/run-event-plan.ts +38 -0
  758. package/scripts/run/event/run-event-render.ts +10 -4
  759. package/scripts/run/event/run-event-scope.ts +47 -18
  760. package/scripts/run/event/run-event-stream-emit.ts +64 -11
  761. package/scripts/run/event/run-event-stream.ts +172 -43
  762. package/scripts/run/event/run-event-watch.ts +4 -6
  763. package/scripts/run/hold/run-hold-cli.ts +65 -62
  764. package/scripts/run/hold/run-hold.ts +88 -46
  765. package/scripts/run/merge/run-merge-cli.ts +116 -77
  766. package/scripts/run/merge/run-merge-collect.ts +107 -0
  767. package/scripts/run/merge/run-merge-steps.ts +112 -65
  768. package/scripts/run/merge/run-merge-token.ts +30 -0
  769. package/scripts/run/merge/run-merge.ts +31 -22
  770. package/scripts/run/progress/run-progress-args.ts +4 -4
  771. package/scripts/run/progress/run-progress-cli.ts +39 -50
  772. package/scripts/run/progress/run-progress-clock.ts +25 -32
  773. package/scripts/run/progress/run-progress-config.ts +6 -9
  774. package/scripts/run/progress/run-progress-read.ts +9 -10
  775. package/scripts/run/progress/run-progress.ts +48 -53
  776. package/scripts/run/review/run-review-cli.ts +6 -6
  777. package/scripts/run/review/run-review-steps.ts +6 -6
  778. package/scripts/run/review/run-review.ts +9 -11
  779. package/scripts/run/run-cli-fault.ts +29 -0
  780. package/scripts/run/run-ending-cli.ts +3 -3
  781. package/scripts/run/run-ending.ts +10 -14
  782. package/scripts/run/run-halfrun-resume.ts +6 -8
  783. package/scripts/run/run-headless.ts +25 -12
  784. package/scripts/run/run-invocation.ts +17 -22
  785. package/scripts/run/run-label.ts +7 -5
  786. package/scripts/run/run-liveness-cli.ts +19 -6
  787. package/scripts/run/run-liveness.ts +27 -38
  788. package/scripts/run/run-next-cli.ts +5 -9
  789. package/scripts/run/run-next.ts +4 -5
  790. package/scripts/run/run-parent-cut-hook.ts +10 -12
  791. package/scripts/run/run-preflight.ts +25 -29
  792. package/scripts/run/run-prep-cli.ts +17 -13
  793. package/scripts/run/run-prep-locate.ts +4 -5
  794. package/scripts/run/run-prep.ts +7 -10
  795. package/scripts/run/run-prrun-resume.ts +2 -2
  796. package/scripts/run/run-report-cli.ts +4 -4
  797. package/scripts/run/run-report.ts +9 -14
  798. package/scripts/run/run-retrospective.ts +3 -3
  799. package/scripts/run/run-section.ts +42 -0
  800. package/scripts/run/run-stage-read.ts +2 -2
  801. package/scripts/run/run-stage.ts +6 -4
  802. package/scripts/run/run-status-cli.ts +7 -5
  803. package/scripts/run/run-status.ts +6 -7
  804. package/scripts/run/run-step-cli.ts +13 -15
  805. package/scripts/run/run-step.ts +62 -48
  806. package/scripts/run/run-stop-notify.ts +7 -8
  807. package/scripts/run/run-stranded-cli.ts +1 -1
  808. package/scripts/run/run-stranded-detect.ts +4 -4
  809. package/scripts/run/run-stranded.ts +11 -13
  810. package/scripts/run/run-tail-cli.ts +15 -16
  811. package/scripts/run/run-tail.ts +14 -33
  812. package/scripts/run/run-watcher-guard-cli.ts +3 -4
  813. package/scripts/run/run-watcher-guard.ts +11 -12
  814. package/scripts/run/run-watcher-hook.ts +6 -12
  815. package/scripts/run/ship/run-ship-cli.ts +67 -33
  816. package/scripts/run/ship/run-ship-detach.ts +15 -13
  817. package/scripts/run/ship/run-ship-lock.ts +1 -1
  818. package/scripts/run/ship/run-ship-next.ts +7 -8
  819. package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
  820. package/scripts/run/ship/run-ship-preflight.ts +10 -11
  821. package/scripts/run/ship/run-ship-probe.ts +4 -4
  822. package/scripts/run/ship/run-ship-return.ts +1 -1
  823. package/scripts/run/ship/run-ship-review-steps.ts +43 -24
  824. package/scripts/run/ship/run-ship-review.ts +12 -14
  825. package/scripts/run/ship/run-ship-scoped.ts +15 -6
  826. package/scripts/run/ship/run-ship-stage.ts +80 -26
  827. package/scripts/run/ship/run-ship-steps.ts +26 -16
  828. package/scripts/run/ship/run-ship-stop-text.ts +4 -2
  829. package/scripts/run/ship/run-ship-sync.ts +9 -8
  830. package/scripts/run/ship/run-ship.ts +17 -32
  831. package/scripts/run/tidy/run-tidy-cli.ts +9 -5
  832. package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
  833. package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
  834. package/scripts/run/tidy/run-tidy.ts +4 -3
  835. package/scripts/run/wake/run-wake-cli.ts +27 -33
  836. package/scripts/run/wake/run-wake-describe.ts +76 -29
  837. package/scripts/run/wake/run-wake-driver.ts +14 -14
  838. package/scripts/run/wake/run-wake-handoff.ts +6 -6
  839. package/scripts/run/wake/run-wake-loop.ts +13 -21
  840. package/scripts/run/wake/run-wake-restart.ts +4 -5
  841. package/scripts/run/wake/run-wake-session.ts +23 -27
  842. package/scripts/run/wake/run-wake.ts +57 -328
  843. package/scripts/safe-chain/ci-installer-pin.ts +3 -3
  844. package/scripts/safe-chain/pack-hook.ts +2 -2
  845. package/scripts/safe-chain/preinstall-command.ts +2 -2
  846. package/scripts/security/security-audit-logic.ts +1 -1
  847. package/scripts/security/security-audit-provision-logic.ts +1 -1
  848. package/scripts/security/security-audit-provision.ts +2 -2
  849. package/scripts/security/security-audit.ts +5 -5
  850. package/scripts/security/security-updates-logic.ts +2 -3
  851. package/scripts/security/security-updates.ts +2 -4
  852. package/scripts/self-sync-guard/index.ts +1 -1
  853. package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
  854. package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
  855. package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
  856. package/scripts/sonar/sonar-hotspots.ts +1 -1
  857. package/scripts/sonar/sonar-new-code-cli.ts +1 -1
  858. package/scripts/sonar/sonar-new-code.ts +1 -1
  859. package/scripts/sonar/sonar-project.ts +1 -1
  860. package/scripts/split/split-assess-cli.ts +1 -1
  861. package/scripts/split/split-assess.ts +3 -3
  862. package/scripts/sync/directory-copy-guard.ts +2 -3
  863. package/scripts/sync/managed-config-scope-cli.ts +1 -2
  864. package/scripts/sync/managed-config-scope.ts +4 -4
  865. package/scripts/sync/plugin-skill-directories.ts +2 -2
  866. package/scripts/sync/reconcile-templates.ts +17 -8
  867. package/scripts/sync/removed-skill-manifest.ts +2 -3
  868. package/scripts/sync/sync-ai-files.ts +7 -7
  869. package/scripts/sync/sync-configs.ts +30 -3
  870. package/scripts/sync/sync-hook-safety.ts +2 -2
  871. package/scripts/sync/sync.ts +23 -10
  872. package/scripts/sync/synced-paths.ts +2 -1
  873. package/scripts/sync/workflow-pin-logic.ts +1 -1
  874. package/scripts/test/test-declared-changed.ts +4 -4
  875. package/scripts/test/test-declared-logic.ts +2 -3
  876. package/scripts/test/test-declared-match.ts +25 -4
  877. package/scripts/test/test-declared.ts +26 -9
  878. package/scripts/test/test-red-commit.ts +3 -2
  879. package/scripts/test/test-red-logic.ts +7 -14
  880. package/scripts/test/test-red.ts +12 -47
  881. package/scripts/test/test-related-scope.ts +2 -3
  882. package/scripts/test/test-related.ts +3 -3
  883. package/scripts/test/test-type-logic.ts +1 -2
  884. package/scripts/test/test-unit-guard.ts +13 -17
  885. package/scripts/test/unit-worker-share.ts +7 -8
  886. package/scripts/time-runtime/time-agent-bundles.ts +2 -4
  887. package/scripts/time-runtime/time-background.ts +17 -21
  888. package/scripts/time-runtime/time-batch-guard.ts +67 -342
  889. package/scripts/time-runtime/time-bundle-call.ts +26 -28
  890. package/scripts/time-runtime/time-bundles.ts +11 -12
  891. package/scripts/time-runtime/time-call-identity.ts +1 -1
  892. package/scripts/time-runtime/time-command-key.ts +2 -2
  893. package/scripts/time-runtime/time-density-hook.ts +8 -11
  894. package/scripts/time-runtime/time-density.ts +5 -5
  895. package/scripts/time-runtime/time-followup-stage.ts +7 -7
  896. package/scripts/time-runtime/time-format.ts +5 -5
  897. package/scripts/time-runtime/time-hook-transcript.ts +3 -3
  898. package/scripts/time-runtime/time-instant.ts +1 -1
  899. package/scripts/time-runtime/time-markers.ts +15 -19
  900. package/scripts/time-runtime/time-phase-names.ts +3 -3
  901. package/scripts/time-runtime/time-reported-failure.ts +15 -19
  902. package/scripts/time-runtime/time-round-trips.ts +20 -23
  903. package/scripts/time-runtime/time-shell.ts +8 -8
  904. package/scripts/time-runtime/time-single-check.ts +1 -2
  905. package/scripts/time-runtime/time-spans.ts +35 -40
  906. package/scripts/time-runtime/time-tool-call.ts +15 -16
  907. package/scripts/time-runtime/time-transcript-line.ts +53 -34
  908. package/scripts/time-runtime/time-writes.ts +5 -5
  909. package/scripts/ui/ui-routes-cli.ts +1 -2
  910. package/scripts/ui/ui-routes.ts +1 -2
  911. package/scripts/version/bump-version.ts +1 -1
  912. package/scripts/version/fresh-metadata-cache.ts +2 -2
  913. package/scripts/version/latest-corepack.ts +129 -98
  914. package/scripts/version/latest-lane-guard.ts +1 -1
  915. package/scripts/version/latest-scope-cli.ts +2 -2
  916. package/scripts/version/latest-stamp.ts +1 -2
  917. package/scripts/version/latest-update.ts +2 -2
  918. package/scripts/version/npm-registry.ts +2 -2
  919. package/scripts/version/package-manager-version.ts +18 -0
  920. package/scripts/version/publishable-range-check.ts +2 -1
  921. package/scripts/version/publishable-range.ts +1 -1
  922. package/scripts/version/release-age.ts +11 -11
  923. package/scripts/version/release-hold.ts +2 -2
  924. package/scripts/version/safe-chain-version-update.ts +3 -3
  925. package/scripts/version/version-check-logic.ts +2 -3
  926. package/scripts/version/version-check.ts +1 -2
  927. package/scripts/version/version-command-config.ts +2 -2
  928. package/scripts/version/version-commands.ts +3 -3
  929. package/scripts/version/version-remote.ts +4 -4
  930. package/scripts/version/version-targets.ts +2 -2
  931. package/templates/gitignore +7 -0
  932. package/templates/workflows/github-release.yml +4 -0
  933. package/dist/hooks/chunk-NV2JRZZO.js +0 -6385
  934. package/dist/hooks/chunk-RKUAD3I6.js +0 -90
  935. package/dist/hooks/chunk-WPALEIRX.js +0 -18
  936. package/scripts/backlog/backlog-restructure.ts +0 -152
  937. package/scripts/rules/issue-fold-rule.ts +0 -72
  938. package/scripts/rules/wip-cap.ts +0 -63
  939. package/scripts/run/run-issue-number.ts +0 -19
@@ -3,168 +3,68 @@ import { backlog_budget } from '#scripts/backlog/backlog-budget'
3
3
  import { process_identity } from '#scripts/josh/process-identity'
4
4
  import { process_owner_schema } from '#scripts/josh/process-owner'
5
5
  import { stamp_file } from '#scripts/josh/stamp-file'
6
+ import { json_value } from '#scripts/lib/json-value'
6
7
  import type { CarryRead } from '#scripts/run/carry/run-carry'
7
8
  import { z } from 'zod'
8
9
 
9
- // joshuafolkken/kit#1719. joshuafolkken/kit#1714 made a `backlogrun`'s budget survive the session cut
10
- // and left out the one thing that starts the next session, so the record was carried and the
11
- // keystroke stayed: a cut still ended with a `confirmation` Telegram and a resume line, and a run
12
- // measured to cut about every 50 minutes did nothing at all until a person came back to it. Overnight
13
- // that is the whole night.
14
- //
15
- // This is that starter — a process outside the conversation, which the cut does not end.
16
- //
17
- // **Whether to wake is the record's answer, never a judgement.** `carried` *and* handed off is the one
18
- // state that wakes; `none`, `expired` and `unreadable` stop the supervisor. So the 8-hour whole-run
19
- // bound needs no check of its own here: it **is** the carry record's expiry, so a run past it reads
20
- // `expired` and the supervisor stops (`run-carry.ts` → `CARRY_MAX_AGE_MS`, itself imported from
21
- // `backlog-budget.ts` rather than restated). A bound re-derived here is one that drifts, and it drifts
22
- // silently in the direction that matters — the supervisor would go on waking past a budget the record
23
- // already calls spent.
24
- //
25
- // **A hand-off is what separates a cut from a session that is simply working.** `is_handed_off` is set
26
- // by `run:carry --cut`, and by this supervisor only when it recovers a record whose owner has *died*
27
- // (`run-wake-handoff.ts`, joshuafolkken/kit#2437) — so a live session's record never reads as waiting to
28
- // be woken, and a crash is carried on as if the dead session had cut rather than left standing.
29
- //
30
- // **The supervisor owns the record while its deterministic driver spends the budget.** After a cut or
31
- // dead-owner recovery it adopts the record as this process, so `run:merge` has one live owner to
32
- // count against. A judgment branch first hands the record off; `classify_claim` reads that explicit
33
- // handoff before liveness, allowing one AI session to adopt it even while the supervisor is alive.
34
- // The supervisor does not keep running the driver while that session owns the record.
10
+ // The process outside the conversation that starts the next session after a `backlogrun` cut.
11
+ // Whether to wake is the carry record's answer, never a judgement: `carried` and handed off wakes;
12
+ // `none`, `expired` (the whole-run bound) and `unreadable` stop. A hand-off is set by `run:carry --cut`,
13
+ // or by this supervisor when it recovers a record whose owner died, so a live session never reads as
14
+ // waiting. The supervisor owns the record while its deterministic driver spends the budget; a judgment
15
+ // branch hands it off so one AI session can adopt it.
35
16
 
36
17
  const WAKE_PREFIX = 'josh-run-wake-'
37
- // **Where the output of everything this supervisor starts is kept** (joshuafolkken/kit#1746).
38
- // `detached` is what puts a child outside the conversation; discarding its output was a second choice
39
- // riding along with it, and the two are separate requirements. Discarded, a session that exits without
40
- // claiming the carry record leaves nothing at all to diagnose it by — which is the state
41
- // joshuafolkken/kit#1746 was filed from, where three sessions died silently and the record could say
42
- // only that none of them had arrived.
43
- //
44
- // One file per repository, appended to, so every attempt of every cut is in one place; keyed exactly
45
- // as the wake and carry records are, so the three are found together. `.log` rather than `.json`
46
- // because it holds another process's output verbatim — the distinction `stamp_file.stamp_path`'s
47
- // `suffix` argument exists for.
18
+ // The output of every session this starts, appended per repository so a silent death is diagnosable.
48
19
  const WAKE_LOG_PREFIX = 'josh-run-wake-log-'
49
20
  const WAKE_LOG_SUFFIX = '.log'
50
- // How long a woken session has to claim the carry record before that wake is treated as lost.
51
- //
52
- // **The window is measured from the spawn, so it has to cover everything before the session's first
53
- // `run:carry --begin`** — the agent CLI's cold start, the resident preamble, and reading `SKILL.md`,
54
- // `backlogrun.md`, `backlogrun.md` and the `fullrun` set. Ten minutes is several times the observed cost
55
- // of that and still far inside the roughly 50-minute cut interval this exists to bridge. It was two
56
- // minutes first, which is inside the range a merely *slow* start occupies — and a slow start booked as
57
- // a failure ends the whole overnight run.
58
- //
59
- // **This one window is the only launch-failure detector, deliberately.** Reading the spawned process's
60
- // exit code would catch a missing binary and miss the two failures that actually recur — a session
61
- // that starts and dies during boot, and one that runs but never picks the run up. Asking instead
62
- // whether the record was claimed catches all three, because it tests the thing that was wanted rather
63
- // than the thing that was easy to observe.
21
+ // How long a woken session has to claim the carry record — the only launch-failure detector, since a
22
+ // claim also catches a session that dies in boot or never picks the run up. It covers a slow cold start.
64
23
  const WAKE_GRACE_MS = 600_000
65
- // **A lost wake is retried before it is called a failure**, because stopping is the expensive answer:
66
- // it ends a run nobody is watching, for the night. Three attempts against a ten-minute window is
67
- // half an hour of trying, which outlasts every transient cause worth surviving; past that the cause
68
- // is not transient and a person has to see it.
24
+ // Retried before failing: stopping ends a run nobody is watching.
69
25
  const MAX_WAKE_ATTEMPTS = 3
70
- // **How long a launch may be deferred for want of work before one is woken anyway**
71
- // (joshuafolkken/kit#2417). A run whose backlog stays empty still needs one session to finish it — the
72
- // drain, the retrospective and `run:carry --end` are a session's to do, not this process's — so a
73
- // deferral without a ceiling would leave the record carried until its 8-hour expiry and end on a
74
- // warning instead of a report. The ceiling is the `backlogrun` idle watch's own default, imported
75
- // rather than restated: the supervisor watches the empty backlog for exactly as long as a woken session
76
- // would have, only without paying a session to do it.
26
+ // An empty backlog still needs one session to finish the run, so a deferral is bounded by the
27
+ // `backlogrun` idle watch's own default.
77
28
  const IDLE_CEILING_MS = backlog_budget.DEFAULT_IDLE_MS
78
29
  const NO_WAKES = 0
79
30
  const ONE_WAKE = 1
80
31
 
81
- // The supervisor's own record: which invocation it is watching, which process it is, and how many
82
- // times it has woken a session.
83
32
  interface RunWake {
84
- // Copied from the carry record at `--start`, so the two cannot disagree about what is being
85
- // continued. It is what the woken session is handed as its prompt.
33
+ // Copied from the carry record at `--start`; it is the woken session's prompt.
86
34
  invocation: string
87
35
  profile?: AgentProfile | undefined
88
36
  started_at: string
89
- // The supervisor process. Unlike `run-hold.ts`, which records a pid it explicitly never reads back,
90
- // this one is read: `--list` reports whether the supervisor is still running and `--stop` needs
91
- // something to signal. The start-time token is what tells a reissued pid from the original.
37
+ // Read back by `--list` and `--stop`; the start-time token tells a reissued pid from the original.
92
38
  pid: number
93
39
  process_start?: string | undefined
94
- // Criterion: the number of wakes tracks the carry record's `cuts`. Counting them here is what makes
95
- // that checkable rather than merely argued from the structure. **It counts cuts served, not
96
- // launches**, so a retry of the same cut does not inflate it — `attempts` is what counts those.
97
- //
98
- // **A recovery is a wake without a cut, so `woke` may run ahead of `cuts`** (joshuafolkken/kit#2336).
99
- // When a session claims the record and then dies without cutting, the supervisor re-wakes and the
100
- // replacement's claim is counted here too — so `woke == cuts` becomes `woke >= cuts`, the gap being
101
- // the recoveries whose replacement claim a poll observed. `woke < cuts` still means a cut went
102
- // unserved, and `outstanding_line` remains the authoritative signal of a launch not yet claimed.
103
- //
104
- // **A cut is served when the woken session claims the carry record, not when a process starts**
105
- // (joshuafolkken/kit#1746). Counted at the spawn, the number asserted the very thing the supervisor
106
- // had not yet checked: on 2026-09-10 three sessions were launched for one cut and none of them ever
107
- // claimed the record, while `--list` went on reporting `woke 1 session(s) across 1 cut(s)` for forty
108
- // minutes — the published invariant reading as held throughout the failure it exists to expose. So
109
- // the increment moved to the one pass that observes a claim, and a wake nobody claimed now leaves
110
- // `woke` behind `cuts`, which is what the invariant was always meant to say.
111
- //
112
- // **It is observed at a poll, so it lags a claim by up to one polling interval** — a minute by
113
- // default. A shortfall read within that window is a claim not yet seen rather than one that never
114
- // happened, and the two are told apart by `attempts`: a cut still being retried has launches
115
- // outstanding, and one already claimed has none.
40
+ // Cuts served, counted when a woken session claims the record (not at the spawn), so an unclaimed
41
+ // wake leaves `woke` behind `cuts`. A dead-owner recovery is a wake without a cut, so `woke >= cuts`.
42
+ // Observed at a poll, so it lags a claim by up to one interval.
116
43
  woke: number
117
- // When the last wake happened, cleared as soon as the woken session claims the carry record. Its
118
- // presence is what the grace window above is measured from.
44
+ // The grace window is measured from this; cleared when the woken session claims the record.
119
45
  woke_at?: string | undefined
120
- // Launches for the cut currently being served, reset when a session claims the record. Separate
121
- // from `woke` so a retried cut still reports as one wake against one cut — and, since
122
- // joshuafolkken/kit#1746, so the two say different things: this counts what was started and `woke`
123
- // counts what arrived, which is the gap a silent failure lives in.
46
+ // Launches for the current cut: what was started, against `woke`'s what arrived.
124
47
  attempts?: number | undefined
125
- // The process the last launch produced. It is named in the failure warning rather than killed: a
126
- // session that is merely slow is still doing the run's work, and a supervisor that killed what it
127
- // could not account for would destroy exactly the work it exists to keep going.
48
+ // Named in the failure warning, never killed — a slow session is still doing the run's work.
128
49
  woke_pid?: number | undefined
129
- // When the wait on a still-running predecessor began. **It is its own field rather than a second
130
- // use of `woke_at`, and that is the whole of the bound working as described.** Marked on `woke_at`,
131
- // the first pass of a wait was the last one that could see the predecessor exit — every later pass
132
- // read the mark as an outstanding wake and answered `pending` — so a predecessor that ended two
133
- // seconds after the hold still cost the full grace window on a supervisor whose point is not to
134
- // stall. Kept apart, the predecessor's liveness is read on every pass and the mark only bounds how
135
- // long the wait may last.
136
- held_at?: string | undefined
137
- // The transcript ids of every session this supervisor forced with `--session-id`
138
- // (joshuafolkken/kit#2407). `josh time --run` attributes a whiff only to a session in this list, so
139
- // an unrelated read-only session that moved while the supervisor was alive is no longer counted
140
- // against the wake role — the $7.68 the Issue read as a ceiling becomes the real figure. Appended
141
- // once per launch, retries included, since each retry is a real session that woke and may have done
142
- // nothing, and carried across a supervisor restart exactly like the counters beside it.
50
+ // Every `--session-id` this forced, so `josh time --run` attributes whiffs only to its own sessions.
143
51
  spawned?: ReadonlyArray<string> | undefined
144
- // When the supervisor first deferred a launch because there was no work (joshuafolkken/kit#2417).
145
- // Marked once and cleared by the next launch or claim, so it measures one unbroken idle stretch: it
146
- // bounds the deferral at `IDLE_CEILING_MS`, and `run-wake-loop.ts` stretches the polling interval
147
- // by it, which is the back-off after repeated whiffs.
52
+ // Start of one unbroken idle stretch: bounds the deferral and backs off the polling interval.
148
53
  idle_since?: string | undefined
149
54
  }
150
55
 
151
56
  type WakeStopReason = 'ended' | 'expired' | 'unreadable' | 'failed' | 'stopped'
152
57
 
153
- // What the loop's tidy-up found at its own target (joshuafolkken/kit#1727). `absent` is the ordinary
154
- // `--stop`, `removed` the ordinary end of a loop, and `superseded` the one that has to be said out
155
- // loud: another supervisor holds the record and this process is the replaced one.
58
+ // `superseded`: another supervisor holds the record and this process is the replaced one.
156
59
  type WakeTidyResult = 'absent' | 'removed' | 'superseded'
157
60
 
158
- // `wait` and `pending` are two states rather than one because the wake mark is cleared in the first
159
- // and must survive the second — collapsed into one answer, a supervisor inside its grace window would
160
- // forget it had already woken and wake again every interval. `idle` is a launch the record called for
161
- // and the work did not: nothing is started, and the stretch is marked so it can be bounded.
61
+ // `wait` clears the wake mark and `pending` keeps it, or a supervisor would re-wake every interval.
62
+ // `idle` is a launch the record called for and the work did not.
162
63
  type WakeDecision =
163
64
  | { kind: 'wake' }
164
65
  | { kind: 'idle' }
165
66
  | { kind: 'wait' }
166
67
  | { kind: 'pending' }
167
- | { kind: 'hold' }
168
68
  | { kind: 'failed' }
169
69
  | { kind: 'stop'; reason: WakeStopReason }
170
70
 
@@ -172,24 +72,11 @@ interface WakeDecisionInput {
172
72
  read: CarryRead
173
73
  woke_at: string | undefined
174
74
  attempts: number
175
- // Whether the process named on the carry record is still running. **A cut is the run's last write,
176
- // not the moment its process is gone** — so a supervisor that woke the instant it saw the hand-off
177
- // could have the new session answered `busy`, because `run-carry.ts` → `classify_claim` tests
178
- // `is_foreign_live_owner` before it tests the hand-off. Answered `busy`, the woken session stops
179
- // without claiming anything, and the supervisor would eventually call its own wake a failure and end
180
- // the run. So the predecessor is waited out first.
75
+ // Read only for a record no cut handed off; a handed-off record launches whether its cutter lives or not.
181
76
  is_owner_live: boolean
182
- // When the wait on that predecessor began, so the wait can be bounded without spending the mark
183
- // that measures a launch.
184
- held_at: string | undefined
185
- // **Whether a woken session would find anything to do** (joshuafolkken/kit#2417). Before this the
186
- // decision read the carry record alone, so a session was launched whether or not the backlog held a
187
- // runnable issue or a lane was free — and a session that found nothing ended without touching
188
- // anything, which is the whiff. `undefined` is "cannot tell", and it wakes: a failed read is not an
189
- // empty backlog, and the error that costs a whiff is cheaper than the one that stalls the run.
190
- // Optional for that reason: an input that does not say reads exactly as the record-only decision did.
77
+ // Whether a woken session would find work. `undefined` ("cannot tell") wakes: a whiff is cheaper
78
+ // than a stalled run.
191
79
  has_work?: boolean | undefined
192
- // When the current idle stretch began, so the deferral can be bounded.
193
80
  idle_since?: string | undefined
194
81
  now: Date
195
82
  }
@@ -198,12 +85,8 @@ const WAKE_DECISION: WakeDecision = { kind: 'wake' }
198
85
  const IDLE_DECISION: WakeDecision = { kind: 'idle' }
199
86
  const WAIT_DECISION: WakeDecision = { kind: 'wait' }
200
87
  const PENDING_DECISION: WakeDecision = { kind: 'pending' }
201
- const HOLD_DECISION: WakeDecision = { kind: 'hold' }
202
88
  const FAILED_DECISION: WakeDecision = { kind: 'failed' }
203
89
 
204
- // The three carry reads that are not `carried`, each mapped to why the supervisor stops. `none` is the
205
- // run having ended normally (`run:carry --end`); `expired` is the whole-run bound; `unreadable` is a
206
- // record that cannot be trusted to say anything, which is a reason to stop rather than to guess.
207
90
  const STOP_REASONS: Record<'none' | 'expired' | 'unreadable', WakeStopReason> = {
208
91
  none: 'ended',
209
92
  expired: 'expired',
@@ -215,19 +98,15 @@ const run_wake_schema = process_owner_schema.extend({
215
98
  started_at: z.string(),
216
99
  woke: z.number(),
217
100
  woke_at: z.string().optional(),
218
- // **Every optional field of `RunWake` has to be listed here.** `z.object` strips what it does not
219
- // declare, so a field added to the interface alone round-trips through disk as `undefined` — which
220
- // reads as "no attempt has been made yet" and would restart the retry count on every pass.
101
+ // Every optional `RunWake` field must be listed: `z.object` strips undeclared ones on the round trip.
221
102
  attempts: z.number().optional(),
222
103
  woke_pid: z.number().optional(),
223
- held_at: z.string().optional(),
224
104
  spawned: z.array(z.string()).optional(),
225
105
  idle_since: z.string().optional(),
226
106
  profile: agent_role_profile.PROFILE_SCHEMA.optional(),
227
107
  })
228
108
 
229
- // An unparsable stamp reads as overdue rather than as fresh: a mark whose time cannot be established
230
- // is one that cannot be confirmed to have worked, and the safe direction is to report the failure.
109
+ // An unparsable stamp is overdue: a mark that cannot be confirmed is reported as a failure.
231
110
  function is_overdue(marked_at: string, now: Date, limit_ms: number = WAKE_GRACE_MS): boolean {
232
111
  const marked = Date.parse(marked_at)
233
112
 
@@ -236,10 +115,8 @@ function is_overdue(marked_at: string, now: Date, limit_ms: number = WAKE_GRACE_
236
115
  return now.getTime() - marked > limit_ms
237
116
  }
238
117
 
239
- // **A launch goes out only where there is work, or where the idle stretch has run past its ceiling**
240
- // (joshuafolkken/kit#2417). This is the one gate every launch passes — the first wake of a cut, the
241
- // recovery of a dead owner and a retry alike — because a retry into an empty backlog is the same whiff
242
- // as a first wake into one. Past the ceiling the session is woken anyway, to finish the run.
118
+ // The one gate every launch (first wake, recovery, retry) passes: launch only where there is work, or
119
+ // once the idle stretch passes its ceiling.
243
120
  function launch_or_idle(input: WakeDecisionInput): WakeDecision {
244
121
  if (input.has_work !== false) return WAKE_DECISION
245
122
  if (input.idle_since === undefined) return IDLE_DECISION
@@ -247,12 +124,7 @@ function launch_or_idle(input: WakeDecisionInput): WakeDecision {
247
124
  return is_overdue(input.idle_since, input.now, IDLE_CEILING_MS) ? WAKE_DECISION : IDLE_DECISION
248
125
  }
249
126
 
250
- // **Whether to launch, pend, retry or give up, read from the wake mark alone.** It is reached from two
251
- // places — a record a cut handed off whose predecessor has gone, and a record no cut handed off whose
252
- // owner has *died* (the recovery below) — because both ask the same question once the decision to press
253
- // on has been made: is a wake already out, is it still inside its grace window, and are there retries
254
- // left. `woke_at === undefined` is "nothing outstanding, launch"; inside the window is `pending`; past
255
- // it, a retry while attempts remain and otherwise `failed`.
127
+ // Launch, pend, retry or give up, read from the wake mark alone.
256
128
  function decide_launch(input: WakeDecisionInput): WakeDecision {
257
129
  if (input.woke_at === undefined) return launch_or_idle(input)
258
130
  if (!is_overdue(input.woke_at, input.now)) return PENDING_DECISION
@@ -260,73 +132,32 @@ function decide_launch(input: WakeDecisionInput): WakeDecision {
260
132
  return input.attempts < MAX_WAKE_ATTEMPTS ? launch_or_idle(input) : FAILED_DECISION
261
133
  }
262
134
 
263
- // **A record no cut handed off is one of two things, told apart by the owner's liveness**
264
- // (joshuafolkken/kit#2336). A *live* owner is a session spending the budget — the ordinary in-flight
265
- // state, and there is nothing to do but wait. A *dead* owner is the defect this branch exists for: a
266
- // session that claimed the record and then exited without cutting or ending — a woken session that
267
- // crashed during boot, reported its state and stopped, or was ended by a stray notification — leaves
268
- // the record `carried`, owned by a gone process, with no hand-off. Before this the supervisor answered
269
- // `wait` to both and so waited on the dead one until the 8-hour bound, stopping the whole run in
270
- // silence. Now a dead owner is recovered through the same grace/retry machinery a hand-off uses, so a
271
- // crash between the claim and the next cut re-wakes rather than stranding the invocation.
272
- //
273
- // **`is_owner_live` is `!== false`, so "cannot tell" counts as living** (`run-carry.ts` →
274
- // `is_owner_live`): a liveness read that cannot prove death keeps the safe answer, `wait`, and never
275
- // double-wakes a session that is merely unreadable.
135
+ // A live owner is a session at work; a dead one crashed between its claim and the next cut, and is
136
+ // recovered through the hand-off's grace/retry path. "Cannot tell" counts as living.
276
137
  function decide_not_handed_off(input: WakeDecisionInput): WakeDecision {
277
138
  if (input.is_owner_live) return WAIT_DECISION
278
139
 
279
140
  return decide_launch(input)
280
141
  }
281
142
 
282
- // Only before the first launch for this cut. Once a wake is out, the record's owner is whatever the
283
- // woken session declares, and waiting on it again would stall the grace window indefinitely.
284
- //
285
- // **The wait is bounded, and the bound is not decoration.** The owner is the agent process of the
286
- // session that cut, and an interactive one often outlives its own cut — waited on without a bound, the
287
- // supervisor would pend every interval for the record's whole life, wake nothing, and end on `expired`,
288
- // which sends no warning. That is a silent overnight failure, which is worse than the `busy` race this
289
- // wait exists to avoid: a `busy` merely costs one attempt, and attempts are retried. So the wait is
290
- // marked when it starts and expires into an ordinary wake through the same grace window everything
291
- // else uses.
292
- //
293
- // **And the wait ends the moment the predecessor does, because its liveness is read on every pass.**
294
- // The bound is the ceiling on the wait, never its length: a predecessor that exits two seconds after
295
- // the hold is waited two seconds. That is what `held_at` is a separate field for — marked on `woke_at`,
296
- // this test could not fire a second time, so every wait cost the whole ceiling.
297
- function is_predecessor_exiting(input: WakeDecisionInput): boolean {
298
- if (input.woke_at !== undefined || !input.is_owner_live) return false
299
-
300
- return input.held_at === undefined || !is_overdue(input.held_at, input.now)
301
- }
302
-
303
- // The whole policy, in four lines. Nothing else in this module decides whether to wake.
304
143
  function decide(input: WakeDecisionInput): WakeDecision {
305
144
  if (input.read.kind !== 'carried') return { kind: 'stop', reason: STOP_REASONS[input.read.kind] }
306
145
  if (input.read.carry.is_handed_off !== true) return decide_not_handed_off(input)
307
- if (is_predecessor_exiting(input)) return HOLD_DECISION
308
146
 
309
147
  return decide_launch(input)
310
148
  }
311
149
 
312
- // Keyed on the repository's common git directory, exactly as the carry record is — one supervisor per
313
- // invocation, and every lane of that repository keys alike. `run_carry.repository_directory` is what
314
- // resolves it, so the two records can never key differently.
150
+ // Keyed on the common git directory exactly as the carry record is, so every lane keys alike.
315
151
  function wake_path(git_directory: string): string {
316
152
  return stamp_file.stamp_path(WAKE_PREFIX, git_directory)
317
153
  }
318
154
 
319
- // Keyed on the same directory as the two records, so a person handed one path can find the others.
320
155
  function wake_log_path(git_directory: string): string {
321
156
  return stamp_file.stamp_path(WAKE_LOG_PREFIX, git_directory, WAKE_LOG_SUFFIX)
322
157
  }
323
158
 
324
159
  function parse_wake(raw: string): RunWake | undefined {
325
- try {
326
- return run_wake_schema.parse(JSON.parse(raw))
327
- } catch {
328
- return undefined
329
- }
160
+ return json_value.parse_with(raw, run_wake_schema)
330
161
  }
331
162
 
332
163
  function read_wake(target: string): RunWake | undefined {
@@ -353,24 +184,13 @@ function fresh_wake(invocation: string, now: Date, profile?: AgentProfile): RunW
353
184
  }
354
185
  }
355
186
 
356
- // **`!== false`, so "cannot tell" counts as running.** The two errors are not symmetric: a live
357
- // supervisor read as dead means two supervisors waking two sessions into one budget, while a dead one
358
- // read as live costs a refused `--start` the person can retry after `--stop`. This takes the second.
187
+ // "Cannot tell" counts as running: a refused `--start` is cheaper than two supervisors on one budget.
359
188
  function is_supervisor_live(wake: RunWake): boolean {
360
189
  return process_identity.is_same_process(wake.pid, wake.process_start) !== false
361
190
  }
362
191
 
363
- // A restarted supervisor inherits the whole wake state rather than starting it over. `woke` is
364
- // published against the carry record's `cuts` as an invariant, so a `--stop` / `--start` cycle mid-run
365
- // that reset it would make `--list` under-report and the published check read as a defect that never
366
- // happened. **`woke_at` and `attempts` come with it, and dropping them is not cosmetic**: a restart
367
- // inside the grace window would otherwise see no wake mark, launch a second session for the *same*
368
- // cut, count it as another cut served, and leave two sessions racing for one record. The invocation
369
- // has to match — a different one is a different run, and its state is not this one's.
370
- // **`woke_pid` and `held_at` come across too.** Without the first, a restart inside the grace window
371
- // that then spends its retries reports "the last one was none" in the warning — the one fact the
372
- // warning exists to hand the person, dropped exactly where it is needed. Without the second, a restart
373
- // restarts the bounded wait, which is the ceiling sliding by another road.
192
+ // A restart of the same invocation inherits the whole wake state, or it would re-wake a cut inside
193
+ // its grace window and under-report `woke` against `cuts`.
374
194
  function carried_state(existing: RunWake | undefined, invocation: string): Partial<RunWake> {
375
195
  if (existing?.invocation !== invocation) return { woke: NO_WAKES }
376
196
 
@@ -379,12 +199,7 @@ function carried_state(existing: RunWake | undefined, invocation: string): Parti
379
199
  woke_at: existing.woke_at,
380
200
  attempts: existing.attempts,
381
201
  woke_pid: existing.woke_pid,
382
- held_at: existing.held_at,
383
- // **`spawned` carries across too, or a restart mid-run would lose the ids of every session it
384
- // already started** (joshuafolkken/kit#2407) — and `josh time --run`, reading the record after
385
- // the restart, would under-count the whiffs and read the loss as a saving.
386
202
  spawned: existing.spawned,
387
- // And `idle_since`, or a restart would slide the idle ceiling by the time already spent idle.
388
203
  idle_since: existing.idle_since,
389
204
  ...(existing.profile && { profile: existing.profile }),
390
205
  }
@@ -394,9 +209,7 @@ function is_held_by_live_supervisor(existing: RunWake | undefined): boolean {
394
209
  return existing !== undefined && is_supervisor_live(existing)
395
210
  }
396
211
 
397
- // The second attempt, reached only because something was already at the target: the dead-marker sweep
398
- // `unit-worker-share.ts` does for the unit-suite share, and then one more exclusive create. The record
399
- // is re-read first, because between the two creates it may have become a live supervisor's.
212
+ // Sweep a dead marker and create once more, re-reading first in case a live supervisor took it.
400
213
  function reclaim(target: string, wake: RunWake): RunWake | undefined {
401
214
  if (is_held_by_live_supervisor(read_wake(target))) return undefined
402
215
 
@@ -405,15 +218,8 @@ function reclaim(target: string, wake: RunWake): RunWake | undefined {
405
218
  return stamp_file.create_stamp(target, wake) ? wake : undefined
406
219
  }
407
220
 
408
- // `create_stamp` rather than `write_stamp`: two `--start`s racing must not both come away believing
409
- // they own the record.
410
- //
411
- // **The create is attempted before anything is removed, and that ordering is the exclusion.** Sweeping
412
- // first — which this did, unconditionally — gives the exclusive create nothing to exclude: two claims
413
- // that both read an empty target would each delete what the other had just created, and both would
414
- // then succeed, leaving two supervisors waking two sessions into one carry budget. Attempted first, the
415
- // create is what decides between them, and the sweep runs only where it found something already there
416
- // — including a stamp that could not be parsed at all, which is why the sweep is not simply dropped.
221
+ // The exclusive create runs before any sweep — that ordering is what stops two racing `--start`s
222
+ // from both owning the record.
417
223
  function claim(
418
224
  target: string,
419
225
  invocation: string,
@@ -429,13 +235,7 @@ function claim(
429
235
  return stamp_file.create_stamp(target, wake) ? wake : reclaim(target, wake)
430
236
  }
431
237
 
432
- // A launch marks the attempt and nothing else. `woke` is left alone here because a process that has
433
- // started has not yet done the thing `woke` counts — `count_claim` is where that is decided.
434
- //
435
- // **The forced session id is recorded here, at the launch, because that is where it is known**
436
- // (joshuafolkken/kit#2407). It is appended rather than replaced: a run spawns one session per cut plus
437
- // one per retry, and `josh time --run` needs every id to tell a session it started from an unrelated
438
- // one that merely moved while it was alive.
238
+ // A launch marks the attempt and appends its session id; `woke` waits for `count_claim`.
439
239
  function count_wake(wake: RunWake, now: Date, pid: number, session_id: string): RunWake {
440
240
  const attempts = (wake.attempts ?? NO_WAKES) + ONE_WAKE
441
241
  const spawned = [...(wake.spawned ?? []), session_id]
@@ -447,40 +247,17 @@ function count_wake(wake: RunWake, now: Date, pid: number, session_id: string):
447
247
  spawned,
448
248
  woke_at,
449
249
  woke_pid: pid,
450
- held_at: undefined,
451
250
  idle_since: undefined,
452
251
  }
453
252
  }
454
253
 
455
- // Starts the clock on a wait without launching anything. `attempts` is deliberately untouched, so the
456
- // bounded wait costs no retry: what it buys is that the wait expires into an ordinary wake instead of
457
- // running until the carry record does.
458
- //
459
- // **Marked once, so the ceiling does not slide.** A mark rewritten on every pass would measure from the
460
- // latest pass rather than from the start of the wait, and a predecessor that never exits would then be
461
- // waited on for ever — the unbounded wait this bound exists to prevent, arrived at by another road.
462
- function mark_wait(wake: RunWake, now: Date): RunWake {
463
- return wake.held_at === undefined ? { ...wake, held_at: now.toISOString() } : wake
464
- }
465
-
466
- // Starts the idle stretch a deferred launch is bounded by (joshuafolkken/kit#2417). Marked once, for
467
- // the reason `mark_wait` is: rewritten each pass, the ceiling would slide and never be reached.
254
+ // Marked once: rewritten each pass, the ceiling would slide and never be reached.
468
255
  function mark_idle(wake: RunWake, now: Date): RunWake {
469
256
  return wake.idle_since === undefined ? { ...wake, idle_since: now.toISOString() } : wake
470
257
  }
471
258
 
472
- // **The one pass that observes a claim, and therefore the one place `woke` may grow**
473
- // (joshuafolkken/kit#1746). The supervisor reaches it when the carry record stops reading as handed
474
- // off, which `run-carry.ts` → `adopt_carry` does only from the session that took the record over — so
475
- // the count is of records actually claimed rather than of processes started.
476
- //
477
- // **The mark is what says a wake was outstanding.** Without it this same state is an ordinary live
478
- // session working through its budget, which no supervisor woke and which must not be counted; with
479
- // it, the wake that was pending has just been answered.
480
- //
481
- // `undefined` rather than a deleted key, because `JSON.stringify` drops it on the way to disk and the
482
- // reader treats absent and undefined alike — the same round-trip `run-carry.ts` documents for its own
483
- // optional fields.
259
+ // The one place `woke` grows: the record was claimed while a wake mark was outstanding. Without the
260
+ // mark this is an ordinary live session, which no supervisor woke.
484
261
  function count_claim(wake: RunWake): RunWake {
485
262
  const woke = wake.woke_at === undefined ? wake.woke : wake.woke + ONE_WAKE
486
263
 
@@ -489,64 +266,27 @@ function count_claim(wake: RunWake): RunWake {
489
266
  woke,
490
267
  woke_at: undefined,
491
268
  attempts: undefined,
492
- held_at: undefined,
493
269
  idle_since: undefined,
494
270
  }
495
271
  }
496
272
 
497
- // **Whether the record at the target is this process's own** (joshuafolkken/kit#1727). Everything
498
- // below that decides a write or a removal asks this rather than asking whether a record is there.
499
- //
500
- // **Existence was standing in for ownership, and the two come apart exactly when it matters.** A
501
- // `--stop` that removes the record but does not reach the process — `EPERM`, or a liveness read that
502
- // calls a running process dead — followed by a person's `--start` leaves the old loop awake beside a
503
- // new supervisor's record. Asked only whether *a* record is there, the old loop writes its own pid
504
- // and counters into the new one, and two supervisors then wake two sessions into one carry budget:
505
- // the state `claim`'s exclusive create exists to prevent, reached after the create rather than
506
- // through it. Asked whether the record is *its own*, it finds it is not and does nothing.
507
- //
508
- // **The precedent is `run-carry.ts` alone**, whose `is_owned_by` compares a record's `owner_pid` and
509
- // `owner_start` against the owner the caller declares, and whose `is_foreign_live_owner` is that
510
- // comparison deciding what a caller may touch. `run-hold.ts` is **not** a precedent and reading it as
511
- // one is the mistake this note exists to prevent: it records a pid for the person reading the stop
512
- // message and explicitly never reads it back (`run-hold.ts` → `describe_holder`), which is the
513
- // distinction `RunWake.pid` above already draws.
514
- //
515
- // The one difference from `run-carry.ts` is who the owner is. There the owner is declared from
516
- // outside, because the process spending the budget is not the one writing the record; here the writer
517
- // *is* the owner, so the declaration is `process_identity.own_fields()` and the comparison is against
518
- // this process.
273
+ // Ownership, not existence, decides every write and removal: after a `--stop` that missed the process
274
+ // and a fresh `--start`, the old loop must not write into the new supervisor's record. The writer is
275
+ // the owner here, unlike `run-carry.ts` where the owner is declared from outside.
519
276
  function is_own_wake(wake: RunWake): boolean {
520
277
  return process_identity.is_own_process(wake.pid, wake.process_start)
521
278
  }
522
279
 
523
- // The record only where it is this process's own. It is what the loop reads at the top of each pass,
524
- // so a supervisor whose record has been taken over ends **before** it decides anything — refusing the
525
- // write-back alone would still have spawned a session for a run somebody else is already watching.
280
+ // Read at the top of each pass, so a superseded supervisor ends before it spawns anything.
526
281
  function read_own_wake(target: string): RunWake | undefined {
527
282
  const wake = read_wake(target)
528
283
 
529
284
  return wake !== undefined && is_own_wake(wake) ? wake : undefined
530
285
  }
531
286
 
532
- // **Removes only this process's own record.** `--stop` and the dead-marker sweep in `reclaim` keep
533
- // using `remove_wake`, and that is deliberate: a person stopping the supervisor is removing someone
534
- // else's record on purpose, and a sweep is removing a record whose writer is gone. What must not
535
- // happen is the loop's own tidy-up taking a live successor's record with it, which leaves the run
536
- // unwatched with nothing anywhere saying so.
537
- //
538
- // **Read-then-remove, so a take-over landing between the two still costs the successor its record.**
539
- // The same residual window `update_wake` has, and closing it needs an exclusive operation the stamp
540
- // layer does not offer. What this removes is the case that was certain — the loop ending after a
541
- // take-over it had already noticed — rather than the one that needs the hand-over to land inside two
542
- // statements.
543
- //
544
- // **Three answers rather than a boolean, because the caller has to tell two of them apart.** An
545
- // ordinary `--stop` and a take-over both leave this process with nothing to remove, and only the
546
- // second is worth saying anything about — a `false` covering both put the caller in the position of
547
- // re-deriving which one it was from a second read, which is a branch that can be written the wrong
548
- // way round and would then announce a supersession on every ordinary stop. Answered here, the
549
- // distinction is decided once, in the place that already holds the record.
287
+ // The loop's tidy-up removes only its own record (`--stop` and `reclaim` use `remove_wake` on purpose).
288
+ // Three answers, so the caller announces a supersession without re-reading. Read-then-remove leaves a
289
+ // residual window the stamp layer cannot close.
550
290
  function tidy_own_wake(target: string): WakeTidyResult {
551
291
  const wake = read_wake(target)
552
292
 
@@ -558,18 +298,8 @@ function tidy_own_wake(target: string): WakeTidyResult {
558
298
  return 'removed'
559
299
  }
560
300
 
561
- // **Writes only where the record is still there *and* is this process's own.** `--stop` removes it,
562
- // and the loop's pass is not instantaneous — it spawns a process — so an unconditional write-back can
563
- // recreate a record a person has just deleted, leaving a supervisor that outlives its own stop; the
564
- // presence check narrows that window rather than closing it outright, and what closes it is that the
565
- // next pass reads the record again. The ownership check is the second half: a foreign record is
566
- // never written back, however long the pass took.
567
- //
568
- // **That is a claim about the write and about nothing else.** A take-over landing mid-pass is still
569
- // narrowed rather than closed — the pass spawns a process, so a session can go out for a cut the
570
- // successor is also serving, and only the write-back that follows it is refused. What closes the
571
- // window at the top of a pass is `read_own_wake`, and what closes it inside one is nothing here:
572
- // this is a refusal to make the damage permanent, not a lock.
301
+ // Writes only where the record is still there and this process's own, so a pass never recreates a
302
+ // record `--stop` deleted or overwrites a successor's. A refusal to make damage permanent, not a lock.
573
303
  function update_wake(target: string, wake: RunWake): boolean {
574
304
  if (read_own_wake(target) === undefined) return false
575
305
 
@@ -589,7 +319,6 @@ const run_wake = {
589
319
  fresh_wake,
590
320
  is_supervisor_live,
591
321
  mark_idle,
592
- mark_wait,
593
322
  parse_wake,
594
323
  read_own_wake,
595
324
  read_wake,
@@ -5,9 +5,9 @@ import { execaSync } from 'execa'
5
5
 
6
6
  // Where the workflows that install safe-chain on the runner live. Each carries the release and the
7
7
  // installer's SHA-256 as workflow-level env, so one pin per file moves every "Setup safe-chain" step
8
- // at once (joshuafolkken/kit#2711, joshuafolkken/kit#2765). The directories are scanned rather than
8
+ // at once. The directories are scanned rather than
9
9
  // a file list kept, so a workflow another package distributes — app-kit's `dast.yml` and `load.yml`
10
- // — moves with the rest (joshuafolkken/kit#2830); a file without the pin is never a target.
10
+ // — moves with the rest; a file without the pin is never a target.
11
11
  const WORKFLOW_DIRECTORIES = ['.github/workflows', 'templates/workflows']
12
12
  const WORKFLOW_FILE_RE = /\.ya?ml$/u
13
13
  // `[ \t]` rather than `\s`: under the `m` flag `\s*` would run across line ends and swallow the
@@ -27,7 +27,7 @@ function installer_url(version: string): string {
27
27
  }
28
28
 
29
29
  // The local composite actions follow the workflows: kit's own pin lives in
30
- // `.github/actions/setup-pnpm`, which every kit workflow installs through (joshuafolkken/kit#2982).
30
+ // `.github/actions/setup-pnpm`, which every kit workflow installs through.
31
31
  function list_workflows(): Array<string> {
32
32
  const workflows = WORKFLOW_DIRECTORIES.filter((directory) => existsSync(directory)).flatMap(
33
33
  (directory) =>