@joshuafolkken/kit 1.1471.0 → 1.1784.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 (895) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +6 -6
  3. package/.claude/skills/epic-commands/SKILL.md +26 -77
  4. package/.claude/skills/epic-commands/epic-bundle.md +12 -6
  5. package/.claude/skills/epic-commands/execution-waves.md +1 -2
  6. package/.claude/skills/verify-ui/SKILL.md +1 -2
  7. package/.claude/skills/workflow-commands/SKILL.md +12 -14
  8. package/.claude/skills/workflow-commands/background-commands.md +8 -12
  9. package/.claude/skills/workflow-commands/backlogrun-child.md +13 -18
  10. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  11. package/.claude/skills/workflow-commands/backlogrun-lanes.md +23 -28
  12. package/.claude/skills/workflow-commands/backlogrun-park.md +16 -31
  13. package/.claude/skills/workflow-commands/backlogrun-progress.md +12 -21
  14. package/.claude/skills/workflow-commands/backlogrun-recovery.md +12 -12
  15. package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -20
  16. package/.claude/skills/workflow-commands/backlogrun.md +32 -51
  17. package/.claude/skills/workflow-commands/chain-rule.md +18 -11
  18. package/.claude/skills/workflow-commands/delegation.md +13 -8
  19. package/.claude/skills/workflow-commands/entry-sequence.md +10 -12
  20. package/.claude/skills/workflow-commands/followup.md +10 -35
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +38 -49
  22. package/.claude/skills/workflow-commands/fullrun.md +6 -8
  23. package/.claude/skills/workflow-commands/halfrun.md +20 -32
  24. package/.claude/skills/workflow-commands/into-target.md +1 -2
  25. package/.claude/skills/workflow-commands/issue-comments.md +19 -15
  26. package/.claude/skills/workflow-commands/issue-scout.md +5 -4
  27. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  28. package/.claude/skills/workflow-commands/latest-gate.md +9 -18
  29. package/.claude/skills/workflow-commands/needs-human-review.md +11 -19
  30. package/.claude/skills/workflow-commands/observation-filing.md +4 -50
  31. package/.claude/skills/workflow-commands/observation-ledger.md +5 -10
  32. package/.claude/skills/workflow-commands/pre-gate-cut.md +22 -44
  33. package/.claude/skills/workflow-commands/prerequisite.md +11 -18
  34. package/.claude/skills/workflow-commands/progress-watcher.md +3 -8
  35. package/.claude/skills/workflow-commands/prrun.md +6 -12
  36. package/.claude/skills/workflow-commands/retrospective.md +5 -5
  37. package/.claude/skills/workflow-commands/split-assessment.md +14 -4
  38. package/.claude/skills/workflow-commands/target-repository.md +1 -2
  39. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -13
  40. package/.codex/hooks.json +6 -6
  41. package/.github/actions/setup-node/action.yml +10 -1
  42. package/.github/actions/setup-pnpm/action.yml +1 -1
  43. package/.github/dependabot.yml +16 -0
  44. package/.github/release.yml +0 -2
  45. package/.github/workflows/ci.yml +121 -11
  46. package/.github/workflows/publish.yml +10 -3
  47. package/.github/workflows/sonar-qube.yml +1 -0
  48. package/.prettierignore +2 -0
  49. package/.vscode/tasks.json +1 -2
  50. package/CLAUDE.md +4 -8
  51. package/README.md +4 -2
  52. package/SECURITY.md +1 -1
  53. package/cspell/index.yaml +7 -0
  54. package/dist/CLAUDE.md +4 -8
  55. package/dist/commands/document-read-cli.js +882 -0
  56. package/dist/commands/{document-section-cli.js → document-section-main.js} +137 -62
  57. package/dist/commands/read-set-cli.js +1867 -0
  58. package/dist/commands/run-prep-main.js +21653 -0
  59. package/dist/commands/run-step-cli.js +23880 -0
  60. package/dist/config-merge/index.js +5 -1
  61. package/dist/hooks/audit-provision.js +20 -35
  62. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  63. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  64. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  65. package/dist/hooks/{chunk-AS74OU3D.js → chunk-PT5R6UJD.js} +4582 -2118
  66. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  67. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  68. package/dist/hooks/{chunk-E7OIKX5Z.js → chunk-WR2KQAYZ.js} +1863 -382
  69. package/dist/hooks/{chunk-KC5AK2GF.js → chunk-XGBNSWEI.js} +248 -46
  70. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  71. package/dist/hooks/codex-hook-adapter.js +10 -19
  72. package/dist/hooks/format-edited.js +5 -5
  73. package/dist/hooks/inputs.json +436 -257
  74. package/dist/hooks/pretool-guard.js +7 -22
  75. package/dist/hooks/session-lang.js +380 -42
  76. package/dist/hooks/stop-guard.js +8711 -782
  77. package/dist/josh.js +5263 -997
  78. package/dist/self-sync-guard/index.js +74 -10
  79. package/dist/version/index.js +115 -406
  80. package/eslint/base.js +1 -1
  81. package/lefthook/base.yml +8 -4
  82. package/package.json +17 -53
  83. package/pnpm-workspace.yaml +4 -2
  84. package/prompts/coding-standards.md +1 -1
  85. package/prompts/collaboration-workflow/file-edits.md +1 -9
  86. package/prompts/collaboration-workflow/gh-rest.md +1 -2
  87. package/prompts/collaboration-workflow/issue-citation.md +2 -4
  88. package/prompts/collaboration-workflow/issue-template.md +42 -17
  89. package/prompts/collaboration-workflow/lane-instructions.md +34 -0
  90. package/prompts/collaboration-workflow/measurement.md +37 -0
  91. package/prompts/collaboration-workflow/operating-rules.md +6 -12
  92. package/prompts/collaboration-workflow/output-bounds.md +4 -9
  93. package/prompts/collaboration-workflow/overview.md +1 -1
  94. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  95. package/prompts/collaboration-workflow/principles.md +19 -8
  96. package/prompts/collaboration-workflow/report-format.md +37 -57
  97. package/prompts/collaboration-workflow/residency.md +12 -8
  98. package/prompts/collaboration-workflow/rule-delivery.md +3 -11
  99. package/prompts/collaboration-workflow/shell-body.md +8 -18
  100. package/prompts/collaboration-workflow/turn-batching.md +4 -6
  101. package/prompts/collaboration-workflow/upstream-interrupt.md +16 -6
  102. package/prompts/collaboration-workflow/wip-cap.md +7 -7
  103. package/prompts/collaboration-workflow.md +4 -7
  104. package/prompts/refactoring.md +1 -1
  105. package/prompts/review-rubric.md +1 -2
  106. package/prompts/review.md +45 -26
  107. package/prompts/testing-guide.md +10 -45
  108. package/scripts/agent/agent-argv.ts +20 -4
  109. package/scripts/agent/agent-event.ts +15 -15
  110. package/scripts/agent/agent-exit-record.ts +13 -1
  111. package/scripts/agent/agent-role-profile.ts +101 -45
  112. package/scripts/agent/agent-safe-text.ts +60 -0
  113. package/scripts/agent/api-auth.ts +41 -0
  114. package/scripts/agent/api-outage.ts +1 -1
  115. package/scripts/agent/claude-agent-argv.ts +14 -0
  116. package/scripts/agent/codex-agent-argv.ts +2 -0
  117. package/scripts/agent/lane-instructions.ts +144 -0
  118. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  119. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  120. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  121. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  122. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  123. package/scripts/backlog/backlog-arrival.ts +14 -3
  124. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  125. package/scripts/backlog/backlog-budget-main.ts +16 -0
  126. package/scripts/backlog/backlog-budget.ts +6 -7
  127. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  128. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  129. package/scripts/backlog/backlog-drive-args.ts +4 -5
  130. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  131. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  132. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  133. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  134. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  135. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  136. package/scripts/backlog/backlog-drive-named.ts +54 -7
  137. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  138. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  139. package/scripts/backlog/backlog-drive-restore.ts +39 -8
  140. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  141. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  142. package/scripts/backlog/backlog-drive.ts +79 -75
  143. package/scripts/backlog/backlog-next-main.ts +16 -0
  144. package/scripts/backlog/backlog-next-shared.ts +73 -0
  145. package/scripts/backlog/backlog-next.ts +48 -16
  146. package/scripts/backlog/backlog-occupied.ts +69 -0
  147. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  148. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  149. package/scripts/backlog/backlog-offer-main.ts +12 -0
  150. package/scripts/backlog/backlog-offer.ts +36 -3
  151. package/scripts/backlog/backlog-overlap.ts +22 -4
  152. package/scripts/backlog/backlog-plan-read.ts +6 -2
  153. package/scripts/backlog/backlog-plan.ts +18 -4
  154. package/scripts/backlog/backlog-pool.ts +10 -10
  155. package/scripts/backlog/backlog-rank.ts +10 -2
  156. package/scripts/backlog/backlog-ready.ts +137 -18
  157. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  158. package/scripts/backlog/backlog-stalled.ts +52 -16
  159. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  160. package/scripts/backlog/backlog-waves.ts +39 -13
  161. package/scripts/backlog/backlogrun-args.ts +19 -7
  162. package/scripts/backlog/backlogrun-cli.ts +19 -5
  163. package/scripts/backlog/backlogrun-launch.ts +6 -0
  164. package/scripts/backlog/backlogrun-restart.ts +97 -0
  165. package/scripts/backlog/backlogrun-stop.ts +79 -7
  166. package/scripts/behavior/behavior-cli.ts +2 -2
  167. package/scripts/behavior/behavior-rules.ts +47 -24
  168. package/scripts/build/build-bin.ts +2 -16
  169. package/scripts/build/build-claude-md.ts +0 -7
  170. package/scripts/build/build-commands.ts +0 -13
  171. package/scripts/build/build-hooks.ts +49 -48
  172. package/scripts/build/hook-bundle-stamp.ts +29 -11
  173. package/scripts/build/local-bin.ts +1 -1
  174. package/scripts/cases/cases-cli.ts +25 -13
  175. package/scripts/cases/cases-interaction-scan.ts +134 -0
  176. package/scripts/cases/cases-interaction.ts +183 -0
  177. package/scripts/cases/cases-logic.ts +39 -6
  178. package/scripts/ci/pr-classification-main.ts +18 -0
  179. package/scripts/ci/pr-classification.ts +10 -17
  180. package/scripts/clone/clone-scan.ts +1 -1
  181. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  182. package/scripts/cost-runtime/cost-cli.ts +31 -14
  183. package/scripts/cost-runtime/cost-main.ts +12 -0
  184. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  185. package/scripts/delegation/delegation-policy.ts +17 -4
  186. package/scripts/delegation/duplicate-read-guard.ts +2 -10
  187. package/scripts/delegation/investigation-guard.ts +15 -73
  188. package/scripts/delegation/investigation-reads.ts +3 -5
  189. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  190. package/scripts/discovery/repo-discovery.ts +24 -6
  191. package/scripts/doctor/doctor-consumer.ts +2 -5
  192. package/scripts/document/document-byte-budget.ts +9 -6
  193. package/scripts/document/document-scan.ts +1 -1
  194. package/scripts/document/document-section-cli.ts +17 -13
  195. package/scripts/document/document-section-main.ts +12 -0
  196. package/scripts/document/entry-read-budget.ts +2 -2
  197. package/scripts/document/read-set-cli.ts +4 -1
  198. package/scripts/epic/epic-audit-cli.ts +12 -6
  199. package/scripts/epic/epic-audit-orphans.ts +5 -8
  200. package/scripts/epic/epic-audit.ts +52 -1
  201. package/scripts/epic/epic-bundle-apply.ts +137 -0
  202. package/scripts/epic/epic-bundle-cli.ts +32 -121
  203. package/scripts/epic/epic-bundle-evidence.ts +49 -26
  204. package/scripts/epic/epic-bundle-format.ts +116 -0
  205. package/scripts/epic/epic-bundle-main.ts +17 -0
  206. package/scripts/epic/epic-bundle-referenced.ts +14 -3
  207. package/scripts/epic/epic-bundle.ts +17 -9
  208. package/scripts/epic/epic-busy.ts +5 -12
  209. package/scripts/epic/epic-classify.ts +24 -15
  210. package/scripts/epic/epic-cli-argv.ts +31 -0
  211. package/scripts/epic/epic-cli-decide.ts +42 -0
  212. package/scripts/epic/epic-cli.ts +6 -38
  213. package/scripts/epic/epic-close.ts +112 -55
  214. package/scripts/epic/epic-cross-repo.ts +4 -7
  215. package/scripts/epic/epic-decide.ts +119 -0
  216. package/scripts/epic/epic-decision.ts +9 -0
  217. package/scripts/epic/epic-fetch.ts +4 -0
  218. package/scripts/epic/epic-graph.ts +2 -0
  219. package/scripts/epic/epic-issue.ts +5 -1
  220. package/scripts/epic/epic-label-age.ts +1 -1
  221. package/scripts/epic/epic-lane-offer.ts +39 -4
  222. package/scripts/epic/epic-next-main.ts +24 -0
  223. package/scripts/epic/epic-next.ts +6 -24
  224. package/scripts/epic/epic-outside-blocker.ts +6 -2
  225. package/scripts/epic/epic-parse.ts +9 -3
  226. package/scripts/epic/epic-read.ts +1 -0
  227. package/scripts/epic/epic-reconcile.ts +39 -0
  228. package/scripts/epic/epic-run.ts +10 -1
  229. package/scripts/epic/epic-solo.ts +50 -14
  230. package/scripts/epic/epic.ts +41 -7
  231. package/scripts/exports/unused-members-cli.ts +2 -2
  232. package/scripts/followup/followup-checks-event.ts +8 -3
  233. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  234. package/scripts/followup/followup-review-gates.ts +81 -0
  235. package/scripts/followup/git-followup-stages.ts +13 -3
  236. package/scripts/followup/git-followup-workflow.ts +31 -60
  237. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  238. package/scripts/followup/git-pr-followup.ts +36 -8
  239. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  240. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  241. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  242. package/scripts/gate/busy-average.ts +58 -0
  243. package/scripts/gate/check-cpu.ts +60 -0
  244. package/scripts/gate/check-inputs.ts +73 -0
  245. package/scripts/gate/check-reuse.ts +141 -0
  246. package/scripts/gate/command-memory.ts +192 -0
  247. package/scripts/gate/core-admission.ts +218 -28
  248. package/scripts/gate/core-budget-timing.ts +37 -0
  249. package/scripts/gate/core-budget.ts +150 -119
  250. package/scripts/gate/core-wait-record.ts +48 -0
  251. package/scripts/gate/core-wait.ts +162 -0
  252. package/scripts/gate/core-weights.ts +86 -0
  253. package/scripts/gate/free-cores.ts +72 -0
  254. package/scripts/gate/gate-ledger.ts +49 -7
  255. package/scripts/gate/gate-plan.ts +44 -15
  256. package/scripts/gate/gate-report.ts +29 -4
  257. package/scripts/gate/gate-run-steps.ts +195 -0
  258. package/scripts/gate/gate-skip.ts +12 -2
  259. package/scripts/gate/gate-steps.ts +12 -1
  260. package/scripts/gate/held-mark.ts +55 -0
  261. package/scripts/gate/input-fingerprint.ts +42 -0
  262. package/scripts/gate/machine-capacity.ts +124 -31
  263. package/scripts/gate/moved-paths.ts +67 -0
  264. package/scripts/gate/pre-commit-type-check.ts +14 -1
  265. package/scripts/gate/project-checks.ts +5 -12
  266. package/scripts/gate/scoped-green.ts +12 -8
  267. package/scripts/gate/since-green.ts +62 -0
  268. package/scripts/gate/toolchain-inputs.ts +115 -0
  269. package/scripts/gate/verification-gate.ts +65 -129
  270. package/scripts/gate/verification-inputs.ts +250 -0
  271. package/scripts/gh/gh-author-association.ts +96 -9
  272. package/scripts/gh/git-ai-review-scan.ts +4 -2
  273. package/scripts/gh/git-gh-api-path.ts +15 -0
  274. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  275. package/scripts/gh/git-gh-conditional.ts +5 -2
  276. package/scripts/gh/git-gh-issue-read.ts +5 -1
  277. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  278. package/scripts/gh/git-gh-issue-write.ts +77 -17
  279. package/scripts/gh/git-gh-issue.ts +7 -3
  280. package/scripts/gh/git-gh-poll-read.ts +89 -0
  281. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  282. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  283. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  284. package/scripts/gh/git-gh-pr.ts +27 -15
  285. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  286. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  287. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  288. package/scripts/gh/git-pr.ts +13 -1
  289. package/scripts/git/base-tree.ts +19 -2
  290. package/scripts/git/changed-file-scope.ts +6 -4
  291. package/scripts/git/changed-paths.ts +18 -1
  292. package/scripts/git/git-diff-reads.ts +27 -2
  293. package/scripts/git/git-grep-hits.ts +85 -0
  294. package/scripts/git/git-location-environment.ts +1 -1
  295. package/scripts/git/git-merge-conflicts.ts +83 -0
  296. package/scripts/git/git-preflight.ts +37 -12
  297. package/scripts/git/git-push-transport.ts +1 -2
  298. package/scripts/git/git-schemas.ts +17 -7
  299. package/scripts/git/git-spawn.ts +1 -2
  300. package/scripts/git/git-status.ts +4 -4
  301. package/scripts/git/main-merge-main.ts +12 -0
  302. package/scripts/git/main-merge-regenerate.ts +78 -0
  303. package/scripts/git/main-merge.ts +39 -14
  304. package/scripts/git/main-sync-main.ts +12 -0
  305. package/scripts/git/main-sync.ts +0 -9
  306. package/scripts/git/stash/git-stash.ts +27 -4
  307. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  308. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  309. package/scripts/git/stash/stash-pop-main.ts +12 -0
  310. package/scripts/git/stash/stash-push-cli.ts +76 -0
  311. package/scripts/git/stash/stash-push-main.ts +12 -0
  312. package/scripts/hooks/batch-guard.ts +5 -16
  313. package/scripts/hooks/check-commit-message-main.ts +8 -0
  314. package/scripts/hooks/check-commit-message.ts +4 -7
  315. package/scripts/hooks/format-edited-file.ts +8 -24
  316. package/scripts/hooks/pre-commit-lint.ts +118 -0
  317. package/scripts/hooks/pre-push-unit.ts +4 -2
  318. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  319. package/scripts/hooks/pretool-guard.ts +57 -69
  320. package/scripts/hooks/reserved-run.ts +67 -8
  321. package/scripts/hooks/run-hook.sh +18 -11
  322. package/scripts/hooks/shell-rules-notice.ts +37 -0
  323. package/scripts/hooks/stop-actions.ts +185 -0
  324. package/scripts/hooks/stop-guard.ts +72 -27
  325. package/scripts/init/hook-command-rewrite.ts +19 -5
  326. package/scripts/init/hook-launch.ts +15 -12
  327. package/scripts/init/init-actions.ts +0 -6
  328. package/scripts/init/init-ai-copy.ts +10 -36
  329. package/scripts/init/init-bootstrap.ts +9 -8
  330. package/scripts/init/init-dry-run-report.ts +1 -1
  331. package/scripts/init/init-dry-run.ts +1 -1
  332. package/scripts/init/init-file-action.ts +7 -9
  333. package/scripts/init/init-logic-json-merge.ts +2 -2
  334. package/scripts/init/init-logic-migrate.ts +9 -82
  335. package/scripts/init/init-logic.ts +3 -2
  336. package/scripts/init/init-main.ts +12 -0
  337. package/scripts/init/init.ts +5 -12
  338. package/scripts/init/kit-development-versions.ts +3 -7
  339. package/scripts/init/kit-written-paths.ts +2 -2
  340. package/scripts/init/project-profile.ts +5 -4
  341. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  342. package/scripts/init/vscode-tasks.ts +1 -1
  343. package/scripts/issue/defect-origin-cli.ts +106 -0
  344. package/scripts/issue/defect-origin-line.ts +60 -0
  345. package/scripts/issue/defect-origin-main.ts +11 -0
  346. package/scripts/issue/defect-origin.ts +114 -0
  347. package/scripts/issue/defect-rate-cli.ts +34 -78
  348. package/scripts/issue/defect-rate.ts +0 -16
  349. package/scripts/issue/defect-report-cli.ts +128 -0
  350. package/scripts/issue/defect-report-format.ts +56 -0
  351. package/scripts/issue/defect-report-main.ts +11 -0
  352. package/scripts/issue/defect-report.ts +160 -0
  353. package/scripts/issue/expected-effect-lint.ts +60 -0
  354. package/scripts/issue/issue-already-done-cli.ts +62 -0
  355. package/scripts/issue/issue-body-or-comment.ts +40 -0
  356. package/scripts/issue/issue-cite-cli.ts +33 -22
  357. package/scripts/issue/issue-cite-main.ts +12 -0
  358. package/scripts/issue/issue-classification.ts +13 -8
  359. package/scripts/issue/issue-comment-cli.ts +10 -24
  360. package/scripts/issue/issue-comment-main.ts +12 -0
  361. package/scripts/issue/issue-evidence-exit.ts +100 -0
  362. package/scripts/issue/issue-file-cli.ts +29 -7
  363. package/scripts/issue/issue-file.ts +19 -19
  364. package/scripts/issue/issue-fold-cli.ts +2 -11
  365. package/scripts/issue/issue-fold-main.ts +12 -0
  366. package/scripts/issue/issue-labels.ts +81 -90
  367. package/scripts/issue/issue-lint-cli.ts +7 -13
  368. package/scripts/issue/issue-lint-main.ts +12 -0
  369. package/scripts/issue/issue-measured-cli.ts +56 -0
  370. package/scripts/issue/issue-merged.ts +19 -2
  371. package/scripts/issue/issue-not-before-label.ts +135 -0
  372. package/scripts/issue/issue-not-before.ts +111 -0
  373. package/scripts/issue/issue-number-shape.ts +15 -1
  374. package/scripts/issue/issue-park.ts +28 -0
  375. package/scripts/issue/issue-plan-cli.ts +151 -0
  376. package/scripts/issue/issue-priority.ts +151 -0
  377. package/scripts/issue/issue-rank.ts +7 -1
  378. package/scripts/issue/issue-read-cli.ts +3 -10
  379. package/scripts/issue/issue-read-main.ts +12 -0
  380. package/scripts/issue/issue-read.ts +29 -5
  381. package/scripts/issue/issue-release-cli.ts +0 -10
  382. package/scripts/issue/issue-release-main.ts +13 -0
  383. package/scripts/issue/issue-release.ts +7 -12
  384. package/scripts/issue/issue-sample-gate.ts +192 -0
  385. package/scripts/issue/issue-sample-source.ts +76 -0
  386. package/scripts/issue/issue-scout-cli.ts +19 -25
  387. package/scripts/issue/issue-scout-main.ts +14 -0
  388. package/scripts/issue/issue-state-cli.ts +0 -10
  389. package/scripts/issue/issue-state-main.ts +12 -0
  390. package/scripts/issue/issue-watch-diff.ts +56 -15
  391. package/scripts/issue/issue-watch.ts +2 -1
  392. package/scripts/issue/issue-wip.ts +2 -7
  393. package/scripts/issue/markdown-section.ts +19 -5
  394. package/scripts/issue/measure-rerun-cli.ts +13 -8
  395. package/scripts/issue/plan-consumers-cli.ts +39 -0
  396. package/scripts/issue/plan-consumers-main.ts +11 -0
  397. package/scripts/issue/plan-consumers-section.ts +55 -0
  398. package/scripts/issue/plan-consumers.ts +127 -0
  399. package/scripts/josh/agent-session-environment.ts +1 -1
  400. package/scripts/josh/command-usage.ts +82 -0
  401. package/scripts/josh/file-map-stamp.ts +49 -16
  402. package/scripts/josh/hook-decision.ts +32 -20
  403. package/scripts/josh/josh-command-map.ts +6 -1
  404. package/scripts/josh/josh-command-types.ts +65 -13
  405. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  406. package/scripts/josh/josh-commands-ai.ts +169 -157
  407. package/scripts/josh/josh-commands-backlog.ts +82 -16
  408. package/scripts/josh/josh-commands-clone.ts +1 -0
  409. package/scripts/josh/josh-commands-development.ts +111 -71
  410. package/scripts/josh/josh-commands-document.ts +43 -1
  411. package/scripts/josh/josh-commands-epic.ts +171 -0
  412. package/scripts/josh/josh-commands-hooks.ts +31 -2
  413. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  414. package/scripts/josh/josh-commands-issue.ts +124 -24
  415. package/scripts/josh/josh-commands-lane.ts +112 -2
  416. package/scripts/josh/josh-commands-lint.ts +19 -8
  417. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  418. package/scripts/josh/josh-commands-pause.ts +29 -0
  419. package/scripts/josh/josh-commands-progress.ts +87 -0
  420. package/scripts/josh/josh-commands-project.ts +138 -9
  421. package/scripts/josh/josh-commands-review.ts +124 -0
  422. package/scripts/josh/josh-commands-run.ts +211 -23
  423. package/scripts/josh/josh-commands-ship.ts +169 -0
  424. package/scripts/josh/josh-commands-split.ts +9 -0
  425. package/scripts/josh/josh-commands-versioning.ts +49 -2
  426. package/scripts/josh/josh-commands-workflow.ts +149 -6
  427. package/scripts/josh/josh-logic.ts +11 -27
  428. package/scripts/josh/josh.ts +14 -5
  429. package/scripts/josh/package-directory.ts +18 -0
  430. package/scripts/josh/process-identity.ts +13 -4
  431. package/scripts/josh/session-language-cli.ts +4 -8
  432. package/scripts/josh/session-language-main.ts +13 -0
  433. package/scripts/josh/session-language.ts +6 -1
  434. package/scripts/josh/shared-cache.ts +90 -0
  435. package/scripts/josh/stamp-file.ts +9 -15
  436. package/scripts/lane/lane-await.ts +51 -12
  437. package/scripts/lane/lane-cache.ts +5 -30
  438. package/scripts/lane/lane-capacity.ts +19 -22
  439. package/scripts/lane/lane-check-stats.ts +97 -0
  440. package/scripts/lane/lane-child-invocation.ts +43 -4
  441. package/scripts/lane/lane-cli.ts +15 -5
  442. package/scripts/lane/lane-close.ts +86 -18
  443. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  444. package/scripts/lane/lane-dispatch.ts +27 -6
  445. package/scripts/lane/lane-gap-stats.ts +156 -0
  446. package/scripts/lane/lane-guard-policy.ts +2 -2
  447. package/scripts/lane/lane-handoff.ts +76 -1
  448. package/scripts/lane/lane-held-stats.ts +129 -0
  449. package/scripts/lane/lane-install.ts +16 -15
  450. package/scripts/lane/lane-launch-cli.ts +0 -9
  451. package/scripts/lane/lane-launch-main.ts +12 -0
  452. package/scripts/lane/lane-ledger-schema.ts +266 -0
  453. package/scripts/lane/lane-ledger.ts +108 -97
  454. package/scripts/lane/lane-limit-cli.ts +19 -9
  455. package/scripts/lane/lane-measure-cli.ts +58 -10
  456. package/scripts/lane/lane-open.ts +9 -1
  457. package/scripts/lane/lane-parked.ts +3 -3
  458. package/scripts/lane/lane-pause-cli.ts +130 -0
  459. package/scripts/lane/lane-pause.ts +158 -0
  460. package/scripts/lane/lane-preserve.ts +29 -1
  461. package/scripts/lane/lane-process-table.ts +166 -0
  462. package/scripts/lane/lane-reap-settle.ts +124 -0
  463. package/scripts/lane/lane-reap.ts +50 -15
  464. package/scripts/lane/lane-registry.ts +33 -10
  465. package/scripts/lane/lane-residents.ts +162 -0
  466. package/scripts/lane/lane-restart.ts +26 -27
  467. package/scripts/lane/lane-round-two-stats.ts +49 -0
  468. package/scripts/lane/lane-sampler.ts +4 -0
  469. package/scripts/lane/lane-session-action.ts +160 -0
  470. package/scripts/lane/lane-session-broker.ts +134 -134
  471. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  472. package/scripts/lane/lane-spans.ts +51 -0
  473. package/scripts/lane/lane-spent.ts +6 -3
  474. package/scripts/lane/lane-stage-stats.ts +7 -2
  475. package/scripts/lane/lane-state.ts +302 -0
  476. package/scripts/lane/lane-stats.ts +58 -4
  477. package/scripts/lane/lane-stop-stats.ts +113 -37
  478. package/scripts/lane/lane-test-related-stats.ts +127 -0
  479. package/scripts/lane/lane-transcript-calls.ts +145 -0
  480. package/scripts/lane/lane-transcript-stats.ts +168 -0
  481. package/scripts/lane/lane-vacant.ts +13 -3
  482. package/scripts/lane/lane-withdraw-cli.ts +72 -0
  483. package/scripts/lane/lane-withdraw.ts +183 -0
  484. package/scripts/lane/process-directories.ts +70 -0
  485. package/scripts/lane/process-lane-marks.ts +94 -0
  486. package/scripts/lib/atomic-write.ts +62 -0
  487. package/scripts/lib/buffered-process.ts +12 -5
  488. package/scripts/lib/cli-flags.ts +53 -0
  489. package/scripts/lib/figure-format.ts +63 -0
  490. package/scripts/lib/json-value.ts +9 -1
  491. package/scripts/lib/package-manifest.ts +35 -0
  492. package/scripts/lib/read-file.ts +3 -1
  493. package/scripts/lib/stamped-memo.ts +63 -0
  494. package/scripts/lib/stdout-on-stderr.ts +24 -0
  495. package/scripts/lib/timeouts.ts +9 -0
  496. package/scripts/lib/transcript-record.ts +91 -0
  497. package/scripts/lines/effective-limit.ts +1 -1
  498. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  499. package/scripts/lint/eslint-daemon.ts +265 -0
  500. package/scripts/lint/format.ts +14 -5
  501. package/scripts/lint/import-graph.ts +279 -0
  502. package/scripts/lint/lint-gate-scope.ts +102 -0
  503. package/scripts/lint/lint-parallel-main.ts +19 -0
  504. package/scripts/lint/lint-parallel.ts +72 -33
  505. package/scripts/lint/lint-related-scope.ts +33 -24
  506. package/scripts/lint/lint-related.ts +38 -6
  507. package/scripts/notify/confirmation-options.ts +1 -2
  508. package/scripts/notify/telegram-notify.ts +20 -20
  509. package/scripts/notify/telegram-test-logic.ts +0 -1
  510. package/scripts/notify/telegram-test-main.ts +8 -0
  511. package/scripts/notify/telegram-test.ts +12 -11
  512. package/scripts/observations/observation-ledger.ts +13 -0
  513. package/scripts/observations/observations-flush-landing.ts +5 -3
  514. package/scripts/observations/observations-flush.ts +6 -1
  515. package/scripts/overrides/overrides-check.ts +2 -5
  516. package/scripts/overrides/overrides-files.ts +2 -1
  517. package/scripts/overrides/overrides-logic.ts +3 -6
  518. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  519. package/scripts/propagate/propagate-publish.ts +2 -7
  520. package/scripts/propagate/propagate-targets.ts +4 -12
  521. package/scripts/refactor/import-graph.ts +9 -7
  522. package/scripts/release/github-release-runs.ts +17 -6
  523. package/scripts/release/release-approval-prune.ts +18 -0
  524. package/scripts/release/release-history.ts +1 -3
  525. package/scripts/release/release-progress.ts +42 -22
  526. package/scripts/release/release-publish-run.ts +39 -0
  527. package/scripts/release/release-publish.ts +6 -6
  528. package/scripts/release/release-scope-cli.ts +0 -10
  529. package/scripts/release/release-scope-main.ts +12 -0
  530. package/scripts/repo/repo-setting.ts +3 -6
  531. package/scripts/repo/required-checks-logic.ts +6 -15
  532. package/scripts/report/report-format-reference.ts +4 -0
  533. package/scripts/report/report-labels.ts +155 -0
  534. package/scripts/report/report-lint-cli.ts +3 -0
  535. package/scripts/report/report-lint.ts +85 -110
  536. package/scripts/report/report-template-cli.ts +59 -0
  537. package/scripts/report/report-template.ts +112 -0
  538. package/scripts/review/acceptance-map-check.ts +61 -0
  539. package/scripts/review/acceptance-map.ts +206 -0
  540. package/scripts/review/removed-tests-check.ts +86 -0
  541. package/scripts/review/removed-tests.ts +149 -0
  542. package/scripts/review/review-brief-cli.ts +82 -16
  543. package/scripts/review/review-brief-main.ts +12 -0
  544. package/scripts/review/review-brief.ts +31 -3
  545. package/scripts/review/review-code-tree.ts +10 -6
  546. package/scripts/review/review-comment-round.ts +26 -8
  547. package/scripts/review/review-finding-ledger.ts +30 -15
  548. package/scripts/review/review-interaction.ts +94 -0
  549. package/scripts/review/review-readers-scan.ts +163 -0
  550. package/scripts/review/review-record-cli.ts +69 -30
  551. package/scripts/review/review-record-main.ts +12 -0
  552. package/scripts/review/review-round-one-blobs.ts +221 -0
  553. package/scripts/review/review-round2-cli.ts +49 -12
  554. package/scripts/review/review-round2.ts +80 -12
  555. package/scripts/review/review-stamps.ts +19 -1
  556. package/scripts/review/review-stop-log.ts +96 -0
  557. package/scripts/review/review-stops-cli.ts +85 -0
  558. package/scripts/review/review-tree.ts +6 -17
  559. package/scripts/review/review-untouched-readers.ts +146 -0
  560. package/scripts/review/test-titles.ts +118 -0
  561. package/scripts/rules/agent-model.ts +67 -0
  562. package/scripts/rules/bash-triggers.ts +46 -3
  563. package/scripts/rules/decision-oracle-batch.ts +9 -1
  564. package/scripts/rules/decision-oracle.ts +2 -2
  565. package/scripts/rules/delivered-rules.ts +90 -3
  566. package/scripts/rules/destructive-command.ts +8 -1
  567. package/scripts/rules/direct-filing.ts +10 -2
  568. package/scripts/rules/direct-issue-comment.ts +117 -0
  569. package/scripts/rules/direct-pr-create.ts +69 -3
  570. package/scripts/rules/early-heartbeat.ts +2 -1
  571. package/scripts/rules/file-body.ts +7 -0
  572. package/scripts/rules/filing-cap.ts +8 -0
  573. package/scripts/rules/firing-point.ts +6 -5
  574. package/scripts/rules/git-argv.ts +72 -14
  575. package/scripts/rules/git-force.ts +12 -2
  576. package/scripts/rules/guard-remedy.ts +121 -0
  577. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  578. package/scripts/rules/implementation-cut.ts +11 -3
  579. package/scripts/rules/index-guard.ts +8 -1
  580. package/scripts/rules/issue-comments.ts +76 -7
  581. package/scripts/rules/josh-git-bare.ts +7 -0
  582. package/scripts/rules/lane-background.ts +67 -25
  583. package/scripts/rules/lane-carry-conflict.ts +6 -0
  584. package/scripts/rules/lane-direct-tool.ts +74 -0
  585. package/scripts/rules/lane-interactive-ask.ts +9 -2
  586. package/scripts/rules/lane-park.ts +45 -23
  587. package/scripts/rules/lane-split-park.ts +10 -2
  588. package/scripts/rules/lane-switch-main.ts +7 -0
  589. package/scripts/rules/last-prompt.ts +50 -5
  590. package/scripts/rules/oracle-consulted.ts +10 -0
  591. package/scripts/rules/oracle-firing.ts +1 -0
  592. package/scripts/rules/oracle-list-cli.ts +7 -0
  593. package/scripts/rules/permission-guards.ts +3 -0
  594. package/scripts/rules/piped-verification.ts +4 -2
  595. package/scripts/rules/poll-loop.ts +7 -0
  596. package/scripts/rules/pr-merge.ts +123 -0
  597. package/scripts/rules/protected-files.ts +32 -5
  598. package/scripts/rules/raw-field-body.ts +6 -0
  599. package/scripts/rules/rule-body-guard.ts +8 -0
  600. package/scripts/rules/rule-list.ts +12 -28
  601. package/scripts/rules/rule-rewrite.ts +114 -0
  602. package/scripts/rules/rule-value-cache.ts +4 -9
  603. package/scripts/rules/rule-value-cli.ts +51 -32
  604. package/scripts/rules/rule-value.ts +8 -2
  605. package/scripts/rules/shell-segments.ts +50 -0
  606. package/scripts/rules/stop-decision.ts +77 -0
  607. package/scripts/rules/stop-rule-rows.ts +64 -0
  608. package/scripts/rules/stop-rules.ts +150 -51
  609. package/scripts/rules/tail-commands.ts +15 -1
  610. package/scripts/rules/test-declared-commit.ts +11 -1
  611. package/scripts/rules/third-party-write.ts +7 -0
  612. package/scripts/rules/timed-rerun.ts +69 -0
  613. package/scripts/rules/worktree-guard.ts +13 -3
  614. package/scripts/run/board/run-board-app-name.ts +23 -0
  615. package/scripts/run/board/run-board-cli.ts +65 -30
  616. package/scripts/run/board/run-board-closed.ts +8 -2
  617. package/scripts/run/board/run-board-earlier.ts +94 -0
  618. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  619. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  620. package/scripts/run/board/run-board-estimate.ts +98 -0
  621. package/scripts/run/board/run-board-fit.ts +153 -36
  622. package/scripts/run/board/run-board-fold.ts +123 -0
  623. package/scripts/run/board/run-board-fresh.ts +2 -2
  624. package/scripts/run/board/run-board-gather-live.ts +29 -0
  625. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  626. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  627. package/scripts/run/board/run-board-gather.ts +187 -0
  628. package/scripts/run/board/run-board-github.ts +119 -31
  629. package/scripts/run/board/run-board-header.ts +86 -21
  630. package/scripts/run/board/run-board-keys.ts +58 -0
  631. package/scripts/run/board/run-board-kind.ts +20 -6
  632. package/scripts/run/board/run-board-labels.ts +118 -71
  633. package/scripts/run/board/run-board-lane-state.ts +109 -0
  634. package/scripts/run/board/run-board-lane-time.ts +122 -0
  635. package/scripts/run/board/run-board-layout.ts +240 -61
  636. package/scripts/run/board/run-board-length.ts +52 -0
  637. package/scripts/run/board/run-board-machine.ts +8 -4
  638. package/scripts/run/board/run-board-main.ts +12 -0
  639. package/scripts/run/board/run-board-notes.ts +52 -31
  640. package/scripts/run/board/run-board-now.ts +1 -1
  641. package/scripts/run/board/run-board-operation.ts +15 -33
  642. package/scripts/run/board/run-board-phase.ts +1 -1
  643. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  644. package/scripts/run/board/run-board-plan.ts +55 -3
  645. package/scripts/run/board/run-board-planning.ts +45 -0
  646. package/scripts/run/board/run-board-priority.ts +44 -0
  647. package/scripts/run/board/run-board-process-groups.ts +195 -0
  648. package/scripts/run/board/run-board-read.ts +153 -13
  649. package/scripts/run/board/run-board-reason.ts +238 -45
  650. package/scripts/run/board/run-board-released.ts +35 -0
  651. package/scripts/run/board/run-board-render-checks.ts +39 -5
  652. package/scripts/run/board/run-board-render-condition.ts +96 -0
  653. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  654. package/scripts/run/board/run-board-render-foot.ts +59 -0
  655. package/scripts/run/board/run-board-render-icon.ts +35 -0
  656. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  657. package/scripts/run/board/run-board-render-lead.ts +80 -0
  658. package/scripts/run/board/run-board-render-legend.ts +117 -47
  659. package/scripts/run/board/run-board-render-notes.ts +156 -29
  660. package/scripts/run/board/run-board-render-processes.ts +196 -0
  661. package/scripts/run/board/run-board-render-section.ts +119 -0
  662. package/scripts/run/board/run-board-render-slot.ts +3 -36
  663. package/scripts/run/board/run-board-render-tail.ts +115 -48
  664. package/scripts/run/board/run-board-render-time.ts +56 -0
  665. package/scripts/run/board/run-board-render-title.ts +117 -24
  666. package/scripts/run/board/run-board-render-waits.ts +125 -0
  667. package/scripts/run/board/run-board-render.ts +206 -259
  668. package/scripts/run/board/run-board-roots.ts +54 -0
  669. package/scripts/run/board/run-board-row-yield.ts +10 -4
  670. package/scripts/run/board/run-board-setup.ts +1 -12
  671. package/scripts/run/board/run-board-snapshot.ts +111 -0
  672. package/scripts/run/board/run-board-spin.ts +2 -2
  673. package/scripts/run/board/run-board-state.ts +23 -29
  674. package/scripts/run/board/run-board-status.ts +206 -79
  675. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  676. package/scripts/run/board/run-board-tick.ts +123 -104
  677. package/scripts/run/board/run-board-usage-board.ts +78 -0
  678. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  679. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  680. package/scripts/run/board/run-board-usage-read.ts +120 -150
  681. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  682. package/scripts/run/board/run-board-usage-text.ts +139 -51
  683. package/scripts/run/board/run-board-usage-top.ts +102 -0
  684. package/scripts/run/board/run-board-usage.ts +89 -72
  685. package/scripts/run/board/run-board-usual.ts +20 -9
  686. package/scripts/run/carry/run-carry-args.ts +4 -7
  687. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  688. package/scripts/run/carry/run-carry.ts +9 -4
  689. package/scripts/run/cut/run-cut-cli.ts +3 -2
  690. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  691. package/scripts/run/cut/run-cut-report.ts +16 -0
  692. package/scripts/run/detached-launch.ts +23 -4
  693. package/scripts/run/entry/run-entry-cli.ts +8 -1
  694. package/scripts/run/event/run-event-cli.ts +1 -5
  695. package/scripts/run/event/run-event-filed.ts +12 -6
  696. package/scripts/run/event/run-event-follow.ts +2 -3
  697. package/scripts/run/event/run-event-render.ts +7 -10
  698. package/scripts/run/event/run-event-scope.ts +20 -2
  699. package/scripts/run/event/run-event-stream-emit.ts +78 -11
  700. package/scripts/run/event/run-event-stream.ts +37 -7
  701. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  702. package/scripts/run/hold/run-hold-cli.ts +93 -22
  703. package/scripts/run/hold/run-hold-main.ts +12 -0
  704. package/scripts/run/hold/run-hold-member.ts +37 -0
  705. package/scripts/run/hold/run-hold-session.ts +46 -0
  706. package/scripts/run/hold/run-hold.ts +7 -1
  707. package/scripts/run/hold/run-stop-notify.ts +183 -0
  708. package/scripts/run/launch-priority.ts +32 -0
  709. package/scripts/run/merge/run-merge-auth.ts +31 -0
  710. package/scripts/run/merge/run-merge-cli.ts +72 -107
  711. package/scripts/run/merge/run-merge-close.ts +74 -0
  712. package/scripts/run/merge/run-merge-collect.ts +6 -13
  713. package/scripts/run/merge/run-merge-driver.ts +71 -0
  714. package/scripts/run/merge/run-merge-main.ts +12 -0
  715. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  716. package/scripts/run/merge/run-merge-restart.ts +39 -0
  717. package/scripts/run/merge/run-merge-ship.ts +20 -4
  718. package/scripts/run/merge/run-merge-signals.ts +123 -0
  719. package/scripts/run/merge/run-merge-steps.ts +128 -83
  720. package/scripts/run/merge/run-merge.ts +53 -40
  721. package/scripts/run/park/run-park-cli.ts +91 -0
  722. package/scripts/run/park/run-park.ts +88 -0
  723. package/scripts/run/park/run-stalled.ts +68 -0
  724. package/scripts/run/pause/run-pause-cli.ts +73 -0
  725. package/scripts/run/pause/run-pause.ts +251 -0
  726. package/scripts/run/progress/run-progress-cli.ts +4 -12
  727. package/scripts/run/progress/run-progress-clock.ts +1 -1
  728. package/scripts/run/progress/run-progress-config.ts +6 -14
  729. package/scripts/run/progress/run-progress-main.ts +12 -0
  730. package/scripts/run/progress/run-progress.ts +1 -4
  731. package/scripts/run/review/run-review.ts +2 -1
  732. package/scripts/run/run-ending.ts +1 -0
  733. package/scripts/run/run-invocation.ts +5 -6
  734. package/scripts/run/run-liveness-cli.ts +6 -8
  735. package/scripts/run/run-liveness.ts +61 -30
  736. package/scripts/run/run-next.ts +1 -1
  737. package/scripts/run/run-parent-cut-hook.ts +2 -2
  738. package/scripts/run/run-poll-hook.ts +157 -0
  739. package/scripts/run/run-preflight.ts +18 -3
  740. package/scripts/run/run-prep-cli.ts +1 -10
  741. package/scripts/run/run-prep-locate.ts +7 -50
  742. package/scripts/run/run-prep-main.ts +12 -0
  743. package/scripts/run/run-prep.ts +6 -0
  744. package/scripts/run/run-report-cli.ts +101 -13
  745. package/scripts/run/run-report-handoff.ts +114 -0
  746. package/scripts/run/run-step-cli.ts +22 -15
  747. package/scripts/run/run-step-section.ts +85 -0
  748. package/scripts/run/run-step.ts +1 -1
  749. package/scripts/run/run-stranded-detect.ts +13 -0
  750. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  751. package/scripts/run/run-watcher-guard.ts +1 -1
  752. package/scripts/run/ship/run-ship-args.ts +121 -0
  753. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  754. package/scripts/run/ship/run-ship-cli.ts +67 -151
  755. package/scripts/run/ship/run-ship-detach.ts +27 -7
  756. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  757. package/scripts/run/ship/run-ship-next.ts +27 -3
  758. package/scripts/run/ship/run-ship-overlap.ts +232 -0
  759. package/scripts/run/ship/run-ship-place.ts +96 -0
  760. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  761. package/scripts/run/ship/run-ship-pre-detach.ts +102 -27
  762. package/scripts/run/ship/run-ship-preflight.ts +161 -30
  763. package/scripts/run/ship/run-ship-probe.ts +11 -3
  764. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  765. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  766. package/scripts/run/ship/run-ship-return.ts +123 -15
  767. package/scripts/run/ship/run-ship-review-steps.ts +105 -149
  768. package/scripts/run/ship/run-ship-review.ts +73 -6
  769. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  770. package/scripts/run/ship/run-ship-stage.ts +55 -6
  771. package/scripts/run/ship/run-ship-steps.ts +46 -15
  772. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  773. package/scripts/run/ship/run-ship-stop-context.ts +206 -0
  774. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  775. package/scripts/run/ship/run-ship-sync.ts +57 -12
  776. package/scripts/run/ship/run-ship.ts +30 -2
  777. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  778. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  779. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  780. package/scripts/run/wake/run-wake-cli.ts +119 -100
  781. package/scripts/run/wake/run-wake-code.ts +83 -0
  782. package/scripts/run/wake/run-wake-driver.ts +19 -8
  783. package/scripts/run/wake/run-wake-loop.ts +34 -3
  784. package/scripts/run/wake/run-wake-main.ts +13 -0
  785. package/scripts/run/wake/run-wake-ports.ts +90 -0
  786. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  787. package/scripts/run/wake/run-wake.ts +2 -1
  788. package/scripts/safe-chain/pack-hook.ts +2 -2
  789. package/scripts/safe-chain/preinstall-command.ts +2 -1
  790. package/scripts/safe-chain/project-config.ts +3 -9
  791. package/scripts/security/security-audit-main.ts +8 -0
  792. package/scripts/security/security-audit-provision-logic.ts +0 -11
  793. package/scripts/security/security-audit-provision-main.ts +12 -0
  794. package/scripts/security/security-audit-provision.ts +11 -26
  795. package/scripts/security/security-audit.ts +6 -7
  796. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  797. package/scripts/split/split-assess-cli.ts +2 -2
  798. package/scripts/split/split-assess.ts +15 -0
  799. package/scripts/split/split-measure.ts +65 -0
  800. package/scripts/sync/claude-settings-merge.ts +8 -15
  801. package/scripts/sync/directory-copy-guard.ts +4 -9
  802. package/scripts/sync/file-content.ts +78 -8
  803. package/scripts/sync/sync-ai-files.ts +3 -5
  804. package/scripts/sync/sync-configs.ts +11 -23
  805. package/scripts/sync/sync-hook-safety.ts +4 -10
  806. package/scripts/sync/sync-main.ts +11 -0
  807. package/scripts/sync/sync.ts +25 -37
  808. package/scripts/test/test-declared-changed.ts +2 -2
  809. package/scripts/test/test-declared.ts +1 -1
  810. package/scripts/test/test-e2e-guard.ts +55 -6
  811. package/scripts/test/test-e2e-stamp.ts +38 -0
  812. package/scripts/test/test-pinned-logic.ts +145 -0
  813. package/scripts/test/test-pinned-main.ts +78 -0
  814. package/scripts/test/test-pinned.ts +100 -0
  815. package/scripts/test/test-read-map.ts +264 -0
  816. package/scripts/test/test-read-recording.ts +91 -0
  817. package/scripts/test/test-read-trace.ts +148 -0
  818. package/scripts/test/test-red-main.ts +12 -0
  819. package/scripts/test/test-red.ts +12 -30
  820. package/scripts/test/test-related-main.ts +18 -0
  821. package/scripts/test/test-related-record.ts +119 -0
  822. package/scripts/test/test-related-scope.ts +229 -43
  823. package/scripts/test/test-related.ts +300 -22
  824. package/scripts/test/test-unit-guard-main.ts +15 -0
  825. package/scripts/test/test-unit-guard.ts +54 -21
  826. package/scripts/test/unit-count-file.ts +37 -0
  827. package/scripts/test/unit-run-marker.ts +162 -0
  828. package/scripts/test/unit-setup-files.ts +51 -0
  829. package/scripts/test/unit-worker-share.ts +71 -137
  830. package/scripts/test/whole-suite-files.ts +63 -0
  831. package/scripts/time-runtime/time-background.ts +20 -2
  832. package/scripts/time-runtime/time-bundles.ts +4 -3
  833. package/scripts/time-runtime/time-density-hook.ts +8 -6
  834. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  835. package/scripts/time-runtime/time-format.ts +5 -28
  836. package/scripts/time-runtime/time-markers.ts +10 -1
  837. package/scripts/time-runtime/time-shell.ts +126 -14
  838. package/scripts/time-runtime/time-spans.ts +1 -0
  839. package/scripts/time-runtime/time-tool-call.ts +7 -0
  840. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  841. package/scripts/uninstall/uninstall.ts +1 -1
  842. package/scripts/version/bump-version-main.ts +12 -0
  843. package/scripts/version/bump-version.ts +25 -25
  844. package/scripts/version/effective-upstream.ts +6 -12
  845. package/scripts/version/latest-corepack.ts +17 -32
  846. package/scripts/version/latest-if-required-cli.ts +93 -0
  847. package/scripts/version/latest-lane-guard-main.ts +8 -0
  848. package/scripts/version/latest-lane-guard.ts +0 -4
  849. package/scripts/version/latest-scope-cli.ts +0 -9
  850. package/scripts/version/latest-scope-main.ts +12 -0
  851. package/scripts/version/latest-update.ts +5 -5
  852. package/scripts/version/npm-registry.ts +44 -6
  853. package/scripts/version/publishable-range-check.ts +5 -16
  854. package/scripts/version/release-age.ts +1 -1
  855. package/scripts/version/release-hold.ts +1 -1
  856. package/scripts/version/release-window.ts +38 -0
  857. package/scripts/version/running-binary.ts +1 -1
  858. package/scripts/version/safe-chain-version-update.ts +3 -8
  859. package/scripts/version/version-targets.ts +6 -28
  860. package/templates/dependabot.yml +29 -0
  861. package/templates/gitignore +10 -3
  862. package/templates/pnpm-workspace.basic.yaml +1 -1
  863. package/templates/sonar-project.properties +3 -2
  864. package/templates/workflows/ci.yml +12 -4
  865. package/templates/workflows/github-release.yml +4 -0
  866. package/tsconfig.sonar.json +1 -1
  867. package/.ncurc.json +0 -3
  868. package/dist/hooks/batch-guard.js +0 -29
  869. package/dist/hooks/chunk-43ZHT22P.js +0 -3495
  870. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  871. package/dist/hooks/chunk-EUMACUK2.js +0 -2038
  872. package/dist/hooks/chunk-H5HVWYXK.js +0 -359
  873. package/dist/hooks/chunk-IIGFYXKC.js +0 -7104
  874. package/dist/hooks/chunk-IX6TTTI6.js +0 -95
  875. package/dist/hooks/chunk-J47HU5H5.js +0 -237
  876. package/dist/hooks/chunk-K4EOONYM.js +0 -45
  877. package/dist/hooks/chunk-K4LMBQC2.js +0 -68
  878. package/dist/hooks/chunk-SHGPANFB.js +0 -56
  879. package/dist/hooks/chunk-YHBZAJSV.js +0 -79
  880. package/dist/hooks/chunk-YYPI7SJZ.js +0 -131
  881. package/dist/hooks/duplicate-read-guard.js +0 -30
  882. package/dist/hooks/investigation-guard.js +0 -32
  883. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  884. package/scripts/cost-runtime/cost-format.ts +0 -29
  885. package/scripts/init/basic-path-migration.ts +0 -24
  886. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  887. package/scripts/josh/josh-commands-guard.ts +0 -38
  888. package/scripts/lint/cross-file-recheck.ts +0 -155
  889. package/scripts/registry-migration/migrate-logic.ts +0 -237
  890. package/scripts/registry-migration/migrate.ts +0 -292
  891. package/scripts/registry-migration/user-npmrc.ts +0 -15
  892. package/scripts/rules/rule-guard.ts +0 -23
  893. package/scripts/rules/rule-registry-rows.ts +0 -282
  894. package/scripts/rules/rule-registry.ts +0 -109
  895. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -0,0 +1,302 @@
1
+ import { readdirSync } from 'node:fs'
2
+ import path from 'node:path'
3
+ import { repository_lock } from '#scripts/git/repository-lock'
4
+ import { session_cite } from '#scripts/issue/session-cite'
5
+ import { stamp_file } from '#scripts/josh/stamp-file'
6
+ import { figure_format } from '#scripts/lib/figure-format'
7
+ import { json_value } from '#scripts/lib/json-value'
8
+ import { run_carry } from '#scripts/run/carry/run-carry'
9
+ import { z } from 'zod'
10
+
11
+ // One record per lane of where it is in its life — opened, running, paused, ended — written only by
12
+ // the lane commands (joshuafolkken/kit#4268), so a reader asks the record rather than guessing from
13
+ // the `.env` mtime, the event stream or the `ps` state.
14
+ //
15
+ // **It is a `stamp_path` keyed on the common git directory**, beside the carry record and the event
16
+ // stream and outside every work tree, so it is the same file from the main checkout and from inside
17
+ // the lane, it outlives `lane:close`'s removal of the lane, and `JOSH_TEMP_ROOT` moves it with every
18
+ // other record the run keeps.
19
+ //
20
+ // **The write is `stamp_file.replace_stamp`'s** — a temporary file beside the target, renamed over it —
21
+ // so two commands writing the same lane at once leave one whole record, never a torn one. **The read,
22
+ // the transition check and that write are one step under a per-record lock**, as the event stream's
23
+ // append is: unlocked, a pause that read `running` could rename its `paused` over a merge's `ended`.
24
+ //
25
+ // **A transition the lifecycle does not have is not written** (an `ended` lane is not paused); it is
26
+ // warned about and the command carries on, as it does when the record cannot be written at all — the
27
+ // record never fails the command that keeps it.
28
+
29
+ const STATE_PREFIX = 'josh-lane-state-'
30
+ const STATE_SUFFIX = '.json'
31
+ const LOCK_SUFFIX = '.lock'
32
+ // A change holds the lock for one read and one rename; a wait this long means a holder is stuck.
33
+ const LOCK_WAIT_MS = 5000
34
+ const LANE_STATES = ['open', 'running', 'paused', 'ended'] as const
35
+ // What a lane with no record is answered with: its state is unknown, so it keeps its place.
36
+ const NO_STATE_HINT = 'no lane state — counted in use'
37
+
38
+ type LaneState = (typeof LANE_STATES)[number]
39
+
40
+ const lane_run_schema = z.object({ started_at: z.string(), owner_pid: z.number().optional() })
41
+
42
+ // A process the last `lane:close` could not end even with a SIGKILL, and why (`lane-reap-settle.ts`).
43
+ const stuck_schema = z.object({ pid: z.number(), reason: z.string() })
44
+
45
+ const lane_state_schema = z.object({
46
+ issue: z.string(),
47
+ run: lane_run_schema.optional(),
48
+ state: z.enum(LANE_STATES),
49
+ launched_at: z.string().optional(),
50
+ changed_at: z.string(),
51
+ changed_by: z.string(),
52
+ stuck: z.array(stuck_schema).optional(),
53
+ })
54
+
55
+ type LaneRun = z.infer<typeof lane_run_schema>
56
+ type LaneStateRecord = z.infer<typeof lane_state_schema>
57
+ type StuckProcess = z.infer<typeof stuck_schema>
58
+ // Each lane's record, by issue; a lane with none is left out (`read_states`).
59
+ type LaneRecords = ReadonlyMap<string, LaneStateRecord>
60
+
61
+ // The states each one moves to. A lane with no record yet (opened before the record existed) moves to
62
+ // any of them.
63
+ const TRANSITIONS: Record<LaneState, ReadonlyArray<LaneState>> = {
64
+ open: ['open', 'running', 'ended'],
65
+ running: ['running', 'paused', 'ended'],
66
+ paused: ['paused', 'running', 'ended'],
67
+ ended: ['ended', 'open'],
68
+ }
69
+
70
+ // One command's change: the state it leaves the lane in, and whether it launched a child — a launch
71
+ // stamps the launch time and the run that launched it, which every other change keeps.
72
+ interface LaneChange {
73
+ issue: string
74
+ state: LaneState
75
+ command: string
76
+ is_launch?: boolean
77
+ }
78
+
79
+ interface StateOptions {
80
+ directory?: string | undefined
81
+ now?: Date
82
+ }
83
+
84
+ type RecordOutcome =
85
+ { kind: 'written'; record: LaneStateRecord } | { kind: 'skipped'; reason: string }
86
+
87
+ function state_path(directory: string, issue: string): string {
88
+ return stamp_file.stamp_path(STATE_PREFIX, directory, `-${issue}${STATE_SUFFIX}`)
89
+ }
90
+
91
+ function is_allowed(from: LaneState | undefined, to: LaneState): boolean {
92
+ return from === undefined || TRANSITIONS[from].includes(to)
93
+ }
94
+
95
+ function read_record(directory: string, issue: string): LaneStateRecord | undefined {
96
+ const raw = stamp_file.read_stamp_text(state_path(directory, issue))
97
+
98
+ return raw === undefined ? undefined : json_value.parse_with(raw, lane_state_schema)
99
+ }
100
+
101
+ function write_record(directory: string, record: LaneStateRecord): void {
102
+ stamp_file.replace_stamp(state_path(directory, record.issue), record)
103
+ }
104
+
105
+ // The run a launch belongs to: the carry's start and owner, read from the same common git directory.
106
+ function current_run(directory: string): LaneRun | undefined {
107
+ const carried = run_carry.read_carry(run_carry.carry_path(directory))
108
+
109
+ if (carried.kind !== 'carried') return undefined
110
+
111
+ return { started_at: carried.carry.started_at, owner_pid: carried.carry.owner_pid }
112
+ }
113
+
114
+ function launch_fields(change: LaneChange, directory: string, now: Date): Partial<LaneStateRecord> {
115
+ if (change.is_launch !== true) return {}
116
+
117
+ return { run: current_run(directory), launched_at: now.toISOString() }
118
+ }
119
+
120
+ function next_record(
121
+ change: LaneChange,
122
+ previous: LaneStateRecord | undefined,
123
+ directory: string,
124
+ now: Date,
125
+ ): LaneStateRecord {
126
+ return {
127
+ // An open starts a fresh life: a reopened lane keeps nothing of the run that launched it before.
128
+ ...(change.state !== 'open' && previous),
129
+ issue: change.issue,
130
+ state: change.state,
131
+ changed_at: now.toISOString(),
132
+ changed_by: change.command,
133
+ ...launch_fields(change, directory, now),
134
+ }
135
+ }
136
+
137
+ function apply_held(change: LaneChange, directory: string, now: Date): RecordOutcome {
138
+ const previous = read_record(directory, change.issue)
139
+
140
+ if (!is_allowed(previous?.state, change.state)) {
141
+ return { kind: 'skipped', reason: `no ${previous?.state ?? ''} → ${change.state} transition` }
142
+ }
143
+
144
+ const record = next_record(change, previous, directory, now)
145
+
146
+ write_record(directory, record)
147
+
148
+ return { kind: 'written', record }
149
+ }
150
+
151
+ const NO_DIRECTORY: RecordOutcome = { kind: 'skipped', reason: 'no git directory' }
152
+
153
+ // The read, the check and the write of one record, under its lock.
154
+ function locked(directory: string, issue: string, held: () => RecordOutcome): RecordOutcome {
155
+ const lock = `${state_path(directory, issue)}${LOCK_SUFFIX}`
156
+ const outcome = repository_lock.with_lock_sync(held, lock, LOCK_WAIT_MS)
157
+
158
+ return outcome ?? { kind: 'skipped', reason: `gave up waiting for the lock at ${lock}` }
159
+ }
160
+
161
+ function apply(change: LaneChange, directory: string, now: Date): RecordOutcome {
162
+ return locked(directory, change.issue, () => apply_held(change, directory, now))
163
+ }
164
+
165
+ function warn(change: LaneChange, reason: string): void {
166
+ console.warn(
167
+ `${change.command} ${session_cite.issue(change.issue)}: lane state not recorded — ${reason}`,
168
+ )
169
+ }
170
+
171
+ async function resolve_directory(directory: string | undefined): Promise<string | undefined> {
172
+ return directory ?? (await run_carry.repository_directory())
173
+ }
174
+
175
+ async function outcome_of(change: LaneChange, options: StateOptions): Promise<RecordOutcome> {
176
+ const directory = await resolve_directory(options.directory)
177
+
178
+ if (directory === undefined) return NO_DIRECTORY
179
+
180
+ return apply(change, directory, options.now ?? new Date())
181
+ }
182
+
183
+ async function settled_outcome(change: LaneChange, options: StateOptions): Promise<RecordOutcome> {
184
+ try {
185
+ return await outcome_of(change, options)
186
+ } catch (error: unknown) {
187
+ return { kind: 'skipped', reason: error instanceof Error ? error.message : String(error) }
188
+ }
189
+ }
190
+
191
+ async function record_change(
192
+ change: LaneChange,
193
+ options: StateOptions = {},
194
+ ): Promise<RecordOutcome> {
195
+ const outcome = await settled_outcome(change, options)
196
+
197
+ if (outcome.kind === 'skipped') warn(change, outcome.reason)
198
+
199
+ return outcome
200
+ }
201
+
202
+ async function read_state(issue: string, directory?: string): Promise<LaneStateRecord | undefined> {
203
+ const root = await resolve_directory(directory)
204
+
205
+ return root === undefined ? undefined : read_record(root, issue)
206
+ }
207
+
208
+ // The issue each record of `directory` is for, read off the file names `state_path` writes.
209
+ function recorded_issues(directory: string): Array<string> {
210
+ const empty = state_path(directory, '')
211
+ const head = path.basename(empty).slice(0, -STATE_SUFFIX.length)
212
+
213
+ return readdirSync(path.dirname(empty))
214
+ .filter((name) => name.startsWith(head) && name.endsWith(STATE_SUFFIX))
215
+ .map((name) => name.slice(head.length, -STATE_SUFFIX.length))
216
+ .filter((issue) => issue.length > 0)
217
+ }
218
+
219
+ /** Every lane's record, a closed lane's included — the record outlives the work tree. */
220
+ async function read_records(directory?: string): Promise<Array<LaneStateRecord>> {
221
+ const root = await resolve_directory(directory)
222
+
223
+ if (root === undefined) return []
224
+
225
+ const records = recorded_issues(root).map((issue) => read_record(root, issue))
226
+
227
+ return records.filter((record) => record !== undefined)
228
+ }
229
+
230
+ function stuck_held(issue: string, stuck: Array<StuckProcess>, directory: string): RecordOutcome {
231
+ const previous = read_record(directory, issue)
232
+
233
+ if (previous === undefined) return { kind: 'skipped', reason: 'no record' }
234
+
235
+ const record = { ...previous, stuck }
236
+
237
+ write_record(directory, record)
238
+
239
+ return { kind: 'written', record }
240
+ }
241
+
242
+ /**
243
+ * Note on the lane's record the processes its close could not end, leaving its state as it is: a lane
244
+ * a close has not finished is not `ended`. A lane with no record is not given one.
245
+ */
246
+ async function record_stuck(
247
+ issue: string,
248
+ stuck: Array<StuckProcess>,
249
+ directory?: string,
250
+ ): Promise<RecordOutcome> {
251
+ const root = await resolve_directory(directory)
252
+
253
+ if (root === undefined) return NO_DIRECTORY
254
+
255
+ return locked(root, issue, () => stuck_held(issue, stuck, root))
256
+ }
257
+
258
+ /** Each of `issues`' records, by issue; an issue with none is left out. */
259
+ async function read_states(
260
+ issues: ReadonlyArray<string>,
261
+ directory?: string,
262
+ ): Promise<LaneRecords> {
263
+ const root = await resolve_directory(directory)
264
+
265
+ if (root === undefined) return new Map()
266
+
267
+ const read = issues.map((issue): [string, LaneStateRecord | undefined] => [
268
+ issue,
269
+ read_record(root, issue),
270
+ ])
271
+
272
+ return new Map(read.filter((entry): entry is [string, LaneStateRecord] => entry[1] !== undefined))
273
+ }
274
+
275
+ /** `paused since 01:28 by lane:pause` — the one wording every reader names a paused lane in. */
276
+ function paused_text(since_ms: number, changed_by: string): string {
277
+ return `paused since ${figure_format.minute_of(since_ms)} by ${changed_by}`
278
+ }
279
+
280
+ /** `paused_text` for a paused record, `undefined` for any other. */
281
+ function paused_note(record: LaneStateRecord | undefined): string | undefined {
282
+ if (record?.state !== 'paused') return undefined
283
+
284
+ return paused_text(Date.parse(record.changed_at), record.changed_by)
285
+ }
286
+
287
+ const lane_state = {
288
+ LANE_STATES,
289
+ NO_STATE_HINT,
290
+ is_allowed,
291
+ paused_note,
292
+ paused_text,
293
+ read_records,
294
+ read_state,
295
+ read_states,
296
+ record_change,
297
+ record_stuck,
298
+ state_path,
299
+ }
300
+
301
+ export { lane_state }
302
+ export type { LaneChange, LaneRecords, LaneState, LaneStateRecord, RecordOutcome, StuckProcess }
@@ -1,5 +1,6 @@
1
1
  import { machine_capacity } from '#scripts/gate/machine-capacity'
2
- import type { GateEntry, LedgerEntry, LoadEntry } from './lane-ledger'
2
+ import { MS_PER_MINUTE } from '#scripts/lib/timeouts'
3
+ import type { DispatchEntry, GateEntry, LedgerEntry, LoadEntry, MergeEntry } from './lane-ledger'
3
4
  import { lane_sampler } from './lane-sampler'
4
5
 
5
6
  // The lane-limit measurement's one table row: the ledger entries of one period
@@ -21,7 +22,6 @@ import { lane_sampler } from './lane-sampler'
21
22
  // **Swap is a rate, not a level.** A sample carries `machine_capacity`'s counter — every page swapped
22
23
  // since boot — so the swap columns are what was swapped between consecutive samples, per hour.
23
24
 
24
- const MS_PER_MINUTE = 60_000
25
25
  const MS_PER_HOUR = 3_600_000
26
26
  // A busy lane pool finishes a gate well within this; a longer silence is time nobody was running work.
27
27
  const ACTIVE_GAP_MS = MS_PER_HOUR
@@ -40,6 +40,7 @@ const COLUMNS = [
40
40
  'merges',
41
41
  'merges / hour',
42
42
  'effective lanes',
43
+ 'lane median (min)',
43
44
  'gate median (min)',
44
45
  'gate max (min)',
45
46
  'load peak',
@@ -65,7 +66,10 @@ function window_of(period_days: number, now_ms: number): StatsWindow {
65
66
  return { since_ms: now_ms - period_days * MS_PER_DAY, until_ms: now_ms }
66
67
  }
67
68
 
68
- function in_window(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow): Array<LedgerEntry> {
69
+ function in_window<T extends { at: string }>(
70
+ entries: ReadonlyArray<T>,
71
+ window: StatsWindow,
72
+ ): Array<T> {
69
73
  return entries.filter((entry) => {
70
74
  const at = Date.parse(entry.at)
71
75
 
@@ -77,6 +81,14 @@ function is_gate(entry: LedgerEntry): entry is GateEntry {
77
81
  return entry.kind === 'gate'
78
82
  }
79
83
 
84
+ function is_merge(entry: LedgerEntry): entry is MergeEntry {
85
+ return entry.kind === 'merge'
86
+ }
87
+
88
+ function is_dispatch(entry: LedgerEntry): entry is DispatchEntry {
89
+ return entry.kind === 'dispatch'
90
+ }
91
+
80
92
  function is_load(entry: LedgerEntry): entry is LoadEntry {
81
93
  return entry.kind === 'load'
82
94
  }
@@ -200,8 +212,49 @@ function throughput_cells(entries: ReadonlyArray<LedgerEntry>): Array<string> {
200
212
  return [String(merges), cell(per_hour), cell(mean(lanes))]
201
213
  }
202
214
 
215
+ function dispatched_before(
216
+ dispatches: ReadonlyArray<DispatchEntry>,
217
+ merge: MergeEntry,
218
+ ): number | undefined {
219
+ const merged_at = Date.parse(merge.at)
220
+ const starts = dispatches
221
+ .filter((dispatch) => dispatch.issue === merge.issue)
222
+ .map((dispatch) => Date.parse(dispatch.at))
223
+ .filter((at) => at <= merged_at)
224
+
225
+ return peak(starts)
226
+ }
227
+
228
+ function lane_minutes(
229
+ dispatches: ReadonlyArray<DispatchEntry>,
230
+ merge: MergeEntry,
231
+ ): number | undefined {
232
+ const start = dispatched_before(dispatches, merge)
233
+
234
+ return start === undefined ? undefined : (Date.parse(merge.at) - start) / MS_PER_MINUTE
235
+ }
236
+
237
+ // One merge's lane time runs from the latest dispatch of its issue — looked up in the whole ledger,
238
+ // since a lane may start before the window — to the merge. A merge no dispatch preceded is skipped.
239
+ function lane_cell(
240
+ entries: ReadonlyArray<LedgerEntry>,
241
+ period: ReadonlyArray<LedgerEntry>,
242
+ ): string {
243
+ const dispatches = entries.filter(is_dispatch)
244
+ const minutes = period
245
+ .filter((entry) => is_merge(entry))
246
+ .map((merge) => lane_minutes(dispatches, merge))
247
+ .filter(is_number)
248
+
249
+ return cell(median(minutes))
250
+ }
251
+
252
+ // A reused gate ran no check, so its few milliseconds would pull the median toward a gate that never ran.
203
253
  function gate_cells(entries: ReadonlyArray<LedgerEntry>): Array<string> {
204
- const minutes = entries.filter(is_gate).map((entry) => entry.elapsed_ms / MS_PER_MINUTE)
254
+ const minutes = entries
255
+ .filter(is_gate)
256
+ .filter((entry) => entry.is_reused !== true)
257
+ .map((entry) => entry.elapsed_ms / MS_PER_MINUTE)
205
258
 
206
259
  return [cell(median(minutes)), cell(peak(minutes))]
207
260
  }
@@ -248,6 +301,7 @@ function row(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow, label: Ro
248
301
  label.limit,
249
302
  String(label.period_days),
250
303
  ...throughput_cells(period),
304
+ lane_cell(entries, period),
251
305
  ...gate_cells(period),
252
306
  ...load_cells(period.filter(is_load)),
253
307
  ])
@@ -1,20 +1,29 @@
1
+ import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
1
2
  import { run_ship_stage } from '#scripts/run/ship/run-ship-stage'
2
3
  import { lane_ledger, type LedgerEntry, type StopEntry } from './lane-ledger'
4
+ import type { IssueAt } from './lane-spans'
3
5
  import { lane_stage_stats } from './lane-stage-stats'
4
6
  import { lane_stats, type StatsWindow } from './lane-stats'
5
7
 
6
8
  // How long a lane stood stopped: the ledger's `stop` entries of one period reduced to one row per stop
7
- // reason — median, maximum, how many stops were resumed and how many never were — printed by
8
- // `josh lane:stats` under the per-stage table, so the stop reason worth removing next is a number.
9
+ // reason — the wait's median, maximum and total, how many waits ended and how many never did — printed
10
+ // by `josh lane:stats` under the per-stage table, so the stop reason worth removing next is a number.
9
11
  //
10
- // **The wait is derived, not recorded**: from a stop to the start of the same issue's next ship stage,
11
- // the way `implement` is. A stop that no ship stage followed — the lane parked, or left stopped — is
12
- // counted under `not resumed` and kept out of the median and the maximum, whose time has no end.
13
- //
14
- // **A re-dispatch of the issue ends the search**: the new child's ship is a fresh lane's work, not the
15
- // resumption of a stop that may be days old.
12
+ // **The wait is derived, not recorded**: from a stop to whichever comes first of the same issue's next
13
+ // ship stage (the lane resumed), its re-dispatch (a fresh lane took it over) and its park on the run's
14
+ // event stream (the run gave up on it) — the time the stop held the issue (joshuafolkken/kit#3997). A
15
+ // stop none of the three followed is counted under `not resumed` and kept out of the median, the
16
+ // maximum and the total, whose time has no end.
16
17
 
17
- const COLUMNS = ['stop', 'median (min)', 'max (min)', 'runs', 'not resumed'] as const
18
+ const COLUMNS = [
19
+ 'stop',
20
+ 'wait median (min)',
21
+ 'wait max (min)',
22
+ 'wait total (min)',
23
+ 'runs',
24
+ 'not resumed',
25
+ 'causes',
26
+ ] as const
18
27
  const { STAGE } = run_ship_stage
19
28
  const { is_dispatch, is_number, is_stage } = lane_stage_stats
20
29
  const REASONS = [
@@ -28,9 +37,19 @@ const REASONS = [
28
37
  STAGE.FOLLOWUP,
29
38
  STAGE.REPORT,
30
39
  ] as const
40
+ // `#<N> parked`, `#<N> parked (<reason>)`, `#<N> waiting on #<M>`, `#<N> cut (<phase>)` and
41
+ // `#<N> resumed` name their issue first.
42
+ const EVENT_ISSUE = /#([1-9]\d*)\b/u
43
+
44
+ // A stop recorded before it carried a cause (joshuafolkken/kit#3998) is counted under this one.
45
+ const UNRECORDED_CAUSE = 'unrecorded'
46
+ const NO_CAUSES = '-'
31
47
 
48
+ // `causes` is a preflight stop's unmet preconditions or a review stop's blocking finding kinds, every
49
+ // one of them, else the stop's one cause.
32
50
  interface StopWait {
33
51
  reason: string
52
+ causes: ReadonlyArray<string>
34
53
  wait_ms: number | undefined
35
54
  }
36
55
 
@@ -38,51 +57,108 @@ function is_stop(entry: LedgerEntry): entry is StopEntry {
38
57
  return entry.kind === lane_ledger.KIND.STOP
39
58
  }
40
59
 
41
- function redispatch_ms(stop: StopEntry, entries: ReadonlyArray<LedgerEntry>): number {
42
- const from_ms = Date.parse(stop.at)
43
- const later = entries
60
+ // Every run event of `kind`, with the issue its text names first.
61
+ function events_of(events: ReadonlyArray<RunEvent>, kind: string): Array<IssueAt> {
62
+ return events
63
+ .filter((event) => event.kind === kind)
64
+ .map((event) => ({
65
+ issue: Number(EVENT_ISSUE.exec(event.text)?.[1]),
66
+ at_ms: Date.parse(event.at),
67
+ }))
68
+ }
69
+
70
+ function parks_of(events: ReadonlyArray<RunEvent>): Array<IssueAt> {
71
+ return events_of(events, run_event_stream.EVENT_KIND.PARK)
72
+ }
73
+
74
+ function ends_of(
75
+ entries: ReadonlyArray<LedgerEntry>,
76
+ parks: ReadonlyArray<IssueAt>,
77
+ ): Array<IssueAt> {
78
+ const resumes = entries
79
+ .filter((entry) => is_stage(entry))
80
+ .map((stage) => ({ issue: stage.issue, at_ms: lane_stage_stats.started_ms(stage) }))
81
+ const dispatches = entries
44
82
  .filter((entry) => is_dispatch(entry))
45
- .filter((entry) => entry.issue === stop.issue)
46
- .map((entry) => Date.parse(entry.at))
47
- .filter((at) => at > from_ms)
83
+ .map((entry) => ({ issue: entry.issue, at_ms: Date.parse(entry.at) }))
48
84
 
49
- return later.length === 0 ? Infinity : Math.min(...later)
85
+ return [...resumes, ...dispatches, ...parks]
50
86
  }
51
87
 
52
- function wait_ms(stop: StopEntry, entries: ReadonlyArray<LedgerEntry>): number | undefined {
88
+ // A stage's start counts from the stop's own instant, so a ship relaunched within the same
89
+ // millisecond still ends the wait; the stage that stopped started before it.
90
+ function wait_ms(stop: StopEntry, ends: ReadonlyArray<IssueAt>): number | undefined {
53
91
  const from_ms = Date.parse(stop.at)
54
- const until_ms = redispatch_ms(stop, entries)
55
- const starts = entries
56
- .filter((entry) => is_stage(entry))
57
- .filter((stage) => stage.issue === stop.issue)
58
- .map((stage) => lane_stage_stats.started_ms(stage))
59
- .filter((start) => start >= from_ms && start < until_ms)
92
+ const later = ends
93
+ .filter((end) => end.issue === stop.issue && end.at_ms >= from_ms)
94
+ .map((end) => end.at_ms - from_ms)
60
95
 
61
- return starts.length === 0 ? undefined : Math.min(...starts) - from_ms
96
+ return later.length === 0 ? undefined : Math.min(...later)
62
97
  }
63
98
 
64
- function waits_of(entries: ReadonlyArray<LedgerEntry>): Array<StopWait> {
65
- return entries
66
- .filter(is_stop)
67
- .map((stop) => ({ reason: stop.reason, wait_ms: wait_ms(stop, entries) }))
99
+ // A stop recorded before it named its preconditions (joshuafolkken/kit#4166) or its finding kinds
100
+ // (joshuafolkken/kit#4426) counts under its cause.
101
+ function causes_of(stop: StopEntry): ReadonlyArray<string> {
102
+ const { preconditions = [], findings = [] } = stop
103
+ const kinds = [...preconditions, ...findings]
104
+
105
+ return kinds.length > 0 ? kinds : [stop.cause ?? UNRECORDED_CAUSE]
106
+ }
107
+
108
+ function waits_of(
109
+ entries: ReadonlyArray<LedgerEntry>,
110
+ ends: ReadonlyArray<IssueAt>,
111
+ ): Array<StopWait> {
112
+ return entries.filter(is_stop).map((stop) => ({
113
+ reason: stop.reason,
114
+ causes: causes_of(stop),
115
+ wait_ms: wait_ms(stop, ends),
116
+ }))
117
+ }
118
+
119
+ function total(values: ReadonlyArray<number>): number | undefined {
120
+ return values.length === 0 ? undefined : values.reduce((sum, value) => sum + value, 0)
121
+ }
122
+
123
+ // `infra 2, check 1` — how many of one reason's stops each cause took, the most frequent first. A stop
124
+ // with two unmet preconditions counts once under each.
125
+ function causes_cell(waits: ReadonlyArray<StopWait>): string {
126
+ const all = waits.flatMap((wait) => wait.causes)
127
+ const counted = [...new Set(all)].map((cause) => ({
128
+ cause,
129
+ count: all.filter((each) => each === cause).length,
130
+ }))
131
+ const ranked = counted.toSorted((left, right) => right.count - left.count)
132
+
133
+ return ranked.length === 0
134
+ ? NO_CAUSES
135
+ : ranked.map(({ cause, count }) => `${cause} ${String(count)}`).join(', ')
68
136
  }
69
137
 
70
138
  function reason_row(reason: string, waits: ReadonlyArray<StopWait>): string {
71
139
  const of_reason = waits.filter((wait) => wait.reason === reason)
72
- const resumed = of_reason.map((wait) => wait.wait_ms).filter((value) => is_number(value))
140
+ const ended = of_reason.map((wait) => wait.wait_ms).filter((value) => is_number(value))
73
141
 
74
142
  return lane_stats.to_row([
75
143
  reason,
76
- lane_stage_stats.cell(lane_stats.median(resumed)),
77
- lane_stage_stats.cell(lane_stats.peak(resumed)),
78
- String(resumed.length),
79
- String(of_reason.length - resumed.length),
144
+ lane_stage_stats.cell(lane_stats.median(ended)),
145
+ lane_stage_stats.cell(lane_stats.peak(ended)),
146
+ lane_stage_stats.cell(total(ended)),
147
+ String(ended.length),
148
+ String(of_reason.length - ended.length),
149
+ causes_cell(of_reason),
80
150
  ])
81
151
  }
82
152
 
83
- // The period's table: `entries` is the whole ledger, filtered here to `window`.
84
- function table(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow): string {
85
- const waits = waits_of(lane_stats.in_window(entries, window))
153
+ // The period's table: `entries` is the whole ledger, filtered here to `window` — only the stops are; a
154
+ // wait may end after the period's last stop. `events` is the run's event stream, read for its parks.
155
+ function table(
156
+ entries: ReadonlyArray<LedgerEntry>,
157
+ window: StatsWindow,
158
+ events: ReadonlyArray<RunEvent> = [],
159
+ ): string {
160
+ const ends = ends_of(entries, parks_of(events))
161
+ const waits = waits_of(lane_stats.in_window(entries, window), ends)
86
162
 
87
163
  return [
88
164
  lane_stats.to_row(COLUMNS),
@@ -91,6 +167,6 @@ function table(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow): string
91
167
  ].join('\n')
92
168
  }
93
169
 
94
- const lane_stop_stats = { REASONS, table }
170
+ const lane_stop_stats = { REASONS, events_of, table }
95
171
 
96
172
  export { lane_stop_stats }