@joshuafolkken/kit 1.1514.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 (858) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +5 -5
  3. package/.claude/skills/epic-commands/SKILL.md +26 -65
  4. package/.claude/skills/epic-commands/epic-bundle.md +3 -1
  5. package/.claude/skills/workflow-commands/SKILL.md +5 -5
  6. package/.claude/skills/workflow-commands/background-commands.md +5 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
  8. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  9. package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
  10. package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
  11. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
  12. package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
  13. package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
  14. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  15. package/.claude/skills/workflow-commands/chain-rule.md +13 -7
  16. package/.claude/skills/workflow-commands/delegation.md +6 -5
  17. package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
  18. package/.claude/skills/workflow-commands/followup.md +9 -31
  19. package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
  20. package/.claude/skills/workflow-commands/fullrun.md +2 -2
  21. package/.claude/skills/workflow-commands/halfrun.md +17 -25
  22. package/.claude/skills/workflow-commands/issue-comments.md +16 -12
  23. package/.claude/skills/workflow-commands/issue-scout.md +2 -2
  24. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  25. package/.claude/skills/workflow-commands/latest-gate.md +7 -12
  26. package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
  27. package/.claude/skills/workflow-commands/observation-filing.md +4 -36
  28. package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
  29. package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
  30. package/.claude/skills/workflow-commands/prerequisite.md +10 -16
  31. package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
  32. package/.claude/skills/workflow-commands/prrun.md +3 -7
  33. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  34. package/.claude/skills/workflow-commands/split-assessment.md +13 -1
  35. package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
  36. package/.codex/hooks.json +5 -5
  37. package/.github/actions/setup-node/action.yml +9 -0
  38. package/.github/actions/setup-pnpm/action.yml +1 -1
  39. package/.github/dependabot.yml +16 -0
  40. package/.github/release.yml +0 -2
  41. package/.github/workflows/ci.yml +120 -10
  42. package/.github/workflows/publish.yml +8 -1
  43. package/.github/workflows/sonar-qube.yml +1 -0
  44. package/.prettierignore +2 -0
  45. package/.vscode/tasks.json +1 -2
  46. package/CLAUDE.md +3 -7
  47. package/README.md +4 -2
  48. package/SECURITY.md +1 -1
  49. package/dist/CLAUDE.md +3 -7
  50. package/dist/commands/document-read-cli.js +882 -0
  51. package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
  52. package/dist/commands/read-set-cli.js +1867 -0
  53. package/dist/commands/run-prep-main.js +21653 -0
  54. package/dist/commands/run-step-cli.js +23880 -0
  55. package/dist/config-merge/index.js +5 -1
  56. package/dist/hooks/audit-provision.js +20 -35
  57. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  58. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  59. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  60. package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
  61. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  62. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  63. package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
  64. package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
  65. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  66. package/dist/hooks/codex-hook-adapter.js +10 -22
  67. package/dist/hooks/format-edited.js +5 -6
  68. package/dist/hooks/inputs.json +443 -317
  69. package/dist/hooks/pretool-guard.js +7 -25
  70. package/dist/hooks/session-lang.js +44 -51
  71. package/dist/hooks/stop-guard.js +7716 -2187
  72. package/dist/josh.js +6002 -3583
  73. package/dist/self-sync-guard/index.js +74 -10
  74. package/dist/version/index.js +115 -406
  75. package/eslint/base.js +1 -1
  76. package/lefthook/base.yml +3 -1
  77. package/package.json +10 -48
  78. package/pnpm-workspace.yaml +4 -2
  79. package/prompts/coding-standards.md +1 -1
  80. package/prompts/collaboration-workflow/file-edits.md +1 -7
  81. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  82. package/prompts/collaboration-workflow/issue-template.md +33 -16
  83. package/prompts/collaboration-workflow/lane-instructions.md +1 -2
  84. package/prompts/collaboration-workflow/measurement.md +37 -0
  85. package/prompts/collaboration-workflow/operating-rules.md +4 -6
  86. package/prompts/collaboration-workflow/output-bounds.md +2 -7
  87. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  88. package/prompts/collaboration-workflow/principles.md +5 -0
  89. package/prompts/collaboration-workflow/report-format.md +31 -60
  90. package/prompts/collaboration-workflow/residency.md +2 -2
  91. package/prompts/collaboration-workflow/shell-body.md +6 -16
  92. package/prompts/collaboration-workflow/turn-batching.md +0 -2
  93. package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
  94. package/prompts/collaboration-workflow/wip-cap.md +1 -1
  95. package/prompts/collaboration-workflow.md +3 -7
  96. package/prompts/refactoring.md +1 -1
  97. package/prompts/review-rubric.md +1 -2
  98. package/prompts/review.md +41 -21
  99. package/prompts/testing-guide.md +8 -43
  100. package/scripts/agent/agent-event.ts +15 -15
  101. package/scripts/agent/agent-exit-record.ts +13 -1
  102. package/scripts/agent/api-auth.ts +41 -0
  103. package/scripts/agent/api-outage.ts +1 -1
  104. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  105. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  106. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  107. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  108. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  109. package/scripts/backlog/backlog-arrival.ts +14 -3
  110. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  111. package/scripts/backlog/backlog-budget-main.ts +16 -0
  112. package/scripts/backlog/backlog-budget.ts +2 -3
  113. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  114. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  115. package/scripts/backlog/backlog-drive-args.ts +4 -5
  116. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  117. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  118. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  119. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  120. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  121. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  122. package/scripts/backlog/backlog-drive-named.ts +53 -6
  123. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  124. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  125. package/scripts/backlog/backlog-drive-restore.ts +30 -7
  126. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  127. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  128. package/scripts/backlog/backlog-drive.ts +79 -75
  129. package/scripts/backlog/backlog-next-main.ts +16 -0
  130. package/scripts/backlog/backlog-next-shared.ts +73 -0
  131. package/scripts/backlog/backlog-next.ts +48 -16
  132. package/scripts/backlog/backlog-occupied.ts +52 -39
  133. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  134. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  135. package/scripts/backlog/backlog-offer-main.ts +12 -0
  136. package/scripts/backlog/backlog-offer.ts +36 -3
  137. package/scripts/backlog/backlog-overlap.ts +22 -4
  138. package/scripts/backlog/backlog-plan-read.ts +6 -2
  139. package/scripts/backlog/backlog-plan.ts +18 -4
  140. package/scripts/backlog/backlog-pool.ts +10 -10
  141. package/scripts/backlog/backlog-rank.ts +10 -2
  142. package/scripts/backlog/backlog-ready.ts +112 -30
  143. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  144. package/scripts/backlog/backlog-stalled.ts +52 -16
  145. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  146. package/scripts/backlog/backlog-waves.ts +39 -13
  147. package/scripts/backlog/backlogrun-args.ts +19 -7
  148. package/scripts/backlog/backlogrun-cli.ts +19 -5
  149. package/scripts/backlog/backlogrun-launch.ts +6 -0
  150. package/scripts/backlog/backlogrun-restart.ts +97 -0
  151. package/scripts/backlog/backlogrun-stop.ts +79 -7
  152. package/scripts/behavior/behavior-cli.ts +2 -2
  153. package/scripts/behavior/behavior-rules.ts +47 -24
  154. package/scripts/build/build-bin.ts +2 -16
  155. package/scripts/build/build-claude-md.ts +0 -7
  156. package/scripts/build/build-commands.ts +0 -13
  157. package/scripts/build/build-hooks.ts +49 -48
  158. package/scripts/build/hook-bundle-stamp.ts +29 -11
  159. package/scripts/build/local-bin.ts +1 -1
  160. package/scripts/cases/cases-cli.ts +25 -13
  161. package/scripts/cases/cases-interaction-scan.ts +134 -0
  162. package/scripts/cases/cases-interaction.ts +183 -0
  163. package/scripts/cases/cases-logic.ts +39 -6
  164. package/scripts/ci/pr-classification-main.ts +18 -0
  165. package/scripts/ci/pr-classification.ts +10 -17
  166. package/scripts/clone/clone-scan.ts +1 -1
  167. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  168. package/scripts/cost-runtime/cost-cli.ts +31 -14
  169. package/scripts/cost-runtime/cost-main.ts +12 -0
  170. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  171. package/scripts/delegation/delegation-policy.ts +17 -4
  172. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  173. package/scripts/delegation/investigation-guard.ts +0 -8
  174. package/scripts/delegation/investigation-reads.ts +3 -4
  175. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  176. package/scripts/discovery/repo-discovery.ts +24 -6
  177. package/scripts/doctor/doctor-consumer.ts +2 -5
  178. package/scripts/document/document-byte-budget.ts +8 -6
  179. package/scripts/document/document-scan.ts +1 -1
  180. package/scripts/document/document-section-cli.ts +0 -8
  181. package/scripts/document/document-section-main.ts +12 -0
  182. package/scripts/epic/epic-audit-cli.ts +12 -6
  183. package/scripts/epic/epic-bundle-apply.ts +137 -0
  184. package/scripts/epic/epic-bundle-cli.ts +32 -121
  185. package/scripts/epic/epic-bundle-format.ts +116 -0
  186. package/scripts/epic/epic-bundle-main.ts +17 -0
  187. package/scripts/epic/epic-busy.ts +5 -12
  188. package/scripts/epic/epic-classify.ts +24 -15
  189. package/scripts/epic/epic-cli-argv.ts +31 -0
  190. package/scripts/epic/epic-cli-decide.ts +42 -0
  191. package/scripts/epic/epic-cli.ts +6 -38
  192. package/scripts/epic/epic-close.ts +112 -55
  193. package/scripts/epic/epic-cross-repo.ts +4 -7
  194. package/scripts/epic/epic-decide.ts +119 -0
  195. package/scripts/epic/epic-decision.ts +9 -0
  196. package/scripts/epic/epic-fetch.ts +4 -0
  197. package/scripts/epic/epic-graph.ts +2 -0
  198. package/scripts/epic/epic-issue.ts +5 -1
  199. package/scripts/epic/epic-label-age.ts +1 -1
  200. package/scripts/epic/epic-lane-offer.ts +39 -4
  201. package/scripts/epic/epic-next-main.ts +24 -0
  202. package/scripts/epic/epic-next.ts +6 -24
  203. package/scripts/epic/epic-outside-blocker.ts +6 -2
  204. package/scripts/epic/epic-parse.ts +9 -3
  205. package/scripts/epic/epic-read.ts +1 -0
  206. package/scripts/epic/epic-reconcile.ts +39 -0
  207. package/scripts/epic/epic-run.ts +10 -1
  208. package/scripts/epic/epic-solo.ts +50 -14
  209. package/scripts/epic/epic.ts +41 -7
  210. package/scripts/exports/unused-members-cli.ts +2 -2
  211. package/scripts/followup/followup-checks-event.ts +8 -3
  212. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  213. package/scripts/followup/followup-review-gates.ts +81 -0
  214. package/scripts/followup/git-followup-stages.ts +13 -3
  215. package/scripts/followup/git-followup-workflow.ts +19 -66
  216. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  217. package/scripts/followup/git-pr-followup.ts +36 -8
  218. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  219. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  220. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  221. package/scripts/gate/busy-average.ts +58 -0
  222. package/scripts/gate/check-cpu.ts +60 -0
  223. package/scripts/gate/check-inputs.ts +39 -95
  224. package/scripts/gate/check-reuse.ts +33 -54
  225. package/scripts/gate/command-memory.ts +192 -0
  226. package/scripts/gate/core-admission.ts +218 -28
  227. package/scripts/gate/core-budget-timing.ts +37 -0
  228. package/scripts/gate/core-budget.ts +80 -98
  229. package/scripts/gate/core-wait-record.ts +48 -0
  230. package/scripts/gate/core-wait.ts +37 -5
  231. package/scripts/gate/core-weights.ts +86 -0
  232. package/scripts/gate/free-cores.ts +27 -4
  233. package/scripts/gate/gate-ledger.ts +32 -4
  234. package/scripts/gate/gate-plan.ts +41 -34
  235. package/scripts/gate/gate-report.ts +14 -2
  236. package/scripts/gate/gate-run-steps.ts +53 -8
  237. package/scripts/gate/gate-skip.ts +12 -2
  238. package/scripts/gate/gate-steps.ts +12 -1
  239. package/scripts/gate/input-fingerprint.ts +42 -0
  240. package/scripts/gate/machine-capacity.ts +65 -31
  241. package/scripts/gate/moved-paths.ts +67 -0
  242. package/scripts/gate/project-checks.ts +5 -12
  243. package/scripts/gate/scoped-green.ts +12 -8
  244. package/scripts/gate/since-green.ts +62 -0
  245. package/scripts/gate/toolchain-inputs.ts +115 -0
  246. package/scripts/gate/verification-gate.ts +27 -24
  247. package/scripts/gate/verification-inputs.ts +250 -0
  248. package/scripts/gh/gh-author-association.ts +96 -9
  249. package/scripts/gh/git-ai-review-scan.ts +4 -2
  250. package/scripts/gh/git-gh-api-path.ts +15 -0
  251. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  252. package/scripts/gh/git-gh-conditional.ts +5 -2
  253. package/scripts/gh/git-gh-issue-read.ts +5 -1
  254. package/scripts/gh/git-gh-issue-write.ts +67 -29
  255. package/scripts/gh/git-gh-issue.ts +7 -3
  256. package/scripts/gh/git-gh-poll-read.ts +89 -0
  257. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  258. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  259. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  260. package/scripts/gh/git-gh-pr.ts +27 -15
  261. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  262. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  263. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  264. package/scripts/git/base-tree.ts +19 -2
  265. package/scripts/git/changed-file-scope.ts +6 -4
  266. package/scripts/git/changed-paths.ts +18 -1
  267. package/scripts/git/git-diff-reads.ts +27 -2
  268. package/scripts/git/git-grep-hits.ts +85 -0
  269. package/scripts/git/git-location-environment.ts +1 -1
  270. package/scripts/git/git-merge-conflicts.ts +83 -0
  271. package/scripts/git/git-preflight.ts +37 -12
  272. package/scripts/git/git-push-transport.ts +1 -2
  273. package/scripts/git/git-schemas.ts +17 -7
  274. package/scripts/git/git-spawn.ts +1 -2
  275. package/scripts/git/git-status.ts +4 -4
  276. package/scripts/git/main-merge-main.ts +12 -0
  277. package/scripts/git/main-merge-regenerate.ts +2 -2
  278. package/scripts/git/main-merge.ts +25 -9
  279. package/scripts/git/main-sync-main.ts +12 -0
  280. package/scripts/git/main-sync.ts +0 -9
  281. package/scripts/git/stash/git-stash.ts +27 -4
  282. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  283. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  284. package/scripts/git/stash/stash-pop-main.ts +12 -0
  285. package/scripts/git/stash/stash-push-cli.ts +76 -0
  286. package/scripts/git/stash/stash-push-main.ts +12 -0
  287. package/scripts/hooks/batch-guard.ts +0 -8
  288. package/scripts/hooks/check-commit-message-main.ts +8 -0
  289. package/scripts/hooks/check-commit-message.ts +4 -7
  290. package/scripts/hooks/format-edited-file.ts +8 -24
  291. package/scripts/hooks/pre-commit-lint.ts +30 -3
  292. package/scripts/hooks/pre-push-unit.ts +4 -2
  293. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  294. package/scripts/hooks/pretool-guard.ts +32 -19
  295. package/scripts/hooks/reserved-run.ts +67 -9
  296. package/scripts/hooks/run-hook.sh +13 -4
  297. package/scripts/hooks/shell-rules-notice.ts +37 -0
  298. package/scripts/hooks/stop-actions.ts +2 -21
  299. package/scripts/hooks/stop-guard.ts +13 -9
  300. package/scripts/init/hook-command-rewrite.ts +19 -5
  301. package/scripts/init/hook-launch.ts +15 -17
  302. package/scripts/init/init-actions.ts +0 -6
  303. package/scripts/init/init-ai-copy.ts +10 -36
  304. package/scripts/init/init-bootstrap.ts +9 -8
  305. package/scripts/init/init-dry-run-report.ts +1 -1
  306. package/scripts/init/init-dry-run.ts +1 -1
  307. package/scripts/init/init-file-action.ts +7 -9
  308. package/scripts/init/init-logic-json-merge.ts +2 -2
  309. package/scripts/init/init-logic-migrate.ts +9 -82
  310. package/scripts/init/init-logic.ts +3 -2
  311. package/scripts/init/init-main.ts +12 -0
  312. package/scripts/init/init.ts +5 -12
  313. package/scripts/init/kit-development-versions.ts +3 -7
  314. package/scripts/init/kit-written-paths.ts +2 -2
  315. package/scripts/init/project-profile.ts +5 -4
  316. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  317. package/scripts/init/vscode-tasks.ts +1 -1
  318. package/scripts/issue/defect-origin-cli.ts +106 -0
  319. package/scripts/issue/defect-origin-line.ts +60 -0
  320. package/scripts/issue/defect-origin-main.ts +11 -0
  321. package/scripts/issue/defect-origin.ts +114 -0
  322. package/scripts/issue/defect-rate-cli.ts +34 -78
  323. package/scripts/issue/defect-rate.ts +0 -16
  324. package/scripts/issue/defect-report-cli.ts +128 -0
  325. package/scripts/issue/defect-report-format.ts +56 -0
  326. package/scripts/issue/defect-report-main.ts +11 -0
  327. package/scripts/issue/defect-report.ts +160 -0
  328. package/scripts/issue/expected-effect-lint.ts +1 -0
  329. package/scripts/issue/issue-already-done-cli.ts +62 -0
  330. package/scripts/issue/issue-body-or-comment.ts +40 -0
  331. package/scripts/issue/issue-cite-cli.ts +0 -9
  332. package/scripts/issue/issue-cite-main.ts +12 -0
  333. package/scripts/issue/issue-classification.ts +12 -7
  334. package/scripts/issue/issue-comment-cli.ts +10 -24
  335. package/scripts/issue/issue-comment-main.ts +12 -0
  336. package/scripts/issue/issue-evidence-exit.ts +100 -0
  337. package/scripts/issue/issue-file-cli.ts +29 -7
  338. package/scripts/issue/issue-file.ts +19 -19
  339. package/scripts/issue/issue-fold-cli.ts +2 -11
  340. package/scripts/issue/issue-fold-main.ts +12 -0
  341. package/scripts/issue/issue-labels.ts +81 -90
  342. package/scripts/issue/issue-lint-cli.ts +2 -10
  343. package/scripts/issue/issue-lint-main.ts +12 -0
  344. package/scripts/issue/issue-measured-cli.ts +56 -0
  345. package/scripts/issue/issue-merged.ts +19 -2
  346. package/scripts/issue/issue-not-before-label.ts +135 -0
  347. package/scripts/issue/issue-not-before.ts +111 -0
  348. package/scripts/issue/issue-number-shape.ts +15 -1
  349. package/scripts/issue/issue-park.ts +28 -0
  350. package/scripts/issue/issue-plan-cli.ts +151 -0
  351. package/scripts/issue/issue-priority.ts +151 -0
  352. package/scripts/issue/issue-rank.ts +7 -1
  353. package/scripts/issue/issue-read-cli.ts +3 -10
  354. package/scripts/issue/issue-read-main.ts +12 -0
  355. package/scripts/issue/issue-read.ts +29 -5
  356. package/scripts/issue/issue-release-cli.ts +0 -10
  357. package/scripts/issue/issue-release-main.ts +13 -0
  358. package/scripts/issue/issue-release.ts +7 -12
  359. package/scripts/issue/issue-sample-gate.ts +192 -0
  360. package/scripts/issue/issue-sample-source.ts +76 -0
  361. package/scripts/issue/issue-scout-cli.ts +0 -11
  362. package/scripts/issue/issue-scout-main.ts +14 -0
  363. package/scripts/issue/issue-state-cli.ts +0 -10
  364. package/scripts/issue/issue-state-main.ts +12 -0
  365. package/scripts/issue/issue-watch-diff.ts +56 -15
  366. package/scripts/issue/issue-watch.ts +2 -1
  367. package/scripts/issue/issue-wip.ts +2 -7
  368. package/scripts/issue/measure-rerun-cli.ts +13 -8
  369. package/scripts/issue/plan-consumers-cli.ts +39 -0
  370. package/scripts/issue/plan-consumers-main.ts +11 -0
  371. package/scripts/issue/plan-consumers-section.ts +55 -0
  372. package/scripts/issue/plan-consumers.ts +127 -0
  373. package/scripts/josh/agent-session-environment.ts +1 -1
  374. package/scripts/josh/command-usage.ts +15 -43
  375. package/scripts/josh/file-map-stamp.ts +49 -16
  376. package/scripts/josh/hook-decision.ts +32 -20
  377. package/scripts/josh/josh-command-map.ts +4 -1
  378. package/scripts/josh/josh-command-types.ts +12 -6
  379. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  380. package/scripts/josh/josh-commands-ai.ts +157 -158
  381. package/scripts/josh/josh-commands-backlog.ts +82 -16
  382. package/scripts/josh/josh-commands-clone.ts +1 -0
  383. package/scripts/josh/josh-commands-development.ts +111 -71
  384. package/scripts/josh/josh-commands-document.ts +43 -1
  385. package/scripts/josh/josh-commands-epic.ts +171 -0
  386. package/scripts/josh/josh-commands-hooks.ts +25 -2
  387. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  388. package/scripts/josh/josh-commands-issue.ts +124 -24
  389. package/scripts/josh/josh-commands-lane.ts +103 -2
  390. package/scripts/josh/josh-commands-lint.ts +19 -8
  391. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  392. package/scripts/josh/josh-commands-pause.ts +29 -0
  393. package/scripts/josh/josh-commands-progress.ts +87 -0
  394. package/scripts/josh/josh-commands-project.ts +138 -9
  395. package/scripts/josh/josh-commands-review.ts +124 -0
  396. package/scripts/josh/josh-commands-run.ts +211 -23
  397. package/scripts/josh/josh-commands-ship.ts +169 -0
  398. package/scripts/josh/josh-commands-split.ts +9 -0
  399. package/scripts/josh/josh-commands-versioning.ts +49 -2
  400. package/scripts/josh/josh-commands-workflow.ts +144 -6
  401. package/scripts/josh/josh-logic.ts +6 -13
  402. package/scripts/josh/package-directory.ts +2 -4
  403. package/scripts/josh/process-identity.ts +13 -4
  404. package/scripts/josh/session-language-cli.ts +4 -8
  405. package/scripts/josh/session-language-main.ts +13 -0
  406. package/scripts/josh/session-language.ts +6 -1
  407. package/scripts/josh/shared-cache.ts +90 -0
  408. package/scripts/josh/stamp-file.ts +9 -15
  409. package/scripts/lane/lane-await.ts +51 -12
  410. package/scripts/lane/lane-cache.ts +5 -30
  411. package/scripts/lane/lane-capacity.ts +14 -23
  412. package/scripts/lane/lane-check-stats.ts +62 -21
  413. package/scripts/lane/lane-child-invocation.ts +8 -0
  414. package/scripts/lane/lane-cli.ts +15 -5
  415. package/scripts/lane/lane-close.ts +86 -18
  416. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  417. package/scripts/lane/lane-dispatch.ts +24 -3
  418. package/scripts/lane/lane-gap-stats.ts +156 -0
  419. package/scripts/lane/lane-handoff.ts +69 -1
  420. package/scripts/lane/lane-held-stats.ts +129 -0
  421. package/scripts/lane/lane-install.ts +4 -11
  422. package/scripts/lane/lane-launch-cli.ts +0 -9
  423. package/scripts/lane/lane-launch-main.ts +12 -0
  424. package/scripts/lane/lane-ledger-schema.ts +266 -0
  425. package/scripts/lane/lane-ledger.ts +92 -123
  426. package/scripts/lane/lane-limit-cli.ts +12 -1
  427. package/scripts/lane/lane-measure-cli.ts +57 -11
  428. package/scripts/lane/lane-open.ts +9 -1
  429. package/scripts/lane/lane-parked.ts +3 -3
  430. package/scripts/lane/lane-pause-cli.ts +130 -0
  431. package/scripts/lane/lane-pause.ts +158 -0
  432. package/scripts/lane/lane-process-table.ts +166 -0
  433. package/scripts/lane/lane-reap-settle.ts +124 -0
  434. package/scripts/lane/lane-reap.ts +50 -15
  435. package/scripts/lane/lane-registry.ts +24 -3
  436. package/scripts/lane/lane-residents.ts +162 -0
  437. package/scripts/lane/lane-restart.ts +22 -2
  438. package/scripts/lane/lane-round-two-stats.ts +49 -0
  439. package/scripts/lane/lane-sampler.ts +4 -0
  440. package/scripts/lane/lane-session-action.ts +19 -5
  441. package/scripts/lane/lane-session-broker.ts +102 -21
  442. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  443. package/scripts/lane/lane-spans.ts +51 -0
  444. package/scripts/lane/lane-spent.ts +6 -3
  445. package/scripts/lane/lane-stage-stats.ts +7 -2
  446. package/scripts/lane/lane-state.ts +302 -0
  447. package/scripts/lane/lane-stats.ts +58 -4
  448. package/scripts/lane/lane-stop-stats.ts +113 -37
  449. package/scripts/lane/lane-test-related-stats.ts +127 -0
  450. package/scripts/lane/lane-transcript-calls.ts +145 -0
  451. package/scripts/lane/lane-transcript-stats.ts +168 -0
  452. package/scripts/lane/lane-vacant.ts +13 -3
  453. package/scripts/lane/lane-withdraw-cli.ts +5 -4
  454. package/scripts/lane/lane-withdraw.ts +50 -49
  455. package/scripts/lane/process-directories.ts +70 -0
  456. package/scripts/lane/process-lane-marks.ts +94 -0
  457. package/scripts/lib/atomic-write.ts +62 -0
  458. package/scripts/lib/buffered-process.ts +12 -5
  459. package/scripts/lib/cli-flags.ts +53 -0
  460. package/scripts/lib/figure-format.ts +63 -0
  461. package/scripts/lib/json-value.ts +9 -1
  462. package/scripts/lib/package-manifest.ts +35 -0
  463. package/scripts/lib/read-file.ts +3 -1
  464. package/scripts/lib/stamped-memo.ts +63 -0
  465. package/scripts/lib/stdout-on-stderr.ts +24 -0
  466. package/scripts/lib/timeouts.ts +9 -0
  467. package/scripts/lib/transcript-record.ts +91 -0
  468. package/scripts/lines/effective-limit.ts +1 -1
  469. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  470. package/scripts/lint/eslint-daemon.ts +265 -0
  471. package/scripts/lint/format.ts +11 -2
  472. package/scripts/lint/import-graph.ts +279 -0
  473. package/scripts/lint/lint-gate-scope.ts +102 -0
  474. package/scripts/lint/lint-parallel-main.ts +19 -0
  475. package/scripts/lint/lint-parallel.ts +62 -30
  476. package/scripts/lint/lint-related-scope.ts +30 -24
  477. package/scripts/lint/lint-related.ts +38 -6
  478. package/scripts/notify/confirmation-options.ts +1 -2
  479. package/scripts/notify/telegram-notify.ts +20 -20
  480. package/scripts/notify/telegram-test-logic.ts +0 -1
  481. package/scripts/notify/telegram-test-main.ts +8 -0
  482. package/scripts/notify/telegram-test.ts +2 -6
  483. package/scripts/observations/observation-ledger.ts +13 -0
  484. package/scripts/observations/observations-flush-landing.ts +5 -3
  485. package/scripts/observations/observations-flush.ts +6 -1
  486. package/scripts/overrides/overrides-check.ts +2 -5
  487. package/scripts/overrides/overrides-files.ts +2 -1
  488. package/scripts/overrides/overrides-logic.ts +3 -6
  489. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  490. package/scripts/propagate/propagate-publish.ts +2 -7
  491. package/scripts/propagate/propagate-targets.ts +4 -12
  492. package/scripts/refactor/import-graph.ts +9 -7
  493. package/scripts/release/github-release-runs.ts +17 -6
  494. package/scripts/release/release-approval-prune.ts +18 -0
  495. package/scripts/release/release-history.ts +1 -3
  496. package/scripts/release/release-progress.ts +42 -22
  497. package/scripts/release/release-publish-run.ts +39 -0
  498. package/scripts/release/release-publish.ts +6 -6
  499. package/scripts/release/release-scope-cli.ts +0 -10
  500. package/scripts/release/release-scope-main.ts +12 -0
  501. package/scripts/repo/repo-setting.ts +3 -6
  502. package/scripts/repo/required-checks-logic.ts +6 -15
  503. package/scripts/report/report-format-reference.ts +2 -0
  504. package/scripts/report/report-labels.ts +155 -0
  505. package/scripts/report/report-lint-cli.ts +3 -0
  506. package/scripts/report/report-lint.ts +85 -110
  507. package/scripts/report/report-template-cli.ts +59 -0
  508. package/scripts/report/report-template.ts +112 -0
  509. package/scripts/review/acceptance-map.ts +1 -0
  510. package/scripts/review/removed-tests-check.ts +86 -0
  511. package/scripts/review/removed-tests.ts +149 -0
  512. package/scripts/review/review-brief-cli.ts +81 -15
  513. package/scripts/review/review-brief-main.ts +12 -0
  514. package/scripts/review/review-brief.ts +31 -3
  515. package/scripts/review/review-code-tree.ts +10 -6
  516. package/scripts/review/review-comment-round.ts +26 -8
  517. package/scripts/review/review-finding-ledger.ts +30 -15
  518. package/scripts/review/review-interaction.ts +94 -0
  519. package/scripts/review/review-readers-scan.ts +163 -0
  520. package/scripts/review/review-record-cli.ts +69 -30
  521. package/scripts/review/review-record-main.ts +12 -0
  522. package/scripts/review/review-round-one-blobs.ts +221 -0
  523. package/scripts/review/review-round2-cli.ts +49 -12
  524. package/scripts/review/review-round2.ts +80 -12
  525. package/scripts/review/review-stamps.ts +19 -1
  526. package/scripts/review/review-stop-log.ts +96 -0
  527. package/scripts/review/review-stops-cli.ts +85 -0
  528. package/scripts/review/review-tree.ts +6 -17
  529. package/scripts/review/review-untouched-readers.ts +146 -0
  530. package/scripts/review/test-titles.ts +118 -0
  531. package/scripts/rules/agent-model.ts +8 -0
  532. package/scripts/rules/bash-triggers.ts +46 -3
  533. package/scripts/rules/decision-oracle-batch.ts +9 -1
  534. package/scripts/rules/decision-oracle.ts +2 -2
  535. package/scripts/rules/delivered-rules.ts +80 -2
  536. package/scripts/rules/destructive-command.ts +8 -1
  537. package/scripts/rules/direct-filing.ts +10 -2
  538. package/scripts/rules/direct-issue-comment.ts +117 -0
  539. package/scripts/rules/direct-pr-create.ts +69 -3
  540. package/scripts/rules/early-heartbeat.ts +2 -1
  541. package/scripts/rules/file-body.ts +7 -0
  542. package/scripts/rules/filing-cap.ts +7 -0
  543. package/scripts/rules/git-argv.ts +72 -14
  544. package/scripts/rules/git-force.ts +12 -2
  545. package/scripts/rules/guard-remedy.ts +4 -0
  546. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  547. package/scripts/rules/implementation-cut.ts +11 -3
  548. package/scripts/rules/index-guard.ts +8 -1
  549. package/scripts/rules/issue-comments.ts +9 -1
  550. package/scripts/rules/josh-git-bare.ts +7 -0
  551. package/scripts/rules/lane-background.ts +67 -25
  552. package/scripts/rules/lane-carry-conflict.ts +6 -0
  553. package/scripts/rules/lane-direct-tool.ts +74 -0
  554. package/scripts/rules/lane-interactive-ask.ts +9 -2
  555. package/scripts/rules/lane-park.ts +45 -23
  556. package/scripts/rules/lane-split-park.ts +10 -2
  557. package/scripts/rules/lane-switch-main.ts +7 -0
  558. package/scripts/rules/oracle-consulted.ts +10 -0
  559. package/scripts/rules/oracle-firing.ts +1 -0
  560. package/scripts/rules/permission-guards.ts +3 -0
  561. package/scripts/rules/piped-verification.ts +1 -1
  562. package/scripts/rules/poll-loop.ts +7 -0
  563. package/scripts/rules/pr-merge.ts +123 -0
  564. package/scripts/rules/protected-files.ts +32 -5
  565. package/scripts/rules/raw-field-body.ts +6 -0
  566. package/scripts/rules/rule-body-guard.ts +8 -0
  567. package/scripts/rules/rule-list.ts +9 -28
  568. package/scripts/rules/rule-value-cache.ts +4 -9
  569. package/scripts/rules/rule-value-cli.ts +51 -32
  570. package/scripts/rules/rule-value.ts +1 -1
  571. package/scripts/rules/shell-segments.ts +35 -0
  572. package/scripts/rules/stop-rule-rows.ts +64 -0
  573. package/scripts/rules/stop-rules.ts +3 -4
  574. package/scripts/rules/test-declared-commit.ts +11 -1
  575. package/scripts/rules/third-party-write.ts +7 -0
  576. package/scripts/rules/timed-rerun.ts +69 -0
  577. package/scripts/rules/worktree-guard.ts +13 -3
  578. package/scripts/run/board/run-board-app-name.ts +23 -0
  579. package/scripts/run/board/run-board-cli.ts +65 -32
  580. package/scripts/run/board/run-board-earlier.ts +94 -0
  581. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  582. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  583. package/scripts/run/board/run-board-estimate.ts +98 -0
  584. package/scripts/run/board/run-board-fit.ts +153 -36
  585. package/scripts/run/board/run-board-fold.ts +123 -0
  586. package/scripts/run/board/run-board-fresh.ts +2 -2
  587. package/scripts/run/board/run-board-gather-live.ts +29 -0
  588. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  589. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  590. package/scripts/run/board/run-board-gather.ts +187 -0
  591. package/scripts/run/board/run-board-github.ts +118 -38
  592. package/scripts/run/board/run-board-header.ts +82 -20
  593. package/scripts/run/board/run-board-keys.ts +58 -0
  594. package/scripts/run/board/run-board-kind.ts +20 -6
  595. package/scripts/run/board/run-board-labels.ts +116 -71
  596. package/scripts/run/board/run-board-lane-state.ts +109 -0
  597. package/scripts/run/board/run-board-lane-time.ts +122 -0
  598. package/scripts/run/board/run-board-layout.ts +239 -60
  599. package/scripts/run/board/run-board-length.ts +52 -0
  600. package/scripts/run/board/run-board-machine.ts +8 -4
  601. package/scripts/run/board/run-board-main.ts +12 -0
  602. package/scripts/run/board/run-board-notes.ts +52 -31
  603. package/scripts/run/board/run-board-now.ts +1 -1
  604. package/scripts/run/board/run-board-operation.ts +15 -33
  605. package/scripts/run/board/run-board-phase.ts +1 -1
  606. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  607. package/scripts/run/board/run-board-plan.ts +55 -3
  608. package/scripts/run/board/run-board-planning.ts +45 -0
  609. package/scripts/run/board/run-board-priority.ts +44 -0
  610. package/scripts/run/board/run-board-process-groups.ts +195 -0
  611. package/scripts/run/board/run-board-read.ts +151 -27
  612. package/scripts/run/board/run-board-reason.ts +235 -51
  613. package/scripts/run/board/run-board-released.ts +35 -0
  614. package/scripts/run/board/run-board-render-checks.ts +39 -5
  615. package/scripts/run/board/run-board-render-condition.ts +96 -0
  616. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  617. package/scripts/run/board/run-board-render-foot.ts +59 -0
  618. package/scripts/run/board/run-board-render-icon.ts +35 -0
  619. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  620. package/scripts/run/board/run-board-render-lead.ts +80 -0
  621. package/scripts/run/board/run-board-render-legend.ts +117 -48
  622. package/scripts/run/board/run-board-render-notes.ts +156 -29
  623. package/scripts/run/board/run-board-render-processes.ts +196 -0
  624. package/scripts/run/board/run-board-render-section.ts +119 -0
  625. package/scripts/run/board/run-board-render-slot.ts +3 -36
  626. package/scripts/run/board/run-board-render-tail.ts +115 -48
  627. package/scripts/run/board/run-board-render-time.ts +56 -0
  628. package/scripts/run/board/run-board-render-title.ts +117 -24
  629. package/scripts/run/board/run-board-render-waits.ts +104 -20
  630. package/scripts/run/board/run-board-render.ts +207 -265
  631. package/scripts/run/board/run-board-roots.ts +54 -0
  632. package/scripts/run/board/run-board-row-yield.ts +9 -4
  633. package/scripts/run/board/run-board-setup.ts +1 -12
  634. package/scripts/run/board/run-board-snapshot.ts +111 -0
  635. package/scripts/run/board/run-board-spin.ts +2 -2
  636. package/scripts/run/board/run-board-state.ts +22 -33
  637. package/scripts/run/board/run-board-status.ts +147 -71
  638. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  639. package/scripts/run/board/run-board-tick.ts +122 -107
  640. package/scripts/run/board/run-board-usage-board.ts +78 -0
  641. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  642. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  643. package/scripts/run/board/run-board-usage-read.ts +120 -150
  644. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  645. package/scripts/run/board/run-board-usage-text.ts +139 -51
  646. package/scripts/run/board/run-board-usage-top.ts +102 -0
  647. package/scripts/run/board/run-board-usage.ts +89 -72
  648. package/scripts/run/board/run-board-usual.ts +20 -9
  649. package/scripts/run/carry/run-carry-args.ts +4 -7
  650. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  651. package/scripts/run/carry/run-carry.ts +9 -4
  652. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  653. package/scripts/run/event/run-event-cli.ts +1 -5
  654. package/scripts/run/event/run-event-filed.ts +12 -6
  655. package/scripts/run/event/run-event-follow.ts +2 -3
  656. package/scripts/run/event/run-event-render.ts +6 -10
  657. package/scripts/run/event/run-event-scope.ts +2 -2
  658. package/scripts/run/event/run-event-stream-emit.ts +82 -22
  659. package/scripts/run/event/run-event-stream.ts +34 -8
  660. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  661. package/scripts/run/hold/run-hold-cli.ts +93 -22
  662. package/scripts/run/hold/run-hold-main.ts +12 -0
  663. package/scripts/run/hold/run-hold-member.ts +37 -0
  664. package/scripts/run/hold/run-stop-notify.ts +183 -0
  665. package/scripts/run/merge/run-merge-auth.ts +31 -0
  666. package/scripts/run/merge/run-merge-cli.ts +62 -48
  667. package/scripts/run/merge/run-merge-close.ts +74 -0
  668. package/scripts/run/merge/run-merge-collect.ts +6 -13
  669. package/scripts/run/merge/run-merge-driver.ts +71 -0
  670. package/scripts/run/merge/run-merge-main.ts +12 -0
  671. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  672. package/scripts/run/merge/run-merge-restart.ts +39 -0
  673. package/scripts/run/merge/run-merge-ship.ts +20 -4
  674. package/scripts/run/merge/run-merge-signals.ts +33 -9
  675. package/scripts/run/merge/run-merge-steps.ts +120 -85
  676. package/scripts/run/merge/run-merge.ts +38 -37
  677. package/scripts/run/park/run-park-cli.ts +91 -0
  678. package/scripts/run/park/run-park.ts +88 -0
  679. package/scripts/run/park/run-stalled.ts +68 -0
  680. package/scripts/run/pause/run-pause-cli.ts +73 -0
  681. package/scripts/run/pause/run-pause.ts +251 -0
  682. package/scripts/run/progress/run-progress-cli.ts +4 -12
  683. package/scripts/run/progress/run-progress-clock.ts +1 -1
  684. package/scripts/run/progress/run-progress-config.ts +6 -14
  685. package/scripts/run/progress/run-progress-main.ts +12 -0
  686. package/scripts/run/progress/run-progress.ts +1 -4
  687. package/scripts/run/review/run-review.ts +2 -1
  688. package/scripts/run/run-ending.ts +1 -0
  689. package/scripts/run/run-invocation.ts +5 -6
  690. package/scripts/run/run-liveness-cli.ts +6 -8
  691. package/scripts/run/run-liveness.ts +60 -29
  692. package/scripts/run/run-next.ts +1 -1
  693. package/scripts/run/run-parent-cut-hook.ts +2 -2
  694. package/scripts/run/run-preflight.ts +18 -3
  695. package/scripts/run/run-prep-cli.ts +1 -10
  696. package/scripts/run/run-prep-locate.ts +7 -50
  697. package/scripts/run/run-prep-main.ts +12 -0
  698. package/scripts/run/run-prep.ts +6 -0
  699. package/scripts/run/run-report-cli.ts +101 -13
  700. package/scripts/run/run-report-handoff.ts +114 -0
  701. package/scripts/run/run-step.ts +1 -1
  702. package/scripts/run/run-stranded-detect.ts +13 -0
  703. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  704. package/scripts/run/run-watcher-guard.ts +1 -1
  705. package/scripts/run/ship/run-ship-args.ts +121 -0
  706. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  707. package/scripts/run/ship/run-ship-cli.ts +63 -140
  708. package/scripts/run/ship/run-ship-detach.ts +19 -8
  709. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  710. package/scripts/run/ship/run-ship-next.ts +18 -2
  711. package/scripts/run/ship/run-ship-overlap.ts +42 -5
  712. package/scripts/run/ship/run-ship-place.ts +96 -0
  713. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  714. package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
  715. package/scripts/run/ship/run-ship-preflight.ts +137 -32
  716. package/scripts/run/ship/run-ship-probe.ts +11 -3
  717. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  718. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  719. package/scripts/run/ship/run-ship-return.ts +107 -23
  720. package/scripts/run/ship/run-ship-review-steps.ts +105 -151
  721. package/scripts/run/ship/run-ship-review.ts +73 -6
  722. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  723. package/scripts/run/ship/run-ship-stage.ts +55 -6
  724. package/scripts/run/ship/run-ship-steps.ts +46 -15
  725. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  726. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  727. package/scripts/run/ship/run-ship-sync.ts +43 -6
  728. package/scripts/run/ship/run-ship.ts +30 -2
  729. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  730. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  731. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  732. package/scripts/run/wake/run-wake-cli.ts +119 -100
  733. package/scripts/run/wake/run-wake-code.ts +83 -0
  734. package/scripts/run/wake/run-wake-driver.ts +19 -8
  735. package/scripts/run/wake/run-wake-loop.ts +34 -3
  736. package/scripts/run/wake/run-wake-main.ts +13 -0
  737. package/scripts/run/wake/run-wake-ports.ts +90 -0
  738. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  739. package/scripts/run/wake/run-wake.ts +2 -1
  740. package/scripts/safe-chain/pack-hook.ts +2 -2
  741. package/scripts/safe-chain/preinstall-command.ts +2 -1
  742. package/scripts/safe-chain/project-config.ts +3 -9
  743. package/scripts/security/security-audit-main.ts +8 -0
  744. package/scripts/security/security-audit-provision-logic.ts +0 -11
  745. package/scripts/security/security-audit-provision-main.ts +12 -0
  746. package/scripts/security/security-audit-provision.ts +11 -26
  747. package/scripts/security/security-audit.ts +6 -7
  748. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  749. package/scripts/split/split-assess-cli.ts +2 -2
  750. package/scripts/split/split-assess.ts +15 -0
  751. package/scripts/split/split-measure.ts +65 -0
  752. package/scripts/sync/claude-settings-merge.ts +8 -15
  753. package/scripts/sync/directory-copy-guard.ts +4 -9
  754. package/scripts/sync/file-content.ts +78 -8
  755. package/scripts/sync/sync-ai-files.ts +3 -5
  756. package/scripts/sync/sync-configs.ts +11 -23
  757. package/scripts/sync/sync-hook-safety.ts +4 -10
  758. package/scripts/sync/sync-main.ts +11 -0
  759. package/scripts/sync/sync.ts +25 -37
  760. package/scripts/test/test-declared-changed.ts +2 -2
  761. package/scripts/test/test-declared.ts +1 -1
  762. package/scripts/test/test-e2e-guard.ts +25 -1
  763. package/scripts/test/test-e2e-stamp.ts +38 -0
  764. package/scripts/test/test-pinned-logic.ts +145 -0
  765. package/scripts/test/test-pinned-main.ts +78 -0
  766. package/scripts/test/test-pinned.ts +100 -0
  767. package/scripts/test/test-read-map.ts +264 -0
  768. package/scripts/test/test-read-recording.ts +91 -0
  769. package/scripts/test/test-read-trace.ts +148 -0
  770. package/scripts/test/test-red-main.ts +12 -0
  771. package/scripts/test/test-red.ts +12 -30
  772. package/scripts/test/test-related-main.ts +18 -0
  773. package/scripts/test/test-related-record.ts +119 -0
  774. package/scripts/test/test-related-scope.ts +229 -43
  775. package/scripts/test/test-related.ts +300 -22
  776. package/scripts/test/test-unit-guard-main.ts +15 -0
  777. package/scripts/test/test-unit-guard.ts +42 -24
  778. package/scripts/test/unit-count-file.ts +37 -0
  779. package/scripts/test/unit-run-marker.ts +162 -0
  780. package/scripts/test/unit-setup-files.ts +51 -0
  781. package/scripts/test/unit-worker-share.ts +61 -149
  782. package/scripts/test/whole-suite-files.ts +63 -0
  783. package/scripts/time-runtime/time-background.ts +20 -2
  784. package/scripts/time-runtime/time-bundles.ts +4 -3
  785. package/scripts/time-runtime/time-density-hook.ts +8 -6
  786. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  787. package/scripts/time-runtime/time-format.ts +5 -28
  788. package/scripts/time-runtime/time-markers.ts +10 -1
  789. package/scripts/time-runtime/time-shell.ts +97 -10
  790. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  791. package/scripts/uninstall/uninstall.ts +1 -1
  792. package/scripts/version/bump-version-main.ts +12 -0
  793. package/scripts/version/bump-version.ts +25 -25
  794. package/scripts/version/effective-upstream.ts +6 -12
  795. package/scripts/version/latest-corepack.ts +17 -32
  796. package/scripts/version/latest-if-required-cli.ts +93 -0
  797. package/scripts/version/latest-lane-guard-main.ts +8 -0
  798. package/scripts/version/latest-lane-guard.ts +0 -4
  799. package/scripts/version/latest-scope-cli.ts +0 -9
  800. package/scripts/version/latest-scope-main.ts +12 -0
  801. package/scripts/version/latest-update.ts +5 -5
  802. package/scripts/version/npm-registry.ts +44 -6
  803. package/scripts/version/publishable-range-check.ts +5 -16
  804. package/scripts/version/release-age.ts +1 -1
  805. package/scripts/version/release-hold.ts +1 -1
  806. package/scripts/version/release-window.ts +38 -0
  807. package/scripts/version/running-binary.ts +1 -1
  808. package/scripts/version/safe-chain-version-update.ts +3 -8
  809. package/scripts/version/version-targets.ts +6 -28
  810. package/templates/dependabot.yml +29 -0
  811. package/templates/gitignore +4 -1
  812. package/templates/pnpm-workspace.basic.yaml +1 -1
  813. package/templates/sonar-project.properties +3 -2
  814. package/templates/workflows/ci.yml +12 -4
  815. package/templates/workflows/github-release.yml +4 -0
  816. package/tsconfig.sonar.json +1 -1
  817. package/.ncurc.json +0 -3
  818. package/dist/hooks/batch-guard.js +0 -29
  819. package/dist/hooks/chunk-4KKD2UTK.js +0 -66
  820. package/dist/hooks/chunk-6TS2JD6D.js +0 -237
  821. package/dist/hooks/chunk-7DSBJVFH.js +0 -50
  822. package/dist/hooks/chunk-A65Y4YOR.js +0 -79
  823. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  824. package/dist/hooks/chunk-EFXE6C37.js +0 -81
  825. package/dist/hooks/chunk-GP4IEC4O.js +0 -20
  826. package/dist/hooks/chunk-JP45SOCJ.js +0 -56
  827. package/dist/hooks/chunk-LAOV7NLM.js +0 -45
  828. package/dist/hooks/chunk-M4HGZV7U.js +0 -83
  829. package/dist/hooks/chunk-PF2NZL2A.js +0 -131
  830. package/dist/hooks/chunk-PTICX4OL.js +0 -358
  831. package/dist/hooks/chunk-RT27QRJW.js +0 -6247
  832. package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
  833. package/dist/hooks/chunk-UPUZF3AN.js +0 -279
  834. package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
  835. package/dist/hooks/duplicate-read-guard.js +0 -30
  836. package/dist/hooks/investigation-guard.js +0 -29
  837. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  838. package/scripts/cost-runtime/cost-format.ts +0 -29
  839. package/scripts/init/basic-path-migration.ts +0 -24
  840. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  841. package/scripts/josh/josh-commands-guard.ts +0 -38
  842. package/scripts/josh/josh-usage-automation.ts +0 -121
  843. package/scripts/josh/josh-usage-backlog.ts +0 -180
  844. package/scripts/josh/josh-usage-developer.ts +0 -230
  845. package/scripts/josh/josh-usage-hooks.ts +0 -38
  846. package/scripts/josh/josh-usage-issue.ts +0 -205
  847. package/scripts/josh/josh-usage-review.ts +0 -101
  848. package/scripts/josh/josh-usage-run.ts +0 -252
  849. package/scripts/josh/josh-usage-session.ts +0 -238
  850. package/scripts/josh/josh-usage-workflow.ts +0 -212
  851. package/scripts/lint/cross-file-recheck.ts +0 -155
  852. package/scripts/registry-migration/migrate-logic.ts +0 -237
  853. package/scripts/registry-migration/migrate.ts +0 -292
  854. package/scripts/registry-migration/user-npmrc.ts +0 -15
  855. package/scripts/rules/rule-guard.ts +0 -23
  856. package/scripts/rules/rule-registry-rows.ts +0 -292
  857. package/scripts/rules/rule-registry.ts +0 -112
  858. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -0,0 +1,124 @@
1
+ import { userInfo } from 'node:os'
2
+ import { lane_reap } from './lane-reap'
3
+ import { lane_residents, type ResidentLane } from './lane-residents'
4
+
5
+ // What a close does about the lane's processes once the SIGTERM went out (joshuafolkken/kit#4300).
6
+ //
7
+ // **A SIGTERM is a request, so the close looks again.** After a grace window the lane's directory is
8
+ // read again; whatever is still there gets a SIGKILL, and after a short wait the directory is read a
9
+ // last time. What survives that is reported, each with why it could — another account owns it, or it
10
+ // is stuck in the kernel — so `lane:close` answers `incomplete` and `run:board` can say what is wrong
11
+ // rather than only that something is left.
12
+
13
+ // Long enough for a node process to run its exit handlers.
14
+ const GRACE_MS = 3000
15
+ // A SIGKILL is not handled, so what still answers after this is not going to go.
16
+ const KILL_WAIT_MS = 1000
17
+ const KILL_SIGNAL = 'SIGKILL'
18
+ const STATE_FORMAT = ['-o', 'user=,stat=', '-p']
19
+ const FIELD_SEPARATOR = /\s+/u
20
+ const UNREADABLE_TEXT = "the lane's processes (lsof or ps failed)"
21
+
22
+ interface SettleProbes {
23
+ // `undefined` where the lane's processes could not be read (`lane_residents.residents`).
24
+ residents: (lane: ResidentLane) => Array<number> | undefined
25
+ kill: (pid: number) => boolean
26
+ wait: (milliseconds: number) => Promise<void>
27
+ // Why a process outlived the SIGKILL.
28
+ reason_of: (pid: number) => string
29
+ }
30
+
31
+ interface Survivor {
32
+ pid: number
33
+ reason: string
34
+ }
35
+
36
+ function kill(pid: number): boolean {
37
+ try {
38
+ process.kill(pid, KILL_SIGNAL)
39
+
40
+ return true
41
+ } catch {
42
+ return false
43
+ }
44
+ }
45
+
46
+ async function wait(milliseconds: number): Promise<void> {
47
+ await new Promise((resolve) => setTimeout(resolve, milliseconds))
48
+ }
49
+
50
+ // Another account's process is the usual survivor — a SIGKILL from this one is refused; otherwise
51
+ // `ps`'s state says it, `U` for an uninterruptible wait.
52
+ function reason_from(user: string, state: string): string {
53
+ if (user !== userInfo().username) return `owned by ${user}`
54
+
55
+ return `state ${state}`
56
+ }
57
+
58
+ function reason_of(pid: number): string {
59
+ const printed = lane_reap.run_probe(lane_reap.PS_COMMAND, [...STATE_FORMAT, String(pid)])
60
+ const [user = '', state = ''] = printed.trim().split(FIELD_SEPARATOR)
61
+
62
+ return user.length === 0 ? 'unreadable' : reason_from(user, state)
63
+ }
64
+
65
+ const SYSTEM_PROBES: SettleProbes = {
66
+ residents: (lane) => lane_residents.residents(lane),
67
+ kill,
68
+ wait,
69
+ reason_of,
70
+ }
71
+
72
+ // A reading that failed is not an empty one.
73
+ function is_empty(reading: ReadonlyArray<number> | undefined): boolean {
74
+ return reading?.length === 0
75
+ }
76
+
77
+ async function kill_all(
78
+ lingering: ReadonlyArray<number> | undefined,
79
+ probes: SettleProbes,
80
+ ): Promise<void> {
81
+ const targets = lingering ?? []
82
+
83
+ for (const pid of targets) probes.kill(pid)
84
+
85
+ await probes.wait(KILL_WAIT_MS)
86
+ }
87
+
88
+ function survivors(lane: ResidentLane, probes: SettleProbes): Array<Survivor> | undefined {
89
+ return probes.residents(lane)?.map((pid) => ({ pid, reason: probes.reason_of(pid) }))
90
+ }
91
+
92
+ /**
93
+ * Wait out the SIGTERM a reap sent, SIGKILL what is still in the lane's directory, and answer what
94
+ * outlived even that — the empty list is a lane with no process left, `undefined` a last reading that
95
+ * failed. A failed reading is never read as none: it is read again, and nothing is killed on it.
96
+ */
97
+ async function settle(
98
+ lane: ResidentLane,
99
+ probes: SettleProbes = SYSTEM_PROBES,
100
+ ): Promise<Array<Survivor> | undefined> {
101
+ if (is_empty(probes.residents(lane))) return []
102
+
103
+ await probes.wait(GRACE_MS)
104
+
105
+ const lingering = probes.residents(lane)
106
+
107
+ if (is_empty(lingering)) return []
108
+
109
+ await kill_all(lingering, probes)
110
+
111
+ return survivors(lane, probes)
112
+ }
113
+
114
+ /** How a close's `left_behind` names what `settle` answered; a failed reading is named as such. */
115
+ function survivor_texts(settled: ReadonlyArray<Survivor> | undefined): Array<string> {
116
+ if (settled === undefined) return [UNREADABLE_TEXT]
117
+
118
+ return settled.map((survivor) => `process ${String(survivor.pid)} (${survivor.reason})`)
119
+ }
120
+
121
+ const lane_reap_settle = { GRACE_MS, KILL_WAIT_MS, reason_from, settle, survivor_texts }
122
+
123
+ export type { SettleProbes, Survivor }
124
+ export { lane_reap_settle }
@@ -18,6 +18,9 @@ import { process_tools } from './process-tools'
18
18
  //
19
19
  // **The caller's own ancestry is never touched.** A `lane:close` issued from inside the lane it
20
20
  // closes would otherwise end the very session running it, before it could report.
21
+ //
22
+ // **What runs from the lane outside the tree is `lane-residents.ts`'s** (joshuafolkken/kit#4300): the
23
+ // edit hook's `eslint_d`, a `script` wrapper re-parented to pid 1, found by working directory or mark.
21
24
 
22
25
  const PGREP_COMMAND = 'pgrep'
23
26
  const MATCH_FULL_COMMAND_LINE = '-f'
@@ -26,13 +29,24 @@ const CHILDREN_OF_FLAG = '-P'
26
29
  const PS_COMMAND = '/bin/ps'
27
30
  const PARENT_FORMAT = ['-o', 'ppid=', '-p']
28
31
  const TERMINATE_SIGNAL = 'SIGTERM'
32
+ const CONTINUE_SIGNAL = 'SIGCONT'
29
33
  // `0` addresses the caller's own process group and `1` is init — neither is ever a lane child.
30
34
  const LOWEST_CHILD_PID = 2
31
35
 
32
- interface ReapProbes {
36
+ // The lane a reap or a pause acts on: the child by its issue, the rest by its directory.
37
+ interface LaneProcesses {
38
+ issue: string
39
+ directory: string
40
+ }
41
+
42
+ // What collecting a lane's process tree reads — shared with `lane:pause` (`lane-pause.ts`).
43
+ interface TreeProbes {
33
44
  matching: (pattern: string) => Array<number>
34
45
  children_of: (pid: number) => Array<number>
35
46
  parent_of: (pid: number) => number | undefined
47
+ }
48
+
49
+ interface ReapProbes extends TreeProbes {
36
50
  terminate: (pid: number) => boolean
37
51
  }
38
52
 
@@ -64,9 +78,9 @@ function parent_of(pid: number): number | undefined {
64
78
  return parse_pids(run_probe(PS_COMMAND, [...PARENT_FORMAT, String(pid)]))[0]
65
79
  }
66
80
 
67
- function terminate(pid: number): boolean {
81
+ function send(pid: number, name: NodeJS.Signals): boolean {
68
82
  try {
69
- process.kill(pid, TERMINATE_SIGNAL)
83
+ process.kill(pid, name)
70
84
 
71
85
  return true
72
86
  } catch {
@@ -74,6 +88,16 @@ function terminate(pid: number): boolean {
74
88
  }
75
89
  }
76
90
 
91
+ // A stopped process (`lane:pause`) holds a SIGTERM it handles pending until it is continued, so the
92
+ // terminate is followed by a SIGCONT; a running process ignores it.
93
+ function terminate(pid: number): boolean {
94
+ if (!send(pid, TERMINATE_SIGNAL)) return false
95
+
96
+ send(pid, CONTINUE_SIGNAL)
97
+
98
+ return true
99
+ }
100
+
77
101
  const SYSTEM_PROBES: ReapProbes = {
78
102
  matching: (pattern) => parse_pids(run_probe(PGREP_COMMAND, [MATCH_FULL_COMMAND_LINE, pattern])),
79
103
  children_of: (pid) => parse_pids(run_probe(PGREP_COMMAND, [CHILDREN_OF_FLAG, String(pid)])),
@@ -81,7 +105,7 @@ const SYSTEM_PROBES: ReapProbes = {
81
105
  terminate,
82
106
  }
83
107
 
84
- function ancestry_of(pid: number, probes: ReapProbes): Set<number> {
108
+ function ancestry_of(pid: number, probes: TreeProbes): Set<number> {
85
109
  const ancestry = new Set<number>([pid])
86
110
  let current = probes.parent_of(pid)
87
111
 
@@ -95,11 +119,11 @@ function ancestry_of(pid: number, probes: ReapProbes): Set<number> {
95
119
 
96
120
  // This process and every process above it. The Stop hook reads it to tell whether the session that
97
121
  // declared a carry record's `--owner "$PPID"` is the one it runs under.
98
- function own_ancestry(probes: ReapProbes = SYSTEM_PROBES): Set<number> {
122
+ function own_ancestry(probes: TreeProbes = SYSTEM_PROBES): Set<number> {
99
123
  return ancestry_of(process.pid, probes)
100
124
  }
101
125
 
102
- function tree_of(roots: ReadonlyArray<number>, probes: ReapProbes): Array<number> {
126
+ function tree_of(roots: ReadonlyArray<number>, probes: TreeProbes): Array<number> {
103
127
  const tree: Array<number> = []
104
128
  const pending = [...roots]
105
129
  let next = pending.shift()
@@ -116,35 +140,46 @@ function tree_of(roots: ReadonlyArray<number>, probes: ReapProbes): Array<number
116
140
  return tree
117
141
  }
118
142
 
119
- function roots_of(issue: string, own: Set<number>, probes: ReapProbes): Array<number> {
143
+ function roots_of(issue: string, own: Set<number>, probes: TreeProbes): Array<number> {
120
144
  const pattern = lane_child_invocation.process_pattern(issue)
121
145
 
122
146
  return probes.matching(pattern).filter((pid) => !own.has(pid))
123
147
  }
124
148
 
125
149
  /**
126
- * Terminate every process of the lane child for `issue` and everything under it, sparing the caller's
127
- * own ancestry. Returns the pids that were signalled — the empty list is the healthy case, a child
128
- * that had already ended by itself.
150
+ * Every process of the lane child for `issue` and everything under it, collected before anything is
151
+ * signalled, the caller's own ancestry left out.
129
152
  */
130
- function reap_child(issue: string, probes: ReapProbes = SYSTEM_PROBES): Array<number> {
153
+ function lane_tree(issue: string, probes: TreeProbes = SYSTEM_PROBES): Array<number> {
131
154
  const own = own_ancestry(probes)
132
- const doomed = tree_of(roots_of(issue, own, probes), probes).filter((pid) => !own.has(pid))
133
155
 
134
- return doomed.filter((pid) => probes.terminate(pid))
156
+ return tree_of(roots_of(issue, own, probes), probes).filter((pid) => !own.has(pid))
157
+ }
158
+
159
+ /**
160
+ * Terminate every process of the lane child for `lane.issue` and everything under it, sparing the
161
+ * caller's own ancestry. Returns the pids that were signalled — the empty list is the healthy case, a
162
+ * child that had already ended by itself.
163
+ */
164
+ function reap_child(lane: LaneProcesses, probes: ReapProbes = SYSTEM_PROBES): Array<number> {
165
+ return lane_tree(lane.issue, probes).filter((pid) => probes.terminate(pid))
135
166
  }
136
167
 
137
168
  /** Whether a lane child for `issue` is running, by the same match `reap_child` would end. */
138
- function is_child_running(issue: string, probes: ReapProbes = SYSTEM_PROBES): boolean {
169
+ function is_child_running(issue: string, probes: TreeProbes = SYSTEM_PROBES): boolean {
139
170
  return roots_of(issue, own_ancestry(probes), probes).length > 0
140
171
  }
141
172
 
142
173
  const lane_reap = {
143
174
  is_child_running,
175
+ lane_tree,
144
176
  own_ancestry,
145
177
  parse_pids,
178
+ PS_COMMAND,
146
179
  reap_child,
180
+ run_probe,
181
+ SYSTEM_PROBES,
147
182
  }
148
183
 
149
- export type { ReapProbes }
184
+ export type { LaneProcesses, ReapProbes, TreeProbes }
150
185
  export { lane_reap }
@@ -222,9 +222,28 @@ async function main_repository_root(): Promise<string> {
222
222
  return repo_discovery.main_worktree(await git_command.repository_root())
223
223
  }
224
224
 
225
- /** Every open lane of this repository, lowest issue number first. */
226
- async function list_lanes(): Promise<Array<LaneInfo>> {
227
- const root = lane_paths.lane_root(await main_repository_root())
225
+ /**
226
+ * The directory this repository's lanes live in, read from the main work tree rather than this one —
227
+ * derived from the current work tree, a command run inside a lane would look for lanes inside it.
228
+ */
229
+ async function lane_root_directory(): Promise<string> {
230
+ return lane_paths.lane_root(await main_repository_root())
231
+ }
232
+
233
+ /**
234
+ * The issue's lane by the directory its number implies, registered or not — what ending its processes
235
+ * needs (`lane_reap.reap_child`), so a lane `list_lanes` no longer reads is still reached.
236
+ */
237
+ async function lane_location(issue: string): Promise<Pick<LaneInfo, 'issue' | 'directory'>> {
238
+ return { issue, directory: lane_paths.lane_directory(await lane_root_directory(), issue) }
239
+ }
240
+
241
+ /**
242
+ * Every open lane of this repository, lowest issue number first. `main_root` is the main work tree a
243
+ * caller already resolved — `run:board` resolves it once rather than with a `git` call each read.
244
+ */
245
+ async function list_lanes(main_root?: string): Promise<Array<LaneInfo>> {
246
+ const root = lane_paths.lane_root(main_root ?? (await main_repository_root()))
228
247
  const blocks = await worktree_blocks()
229
248
  const lanes = blocks.map((block) => parse_block(block, root)).filter(is_lane)
230
249
 
@@ -279,6 +298,8 @@ const lane_registry = {
279
298
  find_lane,
280
299
  find_open_lane,
281
300
  has_lanes_in_flight,
301
+ lane_location,
302
+ lane_root_directory,
282
303
  list_lanes,
283
304
  main_repository_root,
284
305
  parse_block,
@@ -0,0 +1,162 @@
1
+ import { spawnSync } from 'node:child_process'
2
+ import path from 'node:path'
3
+ import { PROBE_TIMEOUT_MS } from '#scripts/lib/timeouts'
4
+ import { lane_reap } from './lane-reap'
5
+ import { process_directories } from './process-directories'
6
+ import { process_lane_marks } from './process-lane-marks'
7
+
8
+ // Ending what still runs from a lane's checkout, or carries its mark, when the lane closes
9
+ // (joshuafolkken/kit#4304, joshuafolkken/kit#4315).
10
+ //
11
+ // **The lane child's tree and its `eslint_d` are not everything a lane starts.** A diagnostic the
12
+ // child launched under `script`, or a `node` it detached, is re-parented to pid 1 and outlives the
13
+ // merge: no tree reaches it and no title names it, and `run:board` drew such processes as a leftover
14
+ // holding gigabytes while nothing ended them. Its working directory still sits under the lane, which
15
+ // is what finds it — the same reading the board's leftover is drawn from (`process-directories.ts`).
16
+ // **A process the child started from elsewhere** — a measurement run from the main checkout or `/tmp`
17
+ // — has no such directory, so the lane's mark it inherited finds it instead (`process-lane-marks.ts`):
18
+ // the issue number `lane:dispatch` put in the child's environment. A process without the mark, or with
19
+ // another issue's, is never this lane's.
20
+ //
21
+ // **Only that lane's processes, and never the caller.** Another lane's and the main checkout's
22
+ // unmarked processes are not its. A `lane:close` run from inside the lane would match itself, so its
23
+ // ancestry is spared, as `lane-reap.ts` spares it — and so is its process group: its own helpers
24
+ // (`tsx`'s `esbuild`) and the commands piped beside it share the group, while a detached process
25
+ // (`script`, a new session) has left it.
26
+
27
+ const GROUP_ARGUMENTS = ['-o', 'pid=,pgid=', '-p']
28
+ const PID_SEPARATOR = ','
29
+ // `ps`'s line: the process and its group.
30
+ const PAIR_LENGTH = 2
31
+
32
+ interface ResidentLane {
33
+ issue: string
34
+ directory: string
35
+ }
36
+
37
+ interface ResidentProbes {
38
+ // `undefined` where the working directories could not be read.
39
+ directories: () => ReadonlyMap<number, string> | undefined
40
+ // Each marked process's issue; `undefined` where the marks could not be read.
41
+ marks: () => ReadonlyMap<number, string> | undefined
42
+ own: () => ReadonlySet<number>
43
+ // Each listed process's group; a process gone by then is missing.
44
+ groups_of: (pids: ReadonlyArray<number>) => ReadonlyMap<number, number>
45
+ terminate: (pid: number) => boolean
46
+ }
47
+
48
+ function parse_groups(printed: string): Map<number, number> {
49
+ const pairs = printed
50
+ .split('\n')
51
+ .map((line) => line.trim().split(/\s+/u).map(Number))
52
+ .filter((pair) => pair.length === PAIR_LENGTH && pair.every((id) => Number.isSafeInteger(id)))
53
+
54
+ return new Map(pairs.map(([pid = 0, group = 0]) => [pid, group] as const))
55
+ }
56
+
57
+ // `ps` exits non-zero when a listed process is gone and still prints the rest, so its output is read
58
+ // whatever the exit status.
59
+ function groups_of(pids: ReadonlyArray<number>): Map<number, number> {
60
+ const result = spawnSync(lane_reap.PS_COMMAND, [...GROUP_ARGUMENTS, pids.join(PID_SEPARATOR)], {
61
+ encoding: 'utf8',
62
+ timeout: PROBE_TIMEOUT_MS,
63
+ stdio: ['ignore', 'pipe', 'ignore'],
64
+ })
65
+
66
+ return parse_groups(result.stdout)
67
+ }
68
+
69
+ const SYSTEM_PROBES: ResidentProbes = {
70
+ directories: () => process_directories.list_all(),
71
+ marks: () => process_lane_marks.list_all(),
72
+ own: () => lane_reap.own_ancestry(),
73
+ groups_of,
74
+ terminate: (pid) => lane_reap.SYSTEM_PROBES.terminate(pid),
75
+ }
76
+
77
+ // The candidates outside the caller's process group. The caller's own group unread spares nothing
78
+ // more: its ancestry is spared regardless.
79
+ function outside_own_group(candidates: Array<number>, probes: ResidentProbes): Array<number> {
80
+ if (candidates.length === 0) return candidates
81
+ const groups = probes.groups_of([process.pid, ...candidates])
82
+ const own_group = groups.get(process.pid)
83
+
84
+ return candidates.filter((pid) => own_group === undefined || groups.get(pid) !== own_group)
85
+ }
86
+
87
+ // Every process running from the lane's directory or carrying its mark, once each.
88
+ function lane_processes(
89
+ lane: ResidentLane,
90
+ directories: ReadonlyMap<number, string>,
91
+ marks: ReadonlyMap<number, string>,
92
+ ): Array<number> {
93
+ const root = path.dirname(lane.directory)
94
+ const within = [...directories]
95
+ .filter(([, cwd]) => process_directories.lane_of(cwd, root) === lane.issue)
96
+ .map(([pid]) => pid)
97
+ const marked = [...marks].filter(([, issue]) => issue === lane.issue).map(([pid]) => pid)
98
+
99
+ return [...new Set([...within, ...marked])]
100
+ }
101
+
102
+ /**
103
+ * The processes running from `lane`'s directory or carrying its mark, the caller's ancestry and process
104
+ * group left out; `undefined` where the working directories or the marks could not be read.
105
+ */
106
+ function residents(
107
+ lane: ResidentLane,
108
+ probes: ResidentProbes = SYSTEM_PROBES,
109
+ ): Array<number> | undefined {
110
+ const directories = probes.directories()
111
+ const marks = probes.marks()
112
+
113
+ if (directories === undefined || marks === undefined) return undefined
114
+ const own = probes.own()
115
+ const candidates = lane_processes(lane, directories, marks).filter((pid) => !own.has(pid))
116
+
117
+ return outside_own_group(candidates, probes)
118
+ }
119
+
120
+ /**
121
+ * Terminate the processes still running from `lane`'s directory or carrying its mark, except `spared`
122
+ * — what the close already ended. Returns the pids the signal reached, `undefined` where they could
123
+ * not be read.
124
+ */
125
+ function end_residents(
126
+ lane: ResidentLane,
127
+ spared: ReadonlyArray<number>,
128
+ probes: ResidentProbes = SYSTEM_PROBES,
129
+ ): Array<number> | undefined {
130
+ return residents(lane, probes)
131
+ ?.filter((pid) => !spared.includes(pid))
132
+ .filter((pid) => probes.terminate(pid))
133
+ }
134
+
135
+ /**
136
+ * What `end_residents` did, said for the issue `cited`; `undefined` when nothing of the lane still ran.
137
+ * A reading that failed is said, never read as none.
138
+ */
139
+ function residents_sentence(
140
+ ended: ReadonlyArray<number> | undefined,
141
+ cited: string,
142
+ ): string | undefined {
143
+ if (ended === undefined) {
144
+ return `Could not read which processes still run from the lane for ${cited} (lsof or ps failed); none of them was ended.`
145
+ }
146
+
147
+ if (ended.length === 0) return undefined
148
+
149
+ return `Terminated ${String(ended.length)} process(es) still running from the lane for ${cited}: ${ended.join(', ')}.`
150
+ }
151
+
152
+ /** Print `residents_sentence` to stderr, where a close reports what it ended. */
153
+ function report(ended: ReadonlyArray<number> | undefined, cited: string): void {
154
+ const sentence = residents_sentence(ended, cited)
155
+
156
+ if (sentence !== undefined) console.error(sentence)
157
+ }
158
+
159
+ const lane_residents = { end_residents, parse_groups, report, residents, residents_sentence }
160
+
161
+ export type { ResidentLane, ResidentProbes }
162
+ export { lane_residents }
@@ -1,3 +1,4 @@
1
+ import { git_stash } from '#scripts/git/stash/git-stash'
1
2
  import { issue_cite } from '#scripts/issue/issue-cite'
2
3
  import { IN_PROGRESS_LABEL } from '#scripts/issue/issue-labels'
3
4
  import { issue_number_shape } from '#scripts/issue/issue-number-shape'
@@ -9,13 +10,14 @@ import { lane_dispatch, type DispatchOutcome } from './lane-dispatch'
9
10
  import { lane_preserve, type KeptWork } from './lane-preserve'
10
11
  import { lane_reap } from './lane-reap'
11
12
  import { lane_registry, type LaneInfo } from './lane-registry'
13
+ import { lane_residents } from './lane-residents'
12
14
 
13
15
  // `josh lane:restart <N>` — a person stops a running lane child and starts its issue over in a fresh
14
16
  // session, typically after correcting the Issue's specification mid-run.
15
17
  //
16
18
  // **The restart is a hand-off inside the parent's re-confirm window, not a recovery.** Killing the child
17
19
  // alone would let `lane:await` book it stopped and `run:merge` classify it — an `outage` resumes the old
18
- // session with the old specification in mind, anything else is parked `needs-decision` and counted as a
20
+ // session with the old specification in mind, anything else is parked `run:stalled` and counted as a
19
21
  // failure. `run:cut` already hands a lane to a new process inside `lane:await`'s re-confirm window, so a
20
22
  // child that disappears and reappears under the same `fullrun #<N>` pattern is never collected: the
21
23
  // restart stops, stashes and re-dispatches within that window, and no failure or outage is counted.
@@ -35,6 +37,7 @@ const DISPATCHED_KIND = 'dispatched'
35
37
  const NO_LANE_KIND = 'no-lane'
36
38
  const NOT_RUNNING_KIND = 'not-running'
37
39
  const UNCLAIMED_KIND = 'unclaimed'
40
+ const CONFLICTED_KIND = 'conflicted'
38
41
 
39
42
  type Unsaved = Extract<KeptWork, { kind: 'unsaved' }>
40
43
 
@@ -48,6 +51,7 @@ type Refused =
48
51
  | { kind: typeof NO_LANE_KIND }
49
52
  | { kind: typeof NOT_RUNNING_KIND }
50
53
  | { kind: typeof UNCLAIMED_KIND; reason: string }
54
+ | { kind: typeof CONFLICTED_KIND; directory: string }
51
55
  type RestartOutcome = Restarted | Unsaved | Refused
52
56
 
53
57
  // A cut the stopped child carried would hand its successor the old session's hand-off at
@@ -85,12 +89,19 @@ async function relaunch(lane: LaneInfo): Promise<RestartOutcome> {
85
89
 
86
90
  // A child that ended on its own during the claim (say, right after merging its PR) is a finished child
87
91
  // for `run:merge` to collect — relaunching it would re-run a done issue inside the re-confirm window.
92
+ // What the stopped child started outside its tree goes with it, so the fresh session starts beside none
93
+ // of it (`lane-residents.ts`).
88
94
  async function stop_and_relaunch(lane: LaneInfo): Promise<RestartOutcome> {
89
- if (lane_reap.reap_child(lane.issue).length === 0) return { kind: NOT_RUNNING_KIND }
95
+ const reaped = lane_reap.reap_child(lane)
96
+
97
+ if (reaped.length === 0) return { kind: NOT_RUNNING_KIND }
98
+ lane_residents.report(lane_residents.end_residents(lane, reaped), session_cite.issue(lane.issue))
90
99
 
91
100
  return await relaunch(lane)
92
101
  }
93
102
 
103
+ // A tree with unresolved conflicts (a sync's merge stopped mid-way) cannot be stashed, so it is refused
104
+ // before the stop — stopping first would strand the lane with no child and nothing re-dispatched.
94
105
  /** Stop the running child of `#<N>`'s lane and re-dispatch the issue there in a fresh session. */
95
106
  async function restart(issue: string): Promise<RestartOutcome> {
96
107
  issue_number_shape.require_issue_number(issue)
@@ -98,6 +109,11 @@ async function restart(issue: string): Promise<RestartOutcome> {
98
109
 
99
110
  if (lane === undefined) return { kind: NO_LANE_KIND }
100
111
  if (!lane_reap.is_child_running(issue)) return { kind: NOT_RUNNING_KIND }
112
+
113
+ if (await git_stash.has_conflict(lane.directory)) {
114
+ return { kind: CONFLICTED_KIND, directory: lane.directory }
115
+ }
116
+
101
117
  const claim = await lane_dispatch.claim_marker(issue)
102
118
 
103
119
  if (!claim.is_applied) return { kind: UNCLAIMED_KIND, reason: claim.reason }
@@ -133,6 +149,10 @@ function refused_text(outcome: Refused, issue: string): string {
133
149
  return `No lane is open for ${cited}, so there is no child to restart.`
134
150
  }
135
151
 
152
+ if (outcome.kind === CONFLICTED_KIND) {
153
+ return `The lane for ${cited} has unresolved conflicts, which \`git stash\` cannot keep, so the running child was left as it is — nothing was stopped or re-dispatched. Resolve them, or run \`git -C ${outcome.directory} merge --abort\`, then run \`pnpm josh lane:restart ${issue}\` again.`
154
+ }
155
+
136
156
  if (outcome.kind === UNCLAIMED_KIND) {
137
157
  return `The \`${IN_PROGRESS_LABEL}\` label could not be confirmed on ${cited} (${outcome.reason}), so the running child was left as it is — nothing was stopped or re-dispatched.`
138
158
  }
@@ -0,0 +1,49 @@
1
+ import { lane_ledger, type LedgerEntry, type RoundTwoEntry } from './lane-ledger'
2
+ import { lane_stats, type StatsWindow } from './lane-stats'
3
+
4
+ // Why round 2 ran or was skipped: the ledger's `round-two` entries of one period reduced to one row per
5
+ // verdict and reason code, printed by `josh lane:stats` so the next change — to the procedure, or to
6
+ // what counts as an inert fix — is chosen from counts rather than impressions (joshuafolkken/kit#4064).
7
+
8
+ const COLUMNS = ['round 2', 'code', 'decisions'] as const
9
+ const KEY_SEPARATOR = ' '
10
+ // A period with no decision: the table still prints, so a reader sees zero rather than no table.
11
+ const NONE_ROW = ['none', 'none', '0']
12
+
13
+ function is_round_two(entry: LedgerEntry): entry is RoundTwoEntry {
14
+ return entry.kind === lane_ledger.KIND.ROUND_TWO
15
+ }
16
+
17
+ function counts_of(decisions: ReadonlyArray<RoundTwoEntry>): Map<string, number> {
18
+ const counts = new Map<string, number>()
19
+
20
+ for (const decision of decisions) {
21
+ const key = `${decision.verdict}${KEY_SEPARATOR}${decision.code}`
22
+
23
+ counts.set(key, (counts.get(key) ?? 0) + 1)
24
+ }
25
+
26
+ return counts
27
+ }
28
+
29
+ // The most frequent pair first, so the reason worth acting on leads.
30
+ function rows_of(counts: ReadonlyMap<string, number>): Array<string> {
31
+ return [...counts]
32
+ .toSorted(([, left], [, right]) => right - left)
33
+ .map(([key, count]) => lane_stats.to_row([...key.split(KEY_SEPARATOR), String(count)]))
34
+ }
35
+
36
+ // The period's table: `entries` is the whole ledger, filtered here to `window`.
37
+ function table(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow): string {
38
+ const rows = rows_of(counts_of(lane_stats.in_window(entries, window).filter(is_round_two)))
39
+
40
+ return [
41
+ lane_stats.to_row(COLUMNS),
42
+ lane_stats.to_row(COLUMNS.map(() => '---')),
43
+ ...(rows.length === 0 ? [lane_stats.to_row(NONE_ROW)] : rows),
44
+ ].join('\n')
45
+ }
46
+
47
+ const lane_round_two_stats = { table }
48
+
49
+ export { lane_round_two_stats }
@@ -14,6 +14,10 @@ const SAMPLE_INTERVAL_MS = 60_000
14
14
  // Where the ledger is and what "now" is, overridable so a test reads a fixed ledger at a fixed instant.
15
15
  interface MeasureContext {
16
16
  ledger_path?: string
17
+ // The run's event stream `lane:stats` reads parks from; absent, the repository's own.
18
+ events_path?: string
19
+ // The lane transcript directories `lane:stats` reads tool calls from; absent, this repository's lanes'.
20
+ transcript_directories?: ReadonlyArray<string>
17
21
  now_ms?: number
18
22
  }
19
23
 
@@ -1,10 +1,12 @@
1
1
  import { agent_argv } from '#scripts/agent/agent-argv'
2
2
  import { agent_role_profile, type AgentProvider } from '#scripts/agent/agent-role-profile'
3
+ import { api_auth } from '#scripts/agent/api-auth'
3
4
  import { stamp_file } from '#scripts/josh/stamp-file'
4
5
  import { error_text } from '#scripts/lib/error-message'
5
6
  import { detached_launch, type AttachedLaunchResult } from '#scripts/run/detached-launch'
6
7
  import { run_ship_review } from '#scripts/run/ship/run-ship-review'
7
8
  import { run_ship_stage } from '#scripts/run/ship/run-ship-stage'
9
+ import { run_ship_stop_cause } from '#scripts/run/ship/run-ship-stop-cause'
8
10
  import { run_ship_stop_context } from '#scripts/run/ship/run-ship-stop-context'
9
11
  import { z } from 'zod'
10
12
  import { lane_child_invocation, type ShipStop } from './lane-child-invocation'
@@ -29,6 +31,8 @@ const stop_schema = z
29
31
  flags: z.array(z.string()).readonly(),
30
32
  is_review: z.boolean(),
31
33
  conflicts: z.array(z.string()).readonly().default([]),
34
+ cause: z.enum(run_ship_stop_cause.CAUSE).exactOptional(),
35
+ is_review_stale: z.boolean().exactOptional(),
32
36
  context: run_ship_stop_context.stop_context_schema.exactOptional(),
33
37
  })
34
38
  .strict()
@@ -74,12 +78,22 @@ function review_prompt(lane: LaneInfo, round: ReviewRound): string {
74
78
  return `${prompt_of(target.brief, target.findings, lane.issue)} This is ${tail}`
75
79
  }
76
80
 
77
- function reviewer_answer(result: AttachedLaunchResult): BrokerAnswer {
81
+ // **A reviewer that could not authenticate names it** with `api_auth.AUTH_FAILURE_NOTE`, read off its
82
+ // log's exit record, so the ship stop is not booked as a review finding (joshuafolkken/kit#4216).
83
+ function exited_answer(exit_code: number | null, log_path: string): BrokerAnswer {
84
+ const exited = `the reviewer exited with code ${String(exit_code)}`
85
+
86
+ if (!api_auth.is_auth_failed_transcript(stamp_file.read_stamp_text(log_path))) {
87
+ return failure(exited)
88
+ }
89
+
90
+ return failure(`${api_auth.AUTH_FAILURE_NOTE}: ${exited}`)
91
+ }
92
+
93
+ function reviewer_answer(result: AttachedLaunchResult, log_path: string): BrokerAnswer {
78
94
  if (result.kind === 'failed') return failure(`the reviewer could not start: ${result.note}`)
79
95
 
80
- return result.exit_code === 0
81
- ? SUCCESS
82
- : failure(`the reviewer exited with code ${String(result.exit_code)}`)
96
+ return result.exit_code === 0 ? SUCCESS : exited_answer(result.exit_code, log_path)
83
97
  }
84
98
 
85
99
  async function launch_review(lane: LaneInfo, round: ReviewRound): Promise<BrokerAnswer> {
@@ -103,7 +117,7 @@ async function launch_review(lane: LaneInfo, round: ReviewRound): Promise<Broker
103
117
  console.error,
104
118
  )
105
119
 
106
- return reviewer_answer(result)
120
+ return reviewer_answer(result, target.log)
107
121
  }
108
122
 
109
123
  // An OpenAI lane's successor is its supervisor's to start, never a relaunch's.