@joshuafolkken/kit 1.1229.0 → 1.1370.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (939) hide show
  1. package/.claude/agents/investigator.md +1 -0
  2. package/.claude/settings.json +4 -0
  3. package/.claude/skills/dependency-update/SKILL.md +5 -3
  4. package/.claude/skills/epic-commands/SKILL.md +82 -113
  5. package/.claude/skills/epic-commands/epic-bundle.md +38 -63
  6. package/.claude/skills/epic-commands/execution-waves.md +30 -51
  7. package/.claude/skills/verify-ui/SKILL.md +13 -20
  8. package/.claude/skills/workflow-commands/SKILL.md +10 -10
  9. package/.claude/skills/workflow-commands/background-commands.md +4 -4
  10. package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
  11. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
  12. package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
  13. package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
  14. package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
  15. package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
  16. package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
  17. package/.claude/skills/workflow-commands/backlogrun.md +50 -61
  18. package/.claude/skills/workflow-commands/chain-rule.md +36 -40
  19. package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
  20. package/.claude/skills/workflow-commands/followup.md +24 -20
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
  22. package/.claude/skills/workflow-commands/fullrun.md +10 -10
  23. package/.claude/skills/workflow-commands/halfrun.md +9 -8
  24. package/.claude/skills/workflow-commands/into-target.md +12 -18
  25. package/.claude/skills/workflow-commands/issue-comments.md +11 -26
  26. package/.claude/skills/workflow-commands/kickoff.md +27 -16
  27. package/.claude/skills/workflow-commands/latest-gate.md +18 -29
  28. package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
  29. package/.claude/skills/workflow-commands/observation-filing.md +37 -28
  30. package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
  31. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
  32. package/.claude/skills/workflow-commands/prerequisite.md +23 -15
  33. package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
  34. package/.claude/skills/workflow-commands/prrun.md +3 -3
  35. package/.claude/skills/workflow-commands/retrospective.md +13 -18
  36. package/.claude/skills/workflow-commands/split-assessment.md +6 -4
  37. package/.claude/skills/workflow-commands/target-repository.md +25 -28
  38. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
  39. package/.gitattributes +2 -1
  40. package/.github/workflows/ci.yml +14 -0
  41. package/.github/workflows/publish.yml +2 -0
  42. package/.vscode/tasks.json +14 -0
  43. package/CLAUDE.md +10 -61
  44. package/README.md +38 -57
  45. package/SECURITY.md +1 -1
  46. package/dist/CLAUDE.md +10 -61
  47. package/dist/commands/document-section-cli.js +42 -10
  48. package/dist/config-merge/index.js +11 -2
  49. package/dist/hooks/audit-provision.js +2 -2
  50. package/dist/hooks/batch-guard.js +7 -7
  51. package/dist/hooks/{chunk-FIVDHQGT.js → chunk-43G45XJF.js} +18 -20
  52. package/dist/hooks/{chunk-JUDKDCDP.js → chunk-4TW4MQUL.js} +284 -362
  53. package/dist/hooks/{chunk-5VMKCCC4.js → chunk-76RK6E3H.js} +13 -11
  54. package/dist/hooks/{chunk-RNWHN5BP.js → chunk-DZWZ3DKY.js} +4 -4
  55. package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
  56. package/dist/hooks/{chunk-VC3PZPZO.js → chunk-GG72ANKI.js} +1 -1
  57. package/dist/hooks/{chunk-6HJJXRBX.js → chunk-KPM4YIIX.js} +8 -44
  58. package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
  59. package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
  60. package/dist/hooks/{chunk-TQNPDZNH.js → chunk-NZBHG6FW.js} +7 -5
  61. package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
  62. package/dist/hooks/{chunk-F56MFS4B.js → chunk-R6CRQEAL.js} +4 -4
  63. package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
  64. package/dist/hooks/{chunk-55HHG5PX.js → chunk-TLJYAGZK.js} +799 -903
  65. package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
  66. package/dist/hooks/codex-hook-adapter.js +26 -21
  67. package/dist/hooks/duplicate-read-guard.js +8 -8
  68. package/dist/hooks/format-edited.js +4 -4
  69. package/dist/hooks/inputs.json +213 -197
  70. package/dist/hooks/investigation-guard.js +8 -8
  71. package/dist/hooks/pretool-guard.js +15 -15
  72. package/dist/hooks/session-lang.js +406 -8
  73. package/dist/hooks/stop-guard.js +122 -201
  74. package/dist/josh.js +540 -137
  75. package/dist/version/index.js +15 -13
  76. package/eslint/base.js +43 -5
  77. package/eslint/rules/english-only-prose.js +3 -3
  78. package/eslint/rules/import.js +12 -0
  79. package/eslint/rules/namespace-object-export.js +2 -2
  80. package/package.json +16 -10
  81. package/pnpm-workspace.yaml +2 -4
  82. package/prompts/coding-standards.md +14 -48
  83. package/prompts/collaboration-workflow/file-edits.md +1 -1
  84. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  85. package/prompts/collaboration-workflow/issue-template.md +4 -10
  86. package/prompts/collaboration-workflow/operating-rules.md +7 -8
  87. package/prompts/collaboration-workflow/output-bounds.md +1 -1
  88. package/prompts/collaboration-workflow/overview.md +1 -1
  89. package/prompts/collaboration-workflow/plan-comment.md +2 -1
  90. package/prompts/collaboration-workflow/principles.md +21 -3
  91. package/prompts/collaboration-workflow/report-format.md +16 -29
  92. package/prompts/collaboration-workflow/residency.md +1 -1
  93. package/prompts/collaboration-workflow/rule-delivery.md +7 -95
  94. package/prompts/collaboration-workflow/shell-body.md +3 -23
  95. package/prompts/collaboration-workflow/turn-batching.md +4 -13
  96. package/prompts/collaboration-workflow/wip-cap.md +5 -11
  97. package/prompts/refactoring.md +1 -1
  98. package/prompts/review-rubric.md +3 -22
  99. package/prompts/review.md +15 -38
  100. package/prompts/testing-guide.md +2 -4
  101. package/scripts/adopt/adopt-logic.ts +5 -5
  102. package/scripts/adopt/adopt-toolkits.ts +4 -5
  103. package/scripts/adopt/adopt.ts +2 -3
  104. package/scripts/agent/agent-argv.ts +7 -7
  105. package/scripts/agent/agent-diagnostics.ts +2 -2
  106. package/scripts/agent/agent-exit-record.ts +1 -1
  107. package/scripts/agent/agent-headless.ts +1 -1
  108. package/scripts/agent/agent-launch-environment.ts +6 -1
  109. package/scripts/agent/agent-role-profile.ts +49 -22
  110. package/scripts/agent/agent-session-role.ts +32 -0
  111. package/scripts/agent/api-outage.ts +1 -1
  112. package/scripts/agent/claude-agent-argv.ts +4 -4
  113. package/scripts/agent/claude-result-event.ts +4 -4
  114. package/scripts/agent/codex-hooks.ts +2 -2
  115. package/scripts/agent/interactive-ask.ts +3 -6
  116. package/scripts/auto-ok/auto-ok-cli.ts +46 -60
  117. package/scripts/backlog/backlog-arrival-added.ts +34 -0
  118. package/scripts/backlog/backlog-arrival.ts +54 -17
  119. package/scripts/backlog/backlog-budget-cli.ts +34 -6
  120. package/scripts/backlog/backlog-budget.ts +17 -24
  121. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  122. package/scripts/backlog/backlog-drive-args.ts +5 -4
  123. package/scripts/backlog/backlog-drive-cli.ts +14 -10
  124. package/scripts/backlog/backlog-drive-epic.ts +85 -0
  125. package/scripts/backlog/backlog-drive-launch.ts +1 -1
  126. package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
  127. package/scripts/backlog/backlog-drive-named.ts +39 -9
  128. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  129. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  130. package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
  131. package/scripts/backlog/backlog-drive.ts +43 -28
  132. package/scripts/backlog/backlog-idle.ts +88 -0
  133. package/scripts/backlog/backlog-named.ts +11 -15
  134. package/scripts/backlog/backlog-next.ts +26 -30
  135. package/scripts/backlog/backlog-offer-cli.ts +28 -23
  136. package/scripts/backlog/backlog-offer.ts +7 -7
  137. package/scripts/backlog/backlog-overlap.ts +178 -0
  138. package/scripts/backlog/backlog-plan-cli.ts +14 -90
  139. package/scripts/backlog/backlog-plan-read.ts +111 -0
  140. package/scripts/backlog/backlog-plan.ts +11 -10
  141. package/scripts/backlog/backlog-pool.ts +13 -14
  142. package/scripts/backlog/backlog-rank.ts +11 -11
  143. package/scripts/backlog/backlog-ready.ts +15 -10
  144. package/scripts/backlog/backlog-scope.ts +14 -15
  145. package/scripts/backlog/backlog-stalled-cli.ts +2 -2
  146. package/scripts/backlog/backlog-stalled-detect.ts +4 -4
  147. package/scripts/backlog/backlog-stalled.ts +5 -6
  148. package/scripts/backlog/backlog-waves.ts +4 -4
  149. package/scripts/backlog/backlogrun-args.ts +74 -0
  150. package/scripts/backlog/backlogrun-cli.ts +113 -0
  151. package/scripts/backlog/backlogrun-launch.ts +178 -0
  152. package/scripts/behavior/behavior-assertion.ts +6 -8
  153. package/scripts/behavior/behavior-cli.ts +1 -1
  154. package/scripts/behavior/behavior-rules.ts +3 -3
  155. package/scripts/build/build-claude-md.ts +4 -4
  156. package/scripts/build/build-codex-hooks.ts +2 -2
  157. package/scripts/build/build-commands.ts +1 -1
  158. package/scripts/build/build-hooks.ts +5 -5
  159. package/scripts/build/build.ts +1 -1
  160. package/scripts/build/hook-bundle-stamp.ts +109 -7
  161. package/scripts/build/local-bin.ts +2 -2
  162. package/scripts/cases/cases-cli.ts +1 -1
  163. package/scripts/cases/cases-logic.ts +2 -2
  164. package/scripts/ci/composite-actions.ts +1 -2
  165. package/scripts/ci/pr-classification.ts +2 -2
  166. package/scripts/claude/workflow-destination.ts +1 -1
  167. package/scripts/clone/clone-aggregate.ts +1 -1
  168. package/scripts/clone/clone-fingerprint.ts +1 -1
  169. package/scripts/clone/clone-scan-cli.ts +1 -1
  170. package/scripts/clone/clone-scan.ts +1 -1
  171. package/scripts/config-merge/index.ts +1 -1
  172. package/scripts/config-merge/json-format.ts +1 -3
  173. package/scripts/config-merge/patch-json-array.ts +90 -0
  174. package/scripts/config-merge/patch-json-key.ts +6 -3
  175. package/scripts/config-merge/patch-json-list.ts +1 -1
  176. package/scripts/cost-runtime/codex-usage.ts +1 -1
  177. package/scripts/cost-runtime/context-cut-payback.ts +4 -5
  178. package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
  179. package/scripts/cost-runtime/cost-attribute.ts +3 -3
  180. package/scripts/cost-runtime/cost-blocks.ts +3 -4
  181. package/scripts/cost-runtime/cost-cli.ts +14 -11
  182. package/scripts/cost-runtime/cost-corpus.ts +11 -11
  183. package/scripts/cost-runtime/cost-pricing.ts +4 -4
  184. package/scripts/cost-runtime/cost-tokens.ts +1 -2
  185. package/scripts/cost-runtime/cost-transcript.ts +29 -29
  186. package/scripts/cost-runtime/cost-usage.ts +6 -7
  187. package/scripts/cost-runtime/cost-verdict.ts +10 -11
  188. package/scripts/cost-runtime/own-session.ts +1 -1
  189. package/scripts/cost-runtime/transcript-cwd.ts +2 -2
  190. package/scripts/delegation/delegation-cli.ts +4 -4
  191. package/scripts/delegation/delegation-policy.ts +13 -15
  192. package/scripts/delegation/duplicate-read-guard.ts +9 -10
  193. package/scripts/delegation/fanout-cli.ts +1 -1
  194. package/scripts/delegation/fanout.ts +1 -1
  195. package/scripts/delegation/investigation-guard.ts +18 -22
  196. package/scripts/delegation/investigation-reads.ts +48 -238
  197. package/scripts/discovery/repo-discovery.ts +1 -1
  198. package/scripts/discovery/repo-map-logic.ts +1 -2
  199. package/scripts/discovery/repo-origin.ts +3 -3
  200. package/scripts/discovery/repo-party-cli.ts +2 -2
  201. package/scripts/discovery/repo-party.ts +2 -2
  202. package/scripts/doctor/doctor-consumer.ts +1 -1
  203. package/scripts/doctor/doctor-io.ts +6 -7
  204. package/scripts/doctor/doctor-logic.ts +1 -1
  205. package/scripts/doctor/doctor-ports.ts +1 -1
  206. package/scripts/doctor/doctor.ts +8 -9
  207. package/scripts/document/backlogrun-parent-read-set.ts +5 -6
  208. package/scripts/document/bash-output-cap.ts +5 -7
  209. package/scripts/document/capped-print-part.ts +1 -1
  210. package/scripts/document/capped-print.ts +1 -1
  211. package/scripts/document/document-byte-budget.ts +33 -64
  212. package/scripts/document/document-byte-check.ts +4 -4
  213. package/scripts/document/document-reachability.ts +7 -8
  214. package/scripts/document/document-read-cli.ts +2 -2
  215. package/scripts/document/document-scan.ts +26 -2
  216. package/scripts/document/document-section-cli.ts +6 -8
  217. package/scripts/document/document-section.ts +8 -12
  218. package/scripts/document/edit-files-cli.ts +3 -4
  219. package/scripts/document/entry-read-budget.ts +8 -70
  220. package/scripts/document/entry-read-set.ts +51 -34
  221. package/scripts/document/lane-child-read-set.ts +9 -9
  222. package/scripts/document/read-files-cli.ts +1 -2
  223. package/scripts/document/read-set-cli.ts +16 -19
  224. package/scripts/document/read-set-cost.ts +4 -4
  225. package/scripts/document/read-set-point-of-use.ts +28 -38
  226. package/scripts/document/read-set-pricing.ts +1 -1
  227. package/scripts/document/read-set-trim.ts +3 -3
  228. package/scripts/document/resident-budget.ts +8 -10
  229. package/scripts/epic/epic-add-body.ts +15 -18
  230. package/scripts/epic/epic-add-plan.ts +26 -28
  231. package/scripts/epic/epic-add.ts +32 -25
  232. package/scripts/epic/epic-audit-checks.ts +27 -37
  233. package/scripts/epic/epic-audit-cli.ts +21 -22
  234. package/scripts/epic/epic-audit-orphans.ts +16 -17
  235. package/scripts/epic/epic-audit-rationale.ts +10 -15
  236. package/scripts/epic/epic-audit-report.ts +2 -5
  237. package/scripts/epic/epic-audit.ts +18 -14
  238. package/scripts/epic/epic-body.ts +10 -10
  239. package/scripts/epic/epic-bundle-cli.ts +36 -34
  240. package/scripts/epic/epic-bundle-evidence.ts +5 -5
  241. package/scripts/epic/epic-bundle-gaps.ts +6 -9
  242. package/scripts/epic/epic-bundle-poll.ts +1 -1
  243. package/scripts/epic/epic-bundle-referenced.ts +11 -14
  244. package/scripts/epic/epic-bundle.ts +19 -20
  245. package/scripts/epic/epic-busy.ts +44 -21
  246. package/scripts/epic/epic-candidate-confirm.ts +15 -18
  247. package/scripts/epic/epic-chains.ts +18 -23
  248. package/scripts/epic/epic-classify.ts +11 -12
  249. package/scripts/epic/epic-cli-argv.ts +5 -6
  250. package/scripts/epic/epic-cli-remove.ts +9 -4
  251. package/scripts/epic/epic-cli.ts +38 -26
  252. package/scripts/epic/epic-close-comment.ts +14 -15
  253. package/scripts/epic/epic-close.ts +25 -29
  254. package/scripts/epic/epic-cross-repo.ts +18 -21
  255. package/scripts/epic/epic-decision.ts +14 -18
  256. package/scripts/epic/epic-fetch.ts +25 -31
  257. package/scripts/epic/epic-graph.ts +15 -17
  258. package/scripts/epic/epic-index.ts +14 -16
  259. package/scripts/epic/epic-issue.ts +9 -11
  260. package/scripts/epic/epic-label-age.ts +74 -0
  261. package/scripts/epic/epic-lane-offer.ts +35 -24
  262. package/scripts/epic/epic-nested.ts +1 -1
  263. package/scripts/epic/epic-next-read.ts +8 -8
  264. package/scripts/epic/epic-next-views.ts +12 -12
  265. package/scripts/epic/epic-next.ts +29 -33
  266. package/scripts/epic/epic-outside-blocker.ts +11 -10
  267. package/scripts/epic/epic-parse.ts +22 -24
  268. package/scripts/epic/epic-promote.ts +3 -2
  269. package/scripts/epic/epic-rank.ts +1 -1
  270. package/scripts/epic/epic-read.ts +10 -8
  271. package/scripts/epic/epic-reconcile.ts +8 -6
  272. package/scripts/epic/epic-reference.ts +5 -4
  273. package/scripts/epic/epic-relation-recheck.ts +10 -11
  274. package/scripts/epic/epic-relations.ts +9 -8
  275. package/scripts/epic/epic-remove-plan.ts +4 -5
  276. package/scripts/epic/epic-remove.ts +7 -5
  277. package/scripts/epic/epic-report.ts +18 -20
  278. package/scripts/epic/epic-run.ts +6 -5
  279. package/scripts/epic/epic-sections.ts +2 -2
  280. package/scripts/epic/epic-shape.ts +3 -3
  281. package/scripts/epic/epic-solo-stale.ts +3 -2
  282. package/scripts/epic/epic-solo.ts +8 -8
  283. package/scripts/epic/epic-triage.ts +5 -4
  284. package/scripts/epic/epic-validate.ts +8 -7
  285. package/scripts/epic/epic.ts +5 -5
  286. package/scripts/exports/unused-members-cli.ts +1 -1
  287. package/scripts/followup/followup-issue-number.ts +1 -2
  288. package/scripts/followup/git-followup-cleanup.ts +6 -7
  289. package/scripts/followup/git-followup-finish.ts +11 -13
  290. package/scripts/followup/git-followup-flush.ts +11 -7
  291. package/scripts/followup/git-followup-issue-close.ts +16 -13
  292. package/scripts/followup/git-followup-label.ts +9 -6
  293. package/scripts/followup/git-followup-merged.ts +1 -1
  294. package/scripts/followup/git-followup-pending.ts +7 -9
  295. package/scripts/followup/git-followup-stages.ts +28 -17
  296. package/scripts/followup/git-followup-workflow.ts +19 -21
  297. package/scripts/followup/git-pr-followup-checks.ts +13 -20
  298. package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
  299. package/scripts/followup/git-pr-followup.ts +18 -17
  300. package/scripts/gate/core-admission.ts +162 -0
  301. package/scripts/gate/core-budget.ts +134 -91
  302. package/scripts/gate/gate-ledger.ts +114 -0
  303. package/scripts/gate/gate-log.ts +7 -9
  304. package/scripts/gate/gate-plan.ts +103 -35
  305. package/scripts/gate/gate-report.ts +39 -21
  306. package/scripts/gate/gate-skip.ts +11 -13
  307. package/scripts/gate/gate-steps.ts +5 -1
  308. package/scripts/gate/gate-tree.ts +3 -4
  309. package/scripts/gate/hook-gate-reuse.ts +9 -9
  310. package/scripts/gate/machine-capacity.ts +313 -0
  311. package/scripts/gate/pre-commit-type-check.ts +4 -4
  312. package/scripts/gate/project-checks.ts +12 -4
  313. package/scripts/gate/scoped-green.ts +11 -18
  314. package/scripts/gate/type-check-command.ts +2 -2
  315. package/scripts/gate/type-check-step.ts +4 -4
  316. package/scripts/gate/verification-gate.ts +60 -53
  317. package/scripts/gh/gh-spawn.ts +2 -2
  318. package/scripts/gh/git-ai-review-scan.ts +3 -2
  319. package/scripts/gh/git-gh-api-path.ts +10 -11
  320. package/scripts/gh/git-gh-exec.ts +43 -48
  321. package/scripts/gh/git-gh-failure.ts +6 -9
  322. package/scripts/gh/git-gh-helpers.ts +1 -1
  323. package/scripts/gh/git-gh-issue-list.ts +15 -19
  324. package/scripts/gh/git-gh-issue-read.ts +43 -60
  325. package/scripts/gh/git-gh-issue-rest.ts +14 -15
  326. package/scripts/gh/git-gh-issue-write.ts +52 -40
  327. package/scripts/gh/git-gh-issue.ts +23 -24
  328. package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
  329. package/scripts/gh/git-gh-pr-read.ts +46 -50
  330. package/scripts/gh/git-gh-pr-rest.ts +23 -26
  331. package/scripts/gh/git-gh-pr-review.ts +2 -2
  332. package/scripts/gh/git-gh-pr-rollup.ts +4 -4
  333. package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
  334. package/scripts/gh/git-gh-pr.ts +16 -16
  335. package/scripts/gh/git-gh-reachability.ts +11 -12
  336. package/scripts/gh/git-gh-repo.ts +2 -3
  337. package/scripts/gh/git-gh-rest-state.ts +1 -1
  338. package/scripts/gh/git-pr-ai-review.ts +6 -5
  339. package/scripts/gh/git-pr-checks-eval.ts +28 -30
  340. package/scripts/gh/git-pr-checks-parse.ts +14 -16
  341. package/scripts/gh/git-pr-checks-watch.ts +17 -17
  342. package/scripts/gh/git-pr-checks.ts +20 -23
  343. package/scripts/gh/git-pr-coderabbit.ts +8 -6
  344. package/scripts/gh/git-pr-confirmation.ts +5 -5
  345. package/scripts/gh/git-pr-managed-config.ts +7 -9
  346. package/scripts/gh/git-pr-messages.ts +1 -1
  347. package/scripts/gh/git-pr.ts +15 -16
  348. package/scripts/gh/github-issue-url.ts +8 -9
  349. package/scripts/git/base-tree.ts +66 -0
  350. package/scripts/git/change-base.ts +42 -2
  351. package/scripts/git/changed-file-scope.ts +5 -5
  352. package/scripts/git/changed-paths.ts +1 -2
  353. package/scripts/git/constants.ts +2 -2
  354. package/scripts/git/git-branch.ts +1 -1
  355. package/scripts/git/git-closes-keyword.ts +3 -3
  356. package/scripts/git/git-command.ts +53 -41
  357. package/scripts/git/git-common-directory.ts +3 -3
  358. package/scripts/git/git-diff-reads.ts +14 -15
  359. package/scripts/git/git-error.ts +1 -1
  360. package/scripts/git/git-execa-error.ts +1 -2
  361. package/scripts/git/git-issue.ts +10 -8
  362. package/scripts/git/git-location-environment.ts +3 -4
  363. package/scripts/git/git-ls-remote.ts +6 -8
  364. package/scripts/git/git-pre-push-hook.ts +11 -10
  365. package/scripts/git/git-preflight.ts +5 -5
  366. package/scripts/git/git-push-transport.ts +2 -2
  367. package/scripts/git/git-remote-branch.ts +1 -2
  368. package/scripts/git/git-schemas.ts +16 -23
  369. package/scripts/git/git-spawn-sync.ts +1 -1
  370. package/scripts/git/git-spawn.ts +37 -14
  371. package/scripts/git/git-ssh-keepalive.ts +12 -5
  372. package/scripts/git/git-staging.ts +7 -8
  373. package/scripts/git/git-workflow.ts +1 -1
  374. package/scripts/git/git-worktree.ts +35 -27
  375. package/scripts/git/gone-branch.ts +2 -2
  376. package/scripts/git/listing-cutoff.ts +1 -2
  377. package/scripts/git/lockfile-sync.ts +65 -0
  378. package/scripts/git/main-merge-guard.ts +1 -2
  379. package/scripts/git/main-merge.ts +7 -7
  380. package/scripts/git/main-sync.ts +23 -8
  381. package/scripts/git/parse-json-array.ts +18 -23
  382. package/scripts/git/repository-lock.ts +34 -2
  383. package/scripts/git/stash/git-stash.ts +4 -5
  384. package/scripts/git/stash/stash-orphans.ts +5 -3
  385. package/scripts/git/stash/stash-pop-args.ts +1 -1
  386. package/scripts/git/stash/stash-pop-cli.ts +3 -3
  387. package/scripts/git/stash/stash-sweep-lock.ts +2 -2
  388. package/scripts/hooks/batch-guard.ts +11 -13
  389. package/scripts/hooks/check-commit-message.ts +12 -9
  390. package/scripts/hooks/codex-hook-adapter.ts +16 -10
  391. package/scripts/hooks/edited-cspell.ts +3 -4
  392. package/scripts/hooks/format-edited-cli.ts +1 -1
  393. package/scripts/hooks/format-edited-file.ts +11 -17
  394. package/scripts/hooks/format-rewrite-notice.ts +19 -17
  395. package/scripts/hooks/pre-push-unit.ts +10 -14
  396. package/scripts/hooks/pretool-guard-cli.ts +4 -4
  397. package/scripts/hooks/pretool-guard.ts +93 -18
  398. package/scripts/hooks/reserved-run.ts +2 -2
  399. package/scripts/hooks/step-zero-notice.ts +1 -1
  400. package/scripts/hooks/stop-guard.ts +21 -10
  401. package/scripts/init/basic-path-migration.ts +2 -2
  402. package/scripts/init/claude-kit-only-settings.ts +2 -2
  403. package/scripts/init/claude-plugin-config.ts +2 -2
  404. package/scripts/init/distributed-paths.ts +4 -4
  405. package/scripts/init/hook-command-rewrite.ts +3 -3
  406. package/scripts/init/hook-launch.ts +5 -5
  407. package/scripts/init/init-actions.ts +13 -0
  408. package/scripts/init/init-ai-copy.ts +11 -11
  409. package/scripts/init/init-bootstrap.ts +3 -3
  410. package/scripts/init/init-copy-content.ts +4 -4
  411. package/scripts/init/init-logic-json-merge.ts +7 -9
  412. package/scripts/init/init-logic-migrate.ts +1 -1
  413. package/scripts/init/init-logic-templates.ts +1 -1
  414. package/scripts/init/init-logic-workspace.ts +4 -4
  415. package/scripts/init/init-logic-yaml-merge.ts +2 -2
  416. package/scripts/init/init-logic.ts +19 -22
  417. package/scripts/init/init.ts +12 -8
  418. package/scripts/init/kit-base-preset.ts +1 -1
  419. package/scripts/init/kit-setup-state.ts +1 -1
  420. package/scripts/init/kit-written-paths.ts +1 -2
  421. package/scripts/init/package-manager-pin.ts +35 -0
  422. package/scripts/init/project-profile-cli.ts +1 -1
  423. package/scripts/init/project-profile.ts +3 -3
  424. package/scripts/init/session-language-environment.ts +1 -1
  425. package/scripts/init/start-exec.ts +3 -4
  426. package/scripts/init/start-plan.ts +2 -2
  427. package/scripts/init/start-setup-pr.ts +3 -2
  428. package/scripts/init/start-steps.ts +2 -2
  429. package/scripts/init/tsconfig-preset-migration.ts +1 -1
  430. package/scripts/init/vscode-tasks.ts +62 -0
  431. package/scripts/issue/baseline-measure.ts +2 -2
  432. package/scripts/issue/behavior-change-lint.ts +2 -2
  433. package/scripts/issue/defect-rate-cli.ts +6 -7
  434. package/scripts/issue/defect-rate.ts +37 -27
  435. package/scripts/issue/git-next-issues.ts +9 -8
  436. package/scripts/issue/issue-auto-ok.ts +49 -11
  437. package/scripts/issue/issue-backlinks-cli.ts +5 -5
  438. package/scripts/issue/issue-backlinks.ts +6 -6
  439. package/scripts/issue/issue-cite-cli.ts +20 -18
  440. package/scripts/issue/issue-cite.ts +18 -8
  441. package/scripts/issue/issue-closing-pr.ts +4 -4
  442. package/scripts/issue/issue-comment-cli.ts +6 -4
  443. package/scripts/issue/issue-file-cli.ts +75 -15
  444. package/scripts/issue/issue-file-fold.ts +155 -0
  445. package/scripts/issue/issue-file.ts +14 -6
  446. package/scripts/issue/issue-fold-cli.ts +14 -9
  447. package/scripts/issue/issue-fold.ts +23 -8
  448. package/scripts/issue/issue-labels.ts +46 -37
  449. package/scripts/issue/issue-lint-cli.ts +2 -2
  450. package/scripts/issue/issue-lint.ts +1 -1
  451. package/scripts/issue/issue-merged.ts +10 -4
  452. package/scripts/issue/issue-number-shape.ts +27 -0
  453. package/scripts/issue/issue-rank.ts +1 -1
  454. package/scripts/issue/issue-read-cli.ts +4 -5
  455. package/scripts/issue/issue-read.ts +4 -5
  456. package/scripts/issue/issue-reference.ts +5 -5
  457. package/scripts/issue/issue-release-cli.ts +165 -0
  458. package/scripts/issue/issue-release.ts +58 -0
  459. package/scripts/issue/issue-report-failures.ts +7 -4
  460. package/scripts/issue/issue-scout-cli.ts +11 -11
  461. package/scripts/issue/issue-scout-closed.ts +4 -4
  462. package/scripts/issue/issue-scout.ts +4 -5
  463. package/scripts/issue/issue-state-cli.ts +17 -10
  464. package/scripts/issue/issue-state.ts +12 -13
  465. package/scripts/issue/issue-wip.ts +7 -7
  466. package/scripts/issue/markdown-section.ts +3 -3
  467. package/scripts/issue/measure-rerun-cli.ts +10 -9
  468. package/scripts/issue/reproduction-measure.ts +3 -3
  469. package/scripts/issue/session-cite.ts +56 -0
  470. package/scripts/josh/agent-session-environment.ts +10 -8
  471. package/scripts/josh/cli-body.ts +2 -2
  472. package/scripts/josh/command-suggest.ts +1 -1
  473. package/scripts/josh/file-map-stamp.ts +20 -23
  474. package/scripts/josh/hook-decision.ts +24 -28
  475. package/scripts/josh/josh-command-map.ts +4 -1
  476. package/scripts/josh/josh-command-types.ts +32 -34
  477. package/scripts/josh/josh-commands-ai.ts +6 -6
  478. package/scripts/josh/josh-commands-backlog.ts +15 -3
  479. package/scripts/josh/josh-commands-clone.ts +1 -1
  480. package/scripts/josh/josh-commands-development.ts +33 -4
  481. package/scripts/josh/josh-commands-document.ts +3 -3
  482. package/scripts/josh/josh-commands-guard.ts +3 -3
  483. package/scripts/josh/josh-commands-issue.ts +11 -5
  484. package/scripts/josh/josh-commands-lane.ts +16 -5
  485. package/scripts/josh/josh-commands-lint.ts +1 -1
  486. package/scripts/josh/josh-commands-maintenance.ts +2 -2
  487. package/scripts/josh/josh-commands-run.ts +20 -6
  488. package/scripts/josh/josh-commands-split.ts +1 -2
  489. package/scripts/josh/josh-commands-versioning.ts +5 -5
  490. package/scripts/josh/josh-commands-workflow.ts +30 -22
  491. package/scripts/josh/josh-environment-file.ts +1 -1
  492. package/scripts/josh/josh-in-process.ts +3 -3
  493. package/scripts/josh/josh-logic.ts +10 -10
  494. package/scripts/josh/josh-run.ts +3 -3
  495. package/scripts/josh/josh-verdict.ts +9 -12
  496. package/scripts/josh/josh.ts +3 -3
  497. package/scripts/josh/kit-only.ts +2 -2
  498. package/scripts/josh/path-decision.ts +3 -3
  499. package/scripts/josh/platform-temporary.ts +7 -5
  500. package/scripts/josh/process-identity.ts +24 -6
  501. package/scripts/josh/process-owner.ts +4 -4
  502. package/scripts/josh/session-language-cli.ts +53 -11
  503. package/scripts/josh/session-language.ts +1 -1
  504. package/scripts/josh/stamp-file.ts +48 -29
  505. package/scripts/josh/stamp-record.ts +57 -0
  506. package/scripts/lane/lane-await.ts +35 -11
  507. package/scripts/lane/lane-cache.ts +6 -6
  508. package/scripts/lane/lane-capacity.ts +32 -17
  509. package/scripts/lane/lane-child-invocation.ts +17 -15
  510. package/scripts/lane/lane-child-marker.ts +12 -12
  511. package/scripts/lane/lane-cli.ts +20 -13
  512. package/scripts/lane/lane-close.ts +6 -6
  513. package/scripts/lane/lane-dispatch.ts +61 -72
  514. package/scripts/lane/lane-environment.ts +5 -5
  515. package/scripts/lane/lane-guard-policy.ts +7 -21
  516. package/scripts/lane/lane-handoff.ts +2 -2
  517. package/scripts/lane/lane-install.ts +9 -10
  518. package/scripts/lane/lane-launch-cli.ts +13 -8
  519. package/scripts/lane/lane-ledger.ts +73 -11
  520. package/scripts/lane/lane-leftover.ts +44 -30
  521. package/scripts/lane/lane-limit-cli.ts +160 -0
  522. package/scripts/lane/lane-limit-override.ts +74 -0
  523. package/scripts/lane/lane-load.ts +19 -68
  524. package/scripts/lane/lane-measure-cli.ts +15 -25
  525. package/scripts/lane/lane-occupancy.ts +6 -4
  526. package/scripts/lane/lane-open.ts +25 -24
  527. package/scripts/lane/lane-output.ts +4 -3
  528. package/scripts/lane/lane-paths.ts +22 -8
  529. package/scripts/lane/lane-phase.ts +33 -0
  530. package/scripts/lane/lane-reap.ts +2 -2
  531. package/scripts/lane/lane-registry.ts +27 -15
  532. package/scripts/lane/lane-relaunch.ts +9 -9
  533. package/scripts/lane/lane-report.ts +5 -4
  534. package/scripts/lane/lane-resume.ts +2 -2
  535. package/scripts/lane/lane-sampler.ts +55 -0
  536. package/scripts/lane/lane-seed.ts +7 -7
  537. package/scripts/lane/lane-stage-stats.ts +135 -0
  538. package/scripts/lane/lane-start-point.ts +8 -11
  539. package/scripts/lane/lane-stats.ts +60 -15
  540. package/scripts/lane/lane-stray.ts +140 -0
  541. package/scripts/lane/lane-vacant.ts +1 -1
  542. package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
  543. package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
  544. package/scripts/lane/openai-review-broker.ts +2 -4
  545. package/scripts/lib/ancestor-directories.ts +1 -1
  546. package/scripts/lib/bounded-pool.ts +2 -2
  547. package/scripts/lib/buffered-process.ts +4 -6
  548. package/scripts/lib/caddy-logs.sh +0 -0
  549. package/scripts/lib/cli-flags.ts +39 -6
  550. package/scripts/lib/error-message.ts +1 -1
  551. package/scripts/lib/json-value.ts +17 -3
  552. package/scripts/lib/poll.ts +1 -1
  553. package/scripts/lib/status-icons.ts +3 -3
  554. package/scripts/lib/timed-fetch.ts +1 -1
  555. package/scripts/lib/timeouts.ts +1 -1
  556. package/scripts/lines/bytes-command.ts +3 -4
  557. package/scripts/lines/effective-limit.ts +25 -12
  558. package/scripts/lines/line-budget.ts +47 -55
  559. package/scripts/lines/line-targets.ts +6 -2
  560. package/scripts/lines/lines-command.ts +3 -3
  561. package/scripts/lint/cspell-cached.ts +1 -1
  562. package/scripts/lint/cycle-recheck.ts +122 -0
  563. package/scripts/lint/format.ts +1 -2
  564. package/scripts/lint/lint-parallel.ts +34 -19
  565. package/scripts/lint/lint-related-scope.ts +25 -15
  566. package/scripts/lint/lint-related.ts +6 -7
  567. package/scripts/managed-marker/index.ts +1 -1
  568. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  569. package/scripts/notify/git-notify.ts +9 -7
  570. package/scripts/notify/telegram-notify.ts +53 -37
  571. package/scripts/notify/telegram-test-logic.ts +3 -3
  572. package/scripts/notify/telegram-test.ts +45 -30
  573. package/scripts/observations/observation-ledger-home.ts +14 -8
  574. package/scripts/observations/observation-ledger-line.ts +3 -2
  575. package/scripts/observations/observation-ledger-migrate.ts +3 -4
  576. package/scripts/observations/observation-ledger-prepare.ts +4 -4
  577. package/scripts/observations/observation-ledger.ts +14 -15
  578. package/scripts/observations/observation-record-cli.ts +83 -0
  579. package/scripts/observations/observation-record.ts +91 -0
  580. package/scripts/observations/observations-flush-cli.ts +1 -1
  581. package/scripts/observations/observations-flush-landing.ts +7 -6
  582. package/scripts/observations/observations-flush.ts +26 -27
  583. package/scripts/overrides/overrides-check.ts +18 -8
  584. package/scripts/package/package-scout-cli.ts +1 -1
  585. package/scripts/package/package-scout-format.ts +2 -2
  586. package/scripts/package/package-scout.ts +1 -1
  587. package/scripts/propagate/propagate-git-failure.ts +1 -1
  588. package/scripts/propagate/propagate-git.ts +7 -7
  589. package/scripts/propagate/propagate-plan.ts +2 -2
  590. package/scripts/propagate/propagate-publish.ts +2 -3
  591. package/scripts/propagate/propagate-run.ts +5 -7
  592. package/scripts/propagate/propagate-select.ts +1 -1
  593. package/scripts/propagate/propagate-steps.ts +19 -20
  594. package/scripts/propagate/propagate-targets.ts +6 -10
  595. package/scripts/propagate/propagate.ts +5 -5
  596. package/scripts/refactor/import-graph.ts +1 -1
  597. package/scripts/refactor/refactor-lint.ts +4 -10
  598. package/scripts/refactor/refactor-scan-cli.ts +1 -1
  599. package/scripts/refactor/refactor-scan.ts +2 -2
  600. package/scripts/refactor/refactor-targets.ts +1 -1
  601. package/scripts/release/github-release-cli.ts +25 -3
  602. package/scripts/release/github-release-environment.ts +1 -0
  603. package/scripts/release/github-release-runs.ts +115 -0
  604. package/scripts/release/github-release.ts +13 -67
  605. package/scripts/release/release-cli.ts +21 -4
  606. package/scripts/release/release-history.ts +6 -10
  607. package/scripts/release/release-plan.ts +3 -3
  608. package/scripts/release/release-progress.ts +3 -4
  609. package/scripts/release/release-publish.ts +8 -9
  610. package/scripts/release/release-scope-cli.ts +8 -10
  611. package/scripts/release/release-tag.ts +6 -8
  612. package/scripts/release/release-worktree.ts +5 -5
  613. package/scripts/repo/auto-merge-setting-logic.ts +7 -9
  614. package/scripts/repo/auto-merge-setting.ts +1 -1
  615. package/scripts/repo/repo-setting.ts +4 -4
  616. package/scripts/repo/repository-labels.ts +1 -1
  617. package/scripts/repo/required-checks-logic.ts +3 -3
  618. package/scripts/repo/required-checks-report.ts +1 -1
  619. package/scripts/repo/ruleset-check-cli.ts +1 -1
  620. package/scripts/repo/ruleset-check.ts +1 -1
  621. package/scripts/report/report-format-reference.ts +26 -0
  622. package/scripts/report/report-lint-cli.ts +2 -2
  623. package/scripts/report/report-lint.ts +16 -2
  624. package/scripts/review/disposition-cli.ts +2 -2
  625. package/scripts/review/disposition-logic.ts +1 -1
  626. package/scripts/review/live-evidence.ts +9 -6
  627. package/scripts/review/review-attest-cli.ts +1 -2
  628. package/scripts/review/review-attest.ts +3 -3
  629. package/scripts/review/review-brief-cli.ts +19 -20
  630. package/scripts/review/review-brief.ts +29 -32
  631. package/scripts/review/review-checkout.ts +2 -2
  632. package/scripts/review/review-diff-parts.ts +3 -5
  633. package/scripts/review/review-diff-write.ts +1 -1
  634. package/scripts/review/review-finding-ledger.ts +7 -4
  635. package/scripts/review/review-findings-cli.ts +2 -2
  636. package/scripts/review/review-level.ts +4 -7
  637. package/scripts/review/review-record-cli.ts +73 -16
  638. package/scripts/review/review-record.ts +5 -4
  639. package/scripts/review/review-round2-cli.ts +2 -3
  640. package/scripts/review/review-round2.ts +13 -21
  641. package/scripts/review/review-stamps.ts +9 -71
  642. package/scripts/review/review-tree.ts +4 -5
  643. package/scripts/rules/bash-triggers.ts +4 -4
  644. package/scripts/rules/decision-oracle-batch.ts +5 -6
  645. package/scripts/rules/decision-oracle-stage.ts +1 -1
  646. package/scripts/rules/decision-oracle-tokens.ts +1 -2
  647. package/scripts/rules/decision-oracle.ts +2 -2
  648. package/scripts/rules/delivered-rules.ts +61 -406
  649. package/scripts/rules/destructive-command.ts +2 -2
  650. package/scripts/rules/direct-filing.ts +4 -4
  651. package/scripts/rules/direct-pr-create.ts +2 -2
  652. package/scripts/rules/early-heartbeat.ts +15 -19
  653. package/scripts/rules/file-body.ts +5 -6
  654. package/scripts/rules/filing-cap.ts +6 -7
  655. package/scripts/rules/filing-offer.ts +1 -1
  656. package/scripts/rules/firing-point.ts +6 -6
  657. package/scripts/rules/gh-api.ts +2 -2
  658. package/scripts/rules/git-argv.ts +3 -3
  659. package/scripts/rules/git-force.ts +2 -2
  660. package/scripts/rules/hook-context-line.ts +31 -0
  661. package/scripts/rules/implementation-cut-verdict.ts +5 -8
  662. package/scripts/rules/implementation-cut.ts +35 -32
  663. package/scripts/rules/index-guard.ts +2 -2
  664. package/scripts/rules/issue-citation.ts +7 -7
  665. package/scripts/rules/issue-comments.ts +21 -13
  666. package/scripts/rules/josh-git-bare.ts +2 -2
  667. package/scripts/rules/lane-background.ts +14 -16
  668. package/scripts/rules/lane-carry-conflict.ts +41 -5
  669. package/scripts/rules/lane-interactive-ask.ts +6 -9
  670. package/scripts/rules/lane-park.ts +12 -16
  671. package/scripts/rules/lane-split-park.ts +1 -2
  672. package/scripts/rules/lane-switch-main.ts +10 -13
  673. package/scripts/rules/last-prompt.ts +1 -1
  674. package/scripts/rules/oracle-consulted.ts +5 -5
  675. package/scripts/rules/oracle-firing.ts +6 -9
  676. package/scripts/rules/oracle-list-cli.ts +2 -2
  677. package/scripts/rules/permission-guards.ts +2 -2
  678. package/scripts/rules/piped-verification.ts +79 -9
  679. package/scripts/rules/poll-loop.ts +9 -11
  680. package/scripts/rules/pre-gate-cut.ts +33 -30
  681. package/scripts/rules/prior-comment-read.ts +3 -3
  682. package/scripts/rules/protected-files.ts +25 -13
  683. package/scripts/rules/raw-field-body.ts +3 -4
  684. package/scripts/rules/reply-language.ts +1 -1
  685. package/scripts/rules/rule-body-guard.ts +10 -12
  686. package/scripts/rules/rule-guard.ts +1 -1
  687. package/scripts/rules/rule-list.ts +51 -0
  688. package/scripts/rules/rule-registry-rows.ts +282 -0
  689. package/scripts/rules/rule-registry.ts +109 -0
  690. package/scripts/rules/rule-value-cache.ts +2 -2
  691. package/scripts/rules/rule-value-cli.ts +6 -4
  692. package/scripts/rules/rule-value.ts +61 -22
  693. package/scripts/rules/run-tail-rule.ts +11 -15
  694. package/scripts/rules/shell-body-trigger.ts +7 -7
  695. package/scripts/rules/shell-segments.ts +2 -4
  696. package/scripts/rules/stop-rules.ts +54 -41
  697. package/scripts/rules/tail-commands.ts +1 -1
  698. package/scripts/rules/test-declared-commit.ts +2 -2
  699. package/scripts/rules/third-party-write.ts +3 -3
  700. package/scripts/rules/worktree-guard.ts +12 -5
  701. package/scripts/run/add/run-add-cli.ts +165 -0
  702. package/scripts/run/add/run-add.ts +124 -0
  703. package/scripts/run/board/run-board-cli.ts +207 -0
  704. package/scripts/run/board/run-board-closed.ts +95 -0
  705. package/scripts/run/board/run-board-every.ts +60 -0
  706. package/scripts/run/board/run-board-fetch.ts +38 -0
  707. package/scripts/run/board/run-board-fit.ts +219 -0
  708. package/scripts/run/board/run-board-github.ts +162 -0
  709. package/scripts/run/board/run-board-header.ts +275 -0
  710. package/scripts/run/board/run-board-kind.ts +35 -0
  711. package/scripts/run/board/run-board-labels.ts +299 -0
  712. package/scripts/run/board/run-board-layout.ts +222 -0
  713. package/scripts/run/board/run-board-link.ts +31 -0
  714. package/scripts/run/board/run-board-machine.ts +198 -0
  715. package/scripts/run/board/run-board-notes.ts +103 -0
  716. package/scripts/run/board/run-board-phase.ts +136 -0
  717. package/scripts/run/board/run-board-plan.ts +129 -0
  718. package/scripts/run/board/run-board-read.ts +62 -0
  719. package/scripts/run/board/run-board-render-legend.ts +82 -0
  720. package/scripts/run/board/run-board-render-notes.ts +77 -0
  721. package/scripts/run/board/run-board-render-slot.ts +50 -0
  722. package/scripts/run/board/run-board-render.ts +407 -0
  723. package/scripts/run/board/run-board-scope.ts +17 -0
  724. package/scripts/run/board/run-board-screen.ts +43 -0
  725. package/scripts/run/board/run-board-span.ts +66 -0
  726. package/scripts/run/board/run-board-spin.ts +115 -0
  727. package/scripts/run/board/run-board-state.ts +113 -0
  728. package/scripts/run/board/run-board-status.ts +279 -0
  729. package/scripts/run/board/run-board-tick.ts +210 -0
  730. package/scripts/run/board/run-board-track.ts +22 -0
  731. package/scripts/run/board/run-board-usage-read.ts +255 -0
  732. package/scripts/run/board/run-board-usage-rusage.ts +124 -0
  733. package/scripts/run/board/run-board-usage-text.ts +80 -0
  734. package/scripts/run/board/run-board-usage.ts +165 -0
  735. package/scripts/run/carry/run-carry-added.ts +62 -0
  736. package/scripts/run/carry/run-carry-args.ts +25 -22
  737. package/scripts/run/carry/run-carry-change.ts +1 -1
  738. package/scripts/run/carry/run-carry-cli.ts +71 -48
  739. package/scripts/run/carry/run-carry-conversation.ts +6 -7
  740. package/scripts/run/carry/run-carry-ended.ts +85 -0
  741. package/scripts/run/carry/run-carry-reclaim.ts +1 -1
  742. package/scripts/run/carry/run-carry-stash.ts +3 -2
  743. package/scripts/run/carry/run-carry-streak.ts +8 -10
  744. package/scripts/run/carry/run-carry.ts +85 -89
  745. package/scripts/run/cut/run-cut-args.ts +7 -7
  746. package/scripts/run/cut/run-cut-cli.ts +68 -37
  747. package/scripts/run/cut/run-cut-handoff.ts +15 -15
  748. package/scripts/run/cut/run-cut-report.ts +37 -16
  749. package/scripts/run/cut/run-cut.ts +63 -77
  750. package/scripts/run/detached-launch.ts +35 -50
  751. package/scripts/run/entry/run-entry-cli.ts +48 -27
  752. package/scripts/run/entry/run-entry-stop.ts +7 -9
  753. package/scripts/run/entry/run-entry.ts +5 -6
  754. package/scripts/run/event/run-event-cli.ts +5 -6
  755. package/scripts/run/event/run-event-filed.ts +69 -0
  756. package/scripts/run/event/run-event-follow.ts +3 -3
  757. package/scripts/run/event/run-event-plan.ts +38 -0
  758. package/scripts/run/event/run-event-render.ts +10 -4
  759. package/scripts/run/event/run-event-scope.ts +47 -18
  760. package/scripts/run/event/run-event-stream-emit.ts +64 -11
  761. package/scripts/run/event/run-event-stream.ts +172 -43
  762. package/scripts/run/event/run-event-watch.ts +4 -6
  763. package/scripts/run/hold/run-hold-cli.ts +65 -62
  764. package/scripts/run/hold/run-hold.ts +88 -46
  765. package/scripts/run/merge/run-merge-cli.ts +116 -77
  766. package/scripts/run/merge/run-merge-collect.ts +107 -0
  767. package/scripts/run/merge/run-merge-steps.ts +112 -65
  768. package/scripts/run/merge/run-merge-token.ts +30 -0
  769. package/scripts/run/merge/run-merge.ts +31 -22
  770. package/scripts/run/progress/run-progress-args.ts +4 -4
  771. package/scripts/run/progress/run-progress-cli.ts +39 -50
  772. package/scripts/run/progress/run-progress-clock.ts +25 -32
  773. package/scripts/run/progress/run-progress-config.ts +6 -9
  774. package/scripts/run/progress/run-progress-read.ts +9 -10
  775. package/scripts/run/progress/run-progress.ts +48 -53
  776. package/scripts/run/review/run-review-cli.ts +6 -6
  777. package/scripts/run/review/run-review-steps.ts +6 -6
  778. package/scripts/run/review/run-review.ts +9 -11
  779. package/scripts/run/run-cli-fault.ts +29 -0
  780. package/scripts/run/run-ending-cli.ts +3 -3
  781. package/scripts/run/run-ending.ts +10 -14
  782. package/scripts/run/run-halfrun-resume.ts +6 -8
  783. package/scripts/run/run-headless.ts +25 -12
  784. package/scripts/run/run-invocation.ts +17 -22
  785. package/scripts/run/run-label.ts +7 -5
  786. package/scripts/run/run-liveness-cli.ts +19 -6
  787. package/scripts/run/run-liveness.ts +27 -38
  788. package/scripts/run/run-next-cli.ts +5 -9
  789. package/scripts/run/run-next.ts +4 -5
  790. package/scripts/run/run-parent-cut-hook.ts +10 -12
  791. package/scripts/run/run-preflight.ts +25 -29
  792. package/scripts/run/run-prep-cli.ts +17 -13
  793. package/scripts/run/run-prep-locate.ts +4 -5
  794. package/scripts/run/run-prep.ts +7 -10
  795. package/scripts/run/run-prrun-resume.ts +2 -2
  796. package/scripts/run/run-report-cli.ts +4 -4
  797. package/scripts/run/run-report.ts +9 -14
  798. package/scripts/run/run-retrospective.ts +3 -3
  799. package/scripts/run/run-section.ts +42 -0
  800. package/scripts/run/run-stage-read.ts +2 -2
  801. package/scripts/run/run-stage.ts +6 -4
  802. package/scripts/run/run-status-cli.ts +7 -5
  803. package/scripts/run/run-status.ts +6 -7
  804. package/scripts/run/run-step-cli.ts +13 -15
  805. package/scripts/run/run-step.ts +62 -48
  806. package/scripts/run/run-stop-notify.ts +7 -8
  807. package/scripts/run/run-stranded-cli.ts +1 -1
  808. package/scripts/run/run-stranded-detect.ts +4 -4
  809. package/scripts/run/run-stranded.ts +11 -13
  810. package/scripts/run/run-tail-cli.ts +15 -16
  811. package/scripts/run/run-tail.ts +14 -33
  812. package/scripts/run/run-watcher-guard-cli.ts +3 -4
  813. package/scripts/run/run-watcher-guard.ts +11 -12
  814. package/scripts/run/run-watcher-hook.ts +6 -12
  815. package/scripts/run/ship/run-ship-cli.ts +67 -33
  816. package/scripts/run/ship/run-ship-detach.ts +15 -13
  817. package/scripts/run/ship/run-ship-lock.ts +1 -1
  818. package/scripts/run/ship/run-ship-next.ts +7 -8
  819. package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
  820. package/scripts/run/ship/run-ship-preflight.ts +10 -11
  821. package/scripts/run/ship/run-ship-probe.ts +4 -4
  822. package/scripts/run/ship/run-ship-return.ts +1 -1
  823. package/scripts/run/ship/run-ship-review-steps.ts +43 -24
  824. package/scripts/run/ship/run-ship-review.ts +12 -14
  825. package/scripts/run/ship/run-ship-scoped.ts +15 -6
  826. package/scripts/run/ship/run-ship-stage.ts +80 -26
  827. package/scripts/run/ship/run-ship-steps.ts +26 -16
  828. package/scripts/run/ship/run-ship-stop-text.ts +4 -2
  829. package/scripts/run/ship/run-ship-sync.ts +9 -8
  830. package/scripts/run/ship/run-ship.ts +17 -32
  831. package/scripts/run/tidy/run-tidy-cli.ts +9 -5
  832. package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
  833. package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
  834. package/scripts/run/tidy/run-tidy.ts +4 -3
  835. package/scripts/run/wake/run-wake-cli.ts +27 -33
  836. package/scripts/run/wake/run-wake-describe.ts +76 -29
  837. package/scripts/run/wake/run-wake-driver.ts +14 -14
  838. package/scripts/run/wake/run-wake-handoff.ts +6 -6
  839. package/scripts/run/wake/run-wake-loop.ts +13 -21
  840. package/scripts/run/wake/run-wake-restart.ts +4 -5
  841. package/scripts/run/wake/run-wake-session.ts +23 -27
  842. package/scripts/run/wake/run-wake.ts +57 -328
  843. package/scripts/safe-chain/ci-installer-pin.ts +3 -3
  844. package/scripts/safe-chain/pack-hook.ts +2 -2
  845. package/scripts/safe-chain/preinstall-command.ts +2 -2
  846. package/scripts/security/security-audit-logic.ts +1 -1
  847. package/scripts/security/security-audit-provision-logic.ts +1 -1
  848. package/scripts/security/security-audit-provision.ts +2 -2
  849. package/scripts/security/security-audit.ts +5 -5
  850. package/scripts/security/security-updates-logic.ts +2 -3
  851. package/scripts/security/security-updates.ts +2 -4
  852. package/scripts/self-sync-guard/index.ts +1 -1
  853. package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
  854. package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
  855. package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
  856. package/scripts/sonar/sonar-hotspots.ts +1 -1
  857. package/scripts/sonar/sonar-new-code-cli.ts +1 -1
  858. package/scripts/sonar/sonar-new-code.ts +1 -1
  859. package/scripts/sonar/sonar-project.ts +1 -1
  860. package/scripts/split/split-assess-cli.ts +1 -1
  861. package/scripts/split/split-assess.ts +3 -3
  862. package/scripts/sync/directory-copy-guard.ts +2 -3
  863. package/scripts/sync/managed-config-scope-cli.ts +1 -2
  864. package/scripts/sync/managed-config-scope.ts +4 -4
  865. package/scripts/sync/plugin-skill-directories.ts +2 -2
  866. package/scripts/sync/reconcile-templates.ts +17 -8
  867. package/scripts/sync/removed-skill-manifest.ts +2 -3
  868. package/scripts/sync/sync-ai-files.ts +7 -7
  869. package/scripts/sync/sync-configs.ts +30 -3
  870. package/scripts/sync/sync-hook-safety.ts +2 -2
  871. package/scripts/sync/sync.ts +23 -10
  872. package/scripts/sync/synced-paths.ts +2 -1
  873. package/scripts/sync/workflow-pin-logic.ts +1 -1
  874. package/scripts/test/test-declared-changed.ts +4 -4
  875. package/scripts/test/test-declared-logic.ts +2 -3
  876. package/scripts/test/test-declared-match.ts +25 -4
  877. package/scripts/test/test-declared.ts +26 -9
  878. package/scripts/test/test-red-commit.ts +3 -2
  879. package/scripts/test/test-red-logic.ts +7 -14
  880. package/scripts/test/test-red.ts +12 -47
  881. package/scripts/test/test-related-scope.ts +2 -3
  882. package/scripts/test/test-related.ts +3 -3
  883. package/scripts/test/test-type-logic.ts +1 -2
  884. package/scripts/test/test-unit-guard.ts +13 -17
  885. package/scripts/test/unit-worker-share.ts +7 -8
  886. package/scripts/time-runtime/time-agent-bundles.ts +2 -4
  887. package/scripts/time-runtime/time-background.ts +17 -21
  888. package/scripts/time-runtime/time-batch-guard.ts +67 -342
  889. package/scripts/time-runtime/time-bundle-call.ts +26 -28
  890. package/scripts/time-runtime/time-bundles.ts +11 -12
  891. package/scripts/time-runtime/time-call-identity.ts +1 -1
  892. package/scripts/time-runtime/time-command-key.ts +2 -2
  893. package/scripts/time-runtime/time-density-hook.ts +8 -11
  894. package/scripts/time-runtime/time-density.ts +5 -5
  895. package/scripts/time-runtime/time-followup-stage.ts +7 -7
  896. package/scripts/time-runtime/time-format.ts +5 -5
  897. package/scripts/time-runtime/time-hook-transcript.ts +3 -3
  898. package/scripts/time-runtime/time-instant.ts +1 -1
  899. package/scripts/time-runtime/time-markers.ts +15 -19
  900. package/scripts/time-runtime/time-phase-names.ts +3 -3
  901. package/scripts/time-runtime/time-reported-failure.ts +15 -19
  902. package/scripts/time-runtime/time-round-trips.ts +20 -23
  903. package/scripts/time-runtime/time-shell.ts +8 -8
  904. package/scripts/time-runtime/time-single-check.ts +1 -2
  905. package/scripts/time-runtime/time-spans.ts +35 -40
  906. package/scripts/time-runtime/time-tool-call.ts +15 -16
  907. package/scripts/time-runtime/time-transcript-line.ts +53 -34
  908. package/scripts/time-runtime/time-writes.ts +5 -5
  909. package/scripts/ui/ui-routes-cli.ts +1 -2
  910. package/scripts/ui/ui-routes.ts +1 -2
  911. package/scripts/version/bump-version.ts +1 -1
  912. package/scripts/version/fresh-metadata-cache.ts +2 -2
  913. package/scripts/version/latest-corepack.ts +129 -98
  914. package/scripts/version/latest-lane-guard.ts +1 -1
  915. package/scripts/version/latest-scope-cli.ts +2 -2
  916. package/scripts/version/latest-stamp.ts +1 -2
  917. package/scripts/version/latest-update.ts +2 -2
  918. package/scripts/version/npm-registry.ts +2 -2
  919. package/scripts/version/package-manager-version.ts +18 -0
  920. package/scripts/version/publishable-range-check.ts +2 -1
  921. package/scripts/version/publishable-range.ts +1 -1
  922. package/scripts/version/release-age.ts +11 -11
  923. package/scripts/version/release-hold.ts +2 -2
  924. package/scripts/version/safe-chain-version-update.ts +3 -3
  925. package/scripts/version/version-check-logic.ts +2 -3
  926. package/scripts/version/version-check.ts +1 -2
  927. package/scripts/version/version-command-config.ts +2 -2
  928. package/scripts/version/version-commands.ts +3 -3
  929. package/scripts/version/version-remote.ts +4 -4
  930. package/scripts/version/version-targets.ts +2 -2
  931. package/templates/gitignore +7 -0
  932. package/templates/workflows/github-release.yml +4 -0
  933. package/dist/hooks/chunk-NV2JRZZO.js +0 -6385
  934. package/dist/hooks/chunk-RKUAD3I6.js +0 -90
  935. package/dist/hooks/chunk-WPALEIRX.js +0 -18
  936. package/scripts/backlog/backlog-restructure.ts +0 -152
  937. package/scripts/rules/issue-fold-rule.ts +0 -72
  938. package/scripts/rules/wip-cap.ts +0 -63
  939. package/scripts/run/run-issue-number.ts +0 -19
@@ -1,9 +1,10 @@
1
1
  import { agent_role_profile } from '#scripts/agent/agent-role-profile'
2
2
  import { issue_cite, type IssueCiter } from '#scripts/issue/issue-cite'
3
+ import { session_cite } from '#scripts/issue/session-cite'
3
4
  import { run_liveness } from '#scripts/run/run-liveness'
4
5
  import type { LaneInfo } from './lane-registry'
5
6
 
6
- // What a person reads when they ask what is open (joshuafolkken/kit#1490, joshuafolkken/kit#1494).
7
+ // What a person reads when they ask what is open.
7
8
  //
8
9
  // The dev and preview ports are the ones the registry already resolved through `ports/index.js`
9
10
  // when it read each lane's `.env`, so the numbers printed here are the same ones `josh port` and
@@ -31,7 +32,7 @@ function value_or_unknown(value: number | undefined): string {
31
32
  }
32
33
 
33
34
  // The recorded output path goes last and is labelled, so it is told apart from the directory beside
34
- // it (joshuafolkken/kit#1713). A lane that records none prints `output -` rather than nothing at
35
+ // it. A lane that records none prints `output -` rather than nothing at
35
36
  // all: a session that did not open the lane has to be able to see that the record is missing, not
36
37
  // read a shorter row as one field it failed to notice.
37
38
  function output_column(output: string | undefined): string {
@@ -52,7 +53,7 @@ function event_column(lane: LaneInfo): string {
52
53
  // The plain `#N`, for a caller that could not read the repository the issue would link into.
53
54
  const PLAIN_CITE: IssueCiter = issue_cite.citer(undefined, new Map())
54
55
 
55
- // The issue leads as a citation (joshuafolkken/kit#2943): a lane status report copies this row, and a
56
+ // The issue leads as a citation: a lane status report copies this row, and a
56
57
  // bare `#N` copied into it is what the Stop guard sends back.
57
58
  function describe_lane(lane: LaneInfo, cite: IssueCiter = PLAIN_CITE): string {
58
59
  return [
@@ -84,7 +85,7 @@ function describe_ports(lane: LaneInfo): string {
84
85
  // The one-line confirmation a person reads on standard error while standard output carries the
85
86
  // directory alone, so `dir=$(pnpm josh lane:open 1490)` stays usable.
86
87
  function describe_opened(lane: LaneInfo): string {
87
- return `Opened a lane for #${lane.issue} on ${lane.branch}: ${describe_ports(lane)}.`
88
+ return `Opened a lane for ${session_cite.issue(lane.issue)} on ${lane.branch}: ${describe_ports(lane)}.`
88
89
  }
89
90
 
90
91
  const lane_report = {
@@ -3,8 +3,8 @@ import { api_outage } from '#scripts/agent/api-outage'
3
3
  import type { ClaudeResultEvent } from '#scripts/agent/claude-result-event'
4
4
  import { lane_child_invocation } from './lane-child-invocation'
5
5
 
6
- // How a lane re-dispatch chooses between resuming the disconnected child's session and starting fresh
7
- // (joshuafolkken/kit#2317). The premise the whole issue rests on: a child that could not reach the API
6
+ // How a lane re-dispatch chooses between resuming the disconnected child's session and starting fresh.
7
+ // The premise the whole issue rests on: a child that could not reach the API
8
8
  // left a `session_id` in its exit record, and re-dispatching it as a bare `fullrun #<N>` threw that
9
9
  // context away — a resumed child keeps it and loses only the last round-trip.
10
10
  //
@@ -0,0 +1,55 @@
1
+ import { lane_ledger } from './lane-ledger'
2
+ import { lane_load } from './lane-load'
3
+
4
+ // The machine-load sampler: one `load` entry appended to the lane ledger, once or on a timer.
5
+ //
6
+ // **`start` is how a `backlogrun` samples itself.** `backlog:drive` starts it for as long as its loop
7
+ // runs, so a period needs nobody to remember a second terminal — the sampler `josh lane:sample` offers
8
+ // was started by hand, and a run nobody started it beside recorded no load at all. The timer lives in
9
+ // the drive's own process and is unreferenced: it ends with the drive, never holds it open, and leaves
10
+ // no process or pid file behind to stop.
11
+
12
+ const SAMPLE_INTERVAL_MS = 60_000
13
+
14
+ // Where the ledger is and what "now" is, overridable so a test reads a fixed ledger at a fixed instant.
15
+ interface MeasureContext {
16
+ ledger_path?: string
17
+ now_ms?: number
18
+ }
19
+
20
+ async function take(context: MeasureContext = {}): Promise<void> {
21
+ const at = new Date(context.now_ms ?? Date.now()).toISOString()
22
+
23
+ await lane_ledger.record(await lane_load.sample(at), context.ledger_path)
24
+ }
25
+
26
+ // A timer tick has no caller to raise into, and a sample that could not be read must never end the run
27
+ // it measures.
28
+ async function take_quietly(context: MeasureContext): Promise<void> {
29
+ try {
30
+ await take(context)
31
+ } catch {
32
+ // Best-effort: an unread sample is a gap in the measurement, not a failure of the run.
33
+ }
34
+ }
35
+
36
+ /** Sample now and then every minute; the returned function stops it. */
37
+ function start(context: MeasureContext = {}): () => void {
38
+ void take_quietly(context)
39
+ const timer = setInterval(() => {
40
+ void take_quietly(context)
41
+ }, SAMPLE_INTERVAL_MS).unref()
42
+
43
+ return () => {
44
+ clearInterval(timer)
45
+ }
46
+ }
47
+
48
+ const lane_sampler = {
49
+ SAMPLE_INTERVAL_MS,
50
+ start,
51
+ take,
52
+ }
53
+
54
+ export type { MeasureContext }
55
+ export { lane_sampler }
@@ -1,13 +1,13 @@
1
- // Which seat a lane gets (joshuafolkken/kit#1490, joshuafolkken/kit#1494).
1
+ // Which seat a lane gets.
2
2
 
3
3
  // **The main work tree is seat 0, and nothing here can move it.** Lanes take seats 1..9, so a
4
4
  // project that has never opened one stays on exactly the ports `ports/index.js` already gives it —
5
5
  // `seed × 10` for its seed, the bases themselves for an unset seed, which is what CI runs on.
6
6
  const FIRST_LANE_SEAT = 1
7
- // **Nine seats, because the seat is the units digit of the offset `seed × 10 + lane`.** The seat no
8
- // longer carries the whole port band — the seed does, multiplied by ten — so a lane holds a single
9
- // seat number rather than an absolute seed, and there is no ceiling to check and no "multiple of
10
- // ten" convention for anyone to break (joshuafolkken/kit#1494 removed the band mechanism).
7
+ // **Nine seats, because the seat is the units digit of the offset `seed × 10 + lane`.** The seed,
8
+ // multiplied by ten, carries the port band rather than the seat, so a lane holds a single seat number
9
+ // rather than an absolute seed, and there is no ceiling to check and no "multiple of ten" convention
10
+ // for anyone to break.
11
11
  const LAST_LANE_SEAT = 9
12
12
 
13
13
  /**
@@ -20,8 +20,8 @@ const LAST_LANE_SEAT = 9
20
20
  * wrapped, because wrapping is that same collision under a friendlier name.
21
21
  *
22
22
  * The whole ascending list is returned rather than only the lowest, because the caller claims each
23
- * seat atomically and steps to the next when a concurrent `lane:open` claimed it first
24
- * (joshuafolkken/kit#1494): reading a free set and picking from it are two moments, and the gap
23
+ * seat atomically and steps to the next when a concurrent `lane:open` claimed it first:
24
+ * reading a free set and picking from it are two moments, and the gap
25
25
  * between them is where two opens once chose the same seat.
26
26
  */
27
27
  function free_seats(used: ReadonlyArray<number>): Array<number> {
@@ -0,0 +1,135 @@
1
+ import { run_ship_stage } from '#scripts/run/ship/run-ship-stage'
2
+ import { lane_ledger, type DispatchEntry, type LedgerEntry, type StageEntry } from './lane-ledger'
3
+ import { lane_stats, type StatsWindow } from './lane-stats'
4
+
5
+ // Where a lane's time goes: the ledger's `stage` and `dispatch` entries of one period reduced to one
6
+ // row per stage — median, maximum and how many runs — printed by `josh lane:stats` under the lane-limit
7
+ // row. The rows are in the order a lane passes them.
8
+ //
9
+ // **A stage nothing recorded prints `not measured`, never `0`.** A period that ran no second review
10
+ // round has no `round-2` duration, which is not a round that took no time.
11
+ //
12
+ // **`implement` is derived, not recorded**: from a lane's dispatch to the start of the first ship stage
13
+ // of the same issue that followed it. Nothing has to know, at the hand-off, when the child was
14
+ // dispatched, and a ship resumed after a fix cannot record the implementation twice.
15
+ //
16
+ // **`ci-wait` is `followup`'s own lap, inside the `followup` stage** — a row of its own so the wait for
17
+ // CI reads beside `review`, the round-one review it would overlap.
18
+
19
+ const MS_PER_MINUTE = 60_000
20
+ const DECIMALS = 1
21
+ const NOT_MEASURED = 'not measured'
22
+ const IMPLEMENT = 'implement'
23
+ const COLUMNS = ['stage', 'median (min)', 'max (min)', 'runs'] as const
24
+ const { STAGE } = run_ship_stage
25
+ const STAGES = [
26
+ IMPLEMENT,
27
+ STAGE.PREFLIGHT,
28
+ STAGE.REVIEW,
29
+ STAGE.SYNC,
30
+ STAGE.GATE,
31
+ STAGE.COMMIT,
32
+ STAGE.ROUND_TWO,
33
+ STAGE.FOLLOWUP,
34
+ lane_ledger.CI_WAIT_STAGE,
35
+ STAGE.REPORT,
36
+ ] as const
37
+
38
+ interface Measured {
39
+ implement: ReadonlyArray<number>
40
+ stages: ReadonlyArray<StageEntry>
41
+ }
42
+
43
+ function is_stage(entry: LedgerEntry): entry is StageEntry {
44
+ return entry.kind === lane_ledger.KIND.STAGE
45
+ }
46
+
47
+ function is_dispatch(entry: LedgerEntry): entry is DispatchEntry {
48
+ return entry.kind === lane_ledger.KIND.DISPATCH
49
+ }
50
+
51
+ function is_number(value: number | undefined): value is number {
52
+ return value !== undefined
53
+ }
54
+
55
+ function started_ms(stage: StageEntry): number {
56
+ return Date.parse(stage.at) - stage.elapsed_ms
57
+ }
58
+
59
+ // When the same issue was dispatched again, or never: a child that died before its ship must not have
60
+ // its implementation stretched to the ship of the child that replaced it.
61
+ function next_dispatch_ms(sorted: ReadonlyArray<DispatchEntry>, index: number): number {
62
+ const next = sorted.slice(index + 1).find((entry) => entry.issue === sorted[index]?.issue)
63
+
64
+ return next === undefined ? Infinity : Date.parse(next.at)
65
+ }
66
+
67
+ function implement_ms(
68
+ dispatch: DispatchEntry,
69
+ until_ms: number,
70
+ stages: ReadonlyArray<StageEntry>,
71
+ ): number | undefined {
72
+ const from_ms = Date.parse(dispatch.at)
73
+ const starts = stages
74
+ .filter((stage) => stage.issue === dispatch.issue)
75
+ .map((stage) => started_ms(stage))
76
+ .filter((start) => start >= from_ms && start < until_ms)
77
+
78
+ return starts.length === 0 ? undefined : Math.min(...starts) - from_ms
79
+ }
80
+
81
+ function implement_durations(
82
+ dispatches: ReadonlyArray<DispatchEntry>,
83
+ stages: ReadonlyArray<StageEntry>,
84
+ ): Array<number> {
85
+ const sorted = dispatches.toSorted((left, right) => Date.parse(left.at) - Date.parse(right.at))
86
+
87
+ return sorted
88
+ .map((dispatch, index) => implement_ms(dispatch, next_dispatch_ms(sorted, index), stages))
89
+ .filter(is_number)
90
+ }
91
+
92
+ function durations_of(stage: string, measured: Measured): ReadonlyArray<number> {
93
+ if (stage === IMPLEMENT) return measured.implement
94
+
95
+ return measured.stages.filter((entry) => entry.stage === stage).map((entry) => entry.elapsed_ms)
96
+ }
97
+
98
+ function cell(milliseconds: number | undefined): string {
99
+ return milliseconds === undefined
100
+ ? NOT_MEASURED
101
+ : (milliseconds / MS_PER_MINUTE).toFixed(DECIMALS)
102
+ }
103
+
104
+ function stage_row(stage: string, measured: Measured): string {
105
+ const durations = durations_of(stage, measured)
106
+
107
+ return lane_stats.to_row([
108
+ stage,
109
+ cell(lane_stats.median(durations)),
110
+ cell(lane_stats.peak(durations)),
111
+ String(durations.length),
112
+ ])
113
+ }
114
+
115
+ // The period's table: `entries` is the whole ledger, filtered here to `window`.
116
+ function table(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow): string {
117
+ const period = lane_stats.in_window(entries, window)
118
+ const stages = period.filter(is_stage)
119
+ const measured = { implement: implement_durations(period.filter(is_dispatch), stages), stages }
120
+
121
+ return [
122
+ lane_stats.to_row(COLUMNS),
123
+ lane_stats.to_row(COLUMNS.map(() => '---')),
124
+ ...STAGES.map((stage) => stage_row(stage, measured)),
125
+ ].join('\n')
126
+ }
127
+
128
+ const lane_stage_stats = {
129
+ IMPLEMENT,
130
+ NOT_MEASURED,
131
+ STAGES,
132
+ table,
133
+ }
134
+
135
+ export { lane_stage_stats }
@@ -1,15 +1,14 @@
1
1
  import { git_command } from '#scripts/git/git-command'
2
2
  import { git_remote_branch } from '#scripts/git/git-remote-branch'
3
3
 
4
- // Where a lane is cut from (joshuafolkken/kit#1535).
4
+ // Where a lane is cut from.
5
5
  //
6
6
  // **The bare default-branch name is the wrong start point, because git resolves it to the *local*
7
7
  // `refs/heads/<default>` — a ref nothing in this workflow ever advances.** Merges happen on GitHub
8
8
  // through `pnpm josh followup`, and this repository's main work tree does not have the
9
9
  // default branch checked out, so there is no fast-forward for it to receive. It falls one commit
10
10
  // further behind on every merge, and a lane opened from it starts without the work that was just
11
- // merged. Measured on 2026-09-07: `refs/heads/main` was `e3a68c04` while `refs/remotes/origin/main`
12
- // was `78f746f9`.
11
+ // merged.
13
12
  //
14
13
  // **The remote-tracking ref is the one that is current**, because a fetch updates it without anyone
15
14
  // checking anything out — which is exactly the property the local branch lacks. It is named in full
@@ -20,9 +19,9 @@ const REFS_REMOTES_ORIGIN_PREFIX = 'refs/remotes/origin/'
20
19
 
21
20
  // A fetch *failure* is reported and stepped over rather than raised. `lane:open` has to keep working
22
21
  // with no network at all — offline, and on a clone with no `origin` — and what it degrades to is
23
- // whatever `origin/<default>` already holds, which is still never *behind* the local branch. Note
24
- // what this does not cover: `fetch_branch` runs through `git_spawn.read`, which sets no
25
- // timeout, so a connection that hangs rather than failing blocks here instead of degrading.
22
+ // whatever `origin/<default>` already holds, which is still never *behind* the local branch. A
23
+ // connection that hangs rather than failing degrades the same way: `fetch_branch` runs through
24
+ // `git_spawn.read_remote`, whose budget ends the wait as a failure.
26
25
  async function refresh_default_branch(default_branch: string): Promise<void> {
27
26
  try {
28
27
  await git_command.fetch_branch(default_branch)
@@ -65,7 +64,7 @@ async function resolve(): Promise<string> {
65
64
  return start_point
66
65
  }
67
66
 
68
- // **A branch that already exists is attached to, never cut afresh** (joshuafolkken/kit#1627). Its
67
+ // **A branch that already exists is attached to, never cut afresh**. Its
69
68
  // commits are a child's finished work: `epicrun` leaves a lane's branch behind whenever a child is
70
69
  // parked after pushing, and `lane:close` deletes the local branch while the remote one and the pull
71
70
  // request stay. Cutting a new `<N>-lane` from the default branch there orphans both — and it did so
@@ -130,8 +129,7 @@ async function present_reference(branch_name: string): Promise<string> {
130
129
 
131
130
  // `absent` is the one answer that refuses the ref: the branch is gone from origin, so a ref still
132
131
  // pointing at it is stale and the lane is cut from the default branch as any new one is. Why origin
133
- // itself is asked rather than the remote-tracking ref is `git_remote_branch`'s own comment
134
- // (joshuafolkken/kit#1641 moved the asking there, so `pnpm josh release` could reuse it).
132
+ // itself is asked rather than the remote-tracking ref is `git_remote_branch`'s own comment.
135
133
  async function remote_reference_for(branch_name: string): Promise<string | undefined> {
136
134
  const answer = await git_remote_branch.ask(branch_name)
137
135
 
@@ -148,8 +146,7 @@ async function remote_reference_for(branch_name: string): Promise<string | undef
148
146
  *
149
147
  * `undefined` means **attach**: the branch is already here, so the work tree is put on it and no
150
148
  * branch is created. Every other answer is a commit-ish a new branch is cut from — the remote-tracking
151
- * ref of the lane branch when only the remote has it, and the default branch's when neither does,
152
- * which is the behavior every lane had before joshuafolkken/kit#1627.
149
+ * ref of the lane branch when only the remote has it, and the default branch's when neither does.
153
150
  *
154
151
  * **Nothing here deletes a branch to simplify the call.** That is what would lose the commits this
155
152
  * function exists to keep.
@@ -1,6 +1,8 @@
1
+ import { machine_capacity } from '#scripts/gate/machine-capacity'
1
2
  import type { GateEntry, LedgerEntry, LoadEntry } from './lane-ledger'
3
+ import { lane_sampler } from './lane-sampler'
2
4
 
3
- // The lane-limit measurement's one table row (joshuafolkken/kit#3355): the ledger entries of one period
5
+ // The lane-limit measurement's one table row: the ledger entries of one period
4
6
  // reduced to throughput, gate duration and machine load, in the column order
5
7
  // `docs/maintainers/lane-limit-measurement.md` documents, so the row pastes into #3347's table as is.
6
8
  //
@@ -15,6 +17,9 @@ import type { GateEntry, LedgerEntry, LoadEntry } from './lane-ledger'
15
17
  //
16
18
  // **The means take working samples only** for the same reason: the sampler runs through the nights,
17
19
  // and their idle samples would read four busy lanes as about one. Peaks and minima take every sample.
20
+ //
21
+ // **Swap is a rate, not a level.** A sample carries `machine_capacity`'s counter — every page swapped
22
+ // since boot — so the swap columns are what was swapped between consecutive samples, per hour.
18
23
 
19
24
  const MS_PER_MINUTE = 60_000
20
25
  const MS_PER_HOUR = 3_600_000
@@ -23,6 +28,8 @@ const ACTIVE_GAP_MS = MS_PER_HOUR
23
28
  const MS_PER_DAY = 86_400_000
24
29
  const MB_PER_GB = 1024
25
30
  const HALF = 2
31
+ // Half the sampler's interval: two samples closer than this are not one interval apart.
32
+ const MIN_RATE_GAP_MS = lane_sampler.SAMPLE_INTERVAL_MS / HALF
26
33
  const DECIMALS = 1
27
34
  const MISSING = '—'
28
35
  const CELL_SEPARATOR = ' | '
@@ -37,8 +44,8 @@ const COLUMNS = [
37
44
  'gate max (min)',
38
45
  'load peak',
39
46
  'load mean',
40
- 'swap peak (GB)',
41
- 'swap mean (GB)',
47
+ 'swapped peak (GB/h)',
48
+ 'swapped mean (GB/h)',
42
49
  'free memory min (GB)',
43
50
  'free memory mean (GB)',
44
51
  'load samples',
@@ -107,6 +114,22 @@ function is_working(sample: LoadEntry): sample is WorkingEntry {
107
114
  return (sample.lanes ?? 0) > 0
108
115
  }
109
116
 
117
+ interface SamplePair {
118
+ sample: LoadEntry
119
+ next: LoadEntry
120
+ }
121
+
122
+ // Each sample beside the one that followed it, in time order.
123
+ function sample_pairs(samples: ReadonlyArray<LoadEntry>): Array<SamplePair> {
124
+ const sorted = samples.toSorted((left, right) => Date.parse(left.at) - Date.parse(right.at))
125
+
126
+ return sorted.slice(1).map((next, index) => ({ sample: sorted[index] ?? next, next }))
127
+ }
128
+
129
+ function elapsed_ms({ sample, next }: SamplePair): number {
130
+ return Date.parse(next.at) - Date.parse(sample.at)
131
+ }
132
+
110
133
  function sum_hours(gaps: ReadonlyArray<number>): number | undefined {
111
134
  const active = gaps.filter((gap) => gap <= ACTIVE_GAP_MS).reduce((sum, gap) => sum + gap, 0)
112
135
 
@@ -117,7 +140,7 @@ function sum_hours(gaps: ReadonlyArray<number>): number | undefined {
117
140
  // and gates) no longer than `ACTIVE_GAP_MS`.
118
141
  function gap_hours(entries: ReadonlyArray<LedgerEntry>): number | undefined {
119
142
  const instants = entries
120
- .filter((entry) => !is_load(entry))
143
+ .filter((entry) => entry.kind === 'merge' || is_gate(entry))
121
144
  .map((entry) => Date.parse(entry.at))
122
145
  .toSorted((left, right) => left - right)
123
146
 
@@ -129,16 +152,27 @@ function gap_hours(entries: ReadonlyArray<LedgerEntry>): number | undefined {
129
152
  // The time from each working sample to the next sample. The cap still applies, so a sampler stopped
130
153
  // mid-run does not count its silence as work.
131
154
  function sampled_hours(samples: ReadonlyArray<LoadEntry>): number | undefined {
132
- const sorted = samples.toSorted((left, right) => Date.parse(left.at) - Date.parse(right.at))
133
- const gaps = sorted
134
- .slice(1)
135
- .map((next, index) => ({ sample: sorted[index] ?? next, next }))
155
+ const gaps = sample_pairs(samples)
136
156
  .filter(({ sample }) => is_working(sample))
137
- .map(({ sample, next }) => Date.parse(next.at) - Date.parse(sample.at))
157
+ .map((pair) => elapsed_ms(pair))
138
158
 
139
159
  return sum_hours(gaps)
140
160
  }
141
161
 
162
+ // The GB swapped per hour from one sample to the next. `swapped_mb` is a counter, so only a difference
163
+ // says anything; a gap past `ACTIVE_GAP_MS` is a stopped sampler, whose silence is no rate. A gap under
164
+ // `MIN_RATE_GAP_MS` is no rate either: a drive restarted seconds after its last sample, or a second
165
+ // sampler beside it, would stretch a few seconds' burst to an hour and own the peak.
166
+ function swap_rate(pair: SamplePair): number | undefined {
167
+ const swapped = machine_capacity.swapped_between(pair.sample.swapped_mb, pair.next.swapped_mb)
168
+ const elapsed = elapsed_ms(pair)
169
+ const is_one_interval = elapsed >= MIN_RATE_GAP_MS && elapsed <= ACTIVE_GAP_MS
170
+
171
+ if (swapped === undefined || !is_one_interval) return undefined
172
+
173
+ return swapped / MB_PER_GB / (elapsed / MS_PER_HOUR)
174
+ }
175
+
142
176
  // The hours work was under way; `undefined` when nothing leaves any active time.
143
177
  function active_hours(entries: ReadonlyArray<LedgerEntry>): number | undefined {
144
178
  const samples = entries.filter(is_load)
@@ -172,18 +206,26 @@ function gate_cells(entries: ReadonlyArray<LedgerEntry>): Array<string> {
172
206
  return [cell(median(minutes)), cell(peak(minutes))]
173
207
  }
174
208
 
209
+ function swap_cells(samples: ReadonlyArray<LoadEntry>): Array<string> {
210
+ const pairs = sample_pairs(samples)
211
+ const rates = pairs.map((pair) => swap_rate(pair)).filter(is_number)
212
+ const working_rates = pairs
213
+ .filter(({ sample }) => is_working(sample))
214
+ .map((pair) => swap_rate(pair))
215
+ .filter(is_number)
216
+
217
+ return [cell(peak(rates)), cell(mean(working_rates))]
218
+ }
219
+
175
220
  function load_cells(samples: ReadonlyArray<LoadEntry>): Array<string> {
176
221
  const working = samples.filter(is_working)
177
- const swap = samples.map((sample) => sample.swap_mb).filter(is_number)
178
- const working_swap = working.map((sample) => sample.swap_mb).filter(is_number)
179
- const free = samples.map((sample) => sample.free_mb)
180
- const working_free = working.map((sample) => sample.free_mb)
222
+ const free = samples.map((sample) => sample.available_mb).filter(is_number)
223
+ const working_free = working.map((sample) => sample.available_mb).filter(is_number)
181
224
 
182
225
  return [
183
226
  cell(peak(samples.map((sample) => sample.load))),
184
227
  cell(mean(working.map((sample) => sample.load))),
185
- cell(gigabytes(peak(swap))),
186
- cell(gigabytes(mean(working_swap))),
228
+ ...swap_cells(samples),
187
229
  cell(gigabytes(lowest(free))),
188
230
  cell(gigabytes(mean(working_free))),
189
231
  String(samples.length),
@@ -215,8 +257,11 @@ const lane_stats = {
215
257
  COLUMNS,
216
258
  MISSING,
217
259
  header,
260
+ in_window,
218
261
  median,
262
+ peak,
219
263
  row,
264
+ to_row,
220
265
  window_of,
221
266
  }
222
267
 
@@ -0,0 +1,140 @@
1
+ import { existsSync, lstatSync, readdirSync, rmSync } from 'node:fs'
2
+ import path from 'node:path'
3
+ import { error_text } from '#scripts/lib/error-message'
4
+ import { lane_leftover } from './lane-leftover'
5
+ import { lane_open } from './lane-open'
6
+ import { lane_paths } from './lane-paths'
7
+ import { lane_registry } from './lane-registry'
8
+
9
+ // What the lanes root holds that no registered work tree accounts for.
10
+ //
11
+ // **Every other sweep starts from `git worktree list`**, so a directory whose registration is gone —
12
+ // a lane whose `rmSync` stopped half-way, one whose `.git` points at a registration git pruned, an
13
+ // empty lanes root a lane once nested inside itself — is invisible to all of them, and stays on disk
14
+ // for good. This reads the root itself.
15
+ //
16
+ // **A stray is removed only when removing it loses nothing** — `lane_leftover.foreign_paths`, the one
17
+ // test `lane:open`'s reclaim also applies. One that holds anything else is kept and reported with what
18
+ // it holds; so is every entry whose name the lane machinery never writes, because nothing here knows
19
+ // who put it there. The root's own `.seat-locks` and every registered work tree are not strays.
20
+
21
+ type StrayVerdict = 'foreign' | 'not-a-lane' | 'opening' | 'removed' | 'stuck' | 'unreadable'
22
+
23
+ interface Stray {
24
+ path: string
25
+ verdict: StrayVerdict
26
+ // The paths inside it whose removal would lose something — only on `foreign`.
27
+ foreign: Array<string>
28
+ }
29
+
30
+ function stray_names(root: string, registered: ReadonlySet<string>): Array<string> {
31
+ if (!existsSync(root)) return []
32
+
33
+ return readdirSync(root).filter(
34
+ (name) => name !== lane_paths.SEAT_LOCK_DIR && !registered.has(path.join(root, name)),
35
+ )
36
+ }
37
+
38
+ function is_lane_directory(directory: string): boolean {
39
+ return lane_paths.is_lane_entry(path.basename(directory)) && lstatSync(directory).isDirectory()
40
+ }
41
+
42
+ // A removal that stops part-way is judged by what is left, exactly as `lane:close` judges its own —
43
+ // and what is left is a stray the next sweep reads again.
44
+ function remove(directory: string): StrayVerdict {
45
+ try {
46
+ rmSync(directory, { force: true, recursive: true })
47
+ } catch (error) {
48
+ error_text.trace_swallowed('lane_stray.remove', error)
49
+ }
50
+
51
+ return existsSync(directory) ? 'stuck' : 'removed'
52
+ }
53
+
54
+ // **A `lane:open` in flight holds a seat lock from before its `worktree add` until after the
55
+ // registration**, so while any lock is held a numbered directory may be a lane being created, not a
56
+ // leftover — it is kept, and the next sweep reads it again.
57
+ interface SweepContext {
58
+ recoverable: ReadonlySet<string>
59
+ is_opening: boolean
60
+ }
61
+
62
+ function judge(directory: string, context: SweepContext): Stray {
63
+ if (!is_lane_directory(directory)) return { path: directory, verdict: 'not-a-lane', foreign: [] }
64
+ if (context.is_opening) return { path: directory, verdict: 'opening', foreign: [] }
65
+
66
+ const foreign = lane_leftover.foreign_paths(directory, context.recoverable)
67
+
68
+ if (foreign.length > 0) return { path: directory, verdict: 'foreign', foreign }
69
+
70
+ return { path: directory, verdict: remove(directory), foreign: [] }
71
+ }
72
+
73
+ // One stray that cannot be read — a permission, a file vanishing mid-walk — is kept and reported
74
+ // rather than thrown, so it never stops the sweep of the rest.
75
+ function judge_safely(directory: string, context: SweepContext): Stray {
76
+ try {
77
+ return judge(directory, context)
78
+ } catch (error) {
79
+ error_text.trace_swallowed('lane_stray.judge', error)
80
+
81
+ return { path: directory, verdict: 'unreadable', foreign: [] }
82
+ }
83
+ }
84
+
85
+ /** Remove the lanes root's unregistered leftovers that hold nothing worth keeping; report the rest. */
86
+ async function sweep_strays(): Promise<Array<Stray>> {
87
+ const root = lane_paths.lane_root(await lane_registry.main_repository_root())
88
+ const registered = new Set(await lane_registry.registered_directories())
89
+ const names = stray_names(root, registered)
90
+
91
+ if (names.length === 0) return []
92
+
93
+ const context: SweepContext = {
94
+ recoverable: await lane_leftover.recoverable_objects(),
95
+ is_opening: lane_open.open_in_flight_count(root) > 0,
96
+ }
97
+
98
+ return names.map((name) => judge_safely(path.join(root, name), context))
99
+ }
100
+
101
+ // The foreign paths a report names before it summarizes the rest as a count.
102
+ const NAMED_PATH_LIMIT = 5
103
+
104
+ function named_paths(foreign: ReadonlyArray<string>): string {
105
+ const rest = foreign.length - NAMED_PATH_LIMIT
106
+ const more = rest > 0 ? ` and ${String(rest)} more` : ''
107
+
108
+ return `${foreign.slice(0, NAMED_PATH_LIMIT).join(', ')}${more}`
109
+ }
110
+
111
+ const KEPT_REASONS: Record<Exclude<StrayVerdict, 'foreign' | 'removed'>, string> = {
112
+ 'not-a-lane': 'not a name the lane machinery writes, so it was left alone',
113
+ opening:
114
+ 'a `lane:open` holds a seat lock and this may be its lane; the next sweep reads it again — if no `lane:open` is running, the lock outlived a crash: remove the lanes root `.seat-locks` directory',
115
+ stuck: 'the removal did not finish; the next `pnpm josh lane:prune` tries again',
116
+ unreadable: 'it could not be read, so it was left in place',
117
+ }
118
+
119
+ /** One line per stray, for standard error. */
120
+ function describe(stray: Stray): string {
121
+ if (stray.verdict === 'removed') return `Removed unregistered lane leftover ${stray.path}.`
122
+
123
+ if (stray.verdict === 'foreign') {
124
+ return `Kept ${stray.path}: it holds files git cannot restore (${named_paths(stray.foreign)}). Move them out and delete the directory.`
125
+ }
126
+
127
+ return `Kept ${stray.path}: ${KEPT_REASONS[stray.verdict]}.`
128
+ }
129
+
130
+ /** Sweep, and say on standard error what was removed and what was kept. */
131
+ async function sweep_and_report(): Promise<void> {
132
+ const strays = await sweep_strays()
133
+
134
+ for (const stray of strays) console.error(describe(stray))
135
+ }
136
+
137
+ const lane_stray = { describe, sweep_and_report, sweep_strays }
138
+
139
+ export type { Stray, StrayVerdict }
140
+ export { lane_stray }
@@ -3,7 +3,7 @@ import { run_hold } from '#scripts/run/hold/run-hold'
3
3
  import { lane_await } from './lane-await'
4
4
  import type { LaneInfo } from './lane-registry'
5
5
 
6
- // Whether an open lane holds nothing worth keeping (joshuafolkken/kit#3289): no commit on its branch
6
+ // Whether an open lane holds nothing worth keeping: no commit on its branch
7
7
  // beyond the default branch, a clean work tree, and no child or ship supervisor alive for its issue. A
8
8
  // `backlogrun` cut between `lane:open` and `lane:dispatch` leaves exactly such a lane, and `lane:open`
9
9
  // refuses it as `already-open` — so the next launch of that issue failed on a lane with nothing in it.
@@ -1,4 +1,5 @@
1
1
  import { stamp_file } from '#scripts/josh/stamp-file'
2
+ import { json_value } from '#scripts/lib/json-value'
2
3
  import { z } from 'zod'
3
4
 
4
5
  const DECISION_PREFIX = 'josh-openai-lane-supervisor-decision-'
@@ -16,14 +17,9 @@ function target(lane_directory: string, nonce: string): string {
16
17
  }
17
18
 
18
19
  function read(lane_directory: string, nonce: string): Decision | undefined {
19
- try {
20
- const raw = stamp_file.read_stamp_text(target(lane_directory, nonce)) ?? ''
21
- const value: unknown = JSON.parse(raw)
20
+ const raw = stamp_file.read_stamp_text(target(lane_directory, nonce)) ?? ''
22
21
 
23
- return schema.parse(value)
24
- } catch {
25
- return undefined
26
- }
22
+ return json_value.parse_with(raw, schema)
27
23
  }
28
24
 
29
25
  function decide(lane_directory: string, nonce: string, decision: Decision['decision']): boolean {