@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
@@ -23,22 +23,20 @@ import { review_level, type ReviewLevel } from './review-level'
23
23
  import { review_stamps } from './review-stamps'
24
24
  import { review_tree } from './review-tree'
25
25
 
26
- // `josh review:brief` — print the whole `/code-review` invocation, not just the level
27
- // (joshuafolkken/kit#1241).
26
+ // `josh review:brief` — print the whole `/code-review` invocation, not just the level.
28
27
  //
29
28
  // The level is decided in-process by the `review_level` module and is also exposed on its own as
30
- // `--level-only` (joshuafolkken/kit#1927 folded the former `josh review:level` command in here), so
31
- // the level a brief prints and the level `--level-only` answers can never disagree. What the full
32
- // brief adds is everything else the forked review agent cannot find out for itself: whether the gate
33
- // has passed **or is running** on this tree (joshuafolkken/kit#1242 — the two are started together,
29
+ // `--level-only`, so the level a brief prints and the level `--level-only` answers can never
30
+ // disagree. What the full brief adds is everything else the forked review agent cannot find out for
31
+ // itself: whether the gate has passed **or is running** on this tree (the two are started together,
34
32
  // so "still running" is the usual answer at this point), how this project runs its unit tests, and —
35
33
  // on round 2 — which files the first round's fixes touched.
36
34
 
37
35
  const ARGV_OFFSET = 2
38
36
  const USAGE = 'Usage: josh review:brief [--round <1|2>] | --level-only [--staged] [--json]'
39
37
 
40
- // The rubric's absolute path, resolved against the kit package rather than the review checkout root
41
- // (joshuafolkken/kit#2402). The rubric ships inside the package, so a consumer that keeps no
38
+ // The rubric's absolute path, resolved against the kit package rather than the review checkout root.
39
+ // The rubric ships inside the package, so a consumer that keeps no
42
40
  // `prompts/` of its own still receives it at `node_modules/@joshuafolkken/kit/prompts/`.
43
41
  // `find_package_directory` ascends to the nearest package.json, so this resolves from both the tsx
44
42
  // source and the bundled `dist/josh.js`.
@@ -48,7 +46,7 @@ const RUBRIC_PATH = path.join(
48
46
  review_brief.RUBRIC_RELATIVE_PATH,
49
47
  )
50
48
  const ROUND_FLAG = '--round'
51
- // `review:level` folded in here (joshuafolkken/kit#1927): it was a second command deciding the same
49
+ // `review:level` folded in here: it was a second command deciding the same
52
50
  // thing `review:brief` already prints on its first line, so it is now a mode of this one. `--level-only`
53
51
  // answers the level alone — for a pre-commit review run outside any workflow — and, unlike the full
54
52
  // brief, it never refuses on the scoped-green gate: the level takes no judgement and reads the changed
@@ -93,7 +91,7 @@ function kept_note(taken_at: string): string {
93
91
  // digests describe the implementation as the first round read it. Taking it again on round 2 would
94
92
  // overwrite the very record the delta is measured against.
95
93
  //
96
- // **It is written once per run and never retaken** (joshuafolkken/kit#1441). Overwriting on every
94
+ // **It is written once per run and never retaken**. Overwriting on every
97
95
  // round-1 invocation put a wrong `skip` one command away: run a bare `josh review:brief` after round
98
96
  // 1's fixes are in and the record is retaken against the fixed tree, the fix delta reads empty, and
99
97
  // `josh review:round2 --round-1-closed` fires arm A on unreviewed fix code. Keeping the record the
@@ -110,7 +108,7 @@ function kept_note(taken_at: string): string {
110
108
  // The write is swallowed for the same reason the gate's is: the brief has already been printed and
111
109
  // is correct, so a temp-directory problem must not turn it into a non-zero exit. What a missing
112
110
  // snapshot costs is a round 2 that reviews the whole change — wider, never narrower.
113
- // **The base is recorded beside the file map** (joshuafolkken/kit#1537). The map is a diff against
111
+ // **The base is recorded beside the file map**. The map is a diff against
114
112
  // `change_base`, and `change_base` is recomputed on every invocation — so without the commit it was
115
113
  // measured against, round 2 cannot tell a fix from a base that moved under it, and reports the
116
114
  // difference between two incomparable sets as round 1's fixes.
@@ -137,13 +135,13 @@ function record_round_one(
137
135
  }
138
136
  }
139
137
 
140
- // **Recorded before it is printed, and the write is not swallowed** (joshuafolkken/kit#1522). The
138
+ // **Recorded before it is printed, and the write is not swallowed**. The
141
139
  // nonce the brief prints is a contract the run enforces later; a brief that printed one it had
142
140
  // failed to record would hand the review a command that cannot succeed and the run a check that
143
141
  // answers `not-required` — the guard gone, silently, which is the shape this whole record exists to
144
142
  // remove.
145
143
  //
146
- // **Whether this is a resume is read first** (joshuafolkken/kit#2945): `record_target` drops the
144
+ // **Whether this is a resume is read first**: `record_target` drops the
147
145
  // previous nonce's records, so asked afterwards the finished review would always read as absent. The
148
146
  // findings file is the ship's, keyed on `PROJECT_ROOT` as the ship keys it; a review run outside the
149
147
  // ship writes none, so it never reads as a resume and keeps the whole change.
@@ -180,7 +178,7 @@ async function open_contract(): Promise<{
180
178
  return { checkout, nonce: review_attest.record_target(checkout, checkout.root), resumed_from }
181
179
  }
182
180
 
183
- // Retaken on every round-1 brief, after the pointer it pairs with (joshuafolkken/kit#2945). Swallowed:
181
+ // Retaken on every round-1 brief, after the pointer it pairs with. Swallowed:
184
182
  // a record that failed to write predates the next pointer, so the resume widens rather than narrows.
185
183
  function record_briefed(round: number, tree: Record<string, string>, base?: string): void {
186
184
  if (round !== FIRST_ROUND) return
@@ -200,7 +198,7 @@ interface ComposeRequest {
200
198
  profile: AgentProfile
201
199
  }
202
200
 
203
- // **Swallowed, and the brief keeps its target line** (joshuafolkken/kit#2963): parts that could not be
201
+ // **Swallowed, and the brief keeps its target line**: parts that could not be
204
202
  // written leave the reviewer the whole `git diff` to read, which costs truncated output rather than
205
203
  // scope — the direction every failure here falls.
206
204
  async function read_diff(
@@ -234,9 +232,9 @@ async function compose_brief(request: ComposeRequest): Promise<string> {
234
232
  stamps,
235
233
  // Resolved by the caller rather than printed as a `$(…)` the forked agent would expand: a
236
234
  // subshell that fails expands to nothing, and the bare `git diff` left behind lists only the
237
- // unstaged working tree — a review silently narrowed to a fraction of the change
238
- // (joshuafolkken/kit#1527). One reading is shared with the record written below, so the commit
239
- // the map is stored against is the same one the brief printed (joshuafolkken/kit#1537).
235
+ // unstaged working tree — a review silently narrowed to a fraction of the change.
236
+ // One reading is shared with the record written below, so the commit
237
+ // the map is stored against is the same one the brief printed.
240
238
  base,
241
239
  rubric_path: RUBRIC_PATH,
242
240
  ...contract,
@@ -244,7 +242,7 @@ async function compose_brief(request: ComposeRequest): Promise<string> {
244
242
  })
245
243
  }
246
244
 
247
- // **What is printed and what is recorded are two readings of one thing** (joshuafolkken/kit#1537).
245
+ // **What is printed and what is recorded are two readings of one thing**.
248
246
  // `commit` is what the record stores and round 2 compares, and it has to be a commit: `change_base`
249
247
  // degrades to the default-branch *name* when `merge-base` cannot answer, and two rounds storing that
250
248
  // same name compare equal while the ref moves under them — the guard failing open, which is the
@@ -256,7 +254,7 @@ async function read_bases(): Promise<{ base: string; commit: string | undefined
256
254
  return { base: commit ?? (await git_command.change_base()), commit }
257
255
  }
258
256
 
259
- // **The refusal goes to stderr and the exit code, never into the brief** (joshuafolkken/kit#1511).
257
+ // **The refusal goes to stderr and the exit code, never into the brief**.
260
258
  // A line printed inside a brief is read by the review agent as one more fact about the tree; what has
261
259
  // to happen here is that no brief is composed at all, since composing one is what starts round 1 —
262
260
  // and this command is where `review:attest` mints the nonce a round is counted against, so there is
@@ -318,6 +316,7 @@ async function run_review(round: number, reading: ChangeReading): Promise<number
318
316
  const resolved = agent_role_profile.resolve(agent_role_profile.REVIEWER)
319
317
 
320
318
  if (resolved.kind === 'rejected') return report_error(resolved.note)
319
+ agent_role_profile.warn_of_default()
321
320
  console.info(await compose_brief({ round, paths, tree, base, profile: resolved.profile }))
322
321
  record_round_one(round, tree, commit)
323
322
  record_briefed(round, tree, commit)
@@ -4,15 +4,13 @@ import { review_checkout, type ReviewCheckout } from './review-checkout'
4
4
  import { review_diff_parts, type DiffParts } from './review-diff-parts'
5
5
 
6
6
  // The text `josh review:brief` prints — the `/code-review` invocation, composed from what the run
7
- // already knows (joshuafolkken/kit#1241).
7
+ // already knows.
8
8
  //
9
9
  // **Why a command and not a paragraph in `prompts/review.md`.** `/code-review` runs in a forked
10
10
  // process and reads none of this repository's documents; the only thing that reaches it is the
11
- // argument it is invoked with. Measured on joshuafolkken/kit#1240: both rounds re-ran the unit suite
12
- // `josh gate` had just passed, both fumbled the runner (`npx vitest`, then a retry), and round 2
13
- // re-read the whole diff — 439 seconds for a seven-file change. joshuafolkken/kit#1219 had already
14
- // redefined round 2 as a verification pass **in a document the agent never opens**, which is why it
15
- // cut nothing.
11
+ // argument it is invoked with. Without it a round re-runs the unit suite `josh gate` just passed,
12
+ // fumbles the runner (`npx vitest`, then a retry), and round 2 re-reads the whole diff — a rule
13
+ // written **in a document the agent never opens** cuts nothing.
16
14
  //
17
15
  // **What is mechanical and what is only an instruction.** The round-2 target is mechanical: the
18
16
  // paths are computed from a digest comparison and handed over as the scope. The "already verified"
@@ -22,8 +20,8 @@ import { review_diff_parts, type DiffParts } from './review-diff-parts'
22
20
  const TEST_COMMAND_LINE =
23
21
  '- The unit suite is `pnpm josh test:unit`. Do not reach for `npx vitest`; it is not how this project runs them.'
24
22
 
25
- // **The checkout block, and why the target below names a path instead of assuming one**
26
- // (joshuafolkken/kit#1522). `/code-review` is forked by the harness and inherits the session's
23
+ // **The checkout block, and why the target below names a path instead of assuming one**.
24
+ // `/code-review` is forked by the harness and inherits the session's
27
25
  // working directory, so during a lane run it starts in a tree that holds the previous child's
28
26
  // already-merged code. Reading that tree, it finds nothing wrong and says so — and the run reads
29
27
  // that silence as a clean review. Neither half of this block is a paragraph a person has to remember
@@ -41,7 +39,7 @@ function attest_line(nonce: string): string {
41
39
  return `Attest before you report: run \`pnpm josh review:attest ${nonce}\` from the checkout you actually read. A non-zero exit means it was not the one above — report \`REVIEW TARGET MISMATCH\` and no findings. Never report "no findings" without that command having passed: a review of the wrong tree finds nothing wrong, and the run cannot tell that apart from approval (joshuafolkken/kit#1522).`
42
40
  }
43
41
 
44
- // **The rubric is handed over by path, not pasted in** (joshuafolkken/kit#1927). `/code-review` runs
42
+ // **The rubric is handed over by path, not pasted in**. `/code-review` runs
45
43
  // in a forked process that reads none of this repository's documents, so the severity tests, the nine
46
44
  // categories and the output format never reached it — the review scored the diff on whatever the
47
45
  // forked skill happened to carry. The reviewer has file access (it already runs `git -C <root> …` and
@@ -49,7 +47,7 @@ function attest_line(nonce: string): string {
49
47
  // and applied before anything is reported. Absolute because a forked agent resolves a relative path
50
48
  // against the tree it was spawned in, which is the wrong one during a lane run.
51
49
  //
52
- // **The path is the kit package's, not the review checkout's** (joshuafolkken/kit#2402). The rubric
50
+ // **The path is the kit package's, not the review checkout's**. The rubric
53
51
  // ships inside the kit package (`node_modules/@joshuafolkken/kit/prompts/`), not in a consumer's own
54
52
  // tree — so deriving it from the review checkout root pointed at a `prompts/` a `docs/`-less consumer
55
53
  // never receives, and the review ran without the scoring rules. The caller resolves it against the
@@ -71,7 +69,7 @@ function checkout_block(checkout: ReviewCheckout, nonce: string): string {
71
69
  // `-C <root>` rather than a bare `git diff`, so the command works from whatever directory the
72
70
  // forked agent happens to be sitting in rather than only from the right one.
73
71
  //
74
- // **The base is the merge base, not `main` itself** (joshuafolkken/kit#1527). A linked work tree
72
+ // **The base is the merge base, not `main` itself**. A linked work tree
75
73
  // shares the `main` ref with every other lane, so a two-dot `git diff main` run in an unmerged lane
76
74
  // lists whatever another lane merged in the meantime — in reverse. This line is a command the forked
77
75
  // agent runs, so printing the old spelling would hand it exactly the mixed-in listing the reading
@@ -124,7 +122,7 @@ function verified_line(taken_at: string): string {
124
122
  return `Already verified — do not re-run these:\n- lint, the type check, the spell check and the unit tests all passed on this exact tree at ${taken_at} (\`pnpm josh gate\`).`
125
123
  }
126
124
 
127
- // **The in-flight sentence claims no result, and that is the point** (joshuafolkken/kit#1242). The
125
+ // **The in-flight sentence claims no result, and that is the point**. The
128
126
  // gate and this review are started together, so the honest thing to say is that a gate is running —
129
127
  // not that it passed. What it forbids is re-running the unit suite, which is wasted whether the gate
130
128
  // ends green or red, and it names who joins the result so the reader knows the check is not being
@@ -139,7 +137,7 @@ function in_flight_line(taken_at: string): string {
139
137
  // digests alone it would say a gate is running for as long as nobody edits that tree, about a process
140
138
  // that no longer exists: exactly the state the record must never describe.
141
139
  //
142
- // **The written pid alone did not separate the two** (joshuafolkken/kit#1245). It names whatever holds
140
+ // **The written pid alone did not separate the two**. It names whatever holds
143
141
  // that number now, so once the operating system reissued it the abandoned marker passed the liveness
144
142
  // probe again and this line went back to printing `Running now` about nothing — the same untrue
145
143
  // sentence, reached by a longer route. The record therefore carries the writing process's start time
@@ -156,7 +154,7 @@ function live_marker(
156
154
  return matched
157
155
  }
158
156
 
159
- // **Matching digests are not enough for the green claim** (joshuafolkken/kit#1537). The map covers
157
+ // **Matching digests are not enough for the green claim**. The map covers
160
158
  // the paths the change makes changed, so a merge of the default branch that touches nothing the
161
159
  // branch touches leaves every digest identical while the tree gains code the gate never read —
162
160
  // and the brief would tell the reviewer that lint, the type check, the spell check and the unit tests
@@ -202,8 +200,8 @@ function format_paths(root: string, paths: ReadonlyArray<string>): string {
202
200
  return paths.map((relative) => ` ${root}/${relative}`).join('\n')
203
201
  }
204
202
 
205
- // **An empty target has two readings, and only one of them is "nothing changed"**
206
- // (joshuafolkken/kit#1537). Since the delta is intersected with the change, round 1's fixes can be
203
+ // **An empty target has two readings, and only one of them is "nothing changed"**.
204
+ // Since the delta is intersected with the change, round 1's fixes can be
207
205
  // real and still leave no target — a fix that reverts a file to its base content takes that path out
208
206
  // of `git diff` altogether. Printing "nothing changed since round 1" there would contradict the
209
207
  // `Not in this change` list directly below it, which is the self-disagreement this whole change
@@ -219,10 +217,10 @@ function round_two_target(root: string, scope: RoundTwoScope): string {
219
217
  return scope.dropped.length > 0 ? NOTHING_LEFT_LINE : EMPTY_DELTA_LINE
220
218
  }
221
219
 
222
- // **What round 2 is sent to read, reconciled against the change it is meant to cover**
223
- // (joshuafolkken/kit#1537). The delta alone is not that list. It is the difference between two file
224
- // maps, each one a diff against `change_base` **as it stood when that map was taken** — and nothing
225
- // used to record which commit that was. Move the base between the rounds, which is exactly what a
220
+ // **What round 2 is sent to read, reconciled against the change it is meant to cover**.
221
+ // The delta alone is not that list. It is the difference between two file
222
+ // maps, each one a diff against `change_base` **as it stood when that map was taken**, so the record
223
+ // must name which commit that was. Move the base between the rounds, which is exactly what a
226
224
  // resumed run's merge of the default branch does, and the two maps stop covering the same set of
227
225
  // paths: their difference then names files the branch never touched and misses files it did.
228
226
  //
@@ -247,8 +245,8 @@ function sorted_names(names: ReadonlyArray<string>): ReadonlyArray<string> {
247
245
  }
248
246
 
249
247
  // A record that cannot be compared widens the round to the whole change rather than narrowing it, so
250
- // every path the change touches is a target. This is the same direction joshuafolkken/kit#1241 chose
251
- // for a missing record, extended to a record that is present and unusable.
248
+ // every path the change touches is a target — the same direction as for a missing record, extended
249
+ // to a record that is present and unusable.
252
250
  function whole_change_scope(tree: Record<string, string>): RoundTwoScope {
253
251
  return {
254
252
  recorded_at: undefined,
@@ -320,8 +318,7 @@ function reconciliation(root: string, base: string, scope: RoundTwoScope): Reado
320
318
  ]
321
319
  }
322
320
 
323
- // The snapshot's own timestamp, printed rather than assumed. Since joshuafolkken/kit#1441 the record
324
- // is round 1's own — written once per run, and kept by a later round-1 invocation rather than retaken
321
+ // The snapshot's own timestamp, printed rather than assumed. The record is round 1's own — written once per run, and kept by a later round-1 invocation rather than retaken
325
322
  // against the fixed tree — so this line says how far back the target below is measured from. A record
326
323
  // left behind by a run that never reached `josh followup` makes the target wider, and its timestamp is
327
324
  // the only thing that shows that from here.
@@ -358,8 +355,8 @@ function round_two_block(
358
355
  return narrow_block(scope.recorded_at, scope, root, base)
359
356
  }
360
357
 
361
- // **A resumed round 1 reads what changed since the attested review, reusing round 2's reconciliation**
362
- // (joshuafolkken/kit#2945). A ship that stopped and was re-issued briefed the whole change again, so
358
+ // **A resumed round 1 reads what changed since the attested review, reusing round 2's reconciliation**.
359
+ // A ship that stopped and was re-issued briefed the whole change again, so
363
360
  // the reviewer re-read every file the attested review had just read. The scope is the comparison round
364
361
  // 2 makes, measured from the tree that review was briefed on. Every reading that cannot narrow falls back to the whole
365
362
  // change: no record, a moved base, or an empty target. An empty target is included because a resumed
@@ -406,15 +403,15 @@ interface BriefInput {
406
403
  checkout: ReviewCheckout
407
404
  nonce: string
408
405
  // The commit the change is measured against, resolved by the caller so the printed target carries
409
- // a value rather than a subshell that can fail open (joshuafolkken/kit#1527).
406
+ // a value rather than a subshell that can fail open.
410
407
  base: string
411
408
  // The rubric's absolute path, resolved by the caller against the kit package rather than the review
412
- // checkout, so it resolves in a consumer that ships no `prompts/` of its own (joshuafolkken/kit#2402).
409
+ // checkout, so it resolves in a consumer that ships no `prompts/` of its own.
413
410
  rubric_path: string
414
- // The tree a finished, clean review of this branch was briefed on, so round 1 is a resume
415
- // (joshuafolkken/kit#2945). Absent, round 1 reads the whole change.
411
+ // The tree a finished, clean review of this branch was briefed on, so round 1 is a resume.
412
+ // Absent, round 1 reads the whole change.
416
413
  resumed_from?: FileMapStamp | undefined
417
- // The change written as parts under the Bash output cap (joshuafolkken/kit#2963). Absent when the
414
+ // The change written as parts under the Bash output cap. Absent when the
418
415
  // write failed, and the target line alone then names the change.
419
416
  diff?: { parts: DiffParts; cap: number } | undefined
420
417
  }
@@ -435,7 +432,7 @@ function target_block(input: BriefInput): string {
435
432
  return round_two_block(input.stamps.round_one, input.tree, input.checkout.root, input.base)
436
433
  }
437
434
 
438
- // **Only beside a whole-change target** (joshuafolkken/kit#2963): each part is a path's diff against
435
+ // **Only beside a whole-change target**: each part is a path's diff against
439
436
  // the base, so beside a narrowed round 2 or a resumed round 1 the list would hand the reviewer the
440
437
  // code that narrowing exists to keep out of scope. Decided by the target actually printed, not by
441
438
  // the round: every round that cannot narrow widens through `whole_change_target`, and that round
@@ -1,7 +1,7 @@
1
1
  import { git_command } from '#scripts/git/git-command'
2
2
 
3
3
  // The checkout `josh review:brief` is describing — the one thing the forked `/code-review` agent
4
- // cannot work out for itself (joshuafolkken/kit#1522).
4
+ // cannot work out for itself.
5
5
  //
6
6
  // **`/code-review` runs in a fork that inherits the *session's* working directory, not the run's.**
7
7
  // Where the run implementing the change is a lane — a linked work tree under `.kit-lanes/` — that is
@@ -23,7 +23,7 @@ interface ReviewCheckout {
23
23
 
24
24
  // Three git reads that do not depend on each other, so they are issued together rather than one after
25
25
  // another: the brief is printed in front of a review the run is waiting on. The root is a near-instant
26
- // synchronous `rev-parse` (joshuafolkken/kit#3065); the branch and head still overlap.
26
+ // synchronous `rev-parse`; the branch and head still overlap.
27
27
  async function read_checkout(): Promise<ReviewCheckout> {
28
28
  const [root, branch, head] = await Promise.all([
29
29
  git_command.repository_root(),
@@ -1,8 +1,6 @@
1
- // The change handed to the reviewer as files no larger than the Bash output cap
2
- // (joshuafolkken/kit#2963). The brief used to name the whole change as one `git diff` and the rubric
3
- // as one path, and the forked reviewer printed both through Bash: every print past
4
- // `BASH_MAX_OUTPUT_LENGTH` came back as a truncated preview plus a saved file it then re-read, and both
5
- // stayed in the cached prefix of every later request — 120 overflows and 68 re-reads in one review.
1
+ // The change handed to the reviewer as files no larger than the Bash output cap.
2
+ // A print past `BASH_MAX_OUTPUT_LENGTH` comes back as a truncated preview plus a saved file the
3
+ // reviewer then re-reads, and both stay in the cached prefix of every later request.
6
4
  //
7
5
  // **The diff is split, not shortened.** Each changed path gets its own parts, every part fits under the
8
6
  // cap, and the parts of one path concatenate back to exactly its diff — so the scope a review covers
@@ -4,7 +4,7 @@ import { git_spawn } from '#scripts/git/git-spawn'
4
4
  import { stamp_file } from '#scripts/josh/stamp-file'
5
5
  import { review_diff_parts, type DiffParts } from './review-diff-parts'
6
6
 
7
- // Writes the change as the parts `review-diff-parts.ts` cuts it into (joshuafolkken/kit#2963).
7
+ // Writes the change as the parts `review-diff-parts.ts` cuts it into.
8
8
  //
9
9
  // **One diff per path, read the way the target line defines the change** — `git -C <root> diff
10
10
  // <base> -- <path>` for a tracked path, and the file's own content for an untracked one, which no
@@ -1,5 +1,7 @@
1
+ import { issue_cite } from '#scripts/issue/issue-cite'
2
+
1
3
  // The review-finding line's grammar, its category vocabulary and the aggregation over it — the single
2
- // place all three are defined (joshuafolkken/kit#2325). A `/code-review` round's findings evaporated
4
+ // place all three are defined. A `/code-review` round's findings evaporated
3
5
  // the moment they were fixed, so no one could say which category recurred. They now land in the same
4
6
  // append-only ledger the observation lines use (`.josh/observations/`), under a distinct `- rf:`
5
7
  // prefix so `observation-ledger-line.ts`'s `- k:` grammar never treats them as its own — one ledger,
@@ -60,7 +62,7 @@ function is_valid_file(file: string): boolean {
60
62
  }
61
63
 
62
64
  function issue_field(issue: number): string {
63
- return `#${String(issue)}`
65
+ return issue_cite.plain(issue)
64
66
  }
65
67
 
66
68
  function line_of(fields: ReadonlyArray<string>): string {
@@ -132,7 +134,7 @@ function zero_round_count(content: string): number {
132
134
 
133
135
  // The issue a finding line is keyed to — its fifth field, the `#<N>` token — or `undefined` for a
134
136
  // non-finding or malformed line. The record check reads this to ask whether a given issue's round was
135
- // recorded at all (joshuafolkken/kit#2343).
137
+ // recorded at all.
136
138
  function issue_of(line: string): string | undefined {
137
139
  const fields = line.trimStart().slice(FINDING_PREFIX.length).split(FIELD_SEPARATOR)
138
140
 
@@ -142,7 +144,7 @@ function issue_of(line: string): string | undefined {
142
144
  // **A `none` zero-round line counts as recorded, exactly like a real finding line does.** The gate
143
145
  // asks whether the round was recorded, not whether it found anything — reading the issue field, which
144
146
  // a zero-finding line carries too, is what keeps a clean round's single line from reading as "nobody
145
- // recorded this" (joshuafolkken/kit#2343).
147
+ // recorded this".
146
148
  function has_issue_record(content: string, issue: number): boolean {
147
149
  const target = issue_field(issue)
148
150
 
@@ -158,6 +160,7 @@ const review_finding_ledger = {
158
160
  is_finding_line,
159
161
  is_severity,
160
162
  is_valid_file,
163
+ SEVERITIES,
161
164
  zero_round_count,
162
165
  zero_round_line,
163
166
  }
@@ -3,7 +3,7 @@ import { fileURLToPath } from 'node:url'
3
3
  import { observation_ledger_home } from '#scripts/observations/observation-ledger-home'
4
4
  import { review_finding_ledger, type CategoryCount } from './review-finding-ledger'
5
5
 
6
- // `josh review:findings` — the reader over the review-finding ledger (joshuafolkken/kit#2325). It
6
+ // `josh review:findings` — the reader over the review-finding ledger. It
7
7
  // prints each recurring category's count, most frequent first, and the number of rounds that recorded
8
8
  // zero findings — the denominator that tells a genuinely quiet category apart from one nobody looked
9
9
  // at. The write half is `pnpm josh review:record`; both read one grammar from `review-finding-ledger`.
@@ -26,7 +26,7 @@ function format_report(counts: ReadonlyArray<CategoryCount>, zero_rounds: number
26
26
  return `findings by category:\n${body}\n${zero_line(zero_rounds)}`
27
27
  }
28
28
 
29
- // Every issue's file of the ledger directory is counted (joshuafolkken/kit#2919): a recurring category
29
+ // Every issue's file of the ledger directory is counted: a recurring category
30
30
  // is one whichever issue recorded each sighting.
31
31
  async function run(root: string = observation_ledger_home.ledger_root()): Promise<number> {
32
32
  const content = (await observation_ledger_home.read(root)) ?? ''
@@ -1,5 +1,4 @@
1
- // Which `/code-review` level a change is reviewed at, decided from the changed paths alone
2
- // (joshuafolkken/kit#966).
1
+ // Which `/code-review` level a change is reviewed at, decided from the changed paths alone.
3
2
  //
4
3
  // **The decision takes no judgement.** "This one is small" is a judgement made under cost pressure,
5
4
  // and cost pressure resolves it toward "small" exactly when a defect is most likely to be shipped —
@@ -24,11 +23,9 @@ const REDUCED_LEVEL: ReviewLevel = 'low'
24
23
  // **Documentation is deliberately absent from this list**, which is the opposite of what the
25
24
  // "Non-runtime updates" testing exception does with it, and the difference is not an oversight.
26
25
  // That exception is about whether an automated test could have caught the defect; this is about
27
- // whether a human reading the diff is the only thing that can. Measured on this epic:
28
- // joshuafolkken/kit#963 and #965 were both documentation-only by that classification, and a
29
- // `medium` review found ten real defects in each — dangling pointers into sections that had been
30
- // removed, and citations naming the wrong file, in artifacts distributed to every consumer. No test
31
- // covered them, because prose is what they were.
26
+ // whether a human reading the diff is the only thing that can. Documentation-only diffs carry real
27
+ // defects — dangling pointers into removed sections, and citations naming the wrong file, in
28
+ // artifacts distributed to every consumer — that no test covers, because prose is what they are.
32
29
  const INERT_PATHS: ReadonlyArray<string> = [
33
30
  '.editorconfig',
34
31
  '.gitignore',
@@ -1,31 +1,45 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { fileURLToPath } from 'node:url'
3
+ import { git_gh_issue_write } from '#scripts/gh/git-gh-issue-write'
4
+ import { issue_number_shape } from '#scripts/issue/issue-number-shape'
3
5
  import { cli_flags } from '#scripts/lib/cli-flags'
4
6
  import { observation_ledger_home } from '#scripts/observations/observation-ledger-home'
5
7
  import { review_finding_ledger, type Finding } from './review-finding-ledger'
6
8
  import { review_record, type RecordVerdict } from './review-record'
7
9
 
8
10
  // `josh review:record --issue <N> [<category>:<severity>:<file> ...]` — the one write path for a
9
- // `/code-review` round's findings (joshuafolkken/kit#2325). It appends a `- rf:` line per finding to
11
+ // `/code-review` round's findings. It appends a `- rf:` line per finding to
10
12
  // the issue's own file of the observation ledger, which the run's commit carries like any other
11
13
  // ledger change. **A call with no findings is a zero-finding round, and it still writes one line** — so the
12
14
  // round that found nothing is recorded rather than mistaken for a round nobody reviewed.
13
15
  //
16
+ // **`--comment` records a round that ran after the pull request opened**: the same lines go to the
17
+ // issue as a comment and nothing is appended. A line written to the tree then has no commit of the
18
+ // run's left to ride, so `pnpm josh followup` would push it onto the open pull request and its CI
19
+ // would start over.
20
+ //
14
21
  // `josh review:record --check --issue <N>` is the read half `pnpm josh followup` runs before it
15
- // merges (joshuafolkken/kit#2343): `ok` / `not-required` exit zero, `missing` exits non-zero so the
22
+ // merges: `ok` / `not-required` exit zero, `missing` exits non-zero so the
16
23
  // merge is refused until the round is recorded. It mirrors `josh review:attest --check`.
17
24
 
18
25
  const ARGV_OFFSET = 2
19
26
  const FAILURE_EXIT_CODE = 1
20
- const DATE_END = 10
21
27
  const USAGE =
22
- 'Usage: josh review:record --issue <N> [<category>:<severity>:<file> ...] | josh review:record --check --issue <N>'
28
+ 'Usage: josh review:record --issue <N> [--comment] [<category>:<severity>:<file> ...] | josh review:record --check --issue <N>'
29
+ const FILE_HINT = ' <file>: the cited path, optionally with :line'
23
30
  const CHECK_USAGE = 'Usage: josh review:record --check --issue <N>'
24
31
  const RECORDED_LINE = 'Recorded: the review round for this issue is in the ledger.'
25
32
  const NOT_REQUIRED_LINE =
26
33
  'No review-finding ledger is kept in this checkout, so there is nothing to check.'
27
- const ISSUE_PATTERN = /^[1-9]\d*$/u
28
- const OPTIONS = { issue: { type: 'string' }, check: { type: 'boolean' } } as const
34
+ const COMMENT_HEADING = '### Review round recorded after the pull request opened'
35
+ const COMMENT_NOTE =
36
+ 'Kept here rather than in the observation ledger: a line appended after the commit would be pushed onto the open pull request and restart its CI.'
37
+ const CODE_FENCE = '```'
38
+ const OPTIONS = {
39
+ issue: { type: 'string' },
40
+ check: { type: 'boolean' },
41
+ comment: { type: 'boolean' },
42
+ } as const
29
43
 
30
44
  interface Request {
31
45
  issue: number
@@ -34,6 +48,7 @@ interface Request {
34
48
 
35
49
  interface Parsed {
36
50
  check: boolean
51
+ comment: boolean
37
52
  issue: string | undefined
38
53
  positionals: ReadonlyArray<string>
39
54
  }
@@ -77,6 +92,7 @@ function parse_argv(argv: ReadonlyArray<string>): Parsed | undefined {
77
92
 
78
93
  return {
79
94
  check: parsed.values.check === true,
95
+ comment: parsed.values.comment === true,
80
96
  issue: parsed.values.issue,
81
97
  positionals: parsed.positionals,
82
98
  }
@@ -85,15 +101,26 @@ function parse_argv(argv: ReadonlyArray<string>): Parsed | undefined {
85
101
  function to_request(parsed: Parsed): Request | undefined {
86
102
  const { issue } = parsed
87
103
 
88
- if (issue === undefined || !ISSUE_PATTERN.test(issue)) return undefined
104
+ if (issue === undefined || !issue_number_shape.ISSUE_NUMBER_PATTERN.test(issue)) return undefined
89
105
 
90
106
  const findings = parse_findings(parsed.positionals)
91
107
 
92
108
  return findings === undefined ? undefined : { issue: Number(issue), findings }
93
109
  }
94
110
 
95
- function today(now: Date): string {
96
- return now.toISOString().slice(0, DATE_END)
111
+ // The accepted values are built from the ledger's own vocabulary, so a
112
+ // refused spec names what would have been accepted and a new category appears here unedited.
113
+ function accepted_values(placeholder: string, values: ReadonlyArray<string>): string {
114
+ return ` ${placeholder}: ${values.join(' | ')}`
115
+ }
116
+
117
+ function usage_text(): string {
118
+ return [
119
+ USAGE,
120
+ accepted_values('<category>', review_finding_ledger.CATEGORIES),
121
+ accepted_values('<severity>', review_finding_ledger.SEVERITIES),
122
+ FILE_HINT,
123
+ ].join('\n')
97
124
  }
98
125
 
99
126
  function build_lines(request: Request, date: string): ReadonlyArray<string> {
@@ -115,7 +142,7 @@ function check_line(verdict: RecordVerdict): string {
115
142
  }
116
143
 
117
144
  async function run_check(issue: string | undefined, root: string): Promise<number> {
118
- if (issue === undefined || !ISSUE_PATTERN.test(issue)) {
145
+ if (issue === undefined || !issue_number_shape.ISSUE_NUMBER_PATTERN.test(issue)) {
119
146
  console.error(CHECK_USAGE)
120
147
 
121
148
  return FAILURE_EXIT_CODE
@@ -134,18 +161,41 @@ async function run_check(issue: string | undefined, root: string): Promise<numbe
134
161
  return FAILURE_EXIT_CODE
135
162
  }
136
163
 
137
- // The round lands in its own issue's file (joshuafolkken/kit#2919), so two lanes recording at once
164
+ function comment_body(lines: ReadonlyArray<string>): string {
165
+ return [COMMENT_HEADING, '', COMMENT_NOTE, '', CODE_FENCE, ...lines, CODE_FENCE].join('\n')
166
+ }
167
+
168
+ // **A comment that could not be posted fails the record**: it is the round's only copy, so a
169
+ // swallowed refusal would read as a recorded round that exists nowhere.
170
+ async function post_comment(issue: number, lines: ReadonlyArray<string>): Promise<number> {
171
+ try {
172
+ const url = await git_gh_issue_write.issue_comment(String(issue), comment_body(lines))
173
+
174
+ console.info(`Recorded ${String(lines.length)} review-finding line(s) in ${url.trim()}.`)
175
+
176
+ return 0
177
+ } catch (error) {
178
+ console.error(error instanceof Error ? error.message : String(error))
179
+
180
+ return FAILURE_EXIT_CODE
181
+ }
182
+ }
183
+
184
+ // The round lands in its own issue's file, so two lanes recording at once
138
185
  // write two files, and their pull requests never conflict on the ledger.
139
186
  async function run_record(parsed: Parsed, now: Date, root: string): Promise<number> {
140
187
  const request = to_request(parsed)
141
188
 
142
189
  if (request === undefined) {
143
- console.error(USAGE)
190
+ console.error(usage_text())
144
191
 
145
192
  return FAILURE_EXIT_CODE
146
193
  }
147
194
 
148
- const lines = build_lines(request, today(now))
195
+ const lines = build_lines(request, observation_ledger_home.ledger_date(now))
196
+
197
+ if (parsed.comment) return await post_comment(request.issue, lines)
198
+
149
199
  const ledger_path = observation_ledger_home.issue_path(request.issue, root)
150
200
 
151
201
  await observation_ledger_home.append(ledger_path, lines)
@@ -154,7 +204,7 @@ async function run_record(parsed: Parsed, now: Date, root: string): Promise<numb
154
204
  return 0
155
205
  }
156
206
 
157
- // **The default is the work tree the command runs in, a lane's inside a lane** (joshuafolkken/kit#2919).
207
+ // **The default is the work tree the command runs in, a lane's inside a lane**.
158
208
  // The line rides that tree's own commit or `pnpm josh followup`'s pre-merge ledger commit, and
159
209
  // `--check` reads the same tree, so the two halves can never disagree about where the round is.
160
210
  async function run(
@@ -165,7 +215,7 @@ async function run(
165
215
  const parsed = parse_argv(argv)
166
216
 
167
217
  if (parsed === undefined) {
168
- console.error(USAGE)
218
+ console.error(usage_text())
169
219
 
170
220
  return FAILURE_EXIT_CODE
171
221
  }
@@ -179,7 +229,14 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
179
229
  process.exitCode = await run(argv, new Date())
180
230
  }
181
231
 
182
- const review_record_cli = { build_lines, parse_finding, run }
232
+ const review_record_cli = {
233
+ accepted_values,
234
+ build_lines,
235
+ comment_body,
236
+ parse_finding,
237
+ run,
238
+ usage_text,
239
+ }
183
240
 
184
241
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
185
242