@joshuafolkken/kit 1.1050.0 → 1.1094.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 (581) hide show
  1. package/.claude/settings.json +9 -8
  2. package/.claude/skills/epic-commands/SKILL.md +5 -7
  3. package/.claude/skills/workflow-commands/SKILL.md +19 -11
  4. package/.claude/skills/workflow-commands/background-commands.md +4 -3
  5. package/.claude/skills/workflow-commands/backlogrun-child.md +1 -1
  6. package/.claude/skills/workflow-commands/backlogrun-lanes.md +8 -6
  7. package/.claude/skills/workflow-commands/backlogrun-progress.md +1 -1
  8. package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
  9. package/.claude/skills/workflow-commands/backlogrun.md +2 -2
  10. package/.claude/skills/workflow-commands/chain-rule.md +4 -2
  11. package/.claude/skills/workflow-commands/delegation.md +3 -3
  12. package/.claude/skills/workflow-commands/followup-reference.md +1 -1
  13. package/.claude/skills/workflow-commands/followup.md +7 -3
  14. package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
  15. package/.claude/skills/workflow-commands/fullrun.md +3 -2
  16. package/.claude/skills/workflow-commands/halfrun.md +16 -19
  17. package/.claude/skills/workflow-commands/issue-comments.md +1 -1
  18. package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
  19. package/.claude/skills/workflow-commands/issue-scout.md +1 -1
  20. package/.claude/skills/workflow-commands/kickoff.md +9 -4
  21. package/.claude/skills/workflow-commands/latest-gate.md +1 -1
  22. package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
  23. package/.claude/skills/workflow-commands/observation-filing.md +3 -3
  24. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  25. package/.claude/skills/workflow-commands/prrun.md +36 -0
  26. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  27. package/.claude/skills/workflow-commands/working-tree-hold.md +22 -2
  28. package/.codex/hooks.json +16 -20
  29. package/.github/actions/setup-pnpm/action.yml +93 -0
  30. package/.github/dependabot.yml +5 -1
  31. package/.github/workflows/ci.yml +26 -128
  32. package/.github/workflows/pr-classification.yml +5 -41
  33. package/.github/workflows/publish.yml +33 -38
  34. package/.github/workflows/sonar-qube.yml +37 -4
  35. package/AGENTS.md +12 -2
  36. package/CLAUDE.md +15 -16
  37. package/GEMINI.md +14 -2
  38. package/README.md +59 -18
  39. package/SECURITY.md +36 -6
  40. package/cspell/index.yaml +2 -1
  41. package/dist/CLAUDE.md +15 -16
  42. package/dist/config-merge/index.js +15 -3
  43. package/dist/hooks/batch-guard.js +4 -4
  44. package/dist/hooks/{chunk-HJIISEAC.js → chunk-3C4YCCEF.js} +5 -13
  45. package/dist/hooks/{chunk-EJDX2TOB.js → chunk-7ZPFAVR7.js} +7 -88
  46. package/dist/hooks/{chunk-WQ4OSBSS.js → chunk-E54KGFEQ.js} +2 -2
  47. package/dist/hooks/{chunk-GQ7KP45M.js → chunk-IL27YTPH.js} +2 -2
  48. package/dist/hooks/{chunk-DMQN45FN.js → chunk-KHWHKJOM.js} +3 -3
  49. package/dist/hooks/{chunk-5BK3K7V4.js → chunk-M2XDCUKD.js} +997 -478
  50. package/dist/hooks/{chunk-7VPDUBRN.js → chunk-NKOG3XAV.js} +150 -153
  51. package/dist/hooks/{chunk-NJQOBE6L.js → chunk-O4LL4HTI.js} +2 -7
  52. package/dist/hooks/{chunk-NAS4C7GP.js → chunk-OIZUHPJI.js} +2 -2
  53. package/dist/hooks/{chunk-RLDX5SOC.js → chunk-UD24EAIL.js} +2084 -1412
  54. package/dist/hooks/codex-hook-adapter.js +10 -11
  55. package/dist/hooks/duplicate-read-guard.js +5 -5
  56. package/dist/hooks/format-edited.js +2 -2
  57. package/dist/hooks/inputs.json +279 -0
  58. package/dist/hooks/investigation-guard.js +5 -5
  59. package/dist/hooks/pretool-guard.js +9 -9
  60. package/dist/hooks/session-lang.js +0 -1
  61. package/dist/hooks/stop-guard.js +178 -324
  62. package/dist/josh.js +162 -119
  63. package/dist/managed-marker/index.js +2 -1
  64. package/dist/version/index.js +34 -58
  65. package/eslint/rules/promise.js +5 -0
  66. package/package.json +9 -4
  67. package/prompts/collaboration-workflow/issue-citation.md +5 -5
  68. package/prompts/collaboration-workflow/operating-rules.md +4 -4
  69. package/prompts/collaboration-workflow/overview.md +13 -1
  70. package/prompts/collaboration-workflow/report-format.md +1 -1
  71. package/prompts/collaboration-workflow/residency.md +3 -3
  72. package/prompts/collaboration-workflow/rule-delivery.md +1 -1
  73. package/prompts/collaboration-workflow/turn-batching.md +3 -3
  74. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  75. package/prompts/collaboration-workflow/wip-cap.md +25 -22
  76. package/prompts/collaboration-workflow.md +5 -8
  77. package/prompts/review-rubric.md +1 -1
  78. package/prompts/review.md +3 -3
  79. package/prompts/sonar-hotspot-handling.md +11 -3
  80. package/prompts/testing-guide.md +3 -3
  81. package/scripts/adopt/adopt-toolkits.ts +0 -2
  82. package/scripts/adopt/adopt.ts +0 -2
  83. package/scripts/agent/agent-argv.ts +0 -2
  84. package/scripts/agent/agent-diagnostics.ts +1 -1
  85. package/scripts/agent/agent-role-profile.ts +0 -7
  86. package/scripts/agent/claude-agent-argv.ts +0 -2
  87. package/scripts/agent/codex-agent-argv.ts +1 -1
  88. package/scripts/agent/codex-hooks.ts +92 -0
  89. package/scripts/agent/interactive-ask.ts +1 -1
  90. package/scripts/auto-ok/auto-ok-cli.ts +6 -16
  91. package/scripts/backlog/backlog-budget.ts +0 -2
  92. package/scripts/backlog/backlog-defect-priority.ts +2 -2
  93. package/scripts/backlog/backlog-drive-cli.ts +10 -8
  94. package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
  95. package/scripts/backlog/backlog-drive-named.ts +2 -1
  96. package/scripts/backlog/backlog-drive.ts +76 -16
  97. package/scripts/backlog/backlog-named.ts +0 -3
  98. package/scripts/backlog/backlog-next.ts +9 -15
  99. package/scripts/backlog/backlog-offer-cli.ts +0 -5
  100. package/scripts/backlog/backlog-plan-cli.ts +1 -7
  101. package/scripts/backlog/backlog-plan.ts +1 -1
  102. package/scripts/backlog/backlog-pool.ts +3 -6
  103. package/scripts/backlog/backlog-rank.ts +2 -2
  104. package/scripts/backlog/backlog-ready.ts +19 -3
  105. package/scripts/backlog/backlog-scope.ts +1 -3
  106. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  107. package/scripts/backlog/backlog-stalled.ts +0 -1
  108. package/scripts/backlog/backlog-waves.ts +5 -2
  109. package/scripts/behavior/behavior-cli.ts +1 -1
  110. package/scripts/build/build-codex-hooks.ts +26 -0
  111. package/scripts/build/build-hooks.ts +85 -9
  112. package/scripts/build/hook-bundle-stamp.ts +111 -0
  113. package/scripts/cases/cases-cli.ts +1 -1
  114. package/scripts/cases/cases-logic.ts +1 -1
  115. package/scripts/ci/composite-actions.ts +30 -0
  116. package/scripts/ci/pr-classification.ts +3 -3
  117. package/scripts/claude/workflow-destination.ts +10 -1
  118. package/scripts/clone/clone-fingerprint.ts +0 -1
  119. package/scripts/clone/clone-scan-cli.ts +1 -1
  120. package/scripts/clone/clone-scan.ts +1 -1
  121. package/scripts/config-merge/json-format.ts +0 -1
  122. package/scripts/config-merge/patch-yaml-list.ts +1 -1
  123. package/scripts/cost-runtime/codex-usage.ts +2 -9
  124. package/scripts/cost-runtime/cost-attribute.ts +0 -1
  125. package/scripts/cost-runtime/cost-cli.ts +0 -3
  126. package/scripts/cost-runtime/cost-corpus.ts +0 -2
  127. package/scripts/cost-runtime/cost-format.ts +0 -3
  128. package/scripts/cost-runtime/cost-pricing.ts +0 -1
  129. package/scripts/cost-runtime/cost-tokens.ts +0 -1
  130. package/scripts/delegation/delegation-cli.ts +1 -1
  131. package/scripts/delegation/delegation-policy.ts +0 -1
  132. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  133. package/scripts/delegation/fanout-cli.ts +1 -1
  134. package/scripts/delegation/fanout.ts +0 -2
  135. package/scripts/delegation/investigation-reads.ts +1 -164
  136. package/scripts/discovery/repo-map-logic.ts +0 -1
  137. package/scripts/discovery/repo-party-cli.ts +1 -1
  138. package/scripts/doctor/doctor-consumer.ts +4 -6
  139. package/scripts/doctor/doctor-logic.ts +0 -4
  140. package/scripts/doctor/doctor.ts +14 -9
  141. package/scripts/document/document-byte-budget.ts +4 -5
  142. package/scripts/document/document-byte-check.ts +0 -1
  143. package/scripts/document/document-read-cli.ts +0 -2
  144. package/scripts/document/document-section-cli.ts +1 -1
  145. package/scripts/document/document-section.ts +0 -3
  146. package/scripts/document/edit-files-cli.ts +0 -1
  147. package/scripts/document/entry-read-budget.ts +10 -2
  148. package/scripts/document/lane-child-read-set.ts +1 -6
  149. package/scripts/document/read-files-cli.ts +0 -4
  150. package/scripts/document/read-set-cli.ts +0 -2
  151. package/scripts/document/read-set-point-of-use.ts +1 -0
  152. package/scripts/document/read-set-pricing.ts +0 -1
  153. package/scripts/document/read-set-trim.ts +1 -1
  154. package/scripts/epic/epic-add.ts +1 -1
  155. package/scripts/epic/epic-audit-cli.ts +1 -4
  156. package/scripts/epic/epic-audit-orphans.ts +1 -3
  157. package/scripts/epic/epic-audit-rationale.ts +0 -1
  158. package/scripts/epic/epic-audit-report.ts +0 -2
  159. package/scripts/epic/epic-audit.ts +5 -4
  160. package/scripts/epic/epic-bundle-cli.ts +1 -1
  161. package/scripts/epic/epic-bundle-evidence.ts +0 -1
  162. package/scripts/epic/epic-bundle-referenced.ts +1 -5
  163. package/scripts/epic/epic-bundle.ts +0 -4
  164. package/scripts/epic/epic-busy.ts +4 -5
  165. package/scripts/epic/epic-candidate-confirm.ts +0 -5
  166. package/scripts/epic/epic-classify.ts +2 -2
  167. package/scripts/epic/epic-cli-argv.ts +0 -1
  168. package/scripts/epic/epic-close-comment.ts +1 -1
  169. package/scripts/epic/epic-close.ts +5 -2
  170. package/scripts/epic/epic-cross-repo.ts +2 -4
  171. package/scripts/epic/epic-decision.ts +0 -1
  172. package/scripts/epic/epic-fetch.ts +2 -2
  173. package/scripts/epic/epic-index.ts +2 -3
  174. package/scripts/epic/epic-issue.ts +1 -15
  175. package/scripts/epic/epic-lane-offer.ts +9 -8
  176. package/scripts/epic/epic-nested.ts +1 -1
  177. package/scripts/epic/epic-next-read.ts +1 -3
  178. package/scripts/epic/epic-next-views.ts +0 -1
  179. package/scripts/epic/epic-next.ts +1 -10
  180. package/scripts/epic/epic-parse.ts +0 -1
  181. package/scripts/epic/epic-promote.ts +0 -9
  182. package/scripts/epic/epic-rank.ts +2 -2
  183. package/scripts/epic/epic-read.ts +1 -2
  184. package/scripts/epic/epic-reconcile.ts +1 -1
  185. package/scripts/epic/epic-reference.ts +1 -13
  186. package/scripts/epic/epic-relation-recheck.ts +1 -1
  187. package/scripts/epic/epic-relations.ts +1 -1
  188. package/scripts/epic/epic-remove.ts +1 -1
  189. package/scripts/epic/epic-report.ts +0 -1
  190. package/scripts/epic/epic-run.ts +2 -3
  191. package/scripts/epic/epic-shape.ts +1 -1
  192. package/scripts/epic/epic-solo-stale.ts +107 -0
  193. package/scripts/epic/epic-solo.ts +3 -2
  194. package/scripts/epic/epic-triage.ts +1 -1
  195. package/scripts/epic/epic-validate.ts +1 -1
  196. package/scripts/epic/epic.ts +1 -1
  197. package/scripts/exports/unused-members-cli.ts +53 -0
  198. package/scripts/{git → followup}/followup-issue-number.ts +1 -6
  199. package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
  200. package/scripts/{git → followup}/git-followup-finish.ts +1 -3
  201. package/scripts/{git → followup}/git-followup-flush.ts +2 -2
  202. package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
  203. package/scripts/{git → followup}/git-followup-label.ts +4 -4
  204. package/scripts/followup/git-followup-merged.ts +112 -0
  205. package/scripts/{git → followup}/git-followup-pending.ts +1 -1
  206. package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
  207. package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
  208. package/scripts/{git → followup}/git-pr-followup.ts +53 -16
  209. package/scripts/gate/core-budget.ts +3 -9
  210. package/scripts/gate/gate-plan.ts +7 -4
  211. package/scripts/gate/gate-report.ts +0 -6
  212. package/scripts/gate/gate-tree.ts +1 -1
  213. package/scripts/gate/pre-commit-type-check.ts +0 -6
  214. package/scripts/gate/project-checks.ts +7 -8
  215. package/scripts/gate/scoped-green.ts +0 -1
  216. package/scripts/gate/type-check-step.ts +1 -1
  217. package/scripts/gate/verification-gate.ts +0 -2
  218. package/scripts/gh/fix-gh-packages.ts +15 -12
  219. package/scripts/gh/gh-spawn.ts +2 -2
  220. package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
  221. package/scripts/{git → gh}/git-gh-check.ts +2 -1
  222. package/scripts/{git → gh}/git-gh-exec.ts +1 -1
  223. package/scripts/{git → gh}/git-gh-failure.ts +1 -1
  224. package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
  225. package/scripts/{git → gh}/git-gh-issue-list.ts +2 -0
  226. package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
  227. package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
  228. package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
  229. package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
  230. package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
  231. package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
  232. package/scripts/{git → gh}/git-gh-pr.ts +3 -1
  233. package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
  234. package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
  235. package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
  236. package/scripts/{git → gh}/git-pr-checks.ts +2 -1
  237. package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
  238. package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
  239. package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
  240. package/scripts/{git → gh}/git-pr.ts +3 -3
  241. package/scripts/git/changed-file-scope.ts +0 -1
  242. package/scripts/git/git-branch.ts +3 -6
  243. package/scripts/git/git-commit.ts +1 -1
  244. package/scripts/git/git-common-directory.ts +80 -24
  245. package/scripts/git/git-error.ts +66 -9
  246. package/scripts/git/git-issue.ts +1 -1
  247. package/scripts/git/git-preflight.ts +2 -2
  248. package/scripts/git/git-prompt.ts +6 -31
  249. package/scripts/git/git-push.ts +1 -1
  250. package/scripts/git/git-staging.ts +1 -0
  251. package/scripts/git/git-status.ts +1 -1
  252. package/scripts/git/git-workflow.ts +1 -1
  253. package/scripts/git/gone-branch.ts +1 -0
  254. package/scripts/git/listing-cutoff.ts +1 -1
  255. package/scripts/git/main-merge.ts +1 -1
  256. package/scripts/git/main-sync.ts +19 -1
  257. package/scripts/git/parse-json-array.ts +0 -3
  258. package/scripts/git/repository-lock.ts +16 -16
  259. package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
  260. package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +1 -1
  261. package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
  262. package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
  263. package/scripts/hooks/codex-hook-adapter.ts +0 -1
  264. package/scripts/hooks/edited-cspell.ts +1 -1
  265. package/scripts/hooks/format-edited-file.ts +2 -0
  266. package/scripts/hooks/pre-push-unit.ts +0 -4
  267. package/scripts/hooks/pretool-guard.ts +22 -4
  268. package/scripts/hooks/reserved-run.ts +1 -1
  269. package/scripts/hooks/step-zero-notice.ts +76 -0
  270. package/scripts/hooks/stop-guard.ts +47 -21
  271. package/scripts/init/claude-plugin-config.ts +4 -5
  272. package/scripts/init/hook-command-rewrite.ts +16 -8
  273. package/scripts/init/hook-launch.ts +41 -15
  274. package/scripts/init/init-basic.ts +2 -5
  275. package/scripts/init/init-logic.ts +7 -0
  276. package/scripts/init/init.ts +0 -3
  277. package/scripts/init/project-profile.ts +6 -11
  278. package/scripts/init/start-exec.ts +1 -1
  279. package/scripts/init/start-setup-pr.ts +6 -6
  280. package/scripts/init/start-steps.ts +1 -0
  281. package/scripts/issue/behavior-change-lint.ts +0 -1
  282. package/scripts/issue/defect-rate-cli.ts +3 -3
  283. package/scripts/issue/defect-rate.ts +1 -2
  284. package/scripts/{git → issue}/git-next-issues.ts +3 -3
  285. package/scripts/issue/issue-backlinks-cli.ts +1 -5
  286. package/scripts/issue/issue-cite-cli.ts +2 -6
  287. package/scripts/issue/issue-cite.ts +0 -2
  288. package/scripts/issue/issue-classification.ts +1 -9
  289. package/scripts/issue/issue-closing-pr.ts +4 -4
  290. package/scripts/issue/issue-comment-cli.ts +2 -2
  291. package/scripts/issue/issue-file-cli.ts +5 -5
  292. package/scripts/issue/issue-file.ts +2 -2
  293. package/scripts/issue/issue-fold-cli.ts +1 -1
  294. package/scripts/issue/issue-fold-existing-cli.ts +1 -1
  295. package/scripts/{git → issue}/issue-labels.ts +8 -0
  296. package/scripts/issue/issue-lint-cli.ts +1 -1
  297. package/scripts/issue/issue-merged.ts +2 -2
  298. package/scripts/{git → issue}/issue-rank.ts +1 -1
  299. package/scripts/issue/issue-read-cli.ts +8 -47
  300. package/scripts/issue/issue-read.ts +0 -2
  301. package/scripts/issue/issue-report-failures.ts +80 -0
  302. package/scripts/issue/issue-scout-cli.ts +1 -7
  303. package/scripts/issue/issue-scout-closed.ts +2 -2
  304. package/scripts/issue/issue-scout.ts +0 -2
  305. package/scripts/issue/issue-state-cli.ts +5 -46
  306. package/scripts/issue/issue-state.ts +1 -5
  307. package/scripts/issue/markdown-section.ts +1 -1
  308. package/scripts/issue/measure-rerun-cli.ts +1 -1
  309. package/scripts/issue/reproduction-measure.ts +1 -1
  310. package/scripts/josh/cli-body.ts +1 -1
  311. package/scripts/josh/file-map-stamp.ts +0 -3
  312. package/scripts/josh/josh-command-map.ts +2 -0
  313. package/scripts/josh/josh-commands-ai.ts +9 -102
  314. package/scripts/josh/josh-commands-backlog.ts +5 -1
  315. package/scripts/josh/josh-commands-development.ts +8 -1
  316. package/scripts/josh/josh-commands-issue.ts +2 -2
  317. package/scripts/josh/josh-commands-maintenance.ts +7 -0
  318. package/scripts/josh/josh-commands-project.ts +6 -0
  319. package/scripts/josh/josh-commands-run.ts +114 -0
  320. package/scripts/josh/josh-commands-versioning.ts +8 -0
  321. package/scripts/josh/josh-commands-workflow.ts +2 -2
  322. package/scripts/josh/path-decision.ts +0 -3
  323. package/scripts/josh/process-owner.ts +16 -0
  324. package/scripts/josh/session-language-cli.ts +0 -1
  325. package/scripts/lane/lane-await.ts +3 -6
  326. package/scripts/lane/lane-capacity.ts +6 -3
  327. package/scripts/lane/lane-child-invocation.ts +20 -7
  328. package/scripts/lane/lane-cli.ts +1 -4
  329. package/scripts/lane/lane-close.ts +1 -3
  330. package/scripts/lane/lane-dispatch.ts +3 -4
  331. package/scripts/lane/lane-environment.ts +0 -9
  332. package/scripts/lane/lane-handoff.ts +38 -0
  333. package/scripts/lane/lane-launch-cli.ts +21 -11
  334. package/scripts/lane/lane-open.ts +0 -3
  335. package/scripts/lane/lane-output.ts +0 -1
  336. package/scripts/lane/lane-registry.ts +9 -0
  337. package/scripts/lane/openai-lane-ship.ts +2 -0
  338. package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
  339. package/scripts/lane/openai-lane-supervisor.ts +6 -4
  340. package/scripts/lane/openai-review-broker.ts +3 -0
  341. package/scripts/lib/bounded-pool.ts +1 -0
  342. package/scripts/lib/json-value.ts +5 -4
  343. package/scripts/lib/poll.ts +3 -1
  344. package/scripts/lib/timed-fetch.ts +15 -0
  345. package/scripts/lib/timeouts.ts +13 -0
  346. package/scripts/{yaml → lib}/yaml-document.ts +3 -1
  347. package/scripts/{bytes → lines}/bytes-command.ts +0 -2
  348. package/scripts/lines/lines-command.ts +0 -1
  349. package/scripts/lint/lint-related-scope.ts +0 -1
  350. package/scripts/lint/lint-related.ts +1 -1
  351. package/scripts/{git → notify}/telegram-notify.ts +2 -2
  352. package/scripts/{git → notify}/telegram-test.ts +4 -4
  353. package/scripts/observations/observation-ledger-home.ts +0 -1
  354. package/scripts/observations/observation-ledger-line.ts +0 -1
  355. package/scripts/observations/observation-ledger-migrate.ts +1 -1
  356. package/scripts/observations/observations-flush-landing.ts +3 -3
  357. package/scripts/observations/observations-flush.ts +2 -2
  358. package/scripts/overrides/lockfile-overrides.ts +1 -1
  359. package/scripts/overrides/overrides-logic.ts +1 -1
  360. package/scripts/package/package-scout-cli.ts +2 -7
  361. package/scripts/package/package-scout.ts +0 -2
  362. package/scripts/propagate/propagate-git-failure.ts +0 -1
  363. package/scripts/propagate/propagate-git.ts +0 -2
  364. package/scripts/propagate/propagate-publish.ts +2 -3
  365. package/scripts/propagate/propagate-run.ts +0 -2
  366. package/scripts/propagate/propagate-steps.ts +3 -5
  367. package/scripts/propagate/propagate-targets.ts +0 -4
  368. package/scripts/propagate/propagate.ts +0 -4
  369. package/scripts/refactor/import-graph.ts +0 -1
  370. package/scripts/refactor/refactor-lint.ts +0 -2
  371. package/scripts/refactor/refactor-scan.ts +0 -1
  372. package/scripts/refactor/refactor-targets.ts +0 -1
  373. package/scripts/registry-migration/migrate-logic.ts +0 -2
  374. package/scripts/registry-migration/migrate.ts +19 -9
  375. package/scripts/release/github-release-cli.ts +8 -6
  376. package/scripts/release/github-release-environment.ts +46 -0
  377. package/scripts/release/github-release.ts +151 -94
  378. package/scripts/release/release-history.ts +0 -1
  379. package/scripts/release/release-plan.ts +0 -1
  380. package/scripts/release/release-publish.ts +2 -3
  381. package/scripts/release/release-scope-cli.ts +1 -2
  382. package/scripts/release/release-tag.ts +2 -4
  383. package/scripts/repo/auto-merge-setting-logic.ts +1 -4
  384. package/scripts/repo/repo-setting.ts +1 -1
  385. package/scripts/repo/repository-labels.ts +3 -3
  386. package/scripts/repo/required-checks-logic.ts +206 -0
  387. package/scripts/repo/required-checks-report.ts +71 -0
  388. package/scripts/repo/ruleset-check-cli.ts +53 -0
  389. package/scripts/repo/ruleset-check.ts +147 -0
  390. package/scripts/report/report-lint-cli.ts +0 -4
  391. package/scripts/review/disposition-cli.ts +1 -1
  392. package/scripts/review/live-evidence.ts +1 -1
  393. package/scripts/review/review-attest-cli.ts +0 -6
  394. package/scripts/review/review-attest.ts +4 -16
  395. package/scripts/review/review-brief-cli.ts +23 -6
  396. package/scripts/review/review-brief.ts +21 -8
  397. package/scripts/review/review-diff-parts.ts +89 -0
  398. package/scripts/review/review-diff-write.ts +97 -0
  399. package/scripts/review/review-finding-ledger.ts +0 -1
  400. package/scripts/review/review-record-cli.ts +1 -1
  401. package/scripts/review/review-record.ts +0 -1
  402. package/scripts/review/review-round2-cli.ts +1 -1
  403. package/scripts/review/review-stamps.ts +0 -3
  404. package/scripts/review/review-tree.ts +14 -2
  405. package/scripts/rules/decision-oracle-stage.ts +18 -0
  406. package/scripts/rules/decision-oracle.ts +10 -7
  407. package/scripts/rules/delivered-rules.ts +9 -1
  408. package/scripts/rules/destructive-command.ts +119 -0
  409. package/scripts/rules/direct-filing.ts +1 -1
  410. package/scripts/rules/file-body.ts +0 -3
  411. package/scripts/rules/filing-cap.ts +0 -2
  412. package/scripts/rules/gh-api.ts +7 -2
  413. package/scripts/rules/git-argv.ts +18 -7
  414. package/scripts/rules/git-force.ts +0 -2
  415. package/scripts/rules/implementation-cut.ts +0 -1
  416. package/scripts/rules/index-guard.ts +71 -0
  417. package/scripts/rules/issue-citation.ts +50 -25
  418. package/scripts/rules/lane-background.ts +15 -7
  419. package/scripts/rules/lane-park.ts +13 -6
  420. package/scripts/rules/last-prompt.ts +1 -0
  421. package/scripts/rules/oracle-consulted.ts +1 -1
  422. package/scripts/rules/oracle-firing.ts +1 -0
  423. package/scripts/rules/oracle-list-cli.ts +0 -3
  424. package/scripts/rules/permission-guards.ts +14 -0
  425. package/scripts/rules/protected-files.ts +74 -0
  426. package/scripts/rules/reply-language.ts +1 -1
  427. package/scripts/rules/rule-body-guard.ts +0 -3
  428. package/scripts/rules/rule-value-cli.ts +0 -1
  429. package/scripts/rules/shell-body-trigger.ts +0 -1
  430. package/scripts/rules/shell-segments.ts +0 -1
  431. package/scripts/rules/stop-rules.ts +13 -5
  432. package/scripts/rules/tail-commands.ts +1 -1
  433. package/scripts/rules/test-declared-commit.ts +1 -1
  434. package/scripts/rules/third-party-write.ts +0 -1
  435. package/scripts/rules/worktree-guard.ts +26 -9
  436. package/scripts/run/run-carry-cli.ts +0 -2
  437. package/scripts/run/run-carry-stash.ts +2 -2
  438. package/scripts/run/run-carry-streak.ts +1 -1
  439. package/scripts/run/run-cut-cli.ts +0 -7
  440. package/scripts/run/run-cut.ts +8 -54
  441. package/scripts/run/run-ending-cli.ts +1 -1
  442. package/scripts/run/run-ending.ts +1 -4
  443. package/scripts/run/run-entry-cli.ts +101 -24
  444. package/scripts/run/run-entry.ts +0 -1
  445. package/scripts/run/run-event-cli.ts +0 -2
  446. package/scripts/run/run-event-follow.ts +1 -0
  447. package/scripts/run/run-event-render.ts +1 -1
  448. package/scripts/run/run-event-scope.ts +53 -4
  449. package/scripts/run/run-event-stream.ts +0 -3
  450. package/scripts/run/run-event-watch.ts +1 -0
  451. package/scripts/run/run-halfrun-resume.ts +20 -7
  452. package/scripts/run/run-headless.ts +2 -2
  453. package/scripts/run/run-hold-cli.ts +33 -10
  454. package/scripts/run/run-hold.ts +25 -5
  455. package/scripts/run/run-issue-number.ts +1 -1
  456. package/scripts/run/run-liveness-cli.ts +1 -1
  457. package/scripts/run/run-liveness.ts +2 -3
  458. package/scripts/run/run-merge-cli.ts +5 -13
  459. package/scripts/run/run-merge-steps.ts +5 -5
  460. package/scripts/run/run-merge.ts +1 -1
  461. package/scripts/run/run-next-cli.ts +1 -1
  462. package/scripts/run/run-parent-cut-hook.ts +0 -1
  463. package/scripts/run/run-preflight.ts +2 -9
  464. package/scripts/run/run-prep-cli.ts +2 -2
  465. package/scripts/run/run-prep-locate.ts +1 -1
  466. package/scripts/run/run-progress-cli.ts +4 -7
  467. package/scripts/run/run-progress-clock.ts +6 -34
  468. package/scripts/run/run-progress-config.ts +0 -4
  469. package/scripts/run/run-progress-read.ts +1 -2
  470. package/scripts/run/run-progress.ts +1 -2
  471. package/scripts/run/run-prrun-resume.ts +117 -0
  472. package/scripts/run/run-report-cli.ts +1 -2
  473. package/scripts/run/run-report.ts +0 -1
  474. package/scripts/run/run-retrospective.ts +1 -1
  475. package/scripts/run/run-review-cli.ts +0 -3
  476. package/scripts/run/run-review-steps.ts +2 -0
  477. package/scripts/run/run-review.ts +0 -2
  478. package/scripts/run/run-ship-cli.ts +21 -3
  479. package/scripts/run/run-ship-detach.ts +1 -0
  480. package/scripts/run/run-ship-next.ts +106 -0
  481. package/scripts/run/run-ship-preflight.ts +1 -1
  482. package/scripts/run/run-ship-return.ts +8 -3
  483. package/scripts/run/run-ship-review-steps.ts +18 -4
  484. package/scripts/run/run-ship-review.ts +11 -0
  485. package/scripts/run/run-ship-scoped.ts +1 -0
  486. package/scripts/run/run-ship-steps.ts +1 -1
  487. package/scripts/run/run-ship.ts +0 -1
  488. package/scripts/run/run-stage-read.ts +62 -0
  489. package/scripts/run/run-stage.ts +160 -0
  490. package/scripts/run/run-status-cli.ts +1 -1
  491. package/scripts/run/run-step-cli.ts +21 -14
  492. package/scripts/run/run-step.ts +1 -1
  493. package/scripts/run/run-stop-notify.ts +1 -3
  494. package/scripts/run/run-stranded-cli.ts +0 -4
  495. package/scripts/run/run-stranded-detect.ts +2 -2
  496. package/scripts/run/run-tail-cli.ts +17 -11
  497. package/scripts/run/run-tail.ts +2 -0
  498. package/scripts/run/run-tidy-lanes.ts +2 -1
  499. package/scripts/run/run-tidy-stashes.ts +12 -12
  500. package/scripts/run/run-wake-cli.ts +2 -3
  501. package/scripts/run/run-wake-loop.ts +2 -2
  502. package/scripts/run/run-wake.ts +2 -4
  503. package/scripts/run/run-watcher-guard-cli.ts +0 -4
  504. package/scripts/run/run-watcher-guard.ts +9 -7
  505. package/scripts/run/run-watcher-hook.ts +1 -1
  506. package/scripts/safe-chain/ci-installer-pin.ts +11 -5
  507. package/scripts/safe-chain/project-config.ts +1 -1
  508. package/scripts/security/security-audit-provision-logic.ts +0 -1
  509. package/scripts/security/security-audit-provision.ts +3 -2
  510. package/scripts/security/security-audit.ts +0 -1
  511. package/scripts/security/security-updates-logic.ts +0 -1
  512. package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
  513. package/scripts/sonar/sonar-hotspots.ts +0 -1
  514. package/scripts/sonar/sonar-new-code-cli.ts +150 -0
  515. package/scripts/sonar/sonar-new-code.ts +79 -0
  516. package/scripts/sonar/sonar-project.ts +97 -0
  517. package/scripts/split/split-assess-cli.ts +1 -1
  518. package/scripts/split/split-assess.ts +2 -5
  519. package/scripts/sync/managed-config-scope-cli.ts +1 -1
  520. package/scripts/sync/skill-migration.ts +0 -1
  521. package/scripts/sync/sync-hook-safety.ts +2 -3
  522. package/scripts/sync/sync.ts +1 -8
  523. package/scripts/sync/template-source-logic.ts +0 -1
  524. package/scripts/sync/workflow-pin-logic.ts +16 -28
  525. package/scripts/test/test-declared-logic.ts +0 -1
  526. package/scripts/test/test-declared.ts +0 -2
  527. package/scripts/test/test-red-commit.ts +2 -2
  528. package/scripts/test/test-red.ts +14 -7
  529. package/scripts/test/test-type-logic.ts +1 -1
  530. package/scripts/test/unit-worker-share.ts +7 -16
  531. package/scripts/time-runtime/time-batch-guard.ts +1 -2
  532. package/scripts/time-runtime/time-bundle-call.ts +0 -1
  533. package/scripts/time-runtime/time-bundles.ts +0 -4
  534. package/scripts/time-runtime/time-density-hook.ts +0 -2
  535. package/scripts/time-runtime/time-followup-stage.ts +1 -1
  536. package/scripts/time-runtime/time-format.ts +0 -73
  537. package/scripts/time-runtime/time-round-trips.ts +0 -4
  538. package/scripts/time-runtime/time-single-check.ts +1 -1
  539. package/scripts/time-runtime/time-spans.ts +1 -1
  540. package/scripts/time-runtime/time-transcript-line.ts +1 -2
  541. package/scripts/ui/ui-routes-cli.ts +0 -5
  542. package/scripts/ui/ui-routes.ts +0 -5
  543. package/scripts/version/effective-upstream.ts +2 -2
  544. package/scripts/version/latest-corepack.ts +7 -9
  545. package/scripts/version/latest-scope-cli.ts +0 -2
  546. package/scripts/version/latest-update.ts +0 -2
  547. package/scripts/version/npm-registry.ts +2 -2
  548. package/scripts/version/publishable-range-check.ts +1 -1
  549. package/scripts/version/release-hold.ts +0 -4
  550. package/scripts/version/running-binary.ts +2 -2
  551. package/scripts/version/version-check-logic.ts +0 -2
  552. package/scripts/version/version-remote.ts +3 -3
  553. package/scripts/version/version-targets.ts +4 -4
  554. package/templates/sonar-project.properties +28 -1
  555. package/templates/workflows/dependabot-auto-merge.yml +5 -3
  556. package/templates/workflows/github-release.yml +81 -0
  557. package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
  558. package/prompts/collaboration-workflow/epic-audit.md +0 -5
  559. package/prompts/collaboration-workflow/epic-bundle.md +0 -5
  560. package/scripts/init/plugin-install-hint.ts +0 -47
  561. package/scripts/version/parse-json.ts +0 -13
  562. /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
  563. /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
  564. /package/scripts/{git → gh}/git-gh-command.ts +0 -0
  565. /package/scripts/{git → gh}/git-gh-issue-write.ts +0 -0
  566. /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
  567. /package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +0 -0
  568. /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
  569. /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
  570. /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
  571. /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
  572. /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
  573. /package/scripts/{git → gh}/git-pr-error.ts +0 -0
  574. /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
  575. /package/scripts/{git → gh}/github-issue-url.ts +0 -0
  576. /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
  577. /package/scripts/{git → issue}/issue-reference.ts +0 -0
  578. /package/scripts/{git → lib}/animation-helpers.ts +0 -0
  579. /package/scripts/{git → lib}/git-animation.ts +0 -0
  580. /package/scripts/{git → notify}/git-notify.ts +0 -0
  581. /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
@@ -0,0 +1,160 @@
1
+ // joshuafolkken/kit#3042: the workflow commands form a ladder — `kickoff` → `halfrun` → `prrun` →
2
+ // `fullrun` — and **the command typed decides only how far a run goes; where it starts is read off the
3
+ // issue**. A run that finds work already done resumes after it rather than redoing it, and a command
4
+ // whose stopping point the issue has already reached reports that and stops.
5
+ //
6
+ // This module is the pure half of that rule: the five states an issue can be found in, the four
7
+ // commands, and the one table that maps a (state, command) pair to a start and an end. `run:entry` reads
8
+ // the state (`run-stage-read.ts`) and branches on the answer; the stage table in
9
+ // `docs/how-to/run-issues.md` and each stop's `Next:` line are pinned to this module by
10
+ // `run-stage-document.test.ts`, so the prose cannot drift from what the entry does.
11
+
12
+ const KICKOFF = 'kickoff'
13
+ const HALFRUN = 'halfrun'
14
+ const PRRUN = 'prrun'
15
+ const FULLRUN = 'fullrun'
16
+
17
+ // In ladder order: a command's index plus one is the state rank it brings an issue to.
18
+ const COMMANDS = [KICKOFF, HALFRUN, PRRUN, FULLRUN] as const
19
+
20
+ type StageCommand = (typeof COMMANDS)[number]
21
+
22
+ // What `run:entry` serves when no command is named — the one it served alone before the ladder existed.
23
+ const DEFAULT_COMMAND: StageCommand = FULLRUN
24
+
25
+ const FRESH = 'fresh'
26
+ const PLANNED = 'planned'
27
+ const HALFRUN_STOPPED = 'halfrun-stopped'
28
+ const PRRUN_STOPPED = 'prrun-stopped'
29
+ const MERGED = 'merged'
30
+
31
+ // In ladder order: a state's index is how many rungs the issue has already climbed.
32
+ const STATES = [FRESH, PLANNED, HALFRUN_STOPPED, PRRUN_STOPPED, MERGED] as const
33
+
34
+ type StageState = (typeof STATES)[number]
35
+
36
+ const REACHED = 'reached'
37
+
38
+ // Where a run picks the issue up from each state — the first piece of work not yet done. A merged issue
39
+ // has none: every command has reached it.
40
+ const STARTS: Readonly<Record<StageState, string>> = {
41
+ [FRESH]: 'plan',
42
+ [PLANNED]: 'implement',
43
+ [HALFRUN_STOPPED]: 'gate',
44
+ [PRRUN_STOPPED]: 'followup',
45
+ [MERGED]: REACHED,
46
+ }
47
+
48
+ // Every start a decision can print, in ladder order — the `run:entry` oracle's vocabulary.
49
+ const START_TOKENS: ReadonlyArray<string> = [...new Set(Object.values(STARTS))]
50
+
51
+ // Where each command stops.
52
+ const ENDS: Readonly<Record<StageCommand, string>> = {
53
+ [KICKOFF]: 'plan posted',
54
+ [HALFRUN]: 'gated, before the commit',
55
+ [PRRUN]: 'green, mergeable PR',
56
+ [FULLRUN]: 'merged',
57
+ }
58
+
59
+ const NEXT_PREFIX = 'Next: '
60
+ const NEXT_SEPARATOR = ' | '
61
+ const STATE_HEADER = 'Issue state'
62
+ const CELL_ARROW = ' → '
63
+ const REACHED_CELL = 'reached — report and stop'
64
+
65
+ interface StageFacts {
66
+ is_closed: boolean
67
+ is_prrun_stopped: boolean
68
+ is_halfrun_stopped: boolean
69
+ is_planned: boolean
70
+ }
71
+
72
+ interface StageDecision {
73
+ state: StageState
74
+ command: StageCommand
75
+ // The first piece of work the run does, or `reached` when there is none left for this command.
76
+ start: string
77
+ end: string
78
+ is_reached: boolean
79
+ }
80
+
81
+ function to_command(value: string | undefined): StageCommand | undefined {
82
+ return COMMANDS.find((command) => command === value)
83
+ }
84
+
85
+ // The furthest rung the facts show, so a closed issue is merged whatever its hold still says.
86
+ function state_of(facts: StageFacts): StageState {
87
+ if (facts.is_closed) return MERGED
88
+ if (facts.is_prrun_stopped) return PRRUN_STOPPED
89
+ if (facts.is_halfrun_stopped) return HALFRUN_STOPPED
90
+
91
+ return facts.is_planned ? PLANNED : FRESH
92
+ }
93
+
94
+ function decide(state: StageState, command: StageCommand): StageDecision {
95
+ const is_reached = STATES.indexOf(state) > COMMANDS.indexOf(command)
96
+ const start = is_reached ? REACHED : STARTS[state]
97
+
98
+ return { state, command, start, end: ENDS[command], is_reached }
99
+ }
100
+
101
+ // The commands that go further than `command`, nearest first — what a stop offers next.
102
+ function next_commands(command: StageCommand): ReadonlyArray<StageCommand> {
103
+ return COMMANDS.slice(COMMANDS.indexOf(command) + 1)
104
+ }
105
+
106
+ // The `Next:` line a stop's Telegram and report carry, e.g. `Next: prrun #<N> | fullrun #<N>`.
107
+ function next_line(command: StageCommand, issue: string): string {
108
+ const commands = next_commands(command).map((next) => `${next} #${issue}`)
109
+
110
+ return `${NEXT_PREFIX}${commands.join(NEXT_SEPARATOR)}`
111
+ }
112
+
113
+ function format_decision(issue: string, decision: StageDecision): string {
114
+ const fields = [`at: ${decision.state}`, `to: ${decision.command}`, `start: ${decision.start}`]
115
+
116
+ return `stage #${issue} — ${fields.join(' · ')}`
117
+ }
118
+
119
+ function cell(state: StageState, command: StageCommand): string {
120
+ const decision = decide(state, command)
121
+
122
+ return decision.is_reached ? REACHED_CELL : `${decision.start}${CELL_ARROW}${decision.end}`
123
+ }
124
+
125
+ // The stage table as rows of cells, header first — the shape both documents carry.
126
+ function table_rows(): ReadonlyArray<ReadonlyArray<string>> {
127
+ const header = [STATE_HEADER, ...COMMANDS.map((command) => `\`${command}\``)]
128
+ const rows = STATES.map((state) => [
129
+ `\`${state}\``,
130
+ ...COMMANDS.map((command) => cell(state, command)),
131
+ ])
132
+
133
+ return [header, ...rows]
134
+ }
135
+
136
+ const run_stage = {
137
+ COMMANDS,
138
+ DEFAULT_COMMAND,
139
+ FRESH,
140
+ HALFRUN,
141
+ HALFRUN_STOPPED,
142
+ KICKOFF,
143
+ MERGED,
144
+ PLANNED,
145
+ PRRUN,
146
+ PRRUN_STOPPED,
147
+ REACHED,
148
+ START_TOKENS,
149
+ STATES,
150
+ decide,
151
+ format_decision,
152
+ next_commands,
153
+ next_line,
154
+ state_of,
155
+ table_rows,
156
+ to_command,
157
+ } as const
158
+
159
+ export type { StageCommand, StageDecision, StageFacts, StageState }
160
+ export { run_stage }
@@ -168,7 +168,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
168
168
  process.exitCode = await run(argv)
169
169
  }
170
170
 
171
- const run_status_cli = { USAGE, parse, run }
171
+ const run_status_cli = { parse, run }
172
172
 
173
173
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
174
174
 
@@ -44,18 +44,22 @@ function is_handed_off_here(carry: CarryRead): boolean {
44
44
  return run_headless.is_owned_here(carry.carry, lane_reap.own_ancestry)
45
45
  }
46
46
 
47
+ const UNREADABLE_RUN: RunReads = {
48
+ carry_kind: 'unreadable',
49
+ is_retrospective_done: false,
50
+ is_at_cut_cap: false,
51
+ is_handed_off: false,
52
+ last_event: undefined,
53
+ }
54
+
47
55
  // The run-level reads, keyed on the common git directory both the carry and the event stream share. A
48
56
  // directory that cannot be read leaves the position unknowable, which `next_action` answers `unknown`.
49
- function read_run(directory: string | undefined, issue_number: string): RunReads {
50
- if (directory === undefined) {
51
- return {
52
- carry_kind: 'unreadable',
53
- is_retrospective_done: false,
54
- is_at_cut_cap: false,
55
- is_handed_off: false,
56
- last_event: undefined,
57
- }
58
- }
57
+ function read_run(
58
+ directory: string | undefined,
59
+ issue_number: string,
60
+ is_lane_child: boolean,
61
+ ): RunReads {
62
+ if (directory === undefined) return UNREADABLE_RUN
59
63
 
60
64
  const carry = run_carry.read_carry(run_carry.carry_path(directory))
61
65
  const events = run_event_stream.read_events(run_event_stream.target_of(directory))
@@ -63,11 +67,13 @@ function read_run(directory: string | undefined, issue_number: string): RunReads
63
67
  // invocation left on the stream must not be read as this run's position (joshuafolkken/kit#2395). The
64
68
  // observed defect was a `run:step` that printed `wait` on a fresh run because an old `child-launch` was
65
69
  // still the stream's tail. Another issue's detached ship supervisor is left out the same way
66
- // (joshuafolkken/kit#2428).
70
+ // (joshuafolkken/kit#2428), and so — for a lane child — is every event that does not name its own issue
71
+ // (joshuafolkken/kit#3039).
67
72
  const last = run_event_scope.last_issue_event(
68
73
  events,
69
74
  run_event_scope.scope_of(carry),
70
75
  issue_number,
76
+ is_lane_child,
71
77
  )
72
78
 
73
79
  return {
@@ -82,7 +88,8 @@ function read_run(directory: string | undefined, issue_number: string): RunReads
82
88
  async function gather(issue_number: string): Promise<StepInput> {
83
89
  const reads = await run_prep_cli.gather(issue_number)
84
90
  const parts = run_prep_cli.to_parts(issue_number, reads)
85
- const run_reads = read_run(await run_carry.repository_directory(), issue_number)
91
+ const is_lane_child = lane_child_marker.is_child_of(process.cwd())
92
+ const run_reads = read_run(await run_carry.repository_directory(), issue_number, is_lane_child)
86
93
 
87
94
  return {
88
95
  issue_number,
@@ -94,7 +101,7 @@ async function gather(issue_number: string): Promise<StepInput> {
94
101
  is_retrospective_done: run_reads.is_retrospective_done,
95
102
  is_at_cut_cap: run_reads.is_at_cut_cap,
96
103
  is_handed_off: run_reads.is_handed_off,
97
- is_lane_child: lane_child_marker.is_child_of(process.cwd()),
104
+ is_lane_child,
98
105
  is_consumer: doctor_consumer.is_kit_consumer(find_package_directory(process.cwd())),
99
106
  // Read here rather than in `run-step.ts` so the position logic stays a pure function of its input.
100
107
  is_retrospective_enabled: run_retrospective.is_enabled(),
@@ -128,7 +135,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
128
135
  process.exitCode = await run(argv)
129
136
  }
130
137
 
131
- const run_step_cli = { USAGE, gather, main, run }
138
+ const run_step_cli = { run }
132
139
 
133
140
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
134
141
 
@@ -1,4 +1,4 @@
1
- import { git_stash } from '#scripts/git/git-stash'
1
+ import { git_stash } from '#scripts/git/stash/git-stash'
2
2
  import { latest_scope_cli } from '#scripts/version/latest-scope-cli'
3
3
  import type { CarryRead } from './run-carry'
4
4
  import { run_event_stream } from './run-event-stream'
@@ -1,4 +1,4 @@
1
- import { telegram_notify } from '#scripts/git/telegram-notify'
1
+ import { telegram_notify } from '#scripts/notify/telegram-notify'
2
2
  import type { CarryRead } from './run-carry'
3
3
 
4
4
  // **A `backlogrun` that halts because a person is needed used to reach nobody once the session was
@@ -43,8 +43,6 @@ async function announce(notice: StopNotice): Promise<boolean> {
43
43
  }
44
44
 
45
45
  const run_stop_notify = {
46
- STOP_RECOVERY,
47
- STOP_TITLE,
48
46
  announce,
49
47
  plan,
50
48
  }
@@ -24,8 +24,4 @@ async function main(): Promise<void> {
24
24
  process.exitCode = SUCCESS_EXIT_CODE
25
25
  }
26
26
 
27
- const run_stranded_cli = { main }
28
-
29
27
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
30
-
31
- export { run_stranded_cli }
@@ -1,4 +1,4 @@
1
- import { telegram_notify } from '#scripts/git/telegram-notify'
1
+ import { telegram_notify } from '#scripts/notify/telegram-notify'
2
2
  import { run_carry, type CarryRead, type RunCarry } from './run-carry'
3
3
  import { run_event_stream } from './run-event-stream'
4
4
  import { run_event_stream_emit } from './run-event-stream-emit'
@@ -128,7 +128,7 @@ async function run_stranded_check(): Promise<void> {
128
128
  }
129
129
  }
130
130
 
131
- const run_stranded_detect = { DEFAULT_PORTS, detect_and_report, gather, report, run_stranded_check }
131
+ const run_stranded_detect = { detect_and_report, run_stranded_check }
132
132
 
133
133
  export { run_stranded_detect }
134
134
  export type { DetectPorts, RecordTargets }
@@ -22,7 +22,6 @@ import { run_tail, type TailSection } from './run-tail'
22
22
  // step for a line written on the default branch outside any issue's run.
23
23
 
24
24
  const ARGV_OFFSET = 2
25
- const SUCCESS_EXIT_CODE = 0
26
25
  const FAILURE_EXIT_CODE = 1
27
26
  const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
28
27
  const USAGE = 'Usage: josh run:tail [<issue-number> ...]'
@@ -33,21 +32,27 @@ interface Step {
33
32
  argv: (issues: ReadonlyArray<string>) => ReadonlyArray<string>
34
33
  }
35
34
 
36
- // The steps in the order a run closes on: any ledger line the run's own commit did not carry
37
- // (joshuafolkken/kit#2763) is committed first so the recurrence count is on main — on most runs the
38
- // flush answers `clean` — the citations are read for the completion report, and the release scope is
39
- // decided last.
40
- const FLUSH_STEP: Step = {
41
- header: run_tail.OBSERVATIONS_HEADER,
42
- argv: () => ['observations:flush'],
43
- }
35
+ // The steps in the order a run closes on: the checkout returns to the default branch, any ledger line
36
+ // the run's own commit did not carry (joshuafolkken/kit#2763) is committed so the recurrence count is on
37
+ // main — on most runs the flush answers `clean` — the citations are read for the completion report, and
38
+ // the release scope is decided last.
39
+ //
40
+ // **The return comes first because the flush refuses anywhere else** (joshuafolkken/kit#2979). A run
41
+ // closes right after its merge, still on the feature branch it shipped from, and `josh ship` reaches
42
+ // this report with nothing in between — so the flush stopped a merged run as failed. `main:sync` is the
43
+ // step a person used to type after the fact; it fast-forwards the local default branch before the
44
+ // checkout, so a ledger line appended after the merge is carried along rather than refused.
45
+ const LEDGER_STEPS: ReadonlyArray<Step> = [
46
+ { header: run_tail.SYNC_HEADER, argv: () => ['main:sync'] },
47
+ { header: run_tail.OBSERVATIONS_HEADER, argv: () => ['observations:flush'] },
48
+ ]
44
49
  const REPORT_STEPS: ReadonlyArray<Step> = [
45
50
  { header: run_tail.CITATIONS_HEADER, argv: (issues) => ['issue:cite', ...issues] },
46
51
  { header: run_tail.RELEASE_HEADER, argv: () => ['release:scope'] },
47
52
  ]
48
53
 
49
54
  function steps_for(is_lane_child: boolean): ReadonlyArray<Step> {
50
- return is_lane_child ? REPORT_STEPS : [FLUSH_STEP, ...REPORT_STEPS]
55
+ return is_lane_child ? REPORT_STEPS : [...LEDGER_STEPS, ...REPORT_STEPS]
51
56
  }
52
57
 
53
58
  // Numbers only — a target `issue:cite` reads as an issue, so a stray flag is refused rather than
@@ -75,6 +80,7 @@ async function close_run(issues: ReadonlyArray<string>): Promise<ReadonlyArray<T
75
80
 
76
81
  const is_lane_child = lane_child_marker.is_child_of(process.cwd())
77
82
 
83
+ // eslint-disable-next-line no-await-in-loop -- the tail steps run in their declared order
78
84
  for (const step of steps_for(is_lane_child)) sections.push(await run_step(step, issues))
79
85
 
80
86
  return sections
@@ -100,7 +106,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
100
106
  process.exitCode = await run(argv)
101
107
  }
102
108
 
103
- const run_tail_cli = { SUCCESS_EXIT_CODE, USAGE, close_run, main, parse_issues, run }
109
+ const run_tail_cli = { run }
104
110
 
105
111
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
106
112
 
@@ -9,6 +9,7 @@
9
9
  // each step's output under a header and answers the exit code from the collected codes, so a test pins
10
10
  // the composite without a ledger ever being committed or a release ever read.
11
11
 
12
+ const SYNC_HEADER = '=== sync ==='
12
13
  const OBSERVATIONS_HEADER = '=== observations ==='
13
14
  const CITATIONS_HEADER = '=== citations ==='
14
15
  const RELEASE_HEADER = '=== release ==='
@@ -52,6 +53,7 @@ const run_tail = {
52
53
  CITATIONS_HEADER,
53
54
  OBSERVATIONS_HEADER,
54
55
  RELEASE_HEADER,
56
+ SYNC_HEADER,
55
57
  exit_code,
56
58
  format_report,
57
59
  section_body,
@@ -1,5 +1,5 @@
1
1
  import { git_spawn } from '#scripts/git/git-spawn'
2
- import { git_stash } from '#scripts/git/git-stash'
2
+ import { git_stash } from '#scripts/git/stash/git-stash'
3
3
  import { lane_close } from '#scripts/lane/lane-close'
4
4
  import { lane_registry, type LaneInfo } from '#scripts/lane/lane-registry'
5
5
  import { run_hold } from './run-hold'
@@ -96,6 +96,7 @@ async function tidy_lanes(is_merged: IsMerged): Promise<Array<Outcome>> {
96
96
  const lanes = await lane_registry.list_lanes()
97
97
 
98
98
  for (const lane of lanes) {
99
+ // eslint-disable-next-line no-await-in-loop -- a close prunes the worktree list the next one reads
99
100
  const outcome = await tidy_lane(lane, is_merged)
100
101
 
101
102
  if (outcome !== undefined) outcomes.push(outcome)
@@ -1,6 +1,6 @@
1
- import { git_stash, type StashEntry } from '#scripts/git/git-stash'
2
- import { stash_orphans } from '#scripts/git/stash-orphans'
3
- import { stash_sweep_lock } from '#scripts/git/stash-sweep-lock'
1
+ import { git_stash, type StashEntry } from '#scripts/git/stash/git-stash'
2
+ import { stash_orphans } from '#scripts/git/stash/stash-orphans'
3
+ import { stash_sweep_lock } from '#scripts/git/stash/stash-sweep-lock'
4
4
  import { bounded_pool } from '#scripts/lib/bounded-pool'
5
5
  import { observation_ledger } from '#scripts/observations/observation-ledger'
6
6
  import { observation_ledger_home } from '#scripts/observations/observation-ledger-home'
@@ -18,20 +18,19 @@ const GONE_REASON = 'already dropped by another run'
18
18
  const BUSY_REASON = 'another run held the stash sweep lock'
19
19
 
20
20
  // An entry cut before joshuafolkken/kit#2919 holds its lines at an old single-file path, so the lines
21
- // of every ledger path it touches are carried to the current ledger.
21
+ // of every ledger path it touches are carried to the current ledger. The reads are independent, and the
22
+ // lines come back in path order however the reads finish.
22
23
  async function added_ledger_lines(
23
24
  hash: string,
24
25
  ledger_paths: ReadonlyArray<string>,
25
26
  ): Promise<Array<string>> {
26
- const added: Array<string> = []
27
-
28
- for (const ledger_path of ledger_paths) {
29
- const lines = await git_stash.added_lines(hash, ledger_path)
30
-
31
- added.push(...lines)
32
- }
27
+ const added = await bounded_pool.bounded_map(
28
+ ledger_paths,
29
+ READ_CONCURRENCY,
30
+ async (ledger_path) => await git_stash.added_lines(hash, ledger_path),
31
+ )
33
32
 
34
- return added
33
+ return added.flat()
35
34
  }
36
35
 
37
36
  // How many ledger lines went into the running work tree's ledger before the drop. The duplicate check
@@ -107,6 +106,7 @@ async function tidy_entries(
107
106
  const outcomes: Array<Outcome> = []
108
107
 
109
108
  for (const entry of entries) {
109
+ // eslint-disable-next-line no-await-in-loop -- drops shift the stash stack and append to the same ledger
110
110
  const outcome = await tidy_entry(entry, merged)
111
111
 
112
112
  if (outcome !== undefined) outcomes.push(outcome)
@@ -3,8 +3,8 @@ import { randomUUID } from 'node:crypto'
3
3
  import path from 'node:path'
4
4
  import { fileURLToPath } from 'node:url'
5
5
  import type { AgentProfile } from '#scripts/agent/agent-role-profile'
6
- import { telegram_notify } from '#scripts/git/telegram-notify'
7
6
  import { cli_flags } from '#scripts/lib/cli-flags'
7
+ import { telegram_notify } from '#scripts/notify/telegram-notify'
8
8
  import { run_carry, type CarryRead } from './run-carry'
9
9
  import { run_event_stream } from './run-event-stream'
10
10
  import { run_headless } from './run-headless'
@@ -226,7 +226,7 @@ async function warn_of_stop(stop: LoopStop, body: string, context: WakeContext):
226
226
  }
227
227
 
228
228
  // **Only a failed wake exits non-zero, and the two reasons that newly warn do not**
229
- // (joshuafolkken/kit#1746). The verdict-and-exit-code table in `docs/josh-commands.md` is a contract
229
+ // (joshuafolkken/kit#1746). The verdict-and-exit-code table in `docs/josh-commands-automation.md` is a contract
230
230
  // callers branch on; what `expired` and `unreadable` were missing is the notification, not a different
231
231
  // exit code, and changing both at once would break a caller to fix a silence.
232
232
  function exit_code_of(reason: WakeStopReason): number {
@@ -410,7 +410,6 @@ const run_wake_cli = {
410
410
  NONE_VERDICT,
411
411
  RUNNING_VERDICT,
412
412
  STALE_VERDICT,
413
- STARTED_VERDICT,
414
413
  STOPPED_VERDICT,
415
414
  SUPERVISING_VERDICT,
416
415
  UNKNOWN_VERDICT,
@@ -199,10 +199,12 @@ async function run_loop(target: string, ports: LoopPorts, interval_ms: number):
199
199
  let wake = run_wake.read_own_wake(target)
200
200
 
201
201
  while (wake !== undefined) {
202
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
202
203
  const stop = await run_pass(target, wake, ports)
203
204
 
204
205
  if (stop !== undefined) return stop
205
206
 
207
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
206
208
  await ports.sleep(next_interval(run_wake.read_own_wake(target), interval_ms, ports.now()))
207
209
  wake = run_wake.read_own_wake(target)
208
210
  }
@@ -213,10 +215,8 @@ async function run_loop(target: string, ports: LoopPorts, interval_ms: number):
213
215
  const run_wake_loop = {
214
216
  FAILED_REASON,
215
217
  MAX_BACKOFF_FACTOR,
216
- STOPPED_REASON,
217
218
  next_interval,
218
219
  run_loop,
219
- step,
220
220
  }
221
221
 
222
222
  export type { DriveResult, LoopPorts, LoopStop }
@@ -1,6 +1,7 @@
1
1
  import { agent_role_profile, type AgentProfile } from '#scripts/agent/agent-role-profile'
2
2
  import { backlog_budget } from '#scripts/backlog/backlog-budget'
3
3
  import { process_identity } from '#scripts/josh/process-identity'
4
+ import { process_owner_schema } from '#scripts/josh/process-owner'
4
5
  import { stamp_file } from '#scripts/josh/stamp-file'
5
6
  import { z } from 'zod'
6
7
  import type { CarryRead } from './run-carry'
@@ -209,11 +210,9 @@ const STOP_REASONS: Record<'none' | 'expired' | 'unreadable', WakeStopReason> =
209
210
  unreadable: 'unreadable',
210
211
  }
211
212
 
212
- const run_wake_schema = z.object({
213
+ const run_wake_schema = process_owner_schema.extend({
213
214
  invocation: z.string(),
214
215
  started_at: z.string(),
215
- pid: z.number(),
216
- process_start: z.string().optional(),
217
216
  woke: z.number(),
218
217
  woke_at: z.string().optional(),
219
218
  // **Every optional field of `RunWake` has to be listed here.** `z.object` strips what it does not
@@ -583,7 +582,6 @@ const run_wake = {
583
582
  IDLE_CEILING_MS,
584
583
  MAX_WAKE_ATTEMPTS,
585
584
  WAKE_GRACE_MS,
586
- WAKE_PREFIX,
587
585
  claim,
588
586
  count_claim,
589
587
  count_wake,
@@ -30,8 +30,4 @@ async function main(): Promise<void> {
30
30
  process.exitCode = await run()
31
31
  }
32
32
 
33
- const run_watcher_guard_cli = { run }
34
-
35
33
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
36
-
37
- export { run_watcher_guard_cli }
@@ -1,4 +1,5 @@
1
1
  import { lane_registry } from '#scripts/lane/lane-registry'
2
+ import { run_headless } from './run-headless'
2
3
  import { run_progress_clock } from './run-progress-clock'
3
4
 
4
5
  // A watcher that stopped while children are still in-flight leaves the parent blind to completions
@@ -29,19 +30,21 @@ type GuardResult = { kind: 'ok' } | { kind: 'stale'; note: string }
29
30
 
30
31
  const OK_RESULT: GuardResult = { kind: 'ok' }
31
32
 
32
- // The lanes a parent is still waiting on. A stranded lane has no child working in it, so it is not
33
- // in-flight — the one definition both this guard and the headless stop rule read (`run-headless.ts`).
34
- async function has_lanes_in_flight(): Promise<boolean> {
35
- const all_lanes = await lane_registry.list_lanes()
33
+ // **Only the run that opened the lanes owes them a watcher** (joshuafolkken/kit#2965). The lane listing
34
+ // is machine-wide, so a session with no run of its own — an investigation, a `fullrun` beside a batch —
35
+ // used to be refused for another run's lanes. The session that drives the live `backlogrun` carry
36
+ // record is the one that dispatched them; every other session passes.
37
+ async function owes_watcher(): Promise<boolean> {
38
+ if (!(await run_headless.is_backlog_parent())) return false
36
39
 
37
- return all_lanes.some((lane) => !lane.is_stranded)
40
+ return await lane_registry.has_lanes_in_flight()
38
41
  }
39
42
 
40
43
  // `life_target` is the path returned by `run_progress_read.stamp_target()` or
41
44
  // `run_progress_clock.life_target_of(git_directory)`. Passed in rather than resolved here so the
42
45
  // caller can use whichever resolution fits its sync/async context.
43
46
  async function check(life_target: string): Promise<GuardResult> {
44
- if (!(await has_lanes_in_flight())) return OK_RESULT
47
+ if (!(await owes_watcher())) return OK_RESULT
45
48
 
46
49
  if (run_progress_clock.is_life_fresh(life_target, STALE_THRESHOLD_MS)) return OK_RESULT
47
50
 
@@ -52,7 +55,6 @@ const run_watcher_guard = {
52
55
  STALE_NOTE,
53
56
  STALE_THRESHOLD_MS,
54
57
  check,
55
- has_lanes_in_flight,
56
58
  }
57
59
 
58
60
  export type { GuardResult }
@@ -81,6 +81,6 @@ async function watcher_hook_reason(
81
81
  return await stale_reason(transcript, now_ms)
82
82
  }
83
83
 
84
- const run_watcher_hook = { SWITCH_ENV_KEY, STAMP_PREFIX, transcript_of, watcher_hook_reason }
84
+ const run_watcher_hook = { transcript_of, watcher_hook_reason }
85
85
 
86
86
  export { run_watcher_hook }
@@ -1,5 +1,6 @@
1
1
  import { createHash } from 'node:crypto'
2
2
  import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'
3
+ import { composite_actions } from '#scripts/ci/composite-actions'
3
4
  import { execaSync } from 'execa'
4
5
 
5
6
  // Where the workflows that install safe-chain on the runner live. Each carries the release and the
@@ -25,13 +26,18 @@ function installer_url(version: string): string {
25
26
  return `https://github.com/AikidoSec/safe-chain/releases/download/${version}/install-safe-chain.sh`
26
27
  }
27
28
 
29
+ // The local composite actions follow the workflows: kit's own pin lives in
30
+ // `.github/actions/setup-pnpm`, which every kit workflow installs through (joshuafolkken/kit#2982).
28
31
  function list_workflows(): Array<string> {
29
- return WORKFLOW_DIRECTORIES.filter((directory) => existsSync(directory)).flatMap((directory) =>
30
- readdirSync(directory)
31
- .filter((file_name) => WORKFLOW_FILE_RE.test(file_name))
32
- .toSorted((left, right) => left.localeCompare(right))
33
- .map((file_name) => `${directory}/${file_name}`),
32
+ const workflows = WORKFLOW_DIRECTORIES.filter((directory) => existsSync(directory)).flatMap(
33
+ (directory) =>
34
+ readdirSync(directory)
35
+ .filter((file_name) => WORKFLOW_FILE_RE.test(file_name))
36
+ .toSorted((left, right) => left.localeCompare(right))
37
+ .map((file_name) => `${directory}/${file_name}`),
34
38
  )
39
+
40
+ return [...workflows, ...composite_actions.list()]
35
41
  }
36
42
 
37
43
  function extract_pinned_version(content: string): string | undefined {
@@ -1,8 +1,8 @@
1
1
  import { existsSync, readFileSync, writeFileSync } from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import { file_reader } from '#scripts/lib/read-file'
4
+ import { yaml_document } from '#scripts/lib/yaml-document'
4
5
  import { release_age } from '#scripts/version/release-age'
5
- import { yaml_document } from '#scripts/yaml/yaml-document'
6
6
  import { dump } from 'js-yaml'
7
7
  import { z } from 'zod'
8
8
 
@@ -191,7 +191,6 @@ function format_below_floor(version: string): string {
191
191
  }
192
192
 
193
193
  const security_audit_provision_logic = {
194
- FORCED_DOWNLOAD_TIMEOUT_MS,
195
194
  RETRY_INTERVAL_MS,
196
195
  SESSION_DOWNLOAD_TIMEOUT_MS,
197
196
  SCANNER_VERSION,
@@ -5,6 +5,7 @@ import { fileURLToPath } from 'node:url'
5
5
  import { PROJECT_ROOT } from '#scripts/init/init-paths'
6
6
  import { stamp_file } from '#scripts/josh/stamp-file'
7
7
  import { error_text } from '#scripts/lib/error-message'
8
+ import { timed_fetch } from '#scripts/lib/timed-fetch'
8
9
  import { security_audit } from './security-audit'
9
10
  import { security_audit_logic } from './security-audit-logic'
10
11
  import { security_audit_provision_logic, type ScannerAsset } from './security-audit-provision-logic'
@@ -33,7 +34,7 @@ interface ProvisionOutcome {
33
34
  // catch-all would drop the release URL out of the message that names where the fetch went.
34
35
  async function download(url: string, timeout_ms: number): Promise<DownloadOutcome> {
35
36
  try {
36
- const response = await fetch(url, { signal: AbortSignal.timeout(timeout_ms) })
37
+ const response = await timed_fetch(url, {}, timeout_ms)
37
38
  if (!response.ok) return { reason: `HTTP ${String(response.status)}` }
38
39
 
39
40
  return { content: Buffer.from(await response.arrayBuffer()), reason: '' }
@@ -180,6 +181,6 @@ async function main(): Promise<void> {
180
181
 
181
182
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
182
183
 
183
- const security_audit_provision = { attempt, download, install, main, provision, report }
184
+ const security_audit_provision = { attempt, provision, report }
184
185
 
185
186
  export { security_audit_provision }