@joshuafolkken/kit 1.1010.0 → 1.1050.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 (350) hide show
  1. package/.claude/settings.json +1 -5
  2. package/.claude/skills/dependency-update/SKILL.md +6 -3
  3. package/.claude/skills/epic-commands/SKILL.md +46 -17
  4. package/.claude/skills/verify-ui/SKILL.md +1 -1
  5. package/.claude/skills/workflow-commands/SKILL.md +10 -25
  6. package/.claude/skills/workflow-commands/background-commands.md +1 -1
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +6 -4
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +6 -0
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +30 -36
  11. package/.claude/skills/workflow-commands/backlogrun-steps.md +16 -16
  12. package/.claude/skills/workflow-commands/backlogrun.md +3 -12
  13. package/.claude/skills/workflow-commands/chain-rule.md +2 -2
  14. package/.claude/skills/workflow-commands/followup-reference.md +2 -2
  15. package/.claude/skills/workflow-commands/fullrun-steps.md +4 -3
  16. package/.claude/skills/workflow-commands/fullrun.md +1 -1
  17. package/.claude/skills/workflow-commands/halfrun.md +2 -1
  18. package/.claude/skills/workflow-commands/into-target.md +1 -1
  19. package/.claude/skills/workflow-commands/issue-comments.md +1 -1
  20. package/.claude/skills/workflow-commands/observation-filing.md +80 -126
  21. package/.claude/skills/workflow-commands/pre-gate-cut.md +33 -36
  22. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  23. package/.claude/skills/workflow-commands/working-tree-hold.md +2 -2
  24. package/.codex/hooks.json +1 -5
  25. package/.github/workflows/auto-tag.yml +21 -0
  26. package/.github/workflows/publish.yml +9 -10
  27. package/.github/workflows/sonar-qube.yml +1 -1
  28. package/AGENTS.md +4 -25
  29. package/CLAUDE.md +24 -38
  30. package/GEMINI.md +4 -24
  31. package/README.md +22 -56
  32. package/dist/CLAUDE.md +24 -38
  33. package/dist/hooks/batch-guard.js +4 -4
  34. package/dist/hooks/{chunk-6PSTVOLH.js → chunk-5BK3K7V4.js} +114 -90
  35. package/dist/hooks/{chunk-PAXMLGSS.js → chunk-7VPDUBRN.js} +93 -175
  36. package/dist/hooks/{chunk-KPZN42RT.js → chunk-DMQN45FN.js} +3 -3
  37. package/dist/hooks/{chunk-WMIR5SNX.js → chunk-EJDX2TOB.js} +13 -3
  38. package/dist/hooks/{chunk-A2H5I2VD.js → chunk-GQ7KP45M.js} +2 -2
  39. package/dist/hooks/{chunk-4GDR2YTV.js → chunk-HJIISEAC.js} +4 -4
  40. package/dist/hooks/{chunk-AWTFKKFW.js → chunk-NAS4C7GP.js} +6 -33
  41. package/dist/hooks/{chunk-56LGMJJV.js → chunk-NJQOBE6L.js} +2 -2
  42. package/dist/hooks/{chunk-EZLHXKJ6.js → chunk-RLDX5SOC.js} +1222 -941
  43. package/dist/hooks/{chunk-GBJUERYK.js → chunk-WQ4OSBSS.js} +10 -3
  44. package/dist/hooks/codex-hook-adapter.js +10 -10
  45. package/dist/hooks/duplicate-read-guard.js +5 -5
  46. package/dist/hooks/format-edited.js +15 -34
  47. package/dist/hooks/investigation-guard.js +5 -5
  48. package/dist/hooks/pretool-guard.js +23 -16
  49. package/dist/hooks/stop-guard.js +21 -200
  50. package/dist/josh.js +42 -125
  51. package/dist/version/index.js +466 -42
  52. package/eslint/base.js +2 -11
  53. package/package.json +36 -10
  54. package/prompts/coding-standards.md +15 -290
  55. package/prompts/collaboration-workflow/cross-repo-epic.md +2 -51
  56. package/prompts/collaboration-workflow/epic-audit.md +2 -53
  57. package/prompts/collaboration-workflow/epic-bundle.md +2 -106
  58. package/prompts/collaboration-workflow/file-edits.md +6 -53
  59. package/prompts/collaboration-workflow/issue-template.md +4 -4
  60. package/prompts/collaboration-workflow/operating-rules.md +18 -75
  61. package/prompts/collaboration-workflow/principles.md +74 -0
  62. package/prompts/collaboration-workflow/residency.md +55 -15
  63. package/prompts/collaboration-workflow/rule-delivery.md +5 -46
  64. package/prompts/collaboration-workflow/shell-body.md +7 -9
  65. package/prompts/collaboration-workflow/turn-batching.md +21 -37
  66. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  67. package/prompts/collaboration-workflow/wip-cap.md +15 -18
  68. package/prompts/collaboration-workflow.md +22 -28
  69. package/prompts/sonar-hotspot-handling.md +1 -1
  70. package/scripts/adopt/adopt-logic.ts +2 -2
  71. package/scripts/adopt/adopt-toolkits.ts +3 -1
  72. package/scripts/adopt/adopt.ts +2 -2
  73. package/scripts/agent/agent-event.ts +2 -9
  74. package/scripts/agent/agent-exit-record.ts +2 -9
  75. package/scripts/auto-ok/auto-ok-cli.ts +9 -9
  76. package/scripts/backlog/backlog-budget-cli.ts +2 -6
  77. package/scripts/backlog/backlog-drive-cli.ts +20 -10
  78. package/scripts/backlog/backlog-drive.ts +50 -16
  79. package/scripts/backlog/backlog-next.ts +24 -8
  80. package/scripts/backlog/backlog-offer-cli.ts +6 -5
  81. package/scripts/backlog/backlog-plan-cli.ts +5 -1
  82. package/scripts/backlog/backlog-plan.ts +1 -1
  83. package/scripts/backlog/backlog-pool.ts +31 -11
  84. package/scripts/backlog/backlog-rank.ts +106 -0
  85. package/scripts/backlog/backlog-waves.ts +42 -29
  86. package/scripts/build/build-bin.ts +2 -1
  87. package/scripts/build/build-config-merge.ts +2 -1
  88. package/scripts/build/build-hooks.ts +31 -6
  89. package/scripts/build/build-managed-marker.ts +2 -1
  90. package/scripts/build/build-self-sync-guard.ts +2 -1
  91. package/scripts/build/build-version.ts +2 -1
  92. package/scripts/cases/cases-logic.ts +2 -6
  93. package/scripts/ci/pr-classification.ts +13 -11
  94. package/scripts/cost-runtime/cost-transcript.ts +4 -11
  95. package/scripts/delegation/delegation-policy.ts +11 -0
  96. package/scripts/doctor/doctor-consumer.ts +5 -12
  97. package/scripts/doctor/doctor-ports.ts +2 -2
  98. package/scripts/document/document-byte-budget.ts +13 -21
  99. package/scripts/document/document-section.ts +2 -6
  100. package/scripts/document/entry-read-budget.ts +6 -5
  101. package/scripts/{git/git-epic-add-body.ts → epic/epic-add-body.ts} +23 -23
  102. package/scripts/{git/git-epic-add-plan.ts → epic/epic-add-plan.ts} +23 -26
  103. package/scripts/{git/git-epic-add.ts → epic/epic-add.ts} +17 -17
  104. package/scripts/epic/epic-audit-cli.ts +4 -4
  105. package/scripts/epic/epic-audit-orphans.ts +2 -2
  106. package/scripts/epic/epic-audit-rationale.ts +1 -1
  107. package/scripts/epic/epic-audit.ts +1 -1
  108. package/scripts/{git/git-epic-body.ts → epic/epic-body.ts} +6 -6
  109. package/scripts/epic/epic-bundle-cli.ts +1 -1
  110. package/scripts/epic/epic-bundle.ts +2 -2
  111. package/scripts/epic/epic-candidate-confirm.ts +2 -1
  112. package/scripts/{git/git-epic-chains.ts → epic/epic-chains.ts} +4 -4
  113. package/{scripts-ai → scripts/epic}/epic-check.ts +5 -4
  114. package/{scripts-ai → scripts/epic}/epic-cli.ts +4 -4
  115. package/scripts/{git/git-epic-close-comment.ts → epic/epic-close-comment.ts} +9 -9
  116. package/scripts/{git/git-epic-close.ts → epic/epic-close.ts} +23 -19
  117. package/scripts/epic/epic-cross-repo.ts +21 -38
  118. package/scripts/{git/git-epic-decision.ts → epic/epic-decision.ts} +12 -14
  119. package/scripts/epic/epic-fetch.ts +3 -3
  120. package/scripts/epic/epic-graph.ts +3 -3
  121. package/scripts/epic/epic-index.ts +2 -2
  122. package/scripts/epic/epic-issue.ts +1 -1
  123. package/scripts/epic/epic-lane-offer.ts +11 -22
  124. package/scripts/epic/epic-next.ts +3 -3
  125. package/scripts/{git/git-epic-parse.ts → epic/epic-parse.ts} +3 -3
  126. package/scripts/{git/git-epic-promote.ts → epic/epic-promote.ts} +10 -10
  127. package/scripts/epic/epic-rank.ts +37 -0
  128. package/scripts/{git/git-epic-read.ts → epic/epic-read.ts} +9 -9
  129. package/scripts/{git/git-epic-reconcile.ts → epic/epic-reconcile.ts} +18 -20
  130. package/scripts/{git/git-epic-reference.ts → epic/epic-reference.ts} +4 -23
  131. package/scripts/epic/epic-relation-recheck.ts +4 -3
  132. package/scripts/{git/git-epic-relations.ts → epic/epic-relations.ts} +5 -5
  133. package/scripts/{git/git-epic-remove-plan.ts → epic/epic-remove-plan.ts} +17 -19
  134. package/scripts/{git/git-epic-remove.ts → epic/epic-remove.ts} +13 -13
  135. package/scripts/{git/git-epic-run.ts → epic/epic-run.ts} +27 -27
  136. package/scripts/{git/git-epic-sections.ts → epic/epic-sections.ts} +6 -6
  137. package/scripts/{git/git-epic-shape.ts → epic/epic-shape.ts} +7 -7
  138. package/scripts/epic/epic-solo.ts +29 -28
  139. package/scripts/{git/git-epic-validate.ts → epic/epic-validate.ts} +13 -13
  140. package/{scripts-ai → scripts/epic}/epic.ts +17 -16
  141. package/scripts/gh/fix-gh-packages.ts +2 -1
  142. package/scripts/gh/gh-spawn.ts +12 -10
  143. package/scripts/git/constants.ts +1 -1
  144. package/scripts/git/git-branch.ts +10 -1
  145. package/scripts/git/git-command.ts +2 -2
  146. package/scripts/git/git-error.ts +2 -5
  147. package/scripts/git/git-execa-error.ts +6 -1
  148. package/{scripts-ai → scripts/git}/git-followup-finish.ts +7 -7
  149. package/scripts/git/git-followup-flush.ts +74 -48
  150. package/scripts/git/git-followup-issue-close.ts +2 -2
  151. package/scripts/git/git-followup-label.ts +1 -1
  152. package/scripts/git/git-followup-pending.ts +1 -1
  153. package/{scripts-ai → scripts/git}/git-followup-workflow.ts +23 -11
  154. package/scripts/git/git-gh-exec.ts +85 -26
  155. package/scripts/git/git-gh-issue-read.ts +2 -2
  156. package/scripts/git/git-gh-issue-rest.ts +2 -2
  157. package/scripts/git/git-gh-issue-write.ts +6 -6
  158. package/scripts/git/git-gh-pr-read.ts +0 -21
  159. package/scripts/git/git-gh-pr.ts +2 -23
  160. package/scripts/git/git-next-issues.ts +34 -5
  161. package/scripts/git/git-pr-followup-wrapup.ts +2 -6
  162. package/scripts/git/git-preflight.ts +25 -10
  163. package/scripts/git/git-push-transport.ts +12 -69
  164. package/scripts/git/git-spawn.ts +79 -3
  165. package/scripts/git/git-ssh-keepalive.ts +74 -0
  166. package/scripts/git/git-staging.ts +21 -9
  167. package/{scripts-ai → scripts/git}/git-workflow.ts +11 -11
  168. package/scripts/git/github-issue-url.ts +1 -1
  169. package/scripts/git/gone-branch.ts +3 -2
  170. package/scripts/git/issue-labels.ts +13 -1
  171. package/scripts/git/issue-rank.ts +89 -0
  172. package/scripts/git/issue-reference.ts +19 -0
  173. package/scripts/git/main-merge.ts +2 -1
  174. package/scripts/git/main-sync.ts +3 -2
  175. package/scripts/git/schemas.ts +1 -1
  176. package/scripts/git/stash-pop-args.ts +7 -13
  177. package/scripts/git/stash-pop-cli.ts +2 -1
  178. package/{scripts-ai → scripts/git}/telegram-test-logic.ts +2 -2
  179. package/{scripts-ai → scripts/git}/telegram-test.ts +7 -7
  180. package/scripts/hooks/format-edited-cli.ts +15 -0
  181. package/scripts/hooks/format-edited-file.ts +2 -9
  182. package/scripts/hooks/format-rewrite-notice.ts +2 -8
  183. package/scripts/hooks/pretool-guard-cli.ts +21 -0
  184. package/scripts/hooks/pretool-guard.ts +14 -15
  185. package/scripts/init/init-ai-copy.ts +2 -5
  186. package/scripts/init/init.ts +8 -4
  187. package/scripts/init/start-exec.ts +7 -1
  188. package/scripts/init/start-plan.ts +18 -5
  189. package/scripts/init/start-setup-pr.ts +46 -19
  190. package/scripts/init/start-steps.ts +43 -10
  191. package/scripts/init/start.ts +42 -11
  192. package/scripts/issue/issue-cite.ts +19 -1
  193. package/scripts/issue/issue-comment-cli.ts +2 -1
  194. package/scripts/issue/issue-file-cli.ts +2 -1
  195. package/scripts/issue/issue-fold-cli.ts +9 -16
  196. package/scripts/issue/issue-scout-cli.ts +8 -13
  197. package/scripts/issue/measure-rerun-cli.ts +7 -6
  198. package/scripts/josh/josh-command-map.ts +0 -102
  199. package/scripts/josh/josh-commands-ai.ts +2 -2
  200. package/scripts/josh/josh-commands-backlog.ts +1 -1
  201. package/scripts/josh/josh-commands-development.ts +3 -3
  202. package/scripts/josh/josh-commands-project.ts +1 -1
  203. package/scripts/josh/josh-commands-workflow.ts +4 -4
  204. package/scripts/lane/lane-child-marker.ts +16 -2
  205. package/scripts/lane/lane-cli.ts +34 -15
  206. package/scripts/lane/lane-open.ts +3 -2
  207. package/scripts/lane/lane-registry.ts +3 -6
  208. package/scripts/lane/lane-report.ts +10 -4
  209. package/scripts/lib/cli-flags.ts +20 -2
  210. package/scripts/lib/error-message.ts +9 -0
  211. package/scripts/lib/read-file.ts +26 -2
  212. package/scripts/observations/observation-ledger-home.ts +98 -26
  213. package/scripts/observations/observation-ledger-migrate.ts +26 -21
  214. package/scripts/observations/observation-ledger-prepare.ts +10 -20
  215. package/scripts/observations/observation-ledger.ts +58 -25
  216. package/scripts/observations/observations-flush-cli.ts +6 -23
  217. package/scripts/observations/observations-flush-landing.ts +2 -1
  218. package/scripts/observations/observations-flush.ts +29 -20
  219. package/scripts/package/package-scout-cli.ts +8 -16
  220. package/scripts/ports/port-command.ts +2 -1
  221. package/scripts/propagate/propagate-plan.ts +185 -0
  222. package/scripts/propagate/propagate-publish.ts +6 -7
  223. package/scripts/propagate/propagate-run.ts +5 -1
  224. package/scripts/propagate/propagate-steps.ts +18 -2
  225. package/scripts/propagate/propagate-targets.ts +13 -2
  226. package/scripts/propagate/propagate.ts +63 -44
  227. package/scripts/refactor/import-graph.ts +2 -6
  228. package/scripts/registry-migration/migrate-logic.ts +1 -0
  229. package/scripts/registry-migration/migrate.ts +3 -2
  230. package/scripts/registry-migration/user-npmrc.ts +2 -2
  231. package/scripts/release/github-release.ts +1 -1
  232. package/scripts/release/release-cli.ts +2 -1
  233. package/scripts/repo/repo-setting.ts +10 -8
  234. package/scripts/review/review-attest.ts +44 -0
  235. package/scripts/review/review-brief-cli.ts +49 -2
  236. package/scripts/review/review-brief.ts +46 -1
  237. package/scripts/review/review-finding-ledger.ts +3 -3
  238. package/scripts/review/review-findings-cli.ts +4 -11
  239. package/scripts/review/review-record-cli.ts +14 -11
  240. package/scripts/review/review-record.ts +6 -16
  241. package/scripts/review/review-stamps.ts +7 -0
  242. package/scripts/rules/decision-oracle.ts +2 -2
  243. package/scripts/rules/implementation-cut.ts +1 -1
  244. package/scripts/rules/issue-fold.ts +1 -2
  245. package/scripts/rules/lane-carry-conflict.ts +1 -2
  246. package/scripts/rules/lane-park.ts +1 -2
  247. package/scripts/rules/pre-gate-cut.ts +2 -2
  248. package/scripts/rules/rule-body-guard.ts +2 -2
  249. package/scripts/rules/rule-value-cache.ts +99 -0
  250. package/scripts/rules/rule-value-cli.ts +10 -9
  251. package/scripts/rules/rule-value.ts +1 -1
  252. package/scripts/run/run-carry-args.ts +2 -6
  253. package/scripts/run/run-carry-cli.ts +5 -7
  254. package/scripts/run/run-cut-args.ts +7 -13
  255. package/scripts/run/run-ending-cli.ts +4 -7
  256. package/scripts/run/run-event-stream.ts +2 -5
  257. package/scripts/run/run-headless.ts +22 -6
  258. package/scripts/run/run-liveness-cli.ts +4 -7
  259. package/scripts/run/run-parent-cut-hook.ts +144 -0
  260. package/scripts/run/run-progress-args.ts +2 -6
  261. package/scripts/run/run-progress-cli.ts +2 -1
  262. package/scripts/run/run-progress-read.ts +2 -1
  263. package/scripts/run/run-progress.ts +21 -8
  264. package/scripts/run/run-ship-cli.ts +6 -74
  265. package/scripts/run/run-ship-preflight.ts +87 -0
  266. package/scripts/run/run-ship-review-steps.ts +5 -26
  267. package/scripts/run/run-ship-review.ts +9 -0
  268. package/scripts/run/run-ship-scoped.ts +44 -0
  269. package/scripts/run/run-ship-stage.ts +5 -1
  270. package/scripts/run/run-ship-steps.ts +105 -0
  271. package/scripts/run/run-ship.ts +2 -0
  272. package/scripts/run/run-tail-cli.ts +3 -3
  273. package/scripts/run/run-tidy-stashes.ts +7 -14
  274. package/scripts/run/run-wake-cli.ts +4 -8
  275. package/scripts/run/run-wake-describe.ts +19 -1
  276. package/scripts/run/run-wake-driver.ts +15 -2
  277. package/scripts/run/run-wake-session.ts +14 -4
  278. package/scripts/run/run-watcher-hook.ts +1 -1
  279. package/scripts/safe-chain/project-config.ts +3 -6
  280. package/scripts/security/security-audit-provision.ts +6 -7
  281. package/scripts/sonar/sonar-hotspots-cli.ts +2 -1
  282. package/scripts/sync/directory-copy-guard.ts +2 -1
  283. package/scripts/sync/sync-ai-files.ts +3 -3
  284. package/scripts/sync/template-source-logic.ts +3 -4
  285. package/scripts/test/e2e-retry-check.ts +3 -6
  286. package/scripts/time-runtime/time-bundle-call.ts +2 -2
  287. package/scripts/ui/ui-routes-cli.ts +3 -6
  288. package/scripts/version/bump-version.ts +2 -1
  289. package/scripts/version/npm-registry.ts +97 -0
  290. package/scripts/version/version-commands.ts +5 -4
  291. package/scripts/version/version-remote.ts +38 -33
  292. package/scripts/version/version-targets.ts +3 -3
  293. package/.claude/skills/workflow-commands/rule-residency.md +0 -267
  294. package/evals/scenarios/consult-not-execute.json +0 -20
  295. package/evals/scenarios/no-implicit-workflow.json +0 -26
  296. package/evals/scenarios/overrides-both-locations.json +0 -29
  297. package/evals/scenarios/upstream-interrupt.json +0 -23
  298. package/evals/scenarios/workflow-skill-loaded.json +0 -16
  299. package/prompts/agent-lint-protocol.json +0 -79
  300. package/prompts/agent-rules.md +0 -63
  301. package/prompts/collaboration-workflow/consultation-vs-execution.md +0 -8
  302. package/prompts/collaboration-workflow/distributed-docs.md +0 -7
  303. package/prompts/collaboration-workflow/durable-rules.md +0 -24
  304. package/prompts/collaboration-workflow/latest-first.md +0 -14
  305. package/prompts/collaboration-workflow/no-clones.md +0 -11
  306. package/prompts/collaboration-workflow/simplicity-first.md +0 -9
  307. package/prompts/collaboration-workflow/single-source-rules.md +0 -13
  308. package/scripts/build/shim-shell.ts +0 -25
  309. package/scripts/claude/skill-meta.ts +0 -37
  310. package/scripts/document/document-scan.ts +0 -108
  311. package/scripts/document/generate-catalog.ts +0 -69
  312. package/scripts/document/retired-phrases.ts +0 -143
  313. package/scripts/document/review-agent-type.ts +0 -46
  314. package/scripts/document/single-source.ts +0 -73
  315. package/scripts/git/git-fixture-workspace.ts +0 -88
  316. package/scripts/hooks/format-edited-file-fixtures.ts +0 -109
  317. package/scripts/hooks/prompt-hooks.ts +0 -38
  318. package/scripts/init/hook-command-bootstrap.ts +0 -83
  319. package/scripts/issue/issue-logic.ts +0 -50
  320. package/scripts/josh/__snapshots__/josh-command-map.test.ts.snap +0 -1227
  321. package/scripts/josh/josh-script-reader.ts +0 -11
  322. package/scripts/package/production-dependency-graph.ts +0 -68
  323. package/scripts/retrospective/retrospective-cli.ts +0 -97
  324. package/scripts/retrospective/retrospective.ts +0 -127
  325. package/scripts/rules/delivered-rules-harness.ts +0 -72
  326. package/scripts/rules/top-level-scripts-guard.ts +0 -47
  327. package/scripts/run/run-carry-flush.ts +0 -58
  328. package/scripts/run/run-transcript.golden.txt +0 -57
  329. package/scripts/run/run-wake-work.ts +0 -108
  330. package/scripts/sync/dependabot-pin-logic.ts +0 -135
  331. package/scripts/test/classify-isolation.ts +0 -149
  332. package/scripts/test/http-fault-injection.ts +0 -79
  333. package/scripts/test/josh-harness-environment.ts +0 -260
  334. package/scripts/test/josh-harness.ts +0 -96
  335. package/scripts/test/pilot-files.ts +0 -452
  336. package/scripts/test/pilot-measure.ts +0 -78
  337. package/scripts/test/test-network-guard.ts +0 -453
  338. package/scripts/test/test-repository-guard.ts +0 -317
  339. package/scripts/test/test-state-guard.ts +0 -85
  340. package/scripts/test/test-stdout-guard.ts +0 -54
  341. package/scripts/test/test-telegram-guard.ts +0 -90
  342. package/scripts/test/unit-guard-environment.ts +0 -12
  343. package/scripts/test/unit-projects.ts +0 -139
  344. package/scripts/test/vitest-include-globs.ts +0 -12
  345. package/scripts/time-runtime/time-batch-guard-fixtures.ts +0 -66
  346. package/scripts-ai/completion-gate.ts +0 -13
  347. package/scripts-ai/environment-loader.ts +0 -9
  348. /package/{scripts-ai → scripts/epic}/epic-cli-argv.ts +0 -0
  349. /package/{scripts-ai → scripts/epic}/epic-cli-remove.ts +0 -0
  350. /package/{scripts-ai → scripts/git}/followup-issue-number.ts +0 -0
@@ -84,7 +84,7 @@ pnpm josh notify --task-type failure --issue-url "<issue-url>" --body "<the reas
84
84
  **The matching itself is unchanged, and so is the reason it is mechanical.** The instruction the mechanical read replaced was skipped in two runs out of three on the day it was measured, and one of those two could not have succeeded by eye at all: `AI_COPY_DIRECTORIES` holds directories, so a distributed path such as `.claude/skills/workflow-commands/backlogrun.md` appears in no list textually.
85
85
 
86
86
  ```bash
87
- pnpm josh sync:scope # managed | clean, naming which list claimed each path; alias: josh sys
87
+ pnpm josh sync:scope # managed | clean, naming which list claimed each path
88
88
  ```
89
89
 
90
90
  - **There is no flag to pass and nothing to approve.** `--managed-config-ignore-reason` is gone with the stop it existed to get past.
@@ -99,7 +99,7 @@ pnpm josh sync:scope # managed | clean, naming which list claimed each path;
99
99
  **The answer: `pnpm josh release:scope`.**
100
100
 
101
101
  ```bash
102
- pnpm josh release:scope # → required | skip | unknown ; alias: josh res
102
+ pnpm josh release:scope # → required | skip | unknown
103
103
  pnpm josh release:scope --json # the same answer as one JSON object
104
104
  ```
105
105
 
@@ -55,7 +55,8 @@ that covers the same work stops the run rather than filing a second Issue (`SKIL
55
55
  `<N>`. (3) Add
56
56
  `in-progress` (as above). (4) Post the agreed plan in the session language: fill the body if blank,
57
57
  otherwise add a comment. (5) If the working tree already has staged or modified files,
58
- `git stash push -m "fullrun new: pre-existing changes"` first. (6) `git switch main && git pull`. (7)
58
+ `git stash push -m "fullrun new: pre-existing changes" -- ':!docs/maintainers/observations'` first
59
+ (joshuafolkken/kit#2919). (6) `git switch main && git pull`. (7)
59
60
  `pnpm josh latest:scope`; on `required` run `josh latest` and load the `dependency-update` skill; on
60
61
  `skip` neither runs (`latest-gate.md` is the single source). If you stashed in (5),
61
62
  `pnpm josh stash:pop "fullrun new: pre-existing changes"` — by message, never a positional `git stash
@@ -78,8 +79,8 @@ release:scope` and close the completion summary with what it answered** (`follow
78
79
  ## The release ask — the last step of either form
79
80
 
80
81
  **One call folds the post-merge bookkeeping** (joshuafolkken/kit#2372): after the merge, `pnpm josh
81
- run:tail <N>` commits the observation ledger (`observations:flush` — skipped by a dispatched lane child,
82
- whose `backlogrun` flushes once at `run:carry --end`; joshuafolkken/kit#2492), reads the completion citations
82
+ run:tail <N>` commits ledger lines written outside any issue's run (`observations:flush`,
83
+ joshuafolkken/kit#2919), reads the completion citations
83
84
  (`issue:cite`, given the closed issue and any follow-ups filed this run) and decides the release scope
84
85
  (`release:scope`) in one round trip, joining each under its own header. **On the clean path `run:tail`
85
86
  runs inside `pnpm josh ship`** as its report step (joshuafolkken/kit#2398), so it is a standalone call
@@ -46,7 +46,7 @@ call reports `hold`.
46
46
  `pnpm josh latest:scope` — update dependencies only on `required` (`latest-gate.md`), never on every
47
47
  run. `run:step` names every later action in order — the verification gate, `pnpm josh followup`,
48
48
  `pnpm josh ms`, the release ask — each read at the point-of-use doc the header lists, never
49
- re-narrated here (`residency.md` → ordering question).
49
+ re-narrated here (`residency.md` → "順序の問い").
50
50
 
51
51
  ## The progress step and the lane-child seam
52
52
 
@@ -59,7 +59,8 @@ back with fixes, treat each as a new round: implement, re-run `pnpm josh gate`,
59
59
  mirror `fullrun new` (1)–(8): derive an English title (or use the provided one) → create the Issue
60
60
  (`pnpm josh issue:file "<title>" --body-file <body-file> --depth <n>`, body per
61
61
  `prompts/collaboration-workflow/issue-template.md`; its duplicate scan is read per `SKILL.md` → §2e) → add `in-progress` → post the agreed plan → stash
62
- any pre-existing changes with `git stash push -m "halfrun new: pre-existing changes"`, popped by
62
+ any pre-existing changes with `git stash push -m "halfrun new: pre-existing changes" -- ':!docs/maintainers/observations'`
63
+ (the pathspec keeps the observation ledger in the tree for this run's commit; joshuafolkken/kit#2919), popped by
63
64
  message with `pnpm josh stash:pop "halfrun new: pre-existing changes"`, never a positional `git stash pop` →
64
65
  `git switch main && git pull` → `pnpm josh latest:scope` → implement → run the gate (as above, `pnpm
65
66
  josh test:e2e` run by **you**) → `pnpm josh run:hold <N> --halfrun-stop` → send the `confirmation`
@@ -39,7 +39,7 @@ new epic" when what gets created is often a single Issue.
39
39
  applies depends on what the target is, and promoting rewrites someone else's Issue into a container.
40
40
  - **A cross-repository target is written `owner/repo#N`** and inserted from that repository's
41
41
  checkout; run there, since `epic --add` reads and writes only the repository it runs from
42
- (`prompts/collaboration-workflow/cross-repo-epic.md`). A bare `#N` resolves to this repository's
42
+ (`.claude/skills/epic-commands/SKILL.md` → "Epics that span repositories"). A bare `#N` resolves to this repository's
43
43
  issue of that number.
44
44
  - **No suffix leaves the behavior exactly as it was.**
45
45
 
@@ -12,7 +12,7 @@ delegated unit executing `fullrun`'s procedure, and the hook keys its once-per-r
12
12
  same turn as whatever else the run already needs:
13
13
 
14
14
  ```bash
15
- pnpm josh issue:read <N> [<N> ...] # body and comments, one call per batch; alias: josh ird
15
+ pnpm josh issue:read <N> [<N> ...] # body and comments, one call per batch
16
16
  gh api repos/{owner}/{repo}/issues/<N>/comments --jq '.[] | {user: .user.login, created_at, body}'
17
17
  ```
18
18
 
@@ -32,13 +32,7 @@ The detail below is read at the filing decision, and the marker suite pins the r
32
32
 
33
33
  ### The depth test — a discretionary filing cites the product work it blocked
34
34
 
35
- **A run that has just spent an hour inside the workflow tooling files findings about the workflow
36
- tooling** (joshuafolkken/kit#1698). Measured on the `backlogrun` of 2026-09-09: 5 Issues shipped and
37
- 15 filed, of which 13 were discretionary — and all 20 were about this package's own run
38
- orchestration or the tools that measure it, with not one change a consumer of the package would see.
39
- **A listing that measures itself has no natural stopping condition**, because every measurement
40
- creates something new to measure. So the condition comes from outside, and **depth is what supplies
41
- it — read off the subject rather than judged**:
35
+ **Depth is read off the subject rather than judged** (joshuafolkken/kit#1698):
42
36
 
43
37
  | Depth | The subject | Where it lives |
44
38
  | --- | --- | --- |
@@ -75,16 +69,14 @@ gh api repos/{owner}/{repo}/labels -f name=depth:2 -f color=c5def5 -f descriptio
75
69
  - **It is read off the subject, exactly as the table is** — so applying it is not a judgement and not
76
70
  a person's to make, which is what separates it from `auto-ok` and `needs-human-review`. Those two
77
71
  decide what a run may do; this one records what an Issue is about and withholds nothing.
78
- - **Applied at filing, not at completion.** A depth assigned when the work finishes is assigned by
79
- whoever happens to close it, and the share below is a question about the *open* backlog — an Issue
80
- that never carried the label was never in the numerator's reach.
72
+ - **Applied at filing, not at completion.**
81
73
  - **An Issue carrying more than one counts as the lowest depth present**, the one closest to the
82
- consumer. It is a fixed tie-break rather than a preference: without one the same backlog measured
83
- twice can answer twice, which is the whole defect joshuafolkken/kit#1729 was filed for.
74
+ consumer.
84
75
  - **An `epic` takes no depth label**, because it has no subject of its own to read one off — its
85
76
  children carry the subjects, and the share below excludes it from the denominator for that same
86
- reason. A depth label present on an Issue the count skips is exactly the ambiguity this section
87
- exists to remove.
77
+ reason.
78
+
79
+ Rationale: `docs/maintainers/observation-filing-rationale.md` → "Why the depth label is applied at filing".
88
80
 
89
81
  - **A discretionary observation at depth 1 or deeper is filed only where it can cite the depth-0 work
90
82
  it stopped or delayed** — named as an Issue number or a run, never as "this would slow runs down".
@@ -96,12 +88,8 @@ gh api repos/{owner}/{repo}/labels -f name=depth:2 -f color=c5def5 -f descriptio
96
88
  - **`route:tier-a` and `route:interrupt` do not take it either**, at any depth: a filing the run
97
89
  cannot proceed without is already citing its own blockage.
98
90
  - **A depth-2 filing — one whose subject is what measures a run — carries a further requirement, on
99
- top of the depth-0 citation above rather than in place of it** (joshuafolkken/kit#1975). The
100
- citation the depth-0 gate asks for is one a slow run can always produce, so it barely bites on a
101
- measurement Issue: "runs are slow" and "the diff is large" both name depth-0 work, while the number
102
- the Issue proposes to produce changes nothing — and a listing that measures itself has no natural
103
- stopping condition precisely there. So a discretionary depth-2 filing states two things the depth-0
104
- citation does not force:
91
+ top of the depth-0 citation above rather than in place of it** (joshuafolkken/kit#1975). A
92
+ discretionary depth-2 filing states two things the depth-0 citation does not force:
105
93
  - **The decision the number would change, named** — the Issue number holding the choice it is
106
94
  waiting on, or a decision a person is about to make. "Slow", "large" and "worth knowing" are not a
107
95
  decision.
@@ -115,15 +103,15 @@ gh api repos/{owner}/{repo}/labels -f name=depth:2 -f color=c5def5 -f descriptio
115
103
  depth-0 observation does not take it because it is the product, and a review round cap's branch-2
116
104
  filing (below) clears its own bar and never reaches this one.
117
105
 
106
+ Rationale: `docs/maintainers/observation-filing-rationale.md` → "Why depth gates a discretionary filing".
107
+
118
108
  **It governs this route only — the fourth row of §2d's table.** A review finding routed to branch 2
119
109
  of `prompts/review.md` → "Review round cap" is filed under that section's own bar — a confirmed
120
110
  defect reaching a runtime path, with a written failure scenario — and **does not take the depth
121
111
  test**: it has already cleared a bar this route has not, so gating it on a citation as well would
122
112
  drop the one kind of finding both documents agree is never dropped. **That bar is the reason, and the
123
- subject's depth is not** — the sentence here used to say that a defect in a `josh` command's behavior
124
- is depth 0 by construction, and joshuafolkken/kit#1694 and joshuafolkken/kit#1703 are both branch-2
125
- filings whose subject is the epic tooling, which the table above puts at depth 1
126
- (joshuafolkken/kit#1675).
113
+ subject's depth is not.** Rationale: `docs/maintainers/observation-filing-rationale.md` → "Why a
114
+ review branch-2 filing skips the depth test".
127
115
 
128
116
  **This is not the count cap that was rejected.** A cap is rationing — past the number the finding is
129
117
  lost, and nothing about it says which findings were worth having. This changes what counts as a
@@ -133,34 +121,26 @@ finding at all, so what it excludes is excluded for a reason a reader can check.
133
121
  a depth-2 Issue that *proposes* a measurement; a pull request that *adds* one — a new report column,
134
122
  section, scope or subcommand, a diagnostic step — states in its body the reader that consumes it: the
135
123
  Issue number that read the value to decide something, or the path of the rule that reads it. **A
136
- measurement with no reader is not added** — this is joshuafolkken/kit#2012's test, the one that
137
- retired every column no decision reads, moved to the moment a column is proposed so the retirement
138
- never has to be filed again. `route:tier-a` and `route:interrupt` carry over unchanged.
124
+ measurement with no reader is not added** (joshuafolkken/kit#2012). `route:tier-a` and
125
+ `route:interrupt` carry over unchanged.
139
126
 
140
127
  ### The depth-0 share — what is counted
141
128
 
142
- **joshuafolkken/kit#1698 set a measurable target: the share of open Issues at depth 0** — 3/23
143
- ≈ 13% on 2026-09-09 (joshuafolkken/kit#1729). Counted by eye it is not reproducible: done again on
144
- 2026-09-10 it produced 3/14 ≈ 21%, and the two figures **are not comparable**: they took different
145
- denominators, and neither said which. So the denominator is fixed here as a rule rather than left to
146
- the counter.
129
+ **The depth-0 share is the share of open Issues at depth 0** (joshuafolkken/kit#1698,
130
+ joshuafolkken/kit#1729).
147
131
 
148
132
  **The denominator is a rule, not a choice, and this is it:**
149
133
 
150
- - **Counted: every open Issue that does not carry `epic`.** An epic is a container for other Issues
151
- rather than a deliverable of its own — counting one counts its children twice, and an epic has no
152
- subject of its own to read a depth off.
134
+ - **Counted: every open Issue that does not carry `epic`.**
153
135
  - **`route:tier-a` and `route:interrupt` are counted like anything else.** The depth test above
154
- exempts them from its *citation* requirement; it never said they are not work. Excluded, a run
155
- could improve the share by choosing a filing route.
156
- - **An Issue with no depth label is in the denominator**, counted separately as `unlabelled`. Left
157
- out, the share would improve every time a filing skipped the label — the one direction a
158
- measurement must never be able to move on its own.
136
+ exempts them from its *citation* requirement; it never said they are not work.
137
+ - **An Issue with no depth label is in the denominator**, counted separately as `unlabelled`.
159
138
  - **The numerator is what is left**: open, non-epic Issues carrying `depth:0`.
160
139
 
161
- **Two readings of the same backlog give the same number**, which is what the hand counts could not
162
- do: the denominator is a rule rather than a choice, so nothing in the count is left to the counter's
163
- judgement.
140
+ **Two readings of the same backlog give the same number**: nothing in the count is left to the
141
+ counter's judgement.
142
+
143
+ Rationale: `docs/maintainers/observation-filing-rationale.md` → "Why the depth-0 denominator is fixed".
164
144
 
165
145
  **What the number is for is not decided here.** Changing what `backlog:next` offers on the strength
166
146
  of it, and setting a target value, are both deliberately out of scope until the current value has
@@ -168,17 +148,19 @@ been measured the same way more than once (joshuafolkken/kit#1729 → 範囲外)
168
148
 
169
149
  ### The ledger — where an observation that cannot cite a blockage goes
170
150
 
171
- **"Not filed" used to mean "gone", and that is what walked the depth test past itself.** The
172
- completion report was the only place such an observation could land, and a completion report is
173
- read once and then scrolls away — so the next run met the same thing as a first sighting, forever.
174
- joshuafolkken/kit#1726 is the worked case: its own body says the depth test would not have filed it,
175
- and it was filed anyway, because **discarding it was the only alternative on offer**
176
- (joshuafolkken/kit#1728).
177
-
178
- - **The destination is `docs/maintainers/observations.md` in the repository the observation is about** — the same
179
- repository the Issue would have been filed into. **The count and the append are both run in that
180
- repository's checkout**, resolved the way §2c (`target-repository.md`) resolves any cross-repository target, and the file is
181
- created on the first append where that repository has none. **The subject decides, never the
151
+ **An observation the depth test turns away is recorded in the ledger, not discarded**
152
+ (joshuafolkken/kit#1728). Rationale: `docs/maintainers/observation-filing-rationale.md` → "Why the
153
+ ledger exists".
154
+
155
+ - **The destination is the `docs/maintainers/observations/` directory in the repository the
156
+ observation is about** — the same repository the Issue would have been filed into — **one file per
157
+ issue** (joshuafolkken/kit#2919): append to `<N>.md` for the issue the run is executing (the number
158
+ its branch leads with, a lane's included), or to `<YYYY-MM-DD>.md` for a line written on the
159
+ default branch outside any issue's run. Parallel lanes therefore write different files, and their
160
+ pull requests never conflict on the ledger. **The count and the append are both run in that
161
+ repository's checkout** — in this repository, the work tree the run is in, a lane's inside a lane —
162
+ resolved the way §2c (`target-repository.md`) resolves any cross-repository target, and the
163
+ directory is created on the first append where that repository has none. **The subject decides, never the
182
164
  working directory**: an observation about this package's own orchestration, seen while a run is
183
165
  inside a repository that consumes it, is recorded here rather than there — the append follows the
184
166
  subject, never the working directory. **A third-party target gets no line either** — Tier C covers
@@ -186,8 +168,8 @@ and it was filed anyway, because **discarding it was the only alternative on off
186
168
  - **It is append-only.** A line is never edited and never deleted, because the count of lines
187
169
  carrying one key is what says whether an observation has recurred; a second sighting is a second
188
170
  line, not a rewrite of the first. **A merge conflict in it is resolved by keeping both sides** —
189
- two lanes appending at once is the ordinary case, and a repeated key is the whole signal, so
190
- dropping either side destroys exactly what the file is for.
171
+ one file per issue should keep it from arising, but a repeated key is the whole signal, so
172
+ dropping either side destroys exactly what the ledger is for.
191
173
  - **The completion report keeps its line too.** The ledger is what the next run can read; the report
192
174
  is what this run's reader sees. Neither replaces the other.
193
175
  - **The append is not the end of it** — a line only becomes readable to anyone else once it has
@@ -215,21 +197,21 @@ A sample, in the shape a real entry takes:
215
197
  ```
216
198
 
217
199
  **`k:example` is reserved for this sample and is never used by a real observation**, so the count
218
- below can be run over the whole file without the sample answering for one. **The grammar is defined
219
- here rather than in the ledger** because this skill is distributed to every repository that consumes
220
- the package and `docs/` is not — a rule that named a definition the reader never received would
221
- leave every consumer's ledger shaped by hand.
200
+ below can be run over the whole ledger without the sample answering for one. **The grammar is defined
201
+ here rather than in the ledger** (`docs/maintainers/observation-filing-rationale.md` → "Why the
202
+ ledger exists").
222
203
 
223
204
  **The identity key is the whole of the repeat test — never a similarity judgement about the prose.**
224
205
  Choose the key from the phenomenon rather than from the run, then count what the ledger already holds
225
- for it, in that repository's checkout rather than the working directory. **The `|| true` is not
226
- decoration**: `grep -c` exits non-zero on a count of zero, which is the first-sighting branch and the
227
- common one, so without it the step reads as a failed command wherever an exit status is being
228
- watched. **A missing file is not a count of zero, though** — there `grep` exits 2 and prints no
229
- number at all, so an empty answer means create the ledger, never that this is a first sighting.
206
+ for it, in that repository's checkout rather than the working directory. **Every file of the
207
+ directory is counted**, because a recurrence is a recurrence whichever issue's file each sighting
208
+ sits in. **The `|| true` is not decoration**: `grep -c` exits non-zero on a count of zero, which is
209
+ the first-sighting branch and the common one, so without it the step reads as a failed command
210
+ wherever an exit status is being watched. **A missing directory is still a first sighting** — `cat`
211
+ complains on standard error and the count is zero; the append below creates the directory.
230
212
 
231
213
  ```bash
232
- grep -c '^- k:<slug> |' <that repository's checkout>/docs/maintainers/observations.md || true
214
+ cat <that repository's checkout>/docs/maintainers/observations/*.md | grep -c '^- k:<slug> |' || true
233
215
  ```
234
216
 
235
217
  Free-text comparison is what the key exists to replace, so two lines that read alike under different
@@ -238,60 +220,40 @@ rather than by editing the one already written.
238
220
 
239
221
  **The depth gate is not withdrawn, and this is not a way around it.** An observation that *can* cite
240
222
  the depth-0 work it stopped is filed exactly as it was before — this route is only for the ones that
241
- could not, and whose sole previous destination was nothing (joshuafolkken/kit#1698's gate stands
242
- unchanged).
223
+ could not.
243
224
 
244
225
  ### The commit path — how an appended line reaches the default branch
245
226
 
246
- **An append nobody commits is an append nobody can count** (joshuafolkken/kit#1756). The ledger was
247
- given a destination and no route out of the working tree the line was written in, and **structurally
248
- nobody was going to commit one**: the parent session that appends never runs `pnpm josh git`, a child
249
- runs it inside a lane work tree that cannot see the parent's checkout, and in the primary checkout
250
- `git add -u` swept the line into whatever unrelated pull request that run was opening. Measured on
251
- the day the ledger shipped, `docs/observations.md` had exactly one commit — the one that created
252
- it — and seven lines had never left a working tree. **So the repeat count below was reading a file
253
- that is empty on every other machine**, and every sighting was a first one, which is the state
254
- joshuafolkken/kit#1728 created the ledger to end.
227
+ **An append nobody commits is an append nobody can count** (joshuafolkken/kit#1756). Rationale:
228
+ `docs/maintainers/observation-filing-rationale.md` → "Why the ledger has a commit path".
255
229
 
256
230
  - **A run's appended lines ride its own commit** (joshuafolkken/kit#2763). `pnpm josh git` stages
257
- `docs/maintainers/observations.md` with the run's other changes, in the one staging step every entry
231
+ `docs/maintainers/observations/` with the run's other changes, in the one staging step every entry
258
232
  point goes through (`scripts/git/git-staging.ts`), so the lines are reviewed and merged with the
259
- pull request of the run that recorded them, and the run's CI is the only wait they cost. Until
260
- #2763 the ledger was excluded there (joshuafolkken/kit#1756) and every run that appended a line
261
- paid a second branch, CI wait and merge after its own — 144 ledger-only pull requests in one month.
233
+ pull request of the run that recorded them, and the run's CI is the only wait they cost.
262
234
  **Record before the commit, not after the merge:** a finding recorded with `pnpm josh review:record`
263
235
  before `pnpm josh git -y` is carried; the time while CI runs is for the records that need no CI
264
236
  result — filing an observation Issue, drafting the completion report.
265
237
  - **A line that breaks the grammar is not carried** (joshuafolkken/kit#2123). The staging step parses
266
- the ledger first — after moving lines still on the old path (joshuafolkken/kit#2724) — and on a
267
- broken line leaves the ledger out of the commit and says so; the commit itself goes ahead.
268
- - **What no run's commit carried is flushed as a pull request of its own** — `pnpm josh
269
- observations:flush`: a lane's lines (next bullets) and a line appended after the commit, such as a
270
- second review round's record. It stages that one path and nothing else, commits it on a branch of
271
- its own, opens a docs-only pull request, waits on the same required checks every other pull request
272
- waits on, merges it and returns the checkout to the default branch. **Nothing is committed to the
273
- default branch directly.**
274
- - **`pnpm josh followup` runs that flush itself, so no run has to remember to** (joshuafolkken/kit#1810).
275
- After the merge and before it releases the working-tree hold, `followup` reads the tree, and **only
276
- when the ledger still holds a pending append** returns the checkout to the default branch
277
- (`pnpm josh ms`) and flushes. A run whose lines rode its commit pays nothing, and a lane skips it
278
- (next bullet). A flush that fails is reported and does not take the merge, the epic close or the
279
- hold release down with it. **A side effect: on a run that did flush, `followup` ends on the default
280
- branch.**
281
- - **A lane's writers use the primary checkout's ledger** (joshuafolkken/kit#2419): a lane refuses
282
- `pnpm josh ms`, so its own copy had no way out. `pnpm josh observations:flush` acts on the primary
283
- checkout from a lane. **A dispatched lane child does not flush at all** (joshuafolkken/kit#2492): its
284
- `run:tail` skips the step, and the `backlogrun` flushes every lane's lines once, in one pull request,
285
- at `pnpm josh run:carry --end`.
286
- - **A lane child's pull request does not carry the lines, and that is deliberate.** Lanes run side by
287
- side, and two pull requests that each append at the ledger's tail conflict with each other the
288
- moment the first merges — a conflict ends the other's CI wait. The batch's single flush at
289
- `run:carry --end` is already one pull request per batch, not one per child.
290
- - **Run by hand it goes in the primary checkout, once per cycle rather than once per observation** —
291
- but with the lines riding the run's commit and `pnpm josh followup` flushing the rest (above), a hand
292
- run is the exception rather than the rule. It refuses off the default branch and refuses a working tree holding anything besides
293
- the ledger, so a run in progress cannot be flushed out from under, and a lane's checkout is never
294
- the one it acts on.
238
+ every file of the ledger first — after moving lines still on an old single-file path
239
+ (joshuafolkken/kit#2724, joshuafolkken/kit#2919) — and on a broken line leaves the ledger out of the
240
+ commit and says so; the commit itself goes ahead.
241
+ - **`pnpm josh followup` commits a line appended after the run's commit onto the pull request, before
242
+ the merge** (joshuafolkken/kit#2919) — a second review round's record is the usual case. After the
243
+ merge gates and before the CI wait, `followup` reads the tree and, **only when the ledger holds a
244
+ pending append**, stages the ledger paths alone, commits them and pushes the branch; the CI wait
245
+ that follows covers the pushed commit. A broken line refuses the merge, because the line would
246
+ otherwise be lost with the branch. A run whose lines rode its commit pays nothing.
247
+ - **A lane carries its own lines, in its own pull request** (joshuafolkken/kit#2919). Its writers
248
+ append to its own tree's `<N>.md`, so the two steps above take them to the default branch exactly as
249
+ they do for a run in the primary checkout. **Nothing is held in the primary checkout for later.**
250
+ - **`pnpm josh observations:flush` is left for a line written outside any issue's run** — the
251
+ date-named file a retrospective or a hand append on the default branch writes. It stages the ledger
252
+ and nothing else, commits it on a branch of its own, opens a docs-only pull request, waits on the
253
+ same required checks every other pull request waits on, merges it and returns the checkout to the
254
+ default branch; a single run's `run:tail` runs it after the merge. It refuses off the default branch
255
+ and refuses a working tree holding anything besides the ledger, so a run in progress cannot be
256
+ flushed out from under. **Nothing is committed to the default branch directly.**
295
257
  - **Nothing to flush is an answer, not a failure.** With the ledger matching the commit it sits on
296
258
  the command prints `clean` and exits 0 — most cycles append nothing, and a command that errored
297
259
  there would be one nobody runs.
@@ -301,10 +263,9 @@ joshuafolkken/kit#1728 created the ledger to end.
301
263
 
302
264
  ### The second sighting is what files it
303
265
 
304
- **A repeat is the citation.** joshuafolkken/kit#1698 asked a discretionary filing to be pulled by a
305
- blockage rather than pushed by a sighting; an observation recorded twice has been pulled — it came
306
- back on its own, which no single sighting can demonstrate. So the gate has a second way through, and
307
- it is counted rather than judged:
266
+ **A repeat is the citation**, so the gate has a second way through, and it is counted rather than
267
+ judged (rationale: `docs/maintainers/observation-filing-rationale.md` → "Why a second sighting
268
+ files"):
308
269
 
309
270
  - **On the count answering exactly `1`, the observation is filed**, at depth 1 or deeper, with no
310
271
  depth-0 citation — `1` and not "1 or more", because a higher count means the Issue was already
@@ -337,19 +298,12 @@ could bite later" line (`backlogrun-child.md` → "What the summary carries, and
337
298
  parent files what survives — under the depth test above, and inside the run's ceiling.
338
299
 
339
300
  **A delegated child does not append to the ledger either — the parent collapses the duplicates and
340
- appends what is left.** The ledger's whole value is that one key means one phenomenon, and a child
341
- holding one Issue's worth of context cannot tell its observation from the sibling lane's: eight
342
- children appending in parallel would write the same thing under eight keys, and every one of them
343
- would then read as a first sighting. The child's route is unchanged and is the only one it has —
301
+ appends what is left.** The child's route is unchanged and is the only one it has —
344
302
  the summary's "Observations that could bite later" line — and the parent chooses the key, checks the
345
- count and writes the line.
346
-
347
- **Two reasons, and a child can solve neither for itself.** It holds one Issue's worth of context, so
348
- **it cannot tell its observation from the one a sibling filed twenty minutes earlier** — the 15
349
- filings of 2026-09-09 were collapsed to 12 within that same day, which means they were collapsible
350
- at the moment they were made. And **the 10-per-run ceiling for this route is the parent's to
351
- count**: six children counting two or three filings each never reach it, which is why it did not
352
- fire once on the run that filed fifteen.
303
+ count and writes the line. **The 10-per-run ceiling for this route is the parent's to count.**
304
+
305
+ Rationale: `docs/maintainers/observation-filing-rationale.md` → "Why a delegated child neither files
306
+ nor appends".
353
307
 
354
308
  **This file is the single source of every procedure above**, and `SKILL.md` → §2i is the single
355
309
  source of the rule they carry out; nothing under `prompts/collaboration-workflow/` restates either
@@ -7,7 +7,7 @@ from the gate onward. Rationale: `docs/maintainers/pre-gate-cut-rationale.md`
7
7
 
8
8
  This file is the single source of the boundary. `run:cut` takes it, and `run:cut --resume` is the
9
9
  check a fresh process makes at its own entry. **A second boundary is added below** — the
10
- implementation-phase cut (joshuafolkken/kit#1933), at a context threshold _during_ implementation.
10
+ implementation-phase cut, at a context threshold _during_ implementation.
11
11
  Everything through "What is carried" describes the pre-gate cut; the later section states only what
12
12
  differs.
13
13
 
@@ -23,7 +23,7 @@ verification the fresh process runs on the tree.
23
23
 
24
24
  The cut is for a **detached** `fullrun` a lane dispatched; a person's interactive `fullrun` never
25
25
  relaunches itself. A dispatched child is told apart **mechanically, by a mark the dispatch sets** — never
26
- by the model reading the shape of its own prompt (joshuafolkken/kit#1904).
26
+ by the model reading the shape of its own prompt.
27
27
 
28
28
  ### The dispatch mark
29
29
 
@@ -44,16 +44,15 @@ checkout, a cut in a lane.
44
44
 
45
45
  ## Taking the cut
46
46
 
47
- **The order is fixed in the chain** (joshuafolkken/kit#2177): `chain-rule.md` step 1 issues
47
+ **The order is fixed in the chain**: `chain-rule.md` step 1 issues
48
48
  `pnpm josh run:cut <N>` after `pnpm josh main:merge`, before the scoped pair and the gate. **The command
49
- is issued unconditionally**; `run:cut` itself decides whether the cut is warranted
50
- (joshuafolkken/kit#2312), so a short lane with nothing to drop is answered `under-threshold` and walks on
49
+ is issued unconditionally**; `run:cut` itself decides whether the cut is warranted, so a short lane with nothing to drop is answered `under-threshold` and walks on
51
50
  to the gate rather than relaunching.
52
51
 
53
52
  At the pre-gate boundary, issue:
54
53
 
55
54
  ```bash
56
- pnpm josh run:cut <N> # alias: josh rct
55
+ pnpm josh run:cut <N>
57
56
  ```
58
57
 
59
58
  - `cut` (0) — record written and handed to the lane's launch owner (OpenAI supervisor starts the
@@ -72,25 +71,25 @@ the current process to carry the run on itself.
72
71
 
73
72
  ### The gate refuses until the cut has been taken (joshuafolkken/kit#1864)
74
73
 
75
- **This step was carried as prose and fired exactly never.** Across six measured lane children the cut
76
- was taken **0 times**. So `pnpm josh rule:guard` **refuses `pnpm josh gate`** while this checkout is a
77
- lane and no cut record is carried, handing back the command above. With the ordered step above the
78
- refusal is insurance, not the primary trigger. Rationale:
74
+ **This step was carried as prose and fired exactly never.** In measured lane children the cut was taken **0 times**, so
75
+ `pnpm josh rule:guard` **refuses `pnpm josh gate`** while this checkout is a lane and no cut record is
76
+ carried, handing back the command above. Rationale:
79
77
  `docs/maintainers/pre-gate-cut-rationale.md` → "Why the rules are guards, not prose".
80
78
 
81
79
  - **It fires for a marked child and nowhere else**: the working directory is a lane —
82
80
  `<lane root>/<issue number>` — **and** `JOSH_LANE_CHILD` names that same issue. An interactive
83
81
  `fullrun` carries no mark and runs its gate untouched. `run:cut` uses an open-lane lookup instead, so
84
82
  the guard and the command need not agree byte for byte.
85
- - **It fires only when the recent-window context warrants a cut** (joshuafolkken/kit#2312). The guard
83
+ - **It fires only when the recent-window context warrants a cut**. The guard
86
84
  reads the same `cost_cli.session_verdict` `run:cut` reads, so an `under`-threshold lane is let through
87
85
  to the gate rather than refused.
88
86
  - **It is silent once the cut is carried**, so the resumed process goes straight to the gate.
89
- - **It fires once per run.** A refusal that repeated would wedge the runs that obeyed.
87
+ - **It fires once per run.**
90
88
  - **`--resume`, `--end` and `--json` do not count as taking the cut.**
91
89
 
92
90
  The row, its trigger and the enumeration it joins are
93
- `prompts/collaboration-workflow/rule-delivery.md`; `scripts/rules/pre-gate-cut.test.ts` pins it.
91
+ `prompts/collaboration-workflow/rule-delivery.md`. The suites that pin this and the three guards below:
92
+ `docs/maintainers/pre-gate-cut-rationale.md` → "Which suites pin each guard".
94
93
 
95
94
  ## Resuming — the fresh process's entry check
96
95
 
@@ -106,8 +105,7 @@ pnpm josh run:cut --resume <N>
106
105
  - `resume` (0) — a declared pre-gate cut whose tree matches was verified and taken over. **Skip the
107
106
  title, the plan, the fresh hold claim and the implementation**; re-read the issue body and comments
108
107
  for the plan and the recorded decisions, then go straight to `pnpm josh gate`.
109
- - `resume-impl` (0) — like `resume`, but the cut was taken **during** implementation
110
- (joshuafolkken/kit#1933). Skip the title, the plan, the fresh hold claim and the split assessment,
108
+ - `resume-impl` (0) — like `resume`, but the cut was taken **during** implementation. Skip the title, the plan, the fresh hold claim and the split assessment,
111
109
  re-read the plan, then **continue implementation** — do **not** go straight to the gate.
112
110
  - `handed-off` (0) — a successor has already adopted this cut, `is_handed_off` is spent
113
111
  (joshuafolkken/kit#1935). This process was woken **after** its own cut. **End the turn quietly and do
@@ -154,7 +152,7 @@ decisions are read back from the issue. Rationale:
154
152
 
155
153
  ## The implementation-phase cut — a lane child cuts before the gate too
156
154
 
157
- The **implementation-phase cut** (joshuafolkken/kit#1933) caps the context accumulated _during_
155
+ The **implementation-phase cut** caps the context accumulated _during_
158
156
  implementation — the child ends mid-implementation and a fresh one resumes the lane **back into
159
157
  implementation**.
160
158
 
@@ -162,15 +160,15 @@ implementation**.
162
160
 
163
161
  The guard below refuses on the same measurement the parent uses between children —
164
162
  `cost_verdict.per_request_cost`, read through `cost_cli.session_verdict` (the read-only form of
165
- `pnpm josh cost --cut`, joshuafolkken/kit#2312), single-sourced at `backlogrun-progress.md` → "The
163
+ `pnpm josh cost --cut`), single-sourced at `backlogrun-progress.md` → "The
166
164
  hand-off". The parent's seam and the child's `run_cut.IMPLEMENTATION_CONTEXT_THRESHOLD` share the
167
165
  **135_000** `CONTEXT_CUT_THRESHOLD` (aliased so the tests cannot drift). No separate measurement is
168
166
  built for the lane child.
169
167
 
170
168
  ### It is a guard, fired at the edit that crosses the threshold (joshuafolkken/kit#2310)
171
169
 
172
- **This step was carried as prose and fired exactly never** — measured across five lanes, the cut fired
173
- **0 times** while 33.9% of their requests ran past 200,000 tokens. Rationale:
170
+ **This step was carried as prose and fired exactly never** — the cut fired **0 times** while 33.9% of
171
+ lane requests ran past 200,000 tokens. Rationale:
174
172
  `docs/maintainers/pre-gate-cut-rationale.md` → "Why the rules are guards, not prose".
175
173
 
176
174
  So `pnpm josh rule:guard` **refuses an `Edit` / `Write`** while this checkout is a dispatched lane child
@@ -185,7 +183,7 @@ crossing one successor.
185
183
  - **It fires for a marked child, or a run held outside a lane on a measured `over`**
186
184
  (joshuafolkken/kit#2760); a person's tree holds no run. Outside a lane `cut` relaunches nothing: keep
187
185
  the hold, send a `confirmation` Telegram naming `fullrun #<N>`, end the turn.
188
- - **It fires on every threshold crossing, not once per run** (joshuafolkken/kit#2385) — it re-asks on
186
+ - **It fires on every threshold crossing, not once per run** — it re-asks on
189
187
  each over-threshold edit, including after a `busy` / `failed` / `unready` verdict.
190
188
  - **An edit reissued right after a refusal passes** — so a `busy` / `failed` cut cannot wedge the run:
191
189
  the reissue lands inside a short window and goes through, a genuinely new crossing past it refuses
@@ -196,8 +194,8 @@ crossing one successor.
196
194
  - **The verdict read is reused over a short window** — cached per checkout for a few seconds, so a
197
195
  turn's burst of edits shares one read.
198
196
 
199
- `scripts/rules/implementation-cut.ts` implements the trigger, `scripts/rules/implementation-cut.test.ts`
200
- pins it, and the row joins `prompts/collaboration-workflow/rule-delivery.md`. **A child that ended
197
+ `scripts/rules/implementation-cut.ts` implements the trigger, and the row joins
198
+ `prompts/collaboration-workflow/rule-delivery.md`. **A child that ended
201
199
  without cutting is still detected after the fact by `pnpm josh run:ending <N> --output <path>`**
202
200
  (joshuafolkken/kit#2139). **A single check (`lint:related` / `test:related`) is run after a batch of
203
201
  edits, not after each one.**
@@ -206,12 +204,10 @@ edits, not after each one.**
206
204
 
207
205
  **`CONTEXT_CUT_THRESHOLD` (135_000) is one value, and `cost_verdict.per_request_cost` — the one
208
206
  statistic the parent and the lane child both read — averages the most recent `RECENT_REQUEST_WINDOW`
209
- (10) requests, not the whole session** (joshuafolkken/kit#2295). The value is a derived break-even, not a
210
- chosen number (joshuafolkken/kit#2406): `scripts/cost-runtime/context-cut-payback.ts` computes it from a
211
- cut's one-time preamble rewrite (`POST_CUT_CONTEXT`, ~60_000 tokens — a cut carries a request from ~130k
212
- down to ~60k), the cache multipliers in `cost-pricing.ts`, and a 10-request horizon.
207
+ (10) requests, not the whole session**. The value is computed by
208
+ `scripts/cost-runtime/context-cut-payback.ts`, its single source.
213
209
 
214
- **The cut is conditional** (joshuafolkken/kit#2312): taken only when the recent-window per-request cost
210
+ **The cut is conditional**: taken only when the recent-window per-request cost
215
211
  is over `CONTEXT_CUT_THRESHOLD` — the same statistic and threshold the implementation-phase cut reads, so
216
212
  no second threshold exists. Below it `run:cut` answers `under-threshold` and the gate runs uncut; the
217
213
  guard reads the same verdict and stays silent. An **unmeasurable** session is always cut.
@@ -227,8 +223,8 @@ cut is the same pattern one boundary earlier.
227
223
  ## A lane child records its park before it stops
228
224
 
229
225
  **A dispatched lane child records its park on the Issue before it stops for a decision**
230
- (joshuafolkken/kit#2034). A headless child's only route to ask a person is to park the Issue — measured
231
- on #2012 and #2011, whose questions reached only their final message. Rationale:
226
+ (joshuafolkken/kit#2034). A headless child's only route to ask a person is to park the Issue (#2012,
227
+ #2011). Rationale:
232
228
  `docs/maintainers/pre-gate-cut-rationale.md` → "Why the rules are guards, not prose".
233
229
 
234
230
  **The record, before the Telegram, is the park procedure exactly** — `needs-decision` plus a comment
@@ -255,21 +251,22 @@ lane child — the mark `JOSH_LANE_CHILD` names this lane's own issue — handin
255
251
  on the compliant path is safe.
256
252
 
257
253
  This section is the single source of the lane-child park rule; `scripts/rules/lane-park.ts` implements
258
- the trigger, `scripts/rules/lane-park.test.ts` pins it, and the row joins the enumeration in
254
+ the trigger, and the row joins the enumeration in
259
255
  `prompts/collaboration-workflow/rule-delivery.md`.
260
256
 
261
257
  ### The interactive ask is refused one call earlier
262
258
 
263
259
  (joshuafolkken/kit#2201) The harness refuses an interactive ask in a headless session by **ending the
264
- turn**, so the notify guard never fires — #2178's child did exactly that, the failure
265
- joshuafolkken/kit#2034 set out to prevent, one call upstream. So `pnpm josh rule:guard` **refuses
266
- `AskUserQuestion` for a marked lane child**; the deny returns to the model, and the instruction is to
267
- park the question. It fires on **every occurrence** and stays silent for a person working in a lane.
260
+ turn**, so the notify guard never fires (#2178 — the failure joshuafolkken/kit#2034 set out to prevent,
261
+ one call upstream). So `pnpm josh rule:guard` **refuses `AskUserQuestion` for a marked lane child**; the
262
+ deny returns to the model, and the instruction is to park the question. It fires on **every occurrence**
263
+ and stays silent for a person working in a lane. Rationale:
264
+ `docs/maintainers/pre-gate-cut-rationale.md` → "Why the rules are guards, not prose".
268
265
 
269
266
  **A child that slips past it is still recoverable** — `pnpm josh run:ending` lifts the refused ask out
270
267
  of the exit record's `permission_denials` into the `abandoned` verdict's park basis, so the parent puts
271
- it into the park comment. `scripts/rules/lane-interactive-ask.ts` implements the trigger,
272
- `scripts/rules/lane-interactive-ask.test.ts` pins it, and `scripts/agent/interactive-ask.ts` is the
268
+ it into the park comment. `scripts/rules/lane-interactive-ask.ts` implements the trigger, and
269
+ `scripts/agent/interactive-ask.ts` is the
273
270
  shared extractor the guard and `run:ending` both read.
274
271
 
275
272
  This file is the single source of the rule.
@@ -18,7 +18,7 @@ another is the failure this section exists to prevent:
18
18
  | A defect originating in **another package** | File the upstream Issue and **stop** — Tier A for a first-party target; a third-party one is Tier C, recorded and drafted rather than filed (`CLAUDE.md` → "Cross-package problems"; `prompts/collaboration-workflow/upstream-interrupt.md`) |
19
19
  | This Issue was really **several** (a split) | File the children and the epic and **stop** — except under `backlogrun`, whose authorization already covers a batch, so the children are filed and run through (`split-assessment.md`) |
20
20
  | Another Issue in **this** repository has to land first (**a prerequisite**) | This section |
21
- | Something worth filing that is **none of the three** (**an observation**) | File it **without asking** — Tier A for a first-party target — and **carry the run straight on**: nothing is stashed, nothing is parked (§2i). **A delegated child does not file here**, and a filing at depth 1 or deeper cites the depth-0 work it blocked; one that cannot cite it goes to `docs/maintainers/observations.md` and is filed on its second sighting — all of them §2i's |
21
+ | Something worth filing that is **none of the three** (**an observation**) | File it **without asking** — Tier A for a first-party target — and **carry the run straight on**: nothing is stashed, nothing is parked (§2i). **A delegated child does not file here**, and a filing at depth 1 or deeper cites the depth-0 work it blocked; one that cannot cite it goes to the run's own `docs/maintainers/observations/<N>.md` and is filed on its second sighting — all of them §2i's |
22
22
 
23
23
  **File the prerequisite with the `route:tier-a` label**, so a Tier A filing made during implementation
24
24
  stays countable by filing route afterwards. **This paragraph belongs to the prerequisite row, not to