@joshuafolkken/kit 1.1453.0 → 1.1471.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.
- package/.claude/skills/dependency-update/SKILL.md +26 -55
- package/.claude/skills/epic-commands/SKILL.md +87 -148
- package/.claude/skills/epic-commands/epic-bundle.md +45 -77
- package/.claude/skills/epic-commands/execution-waves.md +44 -81
- package/.claude/skills/verify-ui/SKILL.md +25 -50
- package/.claude/skills/workflow-commands/background-commands.md +36 -47
- package/.claude/skills/workflow-commands/backlogrun-child.md +72 -85
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +91 -121
- package/.claude/skills/workflow-commands/backlogrun-park.md +73 -117
- package/.claude/skills/workflow-commands/backlogrun-progress.md +7 -9
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +11 -20
- package/.claude/skills/workflow-commands/backlogrun-steps.md +43 -52
- package/.claude/skills/workflow-commands/chain-rule.md +24 -34
- package/.claude/skills/workflow-commands/followup.md +57 -76
- package/.claude/skills/workflow-commands/halfrun.md +2 -1
- package/.claude/skills/workflow-commands/issue-comments.md +43 -60
- package/.claude/skills/workflow-commands/kickoff.md +65 -74
- package/.claude/skills/workflow-commands/observation-filing.md +62 -107
- package/.claude/skills/workflow-commands/observation-ledger.md +56 -111
- package/.claude/skills/workflow-commands/pre-gate-cut.md +89 -138
- package/.claude/skills/workflow-commands/prerequisite.md +10 -15
- package/.claude/skills/workflow-commands/progress-watcher.md +21 -26
- package/.claude/skills/workflow-commands/prrun.md +2 -1
- package/.claude/skills/workflow-commands/retrospective.md +31 -50
- package/.claude/skills/workflow-commands/split-assessment.md +34 -58
- package/.claude/skills/workflow-commands/working-tree-hold.md +54 -71
- package/CLAUDE.md +7 -6
- package/README.md +2 -9
- package/dist/CLAUDE.md +7 -6
- package/dist/hooks/batch-guard.js +6 -6
- package/dist/hooks/{chunk-Y3GKIKGW.js → chunk-43ZHT22P.js} +31 -15
- package/dist/hooks/{chunk-MBJYQPEK.js → chunk-AS74OU3D.js} +24 -8
- package/dist/hooks/{chunk-3C4XRYG6.js → chunk-E7OIKX5Z.js} +17 -12
- package/dist/hooks/{chunk-Z4XI7CZS.js → chunk-EUMACUK2.js} +18 -12
- package/dist/hooks/{chunk-NO4AALP5.js → chunk-H5HVWYXK.js} +4 -4
- package/dist/hooks/{chunk-5C7L6FRC.js → chunk-IIGFYXKC.js} +346 -241
- package/dist/hooks/{chunk-W5ZKGTSY.js → chunk-J47HU5H5.js} +14 -3
- package/dist/hooks/{chunk-OLMO72ON.js → chunk-K4EOONYM.js} +1 -1
- package/dist/hooks/{chunk-LBFYEOXJ.js → chunk-K4LMBQC2.js} +4 -4
- package/dist/hooks/{chunk-D3NJXN5M.js → chunk-KC5AK2GF.js} +8 -6
- package/dist/hooks/chunk-SHGPANFB.js +56 -0
- package/dist/hooks/{chunk-EF5GQ6WS.js → chunk-YHBZAJSV.js} +3 -3
- package/dist/hooks/{chunk-SHYUQOIS.js → chunk-YYPI7SJZ.js} +5 -5
- package/dist/hooks/codex-hook-adapter.js +13 -13
- package/dist/hooks/duplicate-read-guard.js +7 -7
- package/dist/hooks/format-edited.js +3 -3
- package/dist/hooks/inputs.json +251 -247
- package/dist/hooks/investigation-guard.js +7 -7
- package/dist/hooks/pretool-guard.js +12 -12
- package/dist/hooks/session-lang.js +6 -5
- package/dist/hooks/stop-guard.js +75 -18
- package/dist/josh.js +6 -7
- package/dist/managed-marker/index.js +1 -2
- package/dist/version/index.js +15 -12
- package/eslint/base.js +2 -1
- package/eslint/rules/unicorn.js +16 -0
- package/package.json +3 -3
- package/prompts/coding-standards.md +12 -22
- package/prompts/collaboration-workflow/file-edits.md +26 -44
- package/prompts/collaboration-workflow/gh-rest.md +20 -36
- package/prompts/collaboration-workflow/glossary.md +5 -7
- package/prompts/collaboration-workflow/issue-citation.md +7 -13
- package/prompts/collaboration-workflow/issue-template.md +29 -29
- package/prompts/collaboration-workflow/operating-rules.md +35 -44
- package/prompts/collaboration-workflow/output-bounds.md +15 -15
- package/prompts/collaboration-workflow/overview.md +14 -19
- package/prompts/collaboration-workflow/plan-comment.md +13 -13
- package/prompts/collaboration-workflow/principles.md +50 -53
- package/prompts/collaboration-workflow/proposal-request.md +1 -9
- package/prompts/collaboration-workflow/report-format.md +32 -49
- package/prompts/collaboration-workflow/residency.md +10 -10
- package/prompts/collaboration-workflow/rule-delivery.md +9 -9
- package/prompts/collaboration-workflow/shell-body.md +11 -21
- package/prompts/collaboration-workflow/turn-batching.md +8 -14
- package/prompts/collaboration-workflow/upstream-interrupt.md +26 -34
- package/prompts/collaboration-workflow/wip-cap.md +24 -30
- package/prompts/collaboration-workflow.md +24 -25
- package/prompts/refactoring.md +33 -43
- package/prompts/review-rubric.md +84 -129
- package/prompts/review.md +111 -141
- package/prompts/sonar-hotspot-handling.md +22 -50
- package/prompts/testing-guide.md +48 -99
- package/scripts/adopt/adopt-toolkits.ts +2 -4
- package/scripts/agent/agent-exit-record.ts +23 -1
- package/scripts/agent/codex-agent-argv.ts +7 -2
- package/scripts/backlog/backlog-budget-cli.ts +1 -2
- package/scripts/backlog/backlog-drive-carried.ts +26 -0
- package/scripts/backlog/backlog-drive-cli.ts +10 -5
- package/scripts/backlog/backlog-drive-named.ts +2 -4
- package/scripts/backlog/backlog-drive-restore.ts +19 -1
- package/scripts/backlog/backlog-drive-seats.ts +27 -0
- package/scripts/backlog/backlog-drive.ts +11 -6
- package/scripts/backlog/backlog-ready.ts +13 -6
- package/scripts/behavior/behavior-rules.ts +3 -2
- package/scripts/cost-runtime/codex-usage.ts +4 -2
- package/scripts/cost-runtime/cost-cli.ts +1 -2
- package/scripts/delegation/investigation-guard.ts +1 -1
- package/scripts/delegation/investigation-reads.ts +1 -1
- package/scripts/discovery/repo-discovery.ts +4 -2
- package/scripts/discovery/repo-origin.ts +2 -4
- package/scripts/doctor/doctor-logic.ts +6 -3
- package/scripts/document/document-byte-budget.ts +27 -27
- package/scripts/document/document-byte-check.ts +1 -2
- package/scripts/document/entry-read-budget.ts +2 -2
- package/scripts/epic/epic-audit-rationale.ts +8 -2
- package/scripts/epic/epic-bundle-cli.ts +1 -2
- package/scripts/epic/epic-chains.ts +6 -2
- package/scripts/epic/epic-close-comment.ts +1 -2
- package/scripts/gate/verification-gate.ts +7 -2
- package/scripts/gh/git-pr-ai-review.ts +12 -1
- package/scripts/gh/git-pr-confirmation.ts +11 -7
- package/scripts/gh/git-pr.ts +6 -2
- package/scripts/git/git-common-directory.ts +3 -3
- package/scripts/git/git-diff-reads.ts +16 -9
- package/scripts/git/git-execa-error.ts +1 -2
- package/scripts/hooks/format-edited-file.ts +10 -4
- package/scripts/hooks/pre-push-unit.ts +15 -4
- package/scripts/hooks/pretool-guard.ts +23 -29
- package/scripts/hooks/step-zero-notice.ts +3 -2
- package/scripts/init/hook-command-rewrite.ts +6 -2
- package/scripts/init/init-logic-deploy-vps.ts +4 -2
- package/scripts/issue/behavior-change-lint.ts +12 -6
- package/scripts/issue/issue-scout-cli.ts +3 -2
- package/scripts/josh/file-map-stamp.ts +1 -3
- package/scripts/josh/hook-decision.ts +17 -2
- package/scripts/josh/josh-commands-workflow.ts +1 -1
- package/scripts/lane/lane-await.ts +3 -2
- package/scripts/lane/lane-child-invocation.ts +14 -1
- package/scripts/lane/lane-guard-policy.ts +4 -4
- package/scripts/lane/lane-ledger.ts +9 -0
- package/scripts/lane/lane-load.ts +9 -2
- package/scripts/lane/lane-measure-cli.ts +2 -0
- package/scripts/lane/lane-parked.ts +18 -0
- package/scripts/lane/lane-process-load.ts +125 -0
- package/scripts/lane/lane-process-stats.ts +93 -0
- package/scripts/lane/lane-registry.ts +8 -3
- package/scripts/lane/lane-session-broker.ts +29 -5
- package/scripts/lane/lane-spent.ts +14 -3
- package/scripts/lane/lane-stats.ts +1 -0
- package/scripts/managed-marker/managed-marker-logic.ts +1 -2
- package/scripts/notify/confirmation-options.ts +59 -0
- package/scripts/notify/notify-opt-in.ts +33 -0
- package/scripts/notify/telegram-notify.ts +25 -8
- package/scripts/notify/telegram-test-logic.ts +33 -1
- package/scripts/notify/telegram-test.ts +4 -2
- package/scripts/overrides/lockfile-overrides.ts +1 -3
- package/scripts/propagate/propagate.ts +1 -2
- package/scripts/release/release-progress.ts +3 -2
- package/scripts/report/report-lint.ts +7 -4
- package/scripts/review/review-record-cli.ts +6 -2
- package/scripts/rules/destructive-command.ts +6 -9
- package/scripts/rules/direct-filing.ts +3 -7
- package/scripts/rules/early-heartbeat.ts +7 -18
- package/scripts/rules/file-body.ts +6 -13
- package/scripts/rules/filing-cap.ts +3 -6
- package/scripts/rules/git-force.ts +5 -9
- package/scripts/rules/implementation-cut.ts +37 -35
- package/scripts/rules/index-guard.ts +4 -7
- package/scripts/rules/issue-comments.ts +5 -15
- package/scripts/rules/josh-git-bare.ts +3 -6
- package/scripts/rules/lane-background.ts +10 -21
- package/scripts/rules/lane-carry-conflict.ts +7 -17
- package/scripts/rules/lane-interactive-ask.ts +6 -11
- package/scripts/rules/lane-park.ts +5 -13
- package/scripts/rules/lane-split-park.ts +2 -7
- package/scripts/rules/lane-switch-main.ts +9 -12
- package/scripts/rules/oracle-consulted.ts +4 -5
- package/scripts/rules/piped-verification.ts +81 -31
- package/scripts/rules/poll-loop.ts +7 -17
- package/scripts/rules/pre-gate-cut.ts +7 -21
- package/scripts/rules/prior-comment-read.ts +7 -5
- package/scripts/rules/protected-files.ts +5 -9
- package/scripts/rules/raw-field-body.ts +3 -7
- package/scripts/rules/rule-body-guard.ts +4 -11
- package/scripts/rules/run-tail-rule.ts +6 -22
- package/scripts/rules/shell-body-trigger.ts +7 -8
- package/scripts/rules/shell-segments.ts +7 -0
- package/scripts/rules/stop-rules.ts +17 -29
- package/scripts/rules/test-declared-commit.ts +4 -10
- package/scripts/rules/third-party-write.ts +5 -10
- package/scripts/rules/worktree-guard.ts +5 -12
- package/scripts/run/board/run-board-github.ts +11 -3
- package/scripts/run/board/run-board-idle.ts +31 -0
- package/scripts/run/board/run-board-read.ts +9 -12
- package/scripts/run/board/run-board-reason.ts +7 -3
- package/scripts/run/board/run-board-state.ts +4 -0
- package/scripts/run/board/run-board-status.ts +18 -3
- package/scripts/run/board/run-board-thanks.ts +7 -2
- package/scripts/run/board/run-board-tick.ts +32 -7
- package/scripts/run/carry/run-carry-args.ts +1 -3
- package/scripts/run/carry/run-carry-conversation.ts +7 -2
- package/scripts/run/cut/run-cut-cli.ts +15 -20
- package/scripts/run/cut/run-cut-decline.ts +72 -0
- package/scripts/run/cut/run-cut-ready.ts +74 -0
- package/scripts/run/cut/run-cut-report.ts +13 -0
- package/scripts/run/cut/run-cut.ts +10 -1
- package/scripts/run/entry/run-entry-stop.ts +6 -3
- package/scripts/run/hold/run-hold-cli.ts +14 -3
- package/scripts/run/hold/run-hold.ts +6 -3
- package/scripts/run/merge/run-merge-cli.ts +30 -7
- package/scripts/run/merge/run-merge-ship.ts +59 -1
- package/scripts/run/merge/run-merge.ts +3 -2
- package/scripts/run/run-ending.ts +31 -3
- package/scripts/run/run-parent-cut-hook.ts +5 -10
- package/scripts/run/run-preflight.ts +1 -2
- package/scripts/run/run-stop-notify.ts +3 -2
- package/scripts/run/run-watcher-guard.ts +6 -3
- package/scripts/run/ship/run-ship-review-steps.ts +13 -4
- package/scripts/run/ship/run-ship-review.ts +15 -2
- package/scripts/run/tidy/run-tidy-cli.ts +3 -3
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -2
- package/scripts/safe-chain/project-config.ts +7 -2
- package/scripts/sync/sync-hook-safety.ts +8 -2
- package/scripts/test/unit-worker-share.ts +3 -2
- package/scripts/time-runtime/time-batch-guard.ts +3 -3
- package/scripts/time-runtime/time-hook-transcript.ts +3 -2
- package/scripts/time-runtime/time-shell.ts +10 -0
- package/scripts/version/effective-upstream.ts +3 -4
- package/scripts/version/kit-version-config.ts +8 -2
- package/scripts/version/latest-corepack.ts +1 -2
- package/scripts/version/release-hold.ts +11 -4
- package/scripts/version/version-commands.ts +12 -4
- package/dist/hooks/chunk-UT7YC3N2.js +0 -56
|
@@ -24,6 +24,6 @@ structure and the label translations are `prompts/collaboration-workflow/report-
|
|
|
24
24
|
- One sentence per line, no internal identifiers, every child named by number. **Never omit
|
|
25
25
|
`Remaining`** — it is the one line that tells this report from a completion report
|
|
26
26
|
- Telegram uses the same format and is **sent with `--task-type confirmation`** (`completion` would
|
|
27
|
-
announce an unfinished epic as done)
|
|
27
|
+
announce an unfinished epic as done), `--recommended` naming the resume command
|
|
28
28
|
- **Write it only when the run stops.** While a run carries on past the threshold it writes none; the
|
|
29
29
|
epic progress comment is the record
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
# `backlogrun` — lanes and concurrency
|
|
2
2
|
|
|
3
|
-
Point-of-use, read one section at a time from `backlogrun.md` → "The route table".
|
|
3
|
+
Point-of-use, read one section at a time from `backlogrun.md` → "The route table". Reasons:
|
|
4
|
+
|
|
5
|
+
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why the lane ceiling is shaped the way it is"
|
|
6
|
+
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why CI concurrency is capped by the lane limit"
|
|
7
|
+
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why a lane's review needs a brief and an attestation"
|
|
8
|
+
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why the lane branch is `<N>-lane` and never switched"
|
|
9
|
+
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why lanes cost as well as buy throughput"
|
|
10
|
+
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why `lane:launch` folds the lane steps into one"
|
|
11
|
+
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Why a committed child's lane is kept"
|
|
12
|
+
- `docs/maintainers/backlogrun-lanes-rationale.md` → "Where each rule came from"
|
|
4
13
|
|
|
5
14
|
## Concurrency: as many children per repository as it has free lanes
|
|
6
15
|
|
|
7
|
-
**One session per repository**, each running only its own repository's children
|
|
8
|
-
|
|
9
|
-
`.claude/skills/epic-commands/SKILL.md` → "
|
|
10
|
-
repository is `.claude/skills/epic-commands/SKILL.md` → "Epics that span repositories". Rationale:
|
|
11
|
-
`docs/maintainers/backlogrun-lanes-rationale.md` → "Why the lane ceiling is shaped the way it is".
|
|
16
|
+
**One session per repository**, each running only its own repository's children. The lane ceiling is
|
|
17
|
+
`.claude/skills/epic-commands/SKILL.md` → "An `in-progress` issue occupies a lane"; a dependency that
|
|
18
|
+
crosses a repository is `.claude/skills/epic-commands/SKILL.md` → "Epics that span repositories".
|
|
12
19
|
|
|
13
20
|
## A solo run
|
|
14
21
|
|
|
@@ -19,65 +26,50 @@ it a defect (not an improvement, refactor, removal or feature)? Is it in kit's o
|
|
|
19
26
|
(lint / type check / spell check / unit tests), the code review, the pre-push hook, or the merge
|
|
20
27
|
checks — not a consumer repository's CI or template? Does it, on `main` now, make unrelated PRs
|
|
21
28
|
answer wrongly (a false green or a false red)? All three, and the issue carries `run:solo`; any one
|
|
22
|
-
missing, and it carries `run:lane`. `backlog:next` and `epic:next --lanes` answer `triage` for an
|
|
23
|
-
with neither, so
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
`docs/maintainers/wip-cap-rationale.md` → "Why a solo run"; provenance:
|
|
27
|
-
`docs/maintainers/backlogrun-lanes-rationale.md` → "Where each rule came from".
|
|
29
|
+
missing, and it carries `run:lane`. `backlog:next` and `epic:next --lanes` answer `triage` for an
|
|
30
|
+
issue with neither, so a filed issue carries one of the two from its filing. **It stops the other
|
|
31
|
+
lanes for one reason only: a batch run on broken verification leaves nobody's result trustworthy.**
|
|
32
|
+
This section is the rule's single source; why: `docs/maintainers/wip-cap-rationale.md` → "Why a solo run".
|
|
28
33
|
|
|
29
34
|
## Lanes — running more than one child at a time
|
|
30
35
|
|
|
31
|
-
`pnpm josh epic:next <E> --repo <owner/repo> --lanes` answers
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
`
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
`
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
**A lane's branch is `<N>-lane`, and the issue number leads it so that the commit path accepts it.**
|
|
54
|
-
**Never switch the lane to another branch** — a switched lane loses its seat, its listing and its
|
|
55
|
-
isolation. So `epic:next` is asked **with** `--lanes`, and everything below runs as written. Rationale:
|
|
56
|
-
`docs/maintainers/backlogrun-lanes-rationale.md` → "Why the lane branch is `<N>-lane` and never
|
|
57
|
-
switched".
|
|
58
|
-
|
|
59
|
-
**Report the throughput gain only with its merge-race cost** — every overlap that becomes a conflict
|
|
60
|
-
costs a resolution, a re-run gate and a review (`backlogrun-recovery.md` → "Conflicts are not predicted"). Rationale:
|
|
61
|
-
`docs/maintainers/backlogrun-lanes-rationale.md` → "Why lanes cost as well as buy throughput".
|
|
36
|
+
`pnpm josh epic:next <E> --repo <owner/repo> --lanes` answers **one issue number per line**, up to the
|
|
37
|
+
free lanes. Each child runs in a **lane**: a linked work tree with its own branch, `.env` and ports
|
|
38
|
+
(`docs/josh-commands-run.md` → "`josh lane:open` / `josh lane:close` / `josh lane:list` / `josh
|
|
39
|
+
lane:prune`"). **Implementation, the verification gate and the review run in parallel; the merges
|
|
40
|
+
stay serial.**
|
|
41
|
+
|
|
42
|
+
**A lane child may cut its own turn before the gate** — `pre-gate-cut.md`, the single source. The
|
|
43
|
+
child is told apart from a person, and handed its resume stage, by `JOSH_LANE_CHILD`
|
|
44
|
+
(`pre-gate-cut.md` → "The dispatch mark" and "The stage is passed to the resumed child").
|
|
45
|
+
|
|
46
|
+
**A lane's review does not inherit the lane, and `pnpm josh review:brief` is what closes that**: it
|
|
47
|
+
prints the lane's root, branch and HEAD, targets written `git -C <root> …`, and a nonce the review
|
|
48
|
+
attests with `pnpm josh review:attest <nonce>`. **The child asks `pnpm josh review:attest --check`
|
|
49
|
+
before it counts a round**, and `pnpm josh followup` asks again before merging; `missing` and
|
|
50
|
+
`mismatch` are refusals. A clean round is checked hardest.
|
|
51
|
+
|
|
52
|
+
**A lane's branch is `<N>-lane`. Never switch the lane to another branch** — it loses its seat,
|
|
53
|
+
listing and isolation. So `epic:next` is asked **with** `--lanes`.
|
|
54
|
+
|
|
55
|
+
**Report the throughput gain only with its merge-race cost** (`backlogrun-recovery.md` → "Conflicts
|
|
56
|
+
are not predicted").
|
|
62
57
|
|
|
63
58
|
### Once per repository, before the first lane opens
|
|
64
59
|
|
|
65
|
-
In the **primary checkout**, in
|
|
66
|
-
|
|
67
|
-
|
|
60
|
+
In the **primary checkout**, in order, never per lane: `pnpm josh ms`; `pnpm josh latest:scope` and the
|
|
61
|
+
update on `required` (`backlogrun-child.md` → "`josh latest` runs once per session, not once per
|
|
62
|
+
child"); `pnpm josh lane:prune`; `pnpm josh run:tidy`.
|
|
68
63
|
|
|
69
|
-
**The rewritten lock file reaches a pull request through the first lane.**
|
|
70
|
-
|
|
71
|
-
record it on
|
|
72
|
-
"backlogrun: josh latest before lanes"` pops it by message** — never a positional `stash pop
|
|
73
|
-
|
|
74
|
-
parent's, before the driver starts.
|
|
64
|
+
**The rewritten lock file reaches a pull request through the first lane.** Only if the update rewrote
|
|
65
|
+
anything: `git stash push -u -m "backlogrun: josh latest before lanes"` in the primary checkout, and
|
|
66
|
+
record it on the first child's Issue. **The first lane's `pnpm josh lane:launch "$n" --stash
|
|
67
|
+
"backlogrun: josh latest before lanes"` pops it by message** — never a positional `stash pop`. **Under
|
|
68
|
+
`backlog:drive` the driver passes `--stash`, never you**; the push stays the parent's.
|
|
75
69
|
|
|
76
70
|
### Opening one lane and dispatching its child
|
|
77
71
|
|
|
78
|
-
**One command opens the lane, prepares it, and dispatches the child — `pnpm josh lane:launch
|
|
79
|
-
`lane:open`, `stash:pop` and `lane:dispatch`, each guard unchanged; rationale:
|
|
80
|
-
`docs/maintainers/backlogrun-lanes-rationale.md` → "Why `lane:launch` folds the lane steps into one"):
|
|
72
|
+
**One command opens the lane, prepares it, and dispatches the child — `pnpm josh lane:launch`**:
|
|
81
73
|
|
|
82
74
|
```bash
|
|
83
75
|
pid=$(pnpm josh lane:launch "$n") || exit 1 # the child's pid on stdout, nothing else
|
|
@@ -90,93 +82,71 @@ pid=$(pnpm josh lane:launch "$n") || exit 1 # the child's pid on stdout, nothi
|
|
|
90
82
|
| empty, non-zero, `already-open` or a failed install | **Park that child and name `pnpm josh lane:close <N>`** — a lock the lane cannot build is a person's to fix |
|
|
91
83
|
| `lane:open` reports a reused `<N>-lane` on stderr | The way back to a child parked after it pushed — **a reused branch is not a fresh lane** |
|
|
92
84
|
|
|
93
|
-
**Nothing switches the lane's branch.** In a lane `lane:open`'s answer replaces `pnpm josh
|
|
94
|
-
preflight
|
|
85
|
+
**Nothing switches the lane's branch.** In a lane, `lane:open`'s answer replaces `pnpm josh
|
|
86
|
+
run:hold`'s preflight; the child claims `run:hold` inside the lane.
|
|
95
87
|
|
|
96
88
|
### Handing the child over
|
|
97
89
|
|
|
98
|
-
The child runs as `fullrun #<N>` in that lane,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
- **
|
|
112
|
-
|
|
113
|
-
trace alone**, because its log will never grow.
|
|
114
|
-
- **The child is started as `fullrun #<N>` with the lane as its working directory.** The batch a
|
|
115
|
-
person approved by typing `backlogrun` covers the child.
|
|
116
|
-
- **It passes `--permission-mode bypassPermissions`, never `--dangerously-skip-permissions`.** A
|
|
117
|
-
current Claude Code ignores the mode `.claude/settings.json` declares, and a new lane worktree is
|
|
118
|
-
never a trusted workspace; that file's `deny` list still refuses what it names, so the run reports
|
|
119
|
-
what stopped rather than loosening it.
|
|
90
|
+
The child runs as `fullrun #<N>` in that lane, with neither `josh latest` nor a progress watcher.
|
|
91
|
+
Everything else is unchanged; `pnpm josh followup` releases the lane's hold at the merge.
|
|
92
|
+
|
|
93
|
+
**The child is started as a process of its own, not as a subagent of this session** (`lane:dispatch`,
|
|
94
|
+
`lane:launch`'s final step):
|
|
95
|
+
|
|
96
|
+
- **It records where the child writes** — `<temp>/josh-lane-dispatch-<N>.log`.
|
|
97
|
+
- **A refusal is an empty capture beside a non-zero exit**, with a `warning` Telegram. **Park that
|
|
98
|
+
child and name the log the message carries**; never re-dispatch into the same lane without reading it.
|
|
99
|
+
- **A child that started with nowhere to write exits zero and warns** — **poll that lane on the
|
|
100
|
+
process trace alone**.
|
|
101
|
+
- **The child is started as `fullrun #<N>` with the lane as its working directory**; the typed
|
|
102
|
+
`backlogrun` covers it.
|
|
103
|
+
- **It passes `--permission-mode bypassPermissions`, never `--dangerously-skip-permissions`.**
|
|
104
|
+
`.claude/settings.json`'s `deny` list still refuses what it names; report what stopped, never loosen it.
|
|
120
105
|
|
|
121
106
|
**Start each child without blocking on it, and poll them all** — a silent one is
|
|
122
|
-
`backlogrun-recovery.md` → "A delegated unit that stopped without reporting", read in that child's
|
|
123
|
-
lane.
|
|
107
|
+
`backlogrun-recovery.md` → "A delegated unit that stopped without reporting", read in that child's lane.
|
|
124
108
|
|
|
125
|
-
**`pnpm josh ms` is the parent's now, not the child's
|
|
126
|
-
|
|
127
|
-
lane is cut from.
|
|
109
|
+
**`pnpm josh ms` is the parent's now, not the child's** — run it in the primary checkout **before
|
|
110
|
+
each `lane:open`**.
|
|
128
111
|
|
|
129
112
|
### Conflicts are not predicted
|
|
130
113
|
|
|
131
114
|
**A child whose pull request conflicts with `main` resolves it in its own lane rather than stopping** —
|
|
132
|
-
read `backlogrun-recovery.md` → "Conflicts are not predicted" when `pnpm josh followup` reports
|
|
133
|
-
conflict.
|
|
115
|
+
read `backlogrun-recovery.md` → "Conflicts are not predicted" when `pnpm josh followup` reports it.
|
|
134
116
|
|
|
135
117
|
### What happens to a lane
|
|
136
118
|
|
|
137
119
|
| When | The lane | Why |
|
|
138
120
|
| --- | --- | --- |
|
|
139
|
-
| The child **merged** | `pnpm josh lane:close <N>` |
|
|
140
|
-
| The child was **parked before its commit** | **Left open**, its uncommitted work in place, its directory and held seat recorded on the Issue | The stash stack is
|
|
141
|
-
| The child was **parked after its commit and push** | **Left open**, its directory and held seat recorded on the Issue |
|
|
142
|
-
| The child hit a **merge conflict** | **Left open** — the resolution happens in it |
|
|
143
|
-
| The child stopped on **`needs-human-review`** | **Left open and untouched** | The uncommitted work
|
|
144
|
-
| The child **failed** | Whichever of the two parked rows applies, plus the consecutive-failure count |
|
|
145
|
-
| **`lane:open` failed on the install** | `pnpm josh lane:close <N>`, then park the child |
|
|
146
|
-
| The lane is **spent** — no child working in it, its Issue closed, not one this run launched and has not collected with `run:merge`, a clean tree, no commit that is on no remote | Nothing to do — `pnpm josh lane:prune` closes it |
|
|
147
|
-
| The run was **interrupted** | Nothing to do — the work tree survives on disk |
|
|
148
|
-
|
|
149
|
-
**A lane closed after a push is reopened by `pnpm josh lane:open <N
|
|
150
|
-
|
|
151
|
-
still has to have reached the remote for that to hold** — a child parked before its commit has nothing
|
|
152
|
-
on `origin`, which is why that row keeps its lane open rather than closing it. Rationale:
|
|
153
|
-
`docs/maintainers/backlogrun-lanes-rationale.md` → "Why a committed child's lane is kept".
|
|
121
|
+
| The child **merged** | `pnpm josh lane:close <N>` | Nothing in that tree is wanted |
|
|
122
|
+
| The child was **parked before its commit** | **Left open**, its uncommitted work in place, its directory and held seat recorded on the Issue | The shared stash stack is unsafe; `lane:close` is a **forced** removal. `pnpm josh lane:launch <N>` re-dispatches into the kept lane (a failed-install lane is still refused) |
|
|
123
|
+
| The child was **parked after its commit and push** | **Left open**, its directory and held seat recorded on the Issue | `lane:close` would take the **local branch**, the resume path |
|
|
124
|
+
| The child hit a **merge conflict** | **Left open** — the resolution happens in it | `backlogrun-recovery.md` → "Conflicts are not predicted"; a park there takes the row above |
|
|
125
|
+
| The child stopped on **`needs-human-review`** | **Left open and untouched** | The uncommitted work is what a person looks at. Name the lane directory in the stop report and Telegram |
|
|
126
|
+
| The child **failed** | Whichever of the two parked rows applies, plus the consecutive-failure count | **A merge conflict is not this row**, and is not counted |
|
|
127
|
+
| **`lane:open` failed on the install** | `pnpm josh lane:close <N>`, then park the child | Frees the seat; a person fixes the cause. Carry pnpm's reason into the park note |
|
|
128
|
+
| The lane is **spent** — no child working in it, its Issue closed, not one this run launched and has not collected with `run:merge`, a clean tree, no commit that is on no remote | Nothing to do — `pnpm josh lane:prune` closes it | Any other lane is kept, with the reason on standard error |
|
|
129
|
+
| The run was **interrupted** | Nothing to do — the work tree survives on disk | **Park that child**, naming the lane and `pnpm josh lane:close <N>` |
|
|
130
|
+
|
|
131
|
+
**A lane closed after a push is reopened by `pnpm josh lane:open <N>`** (a local `<N>-lane`, or one
|
|
132
|
+
from `origin/<N>-lane`). A child parked before its commit has nothing on `origin`, so its lane stays open.
|
|
154
133
|
|
|
155
134
|
**Which row a child takes is decided by what `followup` printed, not by reading the situation.** **What
|
|
156
|
-
it prints is `PR checks failed (merge conflict)`** —
|
|
157
|
-
`mergeStateStatus: DIRTY`
|
|
158
|
-
output line to search for. That string sends the child to resolve the conflict in the lane it is
|
|
159
|
-
standing in. Do not grep the output for `mergeable_state`: that is the REST field name, normalized away
|
|
160
|
-
before anything prints it.
|
|
135
|
+
it prints is `PR checks failed (merge conflict)`** — resolve in the lane. Never search for
|
|
136
|
+
`mergeStateStatus: DIRTY` or `mergeable_state`; neither is printed.
|
|
161
137
|
|
|
162
138
|
**A kept lane holds its seat. Say it in the park comment**: the lane directory, that its seat is held,
|
|
163
|
-
and `pnpm josh lane:close <N>`
|
|
139
|
+
and `pnpm josh lane:close <N>` to give it back.
|
|
164
140
|
|
|
165
|
-
**Release the hold on either parked arm, and leave the lane before closing it
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
`lane:close` does not release the hold for you — the record is keyed to the work tree's git directory,
|
|
170
|
-
so removing the tree strands it. And `cd` out of the lane **before** `pnpm josh lane:close <N>`: the
|
|
171
|
-
close removes the directory the shell is sitting in.
|
|
141
|
+
**Release the hold on either parked arm, and leave the lane before closing it**: `pnpm josh
|
|
142
|
+
run:release <N>` in the lane (**a release names the run it belongs to**); `lane:close` does not
|
|
143
|
+
release it. `cd` out of the lane **before** `pnpm josh lane:close <N>`. **A `needs-human-review` stop is
|
|
144
|
+
not a park and keeps its hold.**
|
|
172
145
|
|
|
173
|
-
**A `needs-human-review` stop ends the run, and the lanes already in flight are allowed to finish
|
|
174
|
-
new lane
|
|
175
|
-
stop.
|
|
146
|
+
**A `needs-human-review` stop ends the run, and the lanes already in flight are allowed to finish** —
|
|
147
|
+
no new lane opens, no unit is killed mid-gate; then report and stop.
|
|
176
148
|
|
|
177
149
|
### CI concurrency
|
|
178
150
|
|
|
179
|
-
**`JOSH_LANE_LIMIT` lowers the ceiling with no code** when CI jobs
|
|
180
|
-
|
|
181
|
-
is the queueing. Rationale: `docs/maintainers/backlogrun-lanes-rationale.md` → "Why CI concurrency is
|
|
182
|
-
capped by the lane limit".
|
|
151
|
+
**`JOSH_LANE_LIMIT` lowers the ceiling with no code** when CI jobs queue — a `checks-wait` growing
|
|
152
|
+
with the lane count in the backlog timing report.
|
|
@@ -1,99 +1,79 @@
|
|
|
1
1
|
# `backlogrun` — a child that cannot finish
|
|
2
2
|
|
|
3
3
|
**Read this file in full when a child cannot finish** — before parking it, before a
|
|
4
|
-
`needs-human-review` stop, or before recording a mid-run prerequisite or split.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
`
|
|
8
|
-
split. Provenance of each rule: `docs/maintainers/backlogrun-park-rationale.md` → "Where each rule came from".
|
|
4
|
+
`needs-human-review` stop, or before recording a mid-run prerequisite or split. Point-of-use, never an
|
|
5
|
+
entry read (`backlogrun.md` points here). Single source of park-and-continue, the `needs-human-review`
|
|
6
|
+
stop, a stale `in-progress`, a mid-run prerequisite and a mid-run split. Provenance:
|
|
7
|
+
`docs/maintainers/backlogrun-park-rationale.md` → "Where each rule came from".
|
|
9
8
|
|
|
10
9
|
## What happens to a child that cannot finish
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- **A
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- **A split found mid-run** files the children and the epic and does not stop the batch, because the
|
|
23
|
-
keyword already authorized a batch — `split-assessment.md` for the assessment, → "Splitting a child
|
|
24
|
-
mid-run" for the branch. The split child is not parked or counted as a failure; its new children
|
|
25
|
-
remain available to the normal `backlog:next` / `epic:next` offer.
|
|
26
|
-
- **`in-progress` left behind by an interrupted run** is → "`in-progress` is removed by
|
|
27
|
-
whoever finds it stale".
|
|
11
|
+
A `backlogrun` child is a `fullrun` under a batch authorization:
|
|
12
|
+
|
|
13
|
+
- **A stop that would end the run parks one issue and the run continues** — → "park and continue".
|
|
14
|
+
- **A prerequisite discovered mid-run is recorded as a dependency rather than parked** — → "A
|
|
15
|
+
prerequisite discovered mid-run"; `prerequisite.md` separates prerequisite, split and upstream
|
|
16
|
+
defect. With no epic, the `blocked-by` is written on the issue itself.
|
|
17
|
+
- **A split found mid-run** files the children and the epic and does not stop the batch —
|
|
18
|
+
`split-assessment.md`, → "Splitting a child mid-run". Not a park, not a failure.
|
|
19
|
+
- **`in-progress` left behind by an interrupted run** — → "`in-progress` is removed by whoever finds
|
|
20
|
+
it stale".
|
|
28
21
|
- **A child released from `needs-decision` is re-dispatched to a lane, never implemented by the
|
|
29
|
-
parent
|
|
30
|
-
|
|
31
|
-
is Tier A" below carries the re-dispatch itself. A released child takes a lane exactly as any batch child
|
|
32
|
-
does.
|
|
22
|
+
parent** — `backlogrun.md` → "Claim nothing at the entry — this parent orchestrates and never
|
|
23
|
+
implements".
|
|
33
24
|
|
|
34
25
|
## The parent does not investigate a lane failure itself
|
|
35
26
|
|
|
36
27
|
**A lane failure whose reason is not on its Issue is read by a unit** — `pnpm josh delegate
|
|
37
|
-
lane-failure-investigation`; the parent checks the cited lines and
|
|
38
|
-
|
|
28
|
+
lane-failure-investigation`; the parent checks the cited lines and `pnpm josh issue:state` before it
|
|
29
|
+
parks, re-dispatches or files.
|
|
39
30
|
|
|
40
31
|
## `needs-human-review` — the one stop that is not a park
|
|
41
32
|
|
|
42
|
-
A child carrying **`needs-human-review`**
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
**This is the exception to park-and-continue below** — rationale:
|
|
48
|
-
`docs/maintainers/backlogrun-park-rationale.md` → "Why `needs-human-review` ends the run instead of parking".
|
|
33
|
+
A child carrying **`needs-human-review`** stops `halfrun`-shaped and **the whole run ends there**:
|
|
34
|
+
implementation and the gate run, nothing is committed, the tree is left dirty and unstashed, a
|
|
35
|
+
`confirmation` Telegram carries the resume command, and the remaining children are not started.
|
|
36
|
+
Rationale: `docs/maintainers/backlogrun-park-rationale.md` → "Why `needs-human-review` ends the run
|
|
37
|
+
instead of parking".
|
|
49
38
|
|
|
50
|
-
**The child goes on holding its repository
|
|
51
|
-
|
|
52
|
-
because releasing it would start the next child on top of uncommitted work. **Its lane is left open and
|
|
53
|
-
untouched**, for the same reason. **Name the lane directory in the stop report and in the Telegram.** The lanes
|
|
54
|
-
already in flight finish; no new lane is opened.
|
|
39
|
+
**The child goes on holding its repository**, and **its lane is left open and untouched**. **Name the
|
|
40
|
+
lane directory in the stop report and in the Telegram.** Lanes in flight finish; no new lane opens.
|
|
55
41
|
|
|
56
|
-
**Never apply or remove the label** — a person's alone.
|
|
57
|
-
`needs-decision` comparison: `needs-human-review.md`, which is the single source.
|
|
42
|
+
**Never apply or remove the label** — a person's alone (`needs-human-review.md`, the single source).
|
|
58
43
|
|
|
59
44
|
## park and continue
|
|
60
45
|
|
|
61
|
-
When a child hits something only a person can decide
|
|
62
|
-
`needs-decision`"
|
|
46
|
+
When a child hits something only a person can decide (→ "Only a person's judgement carries
|
|
47
|
+
`needs-decision`"), **park the child and keep going**:
|
|
63
48
|
|
|
64
49
|
```bash
|
|
65
50
|
gh api repos/{owner}/{repo}/issues/<N>/labels -f 'labels[]=needs-decision'
|
|
66
51
|
pnpm josh issue:comment <N> --body-file <path> # what needs deciding, and the options
|
|
67
52
|
```
|
|
68
53
|
|
|
69
|
-
`in-progress`
|
|
70
|
-
|
|
71
|
-
step 1; the other children are unaffected unless they depend on this one.
|
|
54
|
+
`in-progress` stays; the parked child does **not** hold the repository (`needs-decision` takes
|
|
55
|
+
precedence in `epic:next`). Return to step 1.
|
|
72
56
|
|
|
73
57
|
**A parked child's lane is kept, whether or not it had committed**, and every parked ending owes
|
|
74
|
-
`pnpm josh run:release <N>` — `backlogrun-lanes.md` → "What happens to a lane"
|
|
75
|
-
|
|
58
|
+
`pnpm josh run:release <N>` — `backlogrun-lanes.md` → "What happens to a lane". A lost merge race
|
|
59
|
+
resolves in its lane instead (`backlogrun-recovery.md` → "Conflicts are not predicted").
|
|
76
60
|
|
|
77
61
|
**Parking replaces stopping the session, not the rule that produced the stop** — an upstream defect is
|
|
78
62
|
still filed at once, and a workaround is still forbidden. `epic:bundle`'s `ask` is Tier A, not a park:
|
|
79
|
-
|
|
80
|
-
Issues' `## Decisions`.
|
|
63
|
+
`pnpm josh epic --add <E> <N> --after <M>` and record it on both Issues' `## Decisions`.
|
|
81
64
|
|
|
82
|
-
**Removing the label is Tier A — do it without asking**, once the decision is recorded
|
|
83
|
-
parked child never runs again:
|
|
65
|
+
**Removing the label is Tier A — do it without asking**, once the decision is recorded:
|
|
84
66
|
|
|
85
67
|
```bash
|
|
86
68
|
gh api -X DELETE repos/{owner}/{repo}/issues/<N>/labels/needs-decision 2>/dev/null || true
|
|
87
69
|
```
|
|
88
70
|
|
|
89
71
|
**The released child goes back to a lane, never into the parent's own context** — `pnpm josh
|
|
90
|
-
lane:launch <N
|
|
91
|
-
implements").
|
|
72
|
+
lane:launch <N>`.
|
|
92
73
|
|
|
93
74
|
## Only a person's judgement carries `needs-decision`
|
|
94
75
|
|
|
95
|
-
**`needs-decision` means "a person has to choose", and nothing else.**
|
|
96
|
-
when a run may apply it, by hand or through a park. It carries only:
|
|
76
|
+
**`needs-decision` means "a person has to choose", and nothing else.** It carries only:
|
|
97
77
|
|
|
98
78
|
- a design choice nobody has made;
|
|
99
79
|
- a Tier B toss-up, or a Tier C action (`CLAUDE.md` → "Decision autonomy");
|
|
@@ -108,34 +88,25 @@ It never carries:
|
|
|
108
88
|
- a defect in the running repository's own run tooling — the run fixes it and resumes
|
|
109
89
|
(`prompts/collaboration-workflow/upstream-interrupt.md` → "実行中のリポジトリ自身のラン機構の不具合").
|
|
110
90
|
|
|
111
|
-
**When in doubt, it is Tier A**: decide, comment the decision, and continue. **A label a mechanical step
|
|
112
|
-
failed or abandoned child, a lost merge race
|
|
113
|
-
|
|
91
|
+
**When in doubt, it is Tier A**: decide, comment the decision, and continue. **A label a mechanical step
|
|
92
|
+
applied** (a failed or abandoned child, a lost merge race) is read against this list once its reason is
|
|
93
|
+
known, and removed when the reason is not on it. Rationale:
|
|
114
94
|
`docs/maintainers/backlogrun-park-rationale.md` → "Why a run spends no attention on a non-finding".
|
|
115
95
|
|
|
116
96
|
## `in-progress` is removed by whoever finds it stale
|
|
117
97
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
**
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
for longer: a `halfrun` stopped for manual verification, any run paused mid-child, and a child stopped by
|
|
131
|
-
`needs-human-review` (which waits on a person reading an artifact, and carries its own label alongside
|
|
132
|
-
`in-progress`). **All three leave uncommitted work in the checkout**, so `git status` there is the
|
|
133
|
-
decisive read: a dirty tree means the hold is real — leave the label alone and report, never strip it and
|
|
134
|
-
start a second child on top of that work.
|
|
135
|
-
|
|
136
|
-
**A closed issue's labels are neither a finding nor something to clean up.** A closed issue holds no lane
|
|
137
|
-
(`epic-busy.ts` counts holders from the open listing alone) and `epic:next` never offers it, so
|
|
138
|
-
`in-progress` left behind on one changes nothing. **Do not report it, and do not strip it.**
|
|
98
|
+
An interrupted run leaves `in-progress` behind, which excludes the child from `epic:next` permanently
|
|
99
|
+
and occupies a lane. **A session that detects a stale child removes the label itself** (Tier A) and
|
|
100
|
+
reports it, before continuing. **The rule therefore applies to any open issue in the repository, not
|
|
101
|
+
only to this epic's children** (`epic:next` names the holders on standard error).
|
|
102
|
+
|
|
103
|
+
**Age alone is not the test.** Past the 90-minute window, check what holds it: a `halfrun` stopped for
|
|
104
|
+
manual verification, a run paused mid-child, and a `needs-human-review` child hold it legitimately.
|
|
105
|
+
**All three leave uncommitted work in the checkout**, so `git status` there decides: a dirty tree means
|
|
106
|
+
the hold is real — leave the label and report.
|
|
107
|
+
|
|
108
|
+
**A closed issue's labels are neither a finding nor something to clean up** (no lane, never offered).
|
|
109
|
+
**Do not report it, and do not strip it.**
|
|
139
110
|
|
|
140
111
|
```bash
|
|
141
112
|
gh api -X DELETE repos/{owner}/{repo}/issues/<N>/labels/in-progress 2>/dev/null || true
|
|
@@ -143,50 +114,35 @@ gh api -X DELETE repos/{owner}/{repo}/issues/<N>/labels/in-progress 2>/dev/null
|
|
|
143
114
|
|
|
144
115
|
## A prerequisite discovered mid-run
|
|
145
116
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
source; what follows is this entry's branch.
|
|
150
|
-
|
|
151
|
-
`<M>` below is the child being implemented when the prerequisite turned up; `<N>` is the new Issue.
|
|
117
|
+
Something else in **this** repository has to land first: not a split, not an upstream defect.
|
|
118
|
+
`prerequisite.md` is the single source of the distinction, the `route:tier-a` filing and the ceiling.
|
|
119
|
+
`<M>` is the child in hand; `<N>` the new Issue.
|
|
152
120
|
|
|
153
|
-
1. File the prerequisite
|
|
154
|
-
|
|
155
|
-
2. **Stash the work in progress
|
|
156
|
-
so `<M>`'s half-finished edits are sitting there, and the next child's `pnpm josh ms`
|
|
157
|
-
would refuse or carry them into the prerequisite's branch and PR.
|
|
121
|
+
1. File the prerequisite `<N>` with `route:tier-a` (Tier A, first-party, no confirmation) — **first**,
|
|
122
|
+
because the next step names it.
|
|
123
|
+
2. **Stash the work in progress**:
|
|
158
124
|
|
|
159
125
|
```bash
|
|
160
126
|
git stash push -u -m "backlogrun: paused #<M> for prerequisite #<N>"
|
|
161
127
|
pnpm josh issue:comment <M> --body-file <path> # what was stashed, and that #<N> must land first
|
|
162
128
|
```
|
|
163
129
|
|
|
164
|
-
**`-u` is not optional** (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
"複数 Issue に分割するときの epic Issue", step 4.
|
|
177
|
-
4. **Remove `in-progress` from `<M>`** — `pnpm josh run:release <M>`, which removes the label with the hold.
|
|
178
|
-
This is what lets `<M>` run again: `epic:next` classifies a child carrying `in-progress` as waiting on
|
|
179
|
-
time **before** it looks at any blocker, so a child left labelled is never offered again.
|
|
180
|
-
5. **Do not park.** Go back to step 1 of the loop. `epic:next` classifies the original child as resolving
|
|
181
|
-
on its own and hands back the prerequisite first, so the order is kept with no human input.
|
|
182
|
-
|
|
183
|
-
**A stop a dependency can express is never parked**, and a defect in this repository's own gate or run
|
|
184
|
-
tooling is such a stop — `prerequisite.md` holds that rule and what the driver does with it.
|
|
130
|
+
**`-u` is not optional** (new test files are untracked). **Pop it by message, never by position** —
|
|
131
|
+
`pnpm josh stash:pop "backlogrun: paused #<M> for prerequisite #<N>"` — when `epic:next` offers `<M>`
|
|
132
|
+
again, after its `pnpm josh ms`; expect conflicts.
|
|
133
|
+
3. `pnpm josh epic --add <E> <N> --before <M>` — row, declaration and `blocked-by` in one command;
|
|
134
|
+
never a hand edit. **With no epic**, record `<M>` blocked by `<N>` alone with the `gh api
|
|
135
|
+
…/dependencies/blocked_by` call in
|
|
136
|
+
`prompts/collaboration-workflow/issue-template.md` → "複数 Issue に分割するときの epic Issue", step 4.
|
|
137
|
+
4. **Remove `in-progress` from `<M>`** — `pnpm josh run:release <M>`; a labelled child is never offered again.
|
|
138
|
+
5. **Do not park.** Back to step 1 of the loop; `epic:next` hands back the prerequisite first.
|
|
139
|
+
|
|
140
|
+
**A stop a dependency can express is never parked**, including a defect in this repository's own gate
|
|
141
|
+
or run tooling — `prerequisite.md`.
|
|
185
142
|
|
|
186
143
|
## Splitting a child mid-run
|
|
187
144
|
|
|
188
|
-
|
|
189
|
-
`
|
|
190
|
-
`
|
|
191
|
-
|
|
192
|
-
**that** child and move on. Splitting alone never adds `needs-decision` to the promoted epic.
|
|
145
|
+
Not a reason to stop. File the new children with `route:split` (Tier A, first-party), then
|
|
146
|
+
`pnpm josh epic --add <E> <N...> [--before <M> | --after <M>]` — never a hand edit. Same criteria as
|
|
147
|
+
`kickoff`. If what remains needs a person, park **that** child and move on. Splitting alone never adds
|
|
148
|
+
`needs-decision` to the promoted epic.
|
|
@@ -41,10 +41,9 @@ provenance of each rule: `docs/maintainers/backlogrun-progress-rationale.md` →
|
|
|
41
41
|
## After a named epic completes
|
|
42
42
|
|
|
43
43
|
**When a named epic's children are all processed — merged or parked — the run advances to the next
|
|
44
|
-
named item, and then drains the opted-in backlog** (unless `--only
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
session standing in the repository that owns it ("Who sends the summary, and who propagates" below).
|
|
44
|
+
named item, and then drains the opted-in backlog** (unless `--only`). A completed epic — or a merged
|
|
45
|
+
bare named Issue — is one step of the invocation, never its end. Its summary is sent per "Who sends the
|
|
46
|
+
summary, and who propagates" below.
|
|
48
47
|
|
|
49
48
|
## The hand-off — one session does not have to run the whole batch
|
|
50
49
|
|
|
@@ -88,13 +87,12 @@ park** — nothing is labelled, stashed or filed.
|
|
|
88
87
|
|
|
89
88
|
### Picking the lanes up in the fresh session
|
|
90
89
|
|
|
91
|
-
**Start no child again and open no lane already open.** In one turn: `pnpm josh lane:list` (
|
|
90
|
+
**Start no child again and open no lane already open.** In one turn: `pnpm josh lane:list` (a line
|
|
92
91
|
with a path is a handed-over child, polled per `backlogrun-recovery.md` → "A delegated unit that stopped
|
|
93
92
|
without reporting"), `pnpm josh run:progress --wait --output <handed-over paths>` in the background
|
|
94
|
-
(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
`pnpm josh lane:open <N>` then `pnpm josh lane:dispatch <N>`, never adopted.
|
|
93
|
+
(`run:watcher:guard`), `pnpm josh run:liveness`, and `epic:next --lanes`, a lane per child it offers.
|
|
94
|
+
**A carried-over child finishes in its own unit — never run its `followup` yourself**; one lost in the
|
|
95
|
+
cut is re-dispatched with `pnpm josh lane:open <N>` then `pnpm josh lane:dispatch <N>`.
|
|
98
96
|
|
|
99
97
|
### What carries over
|
|
100
98
|
|