@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
|
@@ -5,76 +5,47 @@ description: Checks after `pnpm update`, `josh latest`, `josh adopt`, `pnpm josh
|
|
|
5
5
|
|
|
6
6
|
# After a dependency-update command
|
|
7
7
|
|
|
8
|
-
`CLAUDE.md` → "Decision autonomy" keeps both prohibitions resident as Tier C
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
that can rewrite dependency versions.
|
|
14
|
-
|
|
15
|
-
This skill is the single source of the overrides protection's procedure;
|
|
16
|
-
`prompts/collaboration-workflow/operating-rules.md` only points here. Overrides were added on
|
|
17
|
-
purpose — for security, compatibility or a working guarantee (for example
|
|
18
|
-
`"esbuild@<=0.24.2": ">=0.25.0"` for Workers build compatibility).
|
|
8
|
+
`CLAUDE.md` → "Decision autonomy" keeps both prohibitions resident as Tier C: never touch `overrides`,
|
|
9
|
+
never touch `devEngines`, without explicit user approval. This skill is the single source of how to check
|
|
10
|
+
whether a command touched them, after `pnpm update`, `josh latest`, `josh adopt` (which runs
|
|
11
|
+
`josh latest`), `pnpm josh overrides`, a Dependabot merge, or any command that rewrites dependency
|
|
12
|
+
versions. Overrides exist on purpose (e.g. `"esbuild@<=0.24.2": ">=0.25.0"` for Workers builds).
|
|
19
13
|
|
|
20
14
|
## 1. Effective overrides live in the workspace — inspect both files
|
|
21
15
|
|
|
22
|
-
**pnpm 11 and 12 read effective overrides only from `pnpm-workspace.yaml`.**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
override. An absent or empty package field says nothing about workspace overrides: app-kit's
|
|
26
|
-
`package.json` has no `pnpm` field, while its workspace has a real override.
|
|
16
|
+
**pnpm 11 and 12 read effective overrides only from `pnpm-workspace.yaml`.** `pnpm.overrides` in
|
|
17
|
+
**`package.json` is ignored** (verified with pnpm 12.6.0). Inspect both to preserve existing
|
|
18
|
+
declarations, but an absent package field says nothing about workspace overrides.
|
|
27
19
|
|
|
28
20
|
## 2. The check is a command you run, not a conclusion you reach
|
|
29
21
|
|
|
30
|
-
**The check is a command you run, not a conclusion you reach.** After `pnpm update`, `josh latest`,
|
|
31
|
-
or any dependency-update command, verify the overrides in both `pnpm-workspace.yaml` and
|
|
32
|
-
`package.json` by running
|
|
33
|
-
|
|
34
22
|
```bash
|
|
35
23
|
git diff -- pnpm-workspace.yaml package.json
|
|
36
24
|
```
|
|
37
25
|
|
|
38
|
-
(after `josh adopt`, which has already committed and returned to the default branch
|
|
39
|
-
|
|
40
|
-
and
|
|
41
|
-
|
|
42
|
-
versions still respect the effective overrides. If any entry was removed, modified, or bumped past
|
|
43
|
-
an override, restore it immediately, investigate why it changed, and report that to the user — never
|
|
44
|
-
keep the change without explicit approval.
|
|
26
|
+
(after `josh adopt`, which has already committed and returned to the default branch:
|
|
27
|
+
`git diff <default>...<branch> -- pnpm-workspace.yaml package.json`). Confirm both overrides blocks
|
|
28
|
+
are untouched **and** `devDependencies` still respect the effective overrides. A removed, modified or
|
|
29
|
+
over-bumped entry: restore it immediately, investigate, and report — never keep it without approval.
|
|
45
30
|
|
|
46
|
-
`josh latest` prints its
|
|
47
|
-
<file>)
|
|
48
|
-
|
|
31
|
+
`josh latest` prints its verdict as its last overrides line (`✔ overrides unchanged (<n> from
|
|
32
|
+
<file>)` or `⚠ overrides changed`); `pnpm josh overrides` compares against a saved snapshot —
|
|
33
|
+
**quote what one printed.**
|
|
49
34
|
|
|
50
35
|
## 3. `devEngines` — the one expected change
|
|
51
36
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
`packageManager` pin (see `scripts/version/latest-corepack.ts` → `sync_development_engines`); the two
|
|
58
|
-
MUST stay exactly equal — **byte-identical, `+sha512…` Corepack integrity suffix included**. pnpm
|
|
59
|
-
compares them as raw strings, so a bare `11.18.0` paired with `pnpm@11.18.0+sha512…` is a mismatch
|
|
60
|
-
and the dual-declaration warning fires; only a character-for-character match suppresses it.
|
|
61
|
-
|
|
62
|
-
So after `josh latest`, **KEEP** a `devEngines.packageManager.version` change **if and only if** it
|
|
63
|
-
now equals everything after `pnpm@` in the new `packageManager` pin (same version string **and** same
|
|
64
|
-
integrity suffix; only the `version` field moved). Reverting it would both undo a valid toolchain
|
|
65
|
-
update **and** re-introduce a `packageManager`/`devEngines` mismatch — the opposite of the rule's
|
|
66
|
-
intent.
|
|
37
|
+
**Exception — the `josh latest` lockstep pnpm bump is expected, NOT a violation.** **KEEP** a
|
|
38
|
+
`devEngines.packageManager.version` change **if and only if** it equals everything after `pnpm@` in
|
|
39
|
+
the new `packageManager` pin — **byte-identical, `+sha512…` Corepack integrity suffix included**
|
|
40
|
+
(`scripts/version/latest-corepack.ts` → `sync_development_engines`). Reverting it would re-introduce
|
|
41
|
+
the mismatch.
|
|
67
42
|
|
|
68
|
-
**Restore + ask
|
|
69
|
-
`packageManager` (a dropped
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
`devEngines.packageManager.onFail` from `"error"` to `"download"` — a user-approved migration that
|
|
73
|
-
leaves `name` and `version` untouched; keep it.
|
|
43
|
+
**Restore + ask** when `devEngines` changed any other way: the version no longer matches
|
|
44
|
+
`packageManager` (a dropped or truncated suffix counts), its structure changed (`name` / `onFail` /
|
|
45
|
+
fields), or something other than `josh latest` touched it. One structural change is expected and
|
|
46
|
+
kept: `josh sync` moving `devEngines.packageManager.onFail` from `"error"` to `"download"`.
|
|
74
47
|
|
|
75
48
|
## 4. When the bump breaks something — fix forward
|
|
76
49
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
`prompts/collaboration-workflow/principles.md` → "latest-first". Fix-forward never authorizes a silent edit to a protected pin: the
|
|
80
|
-
approval gates in sections 1–3 still apply.
|
|
50
|
+
Single source: `prompts/collaboration-workflow/principles.md` → "latest-first". Fix-forward never
|
|
51
|
+
authorizes a silent edit to a protected pin; sections 1–3 still apply.
|
|
@@ -5,9 +5,8 @@ description: Procedures for `josh epic:audit`, `epic:next` and `epic:bundle`. Re
|
|
|
5
5
|
|
|
6
6
|
# The `josh epic:*` commands
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
`docs/maintainers/epic-commands-rationale.md` → "Where each rule came from".
|
|
8
|
+
This skill is the single source for the three commands. Reasons: `docs/maintainers/epic-commands-rationale.md`
|
|
9
|
+
→ "Where each rule came from".
|
|
11
10
|
|
|
12
11
|
The workflow keywords themselves — `kickoff`, `fullrun`, `halfrun`, `prrun`, `backlogrun` — live in the
|
|
13
12
|
`workflow-commands` skill.
|
|
@@ -19,27 +18,23 @@ epic:audit → find contradictions across the children, and fix what it finds (T
|
|
|
19
18
|
backlogrun → which calls epic:next each round
|
|
20
19
|
```
|
|
21
20
|
|
|
22
|
-
Front-loading every `needs-decision`
|
|
23
|
-
|
|
24
|
-
pre-check is `epic:audit`.
|
|
21
|
+
Front-loading every `needs-decision` is `backlogrun`'s job: `backlogrun-steps.md` → "Resolve what
|
|
22
|
+
the plan can resolve, before starting". A `backlogrun #E --only`'s pre-check is `epic:audit`.
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
`epic-bundle.md` when a filing's `epic:bundle` answer places the issue.
|
|
24
|
+
Read `execution-waves.md` only when children need an order between groups (a wave boundary, or a child
|
|
25
|
+
that must run alone), and `epic-bundle.md` only when a filing's `epic:bundle` answer places the issue.
|
|
29
26
|
|
|
30
27
|
## Recording a decision
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
the label-clearing rule itself is `backlogrun-park.md` → "park and continue".
|
|
29
|
+
Record it in both places: the epic's `## Decisions` log, and a comment on each child it applies to.
|
|
30
|
+
Recording a decision removes that child's `needs-decision` label (Tier A; `backlogrun-park.md` →
|
|
31
|
+
"park and continue").
|
|
36
32
|
|
|
37
|
-
- **
|
|
38
|
-
|
|
39
|
-
- **
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
applies to, and **say in the report that the epic's `## Decisions` entry is still pending**.
|
|
33
|
+
- **Decided as a child joins the epic**: `pnpm josh epic --add … --decision-file` writes both
|
|
34
|
+
(`epic-bundle.md`).
|
|
35
|
+
- **About a child the epic already tracks**: that flag refuses an insertion with nothing to add.
|
|
36
|
+
Comment on each child with `pnpm josh issue:comment <N> --body-file <path>`, and **say in the report
|
|
37
|
+
that the epic's `## Decisions` entry is still pending**.
|
|
43
38
|
|
|
44
39
|
```md
|
|
45
40
|
## Decisions
|
|
@@ -55,8 +50,8 @@ the label-clearing rule itself is `backlogrun-park.md` → "park and continue".
|
|
|
55
50
|
|
|
56
51
|
## Creating an epic
|
|
57
52
|
|
|
58
|
-
A split into two or more issues always gets an epic (`prompts/collaboration-workflow/issue-template.md`)
|
|
59
|
-
|
|
53
|
+
A split into two or more issues always gets an epic (`prompts/collaboration-workflow/issue-template.md`),
|
|
54
|
+
created with the command, never by hand:
|
|
60
55
|
|
|
61
56
|
```bash
|
|
62
57
|
pnpm josh epic "<epic-title>" <N1> <N2> ... # order-free batch
|
|
@@ -64,105 +59,71 @@ pnpm josh epic "<epic-title>" <N1> <N2> ... --ordered # argument order is the d
|
|
|
64
59
|
# --rationale-file <path|-> fills Split rationale; --origin <owner/repo#N> adds the backlink
|
|
65
60
|
```
|
|
66
61
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
reasons and the history: `docs/maintainers/epic-commands-rationale.md` → "Creating an epic by hand".
|
|
62
|
+
After any hand edit run `pnpm josh epic:check <E>` (exit 1 when the body no longer parses).
|
|
63
|
+
`pnpm josh followup` closes the epic once every task-list child is closed; one tracking a
|
|
64
|
+
cross-repository child is closed by hand. Without `josh`: `issue-template.md`; the format's history:
|
|
65
|
+
`docs/maintainers/epic-commands-rationale.md` → "Creating an epic by hand".
|
|
72
66
|
|
|
73
67
|
## `josh epic:audit <E>` — contradictions across the children
|
|
74
68
|
|
|
75
|
-
`epic:check` verifies
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
after a child is added or a dependency changed.
|
|
79
|
-
|
|
80
|
-
The cycle and declaration-mismatch checks are `epic:next`'s, reused rather than re-derived. What this
|
|
81
|
-
adds is reading *inside* the children:
|
|
69
|
+
`epic:check` verifies the format; this verifies the children agree. Run it **without being asked**
|
|
70
|
+
when a `backlogrun` starts a named epic's children, and right after a child is added or a dependency
|
|
71
|
+
changed. Cycle and declaration checks are reused from `epic:next`; it adds:
|
|
82
72
|
|
|
83
73
|
| Check | Level |
|
|
84
74
|
| --- | --- |
|
|
85
75
|
| A child's body names another child, nothing orders the two | warning |
|
|
86
|
-
| A child's **acceptance criteria** name another child, nothing orders the two | **error**; a warning once both
|
|
76
|
+
| A child's **acceptance criteria** name another child, nothing orders the two | **error**; a warning once both are closed or when the pair spans two repositories — the child is still offered as runnable until the relation is recorded |
|
|
87
77
|
| A body cites a missing or already-closed issue | warning |
|
|
88
|
-
| A task-list row points at another **epic** | warning — `epic:next` withholds the row
|
|
78
|
+
| A task-list row points at another **epic** | warning — `epic:next` already withholds the row; a person should look |
|
|
89
79
|
| An issue names this epic as parent that the task list does not track | warning |
|
|
90
80
|
| The search for those issues could not read the open backlog | **error** |
|
|
91
81
|
| That search stopped before the end of the backlog | warning |
|
|
92
82
|
|
|
93
|
-
**Only errors fail it** (exit 1)
|
|
94
|
-
|
|
95
|
-
|
|
83
|
+
**Only errors fail it** (exit 1). A forward reference the other child already depends on is not
|
|
84
|
+
reported. A pair is demoted to a warning only when the closed state is **confirmed** (any state but
|
|
85
|
+
`CLOSED` normalizes to `OPEN`).
|
|
96
86
|
|
|
97
|
-
**
|
|
98
|
-
|
|
99
|
-
`OPEN`, so a state that could not be confirmed stays an error.
|
|
87
|
+
**Fixing what it finds is Tier A** — fix it and record why on the issue. Park with `needs-decision`
|
|
88
|
+
only for a design choice nobody has made.
|
|
100
89
|
|
|
101
|
-
|
|
102
|
-
will otherwise stall the work, so fix it without asking and record why on the issue. Park with
|
|
103
|
-
`needs-decision` only when the contradiction is a design choice nobody has made.
|
|
90
|
+
The two `orphan search` findings are about the search, not the children:
|
|
104
91
|
|
|
105
|
-
|
|
106
|
-
|
|
92
|
+
- `✖ orphan search: Could not list the open issues…` — **re-run the audit**; nothing to fix or decide.
|
|
93
|
+
If it keeps failing, check `gh auth status` and the rate limit.
|
|
94
|
+
- `⚠ orphan search: The open-issue scan hit its …` — only the newest 500 issues (or 50 bodies) were
|
|
95
|
+
covered; the audit passes. Look further by hand if an orphan is expected.
|
|
107
96
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
decide, so neither Tier A nor a `needs-decision` park applies. If it keeps failing, check
|
|
112
|
-
`gh auth status` and whether the rate limit has reset.
|
|
113
|
-
- `⚠ orphan search: The open-issue scan hit its …` — the search covered only the newest part of the
|
|
114
|
-
backlog (500 issues, or 50 bodies mentioning the epic). It ran, so the audit passes; read the line,
|
|
115
|
-
and look further down the backlog by hand if an orphan is expected there.
|
|
116
|
-
|
|
117
|
-
**One thing it cannot check** belongs to planning: when a child introduces a new label, command,
|
|
118
|
-
state or artifact, list the existing code referencing that concept and confirm some child owns
|
|
119
|
-
updating it. Label names are single-sourced in `scripts/issue/issue-labels.ts`.
|
|
97
|
+
**It cannot check** that when a child introduces a new label, command, state or artifact, some child
|
|
98
|
+
owns updating the existing code referencing that concept — do that at planning. Label names live in
|
|
99
|
+
`scripts/issue/issue-labels.ts`.
|
|
120
100
|
|
|
121
101
|
History: `docs/maintainers/epic-commands-rationale.md` → "`epic:audit` — why the children are read across".
|
|
122
102
|
|
|
123
103
|
## `josh epic:next <E…>` — what is runnable
|
|
124
104
|
|
|
125
|
-
Returns **every** runnable child, bundled per repository with
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
it. **One unusable graph refuses the whole answer**, and **one reference that does not parse fails
|
|
148
|
-
the read** rather than being dropped. `docs/josh-commands-backlog.md` → "`josh epic:next`" carries the
|
|
149
|
-
worked form.
|
|
150
|
-
|
|
151
|
-
**An `in-progress` issue occupies a lane rather than the whole repository.** The occupancy is counted
|
|
152
|
-
from that repository's own `in-progress` listing — never from anything the session remembers — and
|
|
153
|
-
what is left of `JOSH_LANE_LIMIT` (**default 4**) is what gets offered. At zero the answer is `wait`
|
|
154
|
-
and the holders are named on standard error. A parked child releases its lane; one stopped by
|
|
155
|
-
`needs-human-review` goes on holding one, because its uncommitted work is still in that checkout.
|
|
156
|
-
|
|
157
|
-
**A child that is itself an epic is never offered** — an epic is not a unit of work. It waits on a
|
|
158
|
-
*person*, because no amount of waiting turns an epic into work. **The test is the child's `epic`
|
|
159
|
-
label, never how its task-list row is written**: a row naming `owner/repo#N` is a different property
|
|
160
|
-
and a legitimate one — it disables the epic auto-close by design, which is why a cross-repository
|
|
161
|
-
backlink is prose rather than a row — so a cross-repository child that is not an epic stays
|
|
162
|
-
runnable, and one that is an epic is withheld exactly like a local one. **A parent epic over another
|
|
163
|
-
epic never auto-closes**: the auto-close evaluates only the epics whose own task list holds the issue
|
|
164
|
-
a merge just closed, and a grandchild merging never reaches the grandparent. `epic:audit` reports the
|
|
165
|
-
same row, with that consequence in the finding.
|
|
105
|
+
Returns **every** runnable child, bundled per repository with its local checkout. `--repo <owner/repo>`
|
|
106
|
+
narrows to one and prints a single token (an issue number or the verdict); `--lanes` beside it prints
|
|
107
|
+
one number per line, **up to the number of free lanes in that repository**.
|
|
108
|
+
|
|
109
|
+
- **Several epics answer as one**: every argument before the first flag is an epic; their runnable
|
|
110
|
+
children merge into one pool per repository. **Priority is the order the epics were named**, then
|
|
111
|
+
each epic's own task-list order (its declared chain still decides what is runnable).
|
|
112
|
+
- **Reorder with `pnpm josh epic --add <E> <N> --order-before <M>`** (or `--order-after <M>`), never a
|
|
113
|
+
hand edit; declarations and `blocked-by` relations stay as they were. Moving a row does not free a
|
|
114
|
+
child a chain still holds — the command prints a ⚠️ line instead.
|
|
115
|
+
- **A child two epics track enters once**, kept by the epic named earlier.
|
|
116
|
+
- **One unusable graph refuses the whole answer**; **one reference that does not parse fails the
|
|
117
|
+
read**. Worked form: `docs/josh-commands-backlog.md` → "`josh epic:next`".
|
|
118
|
+
|
|
119
|
+
**An `in-progress` issue occupies a lane, not the repository.** Free lanes are `JOSH_LANE_LIMIT`
|
|
120
|
+
(**default 4**) minus that repository's `in-progress` listing. At zero the answer is `wait`, with the
|
|
121
|
+
holders on standard error. A parked child releases its lane; a `needs-human-review` stop keeps it.
|
|
122
|
+
|
|
123
|
+
**A child that is itself an epic is never offered** and waits on a *person*. The test is the child's
|
|
124
|
+
`epic` label, never how its row is written: a cross-repository `owner/repo#N` row that is not an epic
|
|
125
|
+
stays runnable. **A parent epic over another epic never auto-closes** (a grandchild's merge never
|
|
126
|
+
reaches it); `epic:audit` reports the row.
|
|
166
127
|
|
|
167
128
|
Children that are not runnable are sorted by **whether waiting helps**, never by label:
|
|
168
129
|
|
|
@@ -172,62 +133,42 @@ Children that are not runnable are sorted by **whether waiting helps**, never by
|
|
|
172
133
|
| Waiting on time | Wait and ask again |
|
|
173
134
|
| Waiting on a person | Stop and report |
|
|
174
135
|
|
|
175
|
-
**A blocker outside every named epic is weighed
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
recorded with a native `blocked-by` relation and honoured by naming both epics** — `epic:next <E1>
|
|
181
|
-
<E2>`, or `backlog:next`, whose set is the whole opted-in backlog. The table is
|
|
182
|
-
`docs/josh-commands-backlog.md` → "`josh epic:next`".
|
|
136
|
+
**A blocker outside every named epic is weighed**: closed, it resolves (cross-repository: after its
|
|
137
|
+
release); open and tracked by an epic named in the same call, the child waits on time (or on a person,
|
|
138
|
+
if the blocker does); open and untracked, the child waits on a person and the blocker is named on
|
|
139
|
+
standard error; an unknown state reads as waiting. **Order two epics with a native `blocked-by`
|
|
140
|
+
relation and name both** — `epic:next <E1> <E2>`, or `backlog:next`.
|
|
183
141
|
|
|
184
|
-
Two things stop the command
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
*nothing but* a chain counts as a declaration — a prose line recommending an execution order is a suggestion, not a dependency.
|
|
142
|
+
Two things stop the command: a **circular dependency**, and a **disagreement between the epic body
|
|
143
|
+
and the `blocked-by` relations**. Only a line that is *nothing but* a chain is a declaration — a prose
|
|
144
|
+
line recommending an execution order is a suggestion, not a dependency.
|
|
188
145
|
|
|
189
|
-
Why
|
|
146
|
+
Why: `docs/maintainers/epic-commands-rationale.md` → "`epic:next` — why it answers as it does".
|
|
190
147
|
|
|
191
148
|
## Epics that span repositories
|
|
192
149
|
|
|
193
|
-
Write cross-repository children
|
|
194
|
-
|
|
195
|
-
to implement.
|
|
150
|
+
Write cross-repository children as `owner/repo#N` or a full issue URL. Their state is read through
|
|
151
|
+
`gh api`, so **no local clone is needed to learn it** — only to implement.
|
|
196
152
|
|
|
197
|
-
- **The owner restriction is inherited unchanged**: a
|
|
198
|
-
|
|
199
|
-
- **
|
|
200
|
-
unreadable child leaves it open, exactly as before.
|
|
201
|
-
- **An epic in another repository must be referenced as `owner/repo#N`** — `backlogrun
|
|
153
|
+
- **The owner restriction is inherited unchanged**: a different owner is never a target.
|
|
154
|
+
- **The epic auto-closes only when every cross-repository child's state could be read.**
|
|
155
|
+
- **An epic in another repository is referenced as `owner/repo#N`** — `backlogrun
|
|
202
156
|
joshuafolkken/kit#<E> --only`, `epic:next joshuafolkken/kit#<E> --repo joshuafolkken/app-kit`. A
|
|
203
|
-
bare `#N`
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
branch, or one declaring `private`, ships no release for the check to wait on, so a closed blocker
|
|
214
|
-
there resolves. The answer is read from the blocker repository's own manifest and never from the
|
|
215
|
-
registry (a registry 404 also means "this token may not see it"). A manifest read that fails (rather
|
|
216
|
-
than answering 404) is told apart by HTTP status and still waits.
|
|
217
|
-
|
|
218
|
-
**The evaluation is an AND in that order.** While the blocker is open the registry is never
|
|
219
|
-
consulted, so a run never stalls on a publish from the moment it starts. The target is that exact
|
|
220
|
-
version, never "something newer". **A child no longer bumps the version**: the version moves only
|
|
221
|
-
when `pnpm josh release` runs, so the target is the release that includes the blocker, not the
|
|
222
|
-
default branch's version just after its merge (the previous release). The publish check shares
|
|
223
|
-
`josh propagate`'s implementation; it is not defined twice. History:
|
|
224
|
-
`docs/maintainers/epic-commands-rationale.md` → "Cross-repository epics".
|
|
157
|
+
bare `#N` is this repository's issue.
|
|
158
|
+
- **`epic:next` prints each candidate's local checkout**; none prints `(no local checkout)` and is
|
|
159
|
+
**never cloned on its own**.
|
|
160
|
+
|
|
161
|
+
**A cross-repository dependency resolves only when the blocker is closed and the version its default
|
|
162
|
+
branch declares is in the registry** (checked in that order; that exact version). A child no longer
|
|
163
|
+
bumps the version, so the target is the release that includes the blocker. **Unless that repository
|
|
164
|
+
publishes nothing**: no `package.json` on its default branch, or `private`, resolves on close — read
|
|
165
|
+
from its manifest, never the registry; a failed manifest read (not a 404) still waits. The publish
|
|
166
|
+
check is `josh propagate`'s. History: `docs/maintainers/epic-commands-rationale.md` → "Cross-repository epics".
|
|
225
167
|
|
|
226
168
|
## `josh epic:bundle <N>` — does this new issue belong with one already filed?
|
|
227
169
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
run it by hand only when that step printed `⚠`. **It recommends; it writes nothing.**
|
|
170
|
+
Runs right after any filing; **`pnpm josh issue:file` runs it as its last step** — run it by hand only
|
|
171
|
+
when that step printed `⚠`. **It recommends; it writes nothing.**
|
|
231
172
|
|
|
232
173
|
| Candidates | Do | Tier |
|
|
233
174
|
| --- | --- | --- |
|
|
@@ -239,9 +180,7 @@ run it by hand only when that step printed `⚠`. **It recommends; it writes not
|
|
|
239
180
|
| No strong signal | Nothing | — |
|
|
240
181
|
| **The epic listing was cut short** | **Nothing** — every placing row above is withheld | — |
|
|
241
182
|
|
|
242
|
-
**A placing answer is acted on with `epic-bundle.md
|
|
243
|
-
choosing between epics, and the `--decision-file` record that pays for the choice. `Nothing to
|
|
244
|
-
bundle.` needs no further read.
|
|
183
|
+
**A placing answer is acted on with `epic-bundle.md`**. `Nothing to bundle.` needs no further read.
|
|
245
184
|
|
|
246
185
|
History: `docs/maintainers/epic-commands-rationale.md` → "`epic:bundle` — why issues filed apart are bundled afterwards";
|
|
247
186
|
the reasons behind `epic-bundle.md`: `docs/maintainers/epic-commands-rationale.md` → "`epic:bundle` — why each answer reads as it does";
|
|
@@ -1,44 +1,30 @@
|
|
|
1
1
|
# `epic:bundle` — the detail behind the answer
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Read this when a filing's `epic:bundle` answer places the issue (`add_to_epic`, `create_epic`, or a
|
|
4
|
+
choice between epics), or when `SKILL.md` → "`josh epic:bundle <N>` — does this new issue belong with
|
|
5
|
+
one already filed?" does not settle it. `Nothing to bundle.` needs neither. Reasons:
|
|
6
|
+
`docs/maintainers/epic-commands-rationale.md` → "`epic:bundle` — why each answer reads as it does".
|
|
7
7
|
|
|
8
8
|
**Only two things count as a signal**: the issues referring to each other in prose, or a `blocked-by`
|
|
9
|
-
already recorded between them. **A similar title never counts on its own
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
number, 403 and 429 are a rate limit. The referenced-number reads are capped at twenty, and **only
|
|
29
|
-
the subject's own body is followed**.
|
|
30
|
-
|
|
31
|
-
**`none` is a legitimate answer** — a self-review outside any workflow has no current issue to point
|
|
32
|
-
at, so the issue stays in the backlog: what the procedure requires is running the command and
|
|
33
|
-
following its answer, not landing every issue in an epic. The review-cap follow-up's filing and the
|
|
34
|
-
answer table it acts on are `prompts/review.md` → "Three-way disposition after the cap".
|
|
35
|
-
|
|
36
|
-
**Every row that *places* the issue asserts a negative, so a cut epic listing withholds all of them.**
|
|
37
|
-
"No epic already tracks this issue" — which `create_epic` asserts about the candidates too — is only
|
|
38
|
-
as good as the listing it was read from, and an epic past the cut tracks its children invisibly.
|
|
39
|
-
**`add_to_epic` rests on it as much as `create_epic` does**: adding the issue to the epic a
|
|
40
|
-
*candidate* sits in, while an unseen epic already tracks the issue itself, is the same duplicate by
|
|
41
|
-
another route. The verdict says so itself:
|
|
9
|
+
already recorded between them. **A similar title never counts on its own.**
|
|
10
|
+
|
|
11
|
+
**The release issue is neither a candidate nor a subject**, like an epic — its `blocked-by` relations
|
|
12
|
+
are mechanical. Any other `blocked-by` or prose reference still counts.
|
|
13
|
+
|
|
14
|
+
**The search is not limited to the open backlog.** Every number the subject's own body names is read
|
|
15
|
+
(capped at twenty), whatever its state:
|
|
16
|
+
|
|
17
|
+
- A **closed** reference counts only when an open epic already tracks it; an **open** one counts either way.
|
|
18
|
+
- A **pull request** number is not a candidate.
|
|
19
|
+
- A failed read, or a reference past the cap, is reported as a gap — never folded into "no strong signal".
|
|
20
|
+
- **A number that does not exist is not a gap** — dropped in silence. Told apart **by HTTP status,
|
|
21
|
+
never by `gh`'s wording**: 404 is nothing there; 403 and 429 are a rate limit.
|
|
22
|
+
|
|
23
|
+
**`none` is a legitimate answer** — the issue stays in the backlog. The review-cap follow-up's filing:
|
|
24
|
+
`prompts/review.md` → "Three-way disposition after the cap".
|
|
25
|
+
|
|
26
|
+
**A cut epic listing withholds every placing row**, `add_to_epic` as much as `create_epic` — an unseen
|
|
27
|
+
epic may already track the issue. The verdict says so, and the exit code stays `0`:
|
|
42
28
|
|
|
43
29
|
```text
|
|
44
30
|
Could not confirm which epic already tracks these — do not place this issue in one.
|
|
@@ -46,50 +32,32 @@ Could not confirm which epic already tracks these — do not place this issue in
|
|
|
46
32
|
Related: #<N>
|
|
47
33
|
```
|
|
48
34
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
survives the cut is a membership that *was* found**: the table's first row names the epic it read
|
|
52
|
-
tracking the issue, and epics past the cut cannot unseat it.
|
|
35
|
+
It prints no children or order. What survives the cut is a membership that *was* found (the table's
|
|
36
|
+
first row).
|
|
53
37
|
|
|
54
|
-
**Placing an issue is not merging epics.**
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
and the epic's `## Decisions`. **Merging two epics is a different action, and nothing here proposes
|
|
58
|
-
it.**
|
|
38
|
+
**Placing an issue is not merging epics.** Choosing between two candidate epics is Tier A: take the one
|
|
39
|
+
you recommend and write the decision (taken, rejected, why, date) on **both** the issue and the epic's
|
|
40
|
+
`## Decisions`. **Merging two epics is a different action, and nothing here proposes it.**
|
|
59
41
|
|
|
60
|
-
**An epic and its own parent do not produce the spread verdict
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
cyclic declaration, where there is no inner epic to pick. Stop only where the epics left are
|
|
64
|
-
genuinely too close to separate, which is the toss-up Tier B is for and is rare.
|
|
65
|
-
|
|
66
|
-
**The decision record is what pays for the autonomy** — without it the run has taken a decision
|
|
67
|
-
nobody can find afterwards.
|
|
42
|
+
**An epic and its own parent do not produce the spread verdict** — the issue goes to the inner epic.
|
|
43
|
+
**The narrowing drops parents, never peers**: an unrelated epic beside a nested chain, or a cyclic
|
|
44
|
+
declaration, still asks. Stop (Tier B) only where the epics left are genuinely too close to separate.
|
|
68
45
|
|
|
69
46
|
**Write both halves in the one call that places the issue: `pnpm josh epic --add <E> <N...>
|
|
70
|
-
--decision-file <path|->`.** It appends
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
decision" says what to do instead.
|
|
84
|
-
|
|
85
|
-
**Its sibling runs before the filing, not after it: `pnpm josh issue:scout "<title>"`.** That command
|
|
86
|
-
answers the same epic question for an issue that does not exist yet — this decision, called rather
|
|
87
|
-
than restated — and beside it the one thing this one deliberately refuses: whether the work has
|
|
88
|
-
already been filed, from a title comparison. **Both run**, and neither replaces the other:
|
|
89
|
-
`pnpm josh issue:file` runs the scout before it creates the issue, and `epic:bundle` afterwards, from
|
|
90
|
-
the real number and the relations recorded against it. Full behavior:
|
|
47
|
+
--decision-file <path|->`.** It appends to the epic's `## Decisions` and comments the same text on
|
|
48
|
+
each child added. **Never hand-edit the epic body to add the entry.** Refused before anything is
|
|
49
|
+
written:
|
|
50
|
+
|
|
51
|
+
- **A line that is *nothing but* a `#A -> #B` chain** — it would be read as a declaration. Quote the
|
|
52
|
+
order in backticks or a fenced block.
|
|
53
|
+
- **An empty record, or `--decision-file` with no usable path.**
|
|
54
|
+
|
|
55
|
+
For children the epic already tracks: `SKILL.md` → "Recording a decision".
|
|
56
|
+
|
|
57
|
+
**Its sibling runs before the filing: `pnpm josh issue:scout "<title>"`** — the same epic question for
|
|
58
|
+
an issue not yet filed, plus whether the work is already filed. **Both run**: `pnpm josh issue:file`
|
|
59
|
+
runs the scout before creating the issue and `epic:bundle` after. Full behavior:
|
|
91
60
|
`docs/josh-commands-backlog.md` → "`josh issue:file`".
|
|
92
61
|
|
|
93
62
|
**When the relation carries an order, record it** in `blocked-by` and in the epic's `Dependencies` —
|
|
94
|
-
on an addition as much as on a new epic.
|
|
95
|
-
not. An order **nobody declared is not invented**.
|
|
63
|
+
on an addition as much as on a new epic. An order **nobody declared is not invented**.
|