@erclx/canon 5.41.0 → 5.42.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/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/references/adopted.md +34 -14
- package/claude/skills/auto-ship/REQUIREMENT.md +1 -0
- package/claude/skills/auto-ship/SKILL.md +22 -2
- package/claude/skills/auto-ship/references/draft-mark.md +32 -6
- package/claude/skills/auto-ship/references/failure-recovery.md +15 -13
- package/claude/skills/auto-ship/references/tier-failures.md +31 -10
- package/claude/skills/auto-ship/references/ui-checklist.md +9 -4
- package/claude/skills/auto-ship/references/worktree-name.md +9 -3
- package/claude/skills/build-in-slices/references/adopted.md +35 -21
- package/claude/skills/canvas-board/references/canvas.md +17 -6
- package/claude/skills/canvas-board/references/design.md +26 -7
- package/claude/skills/code-craft/references/adopted.md +58 -20
- package/claude/skills/codebase-layout/references/adopted.md +49 -16
- package/claude/skills/codebase-layout/references/frontend.md +11 -4
- package/claude/skills/codebase-layout/references/tests.md +4 -2
- package/claude/skills/context-fold/references/classify.md +10 -15
- package/claude/skills/context-fold/references/completion-report.md +11 -9
- package/claude/skills/context-fold/references/context-refresh.md +26 -9
- package/claude/skills/context-fold/references/unusable-baseline.md +5 -3
- package/claude/skills/create-rule/REQUIREMENT.md +5 -0
- package/claude/skills/create-rule/SKILL.md +9 -1
- package/claude/skills/create-rule/references/checklist.md +26 -0
- package/claude/skills/create-rule/references/rule.md +98 -20
- package/claude/skills/create-skill/SKILL.md +1 -0
- package/claude/skills/create-skill/references/skill-disclosure.md +10 -2
- package/claude/skills/create-skill/references/skill-frontmatter.md +43 -0
- package/claude/skills/create-skill/references/skill-paths.md +7 -4
- package/claude/skills/create-skill/references/skill-practice.md +6 -3
- package/claude/skills/create-skill/references/skill-requirement.md +4 -2
- package/claude/skills/create-skill/references/skill.md +67 -44
- package/claude/skills/deploy-app/references/vercel.md +2 -1
- package/claude/skills/deprecation-migration/references/adopted.md +44 -25
- package/claude/skills/design-taste/references/adopted.md +9 -1
- package/claude/skills/design-taste/references/craft.md +3 -1
- package/claude/skills/design-taste/references/kinds.md +8 -7
- package/claude/skills/design-taste/references/preflight.md +12 -0
- package/claude/skills/design-taste/references/systems.md +7 -6
- package/claude/skills/design-taste/references/tells.md +24 -25
- package/claude/skills/design-taste/references/vocabulary.md +7 -5
- package/claude/skills/document-health/references/axes.md +54 -30
- package/claude/skills/draft-and-pick/references/live-arms.md +2 -2
- package/claude/skills/draft-doc/references/context.md +4 -3
- package/claude/skills/draft-doc/references/docs.md +6 -3
- package/claude/skills/draft-doc/references/readme/agent-facing.md +6 -0
- package/claude/skills/draft-doc/references/readme/application.md +8 -2
- package/claude/skills/draft-doc/references/readme/cli.md +5 -1
- package/claude/skills/draft-doc/references/readme/library.md +4 -0
- package/claude/skills/draft-doc/references/readme/plugin.md +9 -1
- package/claude/skills/draft-doc/references/readme.md +30 -13
- package/claude/skills/draft-doc/references/requirements.md +17 -4
- package/claude/skills/draft-doc/references/wiki-kind.md +20 -10
- package/claude/skills/draft-figure/references/architecture-set.md +7 -3
- package/claude/skills/draft-figure/references/figures.md +8 -6
- package/claude/skills/draft-figure/references/hand-drawn.md +3 -1
- package/claude/skills/draft-figure/references/mermaid-path.md +19 -9
- package/claude/skills/draft-figure/references/mermaid.md +10 -5
- package/claude/skills/draft-ready/references/ready.md +22 -15
- package/claude/skills/git-branch/references/branch.md +11 -1
- package/claude/skills/git-branch/references/slug.md +17 -5
- package/claude/skills/git-commit/references/commit.md +8 -0
- package/claude/skills/git-commit/references/versioning.md +23 -17
- package/claude/skills/git-followup/REQUIREMENT.md +1 -1
- package/claude/skills/git-followup/SKILL.md +5 -6
- package/claude/skills/git-issue/references/issue.md +29 -16
- package/claude/skills/git-pr/REQUIREMENT.md +1 -5
- package/claude/skills/git-pr/SKILL.md +11 -22
- package/claude/skills/git-pr/references/final-command.md +21 -8
- package/claude/skills/git-pr/references/labels.md +45 -28
- package/claude/skills/git-pr/references/pr.md +28 -9
- package/claude/skills/git-pr/references/publish.md +42 -28
- package/claude/skills/git-pr/references/task-number.md +20 -8
- package/claude/skills/git-ship/SKILL.md +1 -1
- package/claude/skills/plan-feature/references/plan-lifecycle.md +10 -3
- package/claude/skills/plan-feature/references/plan.md +57 -20
- package/claude/skills/plan-groundwork/references/groundwork-spikes.md +4 -1
- package/claude/skills/plan-groundwork/references/groundwork.md +14 -16
- package/claude/skills/plan-intake/references/intake.md +29 -24
- package/claude/skills/pr-evidence/REQUIREMENT.md +40 -0
- package/claude/skills/pr-evidence/SKILL.md +53 -0
- package/claude/skills/pr-evidence/references/evidence.md +150 -0
- package/claude/skills/review-address/references/post-review-findings.md +10 -3
- package/claude/skills/review-address/references/rebase-conflicts.md +15 -7
- package/claude/skills/review-address/references/rest-reads.md +3 -1
- package/claude/skills/review-craft/references/adopted.md +35 -18
- package/claude/skills/review-craft/references/security.md +42 -7
- package/claude/skills/review-craft/references/ui.md +23 -8
- package/claude/skills/review-pr/SKILL.md +6 -6
- package/claude/skills/review-pr/references/body-variants.md +29 -9
- package/claude/skills/review-pr/references/close-out.md +20 -5
- package/claude/skills/review-pr/references/key-changes.md +27 -3
- package/claude/skills/review-pr/references/post.md +83 -31
- package/claude/skills/review-pr/references/scope.md +54 -19
- package/claude/skills/review-ui/references/close-out.md +7 -5
- package/claude/skills/review-ui/references/driving.md +24 -4
- package/claude/skills/review-ui/references/post.md +43 -15
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +67 -17
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +80 -40
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +52 -15
- package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +48 -26
- package/claude/skills/role-orchestrator/references/orchestrator-inbound.md +12 -13
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +72 -36
- package/claude/skills/role-orchestrator/references/orchestrator-output.md +12 -4
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +64 -24
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +80 -26
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +41 -18
- package/claude/skills/role-orchestrator/references/orchestrator-resume.md +19 -7
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +22 -12
- package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +15 -6
- package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +25 -7
- package/claude/skills/role-orchestrator/references/orchestrator-watch.md +34 -8
- package/claude/skills/role-orchestrator/scripts/poll.ts +16 -24
- package/claude/skills/role-worker/REQUIREMENT.md +1 -0
- package/claude/skills/role-worker/SKILL.md +8 -0
- package/claude/skills/search-craft/references/adopted.md +18 -6
- package/claude/skills/session-map/references/session.md +26 -7
- package/claude/skills/session-worktree/references/main-root-writes.md +25 -8
- package/claude/skills/systematic-debugging/references/adopted.md +30 -16
- package/claude/skills/target-check/references/domains.md +39 -11
- package/claude/skills/target-setup/references/detect.md +80 -65
- package/claude/skills/target-setup/references/indexes.md +8 -6
- package/claude/skills/task-board/references/board.md +86 -30
- package/claude/skills/task-board/references/decline.md +29 -13
- package/claude/skills/task-board/references/tasks-decline.md +12 -5
- package/claude/skills/task-board/references/tasks.md +65 -33
- package/claude/skills/task-complete/references/archive.md +41 -17
- package/claude/skills/task-complete/references/receipt-sweep.md +23 -9
- package/claude/skills/task-complete/references/unusable-baseline.md +10 -3
- package/claude/skills/teach-workspace/references/glossary.md +6 -2
- package/claude/skills/teach-workspace/references/lesson-build.md +44 -16
- package/claude/skills/teach-workspace/references/lesson-craft.md +12 -7
- package/claude/skills/teach-workspace/references/pedagogy.md +6 -3
- package/claude/skills/teach-workspace/references/promotion-fold.md +17 -11
- package/claude/skills/teach-workspace/references/promotion.md +31 -8
- package/claude/skills/teach-workspace/references/revisit.md +8 -2
- package/claude/skills/teach-workspace/references/teach.md +17 -9
- package/claude/skills/test-craft/references/adopted.md +48 -14
- package/claude/skills/test-craft/references/component.md +7 -4
- package/claude/skills/test-craft/references/e2e.md +25 -7
- package/claude/skills/test-craft/references/unit.md +3 -1
- package/claude/skills/test-first/references/adopted.md +12 -4
- package/claude/skills/ui-checklist/REQUIREMENT.md +1 -1
- package/claude/skills/ui-checklist/SKILL.md +1 -1
- package/claude/skills/video-craft/references/adopted.md +62 -18
- package/claude/skills/write-human/references/adopted.md +21 -8
- package/docs/workflow/parallel-features.md +1 -1
- package/docs/workflow/skill-map.md +1 -0
- package/package.json +1 -1
- package/src/claude/cases/workflow.ts +5 -0
- package/src/commands/pr.ts +142 -28
- package/src/markdown/scope.ts +144 -0
- package/src/pr/lift.ts +6 -3
- package/src/pr/review-state.ts +182 -0
- package/claude/skills/git-pr/references/evidence.md +0 -124
|
@@ -7,45 +7,59 @@ description: Retirement act the wind-down owes the fleet it dispatched, the talk
|
|
|
7
7
|
|
|
8
8
|
Settle this act before writing the map. A session retired afterwards is one the map already listed as running, and the map is what the next session reads the fleet off.
|
|
9
9
|
|
|
10
|
-
The act reaches every session this one dispatched that no verb can decide. `canon worktrees reclaim` refuses a directory on any of seven conditions
|
|
10
|
+
The act reaches every session this one dispatched that no verb can decide. `canon worktrees reclaim` refuses a directory on any of seven conditions, and three are what this act turns on, being a merged pull request, a clean tree, and no live session holding the directory.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
- A running session trips the third whatever its branch did, and retiring it clears that one, so the retirement runs ahead of the reclaim
|
|
13
|
+
- A worker whose branch has not merged stays undecided once gone, refused on `no-merged-pull-request`
|
|
14
|
+
- A planner stays undecided too, refused as `main-worktree` with a null removal route, since it registers against the tree it was launched from
|
|
15
|
+
- Name the planner as the case always in this set, and scope the act no narrower, since a rule for planners alone leaves the unmerged worker unreached
|
|
15
16
|
|
|
16
17
|
### Which sessions this session may retire unasked
|
|
17
18
|
|
|
18
|
-
Retire what this session dispatched. Report a hand-launched session and leave the act to the operator, since
|
|
19
|
+
Retire what this session dispatched. Report a hand-launched session and leave the act to the operator, since what makes the act safe is a delivery this session received, and it received nothing from a session it never launched.
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
- The `worker-` and `planner-` name prefixes separate the two populations, per `orchestrator-launch.md`
|
|
22
|
+
- A capability gap sits beside that knowledge gap. A hand-launched session is often interactive, and `claude rm <id>` has no id to take for one.
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
### Talk sessions
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
A talk session is the exception inside the dispatched population. Retire it only on the operator's word, given here or carried in the session's own close message, and never on its delivery, at wind-down or any other point.
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
- Its plan landing or its pull request opening tells this session nothing about whether the conversation is over
|
|
29
|
+
- Until the word arrives, report it as held open next to the hand-launched read
|
|
30
|
+
- Find it by the `sessionId` the prior map records or this session's launch output carries, since the client can rename it and drop the `-talk` suffix
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
### Telling a delivered session from a blocked one
|
|
29
33
|
|
|
30
|
-
|
|
34
|
+
No status field carries the difference. `status` reads `busy` or `waiting` off the client record, both describing the last turn rather than the work, so `waiting` is the ordinary answer for a session that reported and stopped. `statusDwellMs` separates a long idle from a short one and nothing else.
|
|
31
35
|
|
|
32
|
-
|
|
36
|
+
The read is the report this session is holding. Retire a session whose delivery arrived here, and leave every other one for the operator.
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
- A plan at `.canon/plans/feature-<slug>.md` corroborates that report and never stands in for it, since a planner can stop on a question after writing it
|
|
39
|
+
- Retiring a blocked session destroys its context and nothing on disk records what it had read, so the act keeps, as the reclaim reading does
|
|
35
40
|
|
|
36
|
-
|
|
41
|
+
### The act, and the order it runs in
|
|
42
|
+
|
|
43
|
+
`claude rm <id>` is meant to remove a background session and its worktree together, though its own report is not reliable, so trust `canon worktrees list` afterward. It takes one target per call, so a wave costs one call per session.
|
|
37
44
|
|
|
38
|
-
|
|
45
|
+
- The argument is the id, which `claude agents --json` carries beside the name on every row, and the name form answers `No job matching`
|
|
46
|
+
- The command belongs to the client, so a target running another client performs whatever removal that client offers
|
|
47
|
+
- Run `canon worktrees reclaim` after the retirements, since it refuses on `held-by-session` and a reclaim taken first finds nothing left to do
|
|
48
|
+
- Report the retired sessions as a list, the hand-launched ones under it as a read rather than an act, and what the reclaim removed below both
|
|
39
49
|
|
|
40
50
|
## Write the map
|
|
41
51
|
|
|
42
|
-
Write the pre-compaction handoff as orchestrator. Invoke `canon:session-map` for the generic half,
|
|
52
|
+
Write the pre-compaction handoff as orchestrator. Invoke `canon:session-map` for the generic half, being the filename, the three core sections, the write procedure, the drift step and the ref it reads, and the citation rule. Everything in this section is the extension this role adds.
|
|
43
53
|
|
|
44
|
-
Settle all three steps below before the door writes, so one write carries the core and the extension together. The door
|
|
54
|
+
Settle all three steps below before the door writes, so one write carries the core and the extension together. The door's success line ends the generic half rather than this runbook, so a session stopping there ships a map missing everything this section adds.
|
|
45
55
|
|
|
46
|
-
1. Add `## Decisions taken under delegated authority` directly after `## State`, holding each decision and why it went that way, so nobody re-proposes it.
|
|
47
|
-
|
|
48
|
-
|
|
56
|
+
1. Add `## Decisions taken under delegated authority` directly after `## State`, holding each decision and why it went that way, so nobody re-proposes it.
|
|
57
|
+
- It sits there because a decision is read against the state it was taken in
|
|
58
|
+
2. Add `## Talk sessions held open` directly after that, one line per open talk session giving its name, its `sessionId`, and its row, or `None.`.
|
|
59
|
+
- The next session reads it to know which sessions it must not retire on a delivery
|
|
60
|
+
3. Close the file with the block below, resolving each runbook path to an absolute one as you write it.
|
|
61
|
+
- Paste `${CLAUDE_SKILL_DIR}/references/orchestrator-resume.md` resolved in place of `<RESUME_RUNBOOK>`
|
|
62
|
+
- Paste `${CLAUDE_SKILL_DIR}/references/orchestrator-poll.md` resolved in place of `<POLL_RUNBOOK>`
|
|
49
63
|
|
|
50
64
|
```markdown
|
|
51
65
|
Resume by loading the orchestrator skill and asking it to resume after a compaction. This repository spells that `/canon:role-orchestrator` followed by the request. Following <RESUME_RUNBOOK> reaches the same place with no skill loaded at all.
|
|
@@ -53,14 +67,22 @@ Resume by loading the orchestrator skill and asking it to resume after a compact
|
|
|
53
67
|
That resume reads the board and stops. It restarts nothing, so the review poll is a second thing owed here, and <POLL_RUNBOOK> holds the prompt and the condition. Do not reach for `session-resume`, which reads tracked work and reports the newest map without restarting this loop.
|
|
54
68
|
```
|
|
55
69
|
|
|
56
|
-
|
|
70
|
+
### Why these sections are the orchestrator's
|
|
71
|
+
|
|
72
|
+
The delegated-authority section is the orchestrator's alone because a worker holds no delegation to have exercised, and a section a session cannot fill teaches its reader to skip the file. The closing block is the orchestrator's because it restarts a review poll no other role runs.
|
|
73
|
+
|
|
74
|
+
- The substitution sits in step 3 because that step ends the write
|
|
75
|
+
- The variable expands while this runbook renders, never when the handoff is read back
|
|
76
|
+
- A path left unresolved reaches a session holding no skill as a string matching nothing. `orchestrator-poll.md` resolves its script at the same point.
|
|
57
77
|
|
|
58
|
-
|
|
78
|
+
### Why the block appears twice
|
|
59
79
|
|
|
60
|
-
That block sits
|
|
80
|
+
That block sits here and again in the file this runbook writes, which is the fix rather than a copy to collapse. A compaction that took the skill body took the routing to this runbook too, so the map carries the invocation itself, and each copy reaches a reader the other cannot.
|
|
61
81
|
|
|
62
|
-
The requirement is a resume request to the orchestrator skill with
|
|
82
|
+
- The requirement is a resume request to the orchestrator skill with it loaded first, and the command shown is this repository's spelling, not the only one
|
|
83
|
+
- The poll restart is named beside it because the resume performs none
|
|
84
|
+
- This runbook varies the door rather than replacing it, stating only what differs, so the two cannot disagree
|
|
63
85
|
|
|
64
|
-
|
|
86
|
+
## Where a lesson goes
|
|
65
87
|
|
|
66
|
-
This session commits nothing, and the orchestrator's boundaries forbid writing a context entry from it. A domain fact
|
|
88
|
+
This session commits nothing, and the orchestrator's boundaries forbid writing a context entry from it. A domain fact goes in the Findings of the task owning the surface, and so does a lesson about how to work, since nothing reads a lesson left only in the map once the next session is past it.
|
|
@@ -7,17 +7,16 @@ description: What each message from another session costs the orchestrator's con
|
|
|
7
7
|
|
|
8
8
|
Part of `role-orchestrator`'s `## Parallelism`. The session reads this file before widening a wave, since review attention is what binds the track count and this is what it costs.
|
|
9
9
|
|
|
10
|
-
Inbound turns are the third input to that judgment. Claude Code delivers a
|
|
11
|
-
message from another session as a new turn whenever this one sits idle, and the
|
|
12
|
-
turn carries the whole accumulated context rather than the few lines the worker
|
|
13
|
-
sent, so one handback from a wide wave costs more than the same handback from a
|
|
14
|
-
narrow one. A recurring review poll bills that window again on every interval it
|
|
15
|
-
fires. Weigh the spend before widening, since it lands on this session's context
|
|
16
|
-
and never on the worker's.
|
|
10
|
+
Inbound turns are the third input to that judgment. Claude Code delivers a message from another session as a new turn whenever this one sits idle, and the turn carries the whole accumulated context rather than the few lines the worker sent.
|
|
17
11
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
- One handback from a wide wave therefore costs more than the same handback from a narrow one
|
|
13
|
+
- A recurring review poll bills that window again on every interval it fires
|
|
14
|
+
- Weigh the spend before widening, since it lands on this session's context and never on the worker's
|
|
15
|
+
|
|
16
|
+
## The control left unset
|
|
17
|
+
|
|
18
|
+
`crossSessionInbound` is the control, on an `accept`, `hold`, `refuse` ladder, and it is deliberately not pulled. Read the ladder before turning concurrency up rather than after, and leave it unset.
|
|
19
|
+
|
|
20
|
+
- `hold` and `refuse` are the two values that bound the cost, and both break the handback this loop runs on
|
|
21
|
+
- A held message reaches nobody until a later `accept` applies, and a refused one is dropped outright
|
|
22
|
+
- `accept` bounds nothing
|
|
@@ -21,42 +21,62 @@ claude --bg --model <model> -n "worker-<project>-<slug>" "/canon:auto-ship <plan
|
|
|
21
21
|
Your controller is the session whose sessionId is <dispatcher-id>. Resolve its current name from that id through canon sessions list --json, which carries sessionId per row, at the moment you send, and never resolve an addressee by name prefix. Message it when the pull request opens, carrying the number, the branch, the head sha, the CI state, and every point you departed from the plan on, and message it again if you stop on a question."
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
`--bg, --background` starts the session as a background agent and returns immediately,
|
|
24
|
+
`--bg, --background` starts the session as a background agent and returns immediately, and `--model` overrides the inheritance `## Pick the model` states. `-n, --name` sets the display name that tells a self-dispatched worker from an operator's own launch in `canon sessions list`.
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
- Pass `-n` on every dispatch, since a launch omitting it names the session for a fragment of its identifier, its send address and all the operator sees
|
|
27
|
+
- The prefix reads `worker-` because that is the role it marks, since a prefix naming another role sends a worker filtering the roster to a sibling or itself
|
|
28
|
+
- Nothing matches the prefix programmatically, which keeps a rename down to three strings
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
### The project and the controller id
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
`<project>` is the basename of the main worktree root, resolved the way `session-worktree` Step 1 does, since `git rev-parse --show-toplevel` inside a linked worktree returns the worktree path. `claude agents` lists every session on the machine with no path column, so `<project>` is all that tells two fleets apart.
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
Read `<dispatcher-id>` with `canon sessions list --self --json` and interpolate the row's `sessionId`. Carry the id rather than the name, since a name can be renamed minutes after launch, inside the window a worker announces its pull request in.
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
- Where the installed CLI answers `--self` with an unknown option, read the `sessionId` from the record the client writes under its configuration directory
|
|
37
|
+
- Say which route answered, so the reader knows whether the id was read or inferred
|
|
35
38
|
|
|
36
|
-
|
|
39
|
+
### How the worker resolves the id
|
|
37
40
|
|
|
38
|
-
The
|
|
41
|
+
The worker resolves that id back to a name through `canon sessions list --json`, which carries `sessionId` per row. The agent listing prints a name and a short ref and no id, so a worker reaching for it first finds no lookup and can conclude there is none.
|
|
42
|
+
|
|
43
|
+
That failure is silent in both directions. The worker goes idle holding the message it owes, and nothing on this side reports the quiet, so the loss surfaces as a missing worktree or a pull request that never opens.
|
|
44
|
+
|
|
45
|
+
### No worktree call and no branch
|
|
46
|
+
|
|
47
|
+
The template carries no worktree call. `auto-ship` Step 0 invokes `canon:role-worker` and then `canon:session-worktree` itself, and neither carries the flag, so both are reachable through the `Skill` tool wherever a call sits in a prompt.
|
|
48
|
+
|
|
49
|
+
- The autoship call carries `<plan>`, the file `orchestrator-dispatch.md` read to derive the branch, so Step 1 takes it as the caller-supplied plan
|
|
50
|
+
- Step 0 runs `canon tasks plan-branch <plan>` on that file and hands the `<type>/<slug>` to `session-worktree` as its tier 0 argument
|
|
51
|
+
- The two sides agree by calling one derivation rather than copying a string, and only a binary lacking `plan-branch` derives by prose
|
|
39
52
|
|
|
40
53
|
### Position zero
|
|
41
54
|
|
|
42
|
-
Put a command whose skill carries `disable-model-invocation: true` at position zero of the launch prompt, followed by a space and its argument, with nothing before it. The client expands a slash command there as a user invocation, which is the route the flag permits.
|
|
55
|
+
Put a command whose skill carries `disable-model-invocation: true` at position zero of the launch prompt, followed by a space and its argument, with nothing before it. The client expands a slash command there as a user invocation, which is the route the flag permits.
|
|
43
56
|
|
|
44
|
-
|
|
57
|
+
- Anything reaching the session as prose falls to the model, which invokes it through the `Skill` tool, a route that answers a flagged skill inconsistently
|
|
58
|
+
- `auto-ship` carries the flag
|
|
59
|
+
- A comma or other punctuation glued to the command name at position zero has failed to expand, so treat the space as part of the rule
|
|
45
60
|
|
|
46
|
-
|
|
61
|
+
Never depend on the `Skill` tool route for a flagged skill. A refusal there tells the session not to replicate the workflow by other means, so a refused worker stops with a clean worktree, the correct outcome. The refusal is sticky inside a session, so recover by re-dispatching onto the same branch with the build template above.
|
|
47
62
|
|
|
48
|
-
|
|
63
|
+
### Shapes needing no expansion
|
|
64
|
+
|
|
65
|
+
The review-address and planning shapes below, and the reviewer shapes in `orchestrator-reviewer-launch.md`, depend on no expansion. None of `role-worker`, `review-address`, `role-planner`, `plan-feature`, `role-reviewer`, or `review-pr` carries the flag, so each keeps its leading word whatever the delimiter or position.
|
|
66
|
+
|
|
67
|
+
The same rule reaches a human relay. Hand an operator one message carrying one command at position zero, since two blocks pasted as separate messages can land as one, where the second never fires.
|
|
49
68
|
|
|
50
69
|
### What the brief may carry
|
|
51
70
|
|
|
52
71
|
The prompt carries pointers and standing context, and stops there. The branch and the plan stay arguments, because a skill resolves an argument through a documented ladder and reads no prose at all. What the prose reaches is the worker's judgment, so it holds only what a session has to weigh:
|
|
53
72
|
|
|
54
73
|
- Name the addressee and what it is owed, which the two message clauses above already do.
|
|
55
|
-
- Carry standing context
|
|
56
|
-
- Leave out anything scope-shaped
|
|
57
|
-
- On a reviewer launch, carry the sibling pull requests in flight, the files each shares with this one, the merge order, and a
|
|
74
|
+
- Carry standing context a cold session cannot derive, such as a constraint settled in conversation that never reached the plan
|
|
75
|
+
- Leave out anything scope-shaped, such as a file list, a naming convention, or a check, which belongs in the plan the review reads back against the diff
|
|
76
|
+
- On a reviewer launch, carry the sibling pull requests in flight, the files each shares with this one, the merge order, and a settled constraint, all as facts
|
|
77
|
+
- Leave out this session's read of the change and the author's argument, which cost the dispatch its independence, and any list of what to look for, which is `review-craft`'s
|
|
58
78
|
|
|
59
|
-
Report the dispatch as loudly as the human-launch line it replaces
|
|
79
|
+
Report the dispatch as loudly as the human-launch line it replaces, naming the branch, the model, the task, and the session name, so a person reading the transcript can follow what fired without watching it happen.
|
|
60
80
|
|
|
61
81
|
## Dispatch to a cloud worker
|
|
62
82
|
|
|
@@ -64,45 +84,59 @@ Read `${CLAUDE_SKILL_DIR}/references/orchestrator-cloud-launch.md` when `orchest
|
|
|
64
84
|
|
|
65
85
|
## Dispatch to address a review
|
|
66
86
|
|
|
67
|
-
`review-address` is a single pass, not a chain, so a launch naming it alone reaches no `role-worker` and
|
|
87
|
+
`review-address` is a single pass, not a chain, so a launch naming it alone reaches no `role-worker` and owes no message. Reach the role directly on this launch instead of wrapping a second chain around one skill.
|
|
68
88
|
|
|
69
|
-
The branch already exists
|
|
89
|
+
The branch already exists, so this shape skips the plan-derived name and takes `<branch>` off the pull request's own head ref. `<slug>` is the directory name of the original build's worktree, `.claude/worktrees/<slug>/`.
|
|
70
90
|
|
|
71
|
-
`EnterWorktree`
|
|
91
|
+
- Enter it with `EnterWorktree`'s `path` form when it is still there, or `git worktree add .claude/worktrees/<slug>/ <branch>` when it was cleaned up
|
|
92
|
+
- `EnterWorktree` refuses that path in the ordinary case, since the idle build session holds a harness-level lock the roster does not report
|
|
93
|
+
- Work in the folder directly with `Bash`, `Read`, and `Edit` instead of retrying the tool
|
|
72
94
|
|
|
73
95
|
```bash
|
|
74
96
|
claude --bg --model <model> -n "worker-<project>-<slug>" "Enter the worktree for <branch> at .claude/worktrees/<slug>/, creating it from that branch if the folder is gone. Run /canon:role-worker, then /canon:review-address. Your controller is the session whose sessionId is <dispatcher-id>, and your reviewer is the session whose sessionId is <reviewer-id>. Resolve each current name from its id through canon sessions list --json, which carries sessionId per row, at the moment you send, and never resolve an addressee by name prefix. Message the reviewer when the address pass finishes, asking it to re-review and carrying what was addressed and the PR's CI state, and send that to the controller instead when the reviewer's id resolves to no live session. Message the controller if you stop on a question."
|
|
75
97
|
```
|
|
76
98
|
|
|
77
|
-
`<dispatcher-id>`, `<model>`, and `<project>` resolve the same way the build shape resolves them above. `<reviewer-id>` is the sessionId the reviewer's own message carried, so a worker launched fresh answers the reviewer directly.
|
|
78
|
-
|
|
79
|
-
Take this shape wherever a review needs answering and no live session already holds the branch. Where one does, message it to run `review-address` instead, per the loop's own step 6, since a session already there needs no second one dispatched onto the same branch.
|
|
99
|
+
`<dispatcher-id>`, `<model>`, and `<project>` resolve the same way the build shape resolves them above. `<reviewer-id>` is the sessionId the reviewer's own message carried, so a worker launched fresh answers the reviewer directly.
|
|
80
100
|
|
|
81
|
-
|
|
101
|
+
- Where no local reviewer is live, as a cloud reviewer always leaves, drop the reviewer clause and send the finished message to the controller
|
|
102
|
+
- Take this shape wherever a review needs answering and no live session holds the branch. Where one does, message it per the loop's step 6.
|
|
103
|
+
- That check is blind to a session working through the direct-path fallback, since it never moves its registered branch off `main`
|
|
104
|
+
- `canon sessions list --branch` then reports nothing holding the branch, so a dispatch landing there collides with nothing the check can see
|
|
82
105
|
|
|
83
106
|
## Dispatch to plan a row
|
|
84
107
|
|
|
85
|
-
`plan-feature` is a procedure rather than a role, so a launch naming it alone reaches no `role-planner` and
|
|
108
|
+
`plan-feature` is a procedure rather than a role, so a launch naming it alone reaches no `role-planner` and owes no message. Reach the role directly, the way the build shape reaches `role-worker`, rather than retyping its obligations as prose.
|
|
86
109
|
|
|
87
|
-
No branch and no worktree exist here and none is created. A planner writes one gitignored file at the main worktree root, so this shape names the row's task file
|
|
110
|
+
No branch and no worktree exist here and none is created. A planner writes one gitignored file at the main worktree root, so this shape names the row's task file and opens with the role.
|
|
111
|
+
|
|
112
|
+
- That write meets the isolation guard as a linked worktree's main-root write does, with no worktree to redirect it to
|
|
113
|
+
- `role-planner` therefore sends it as a `Bash` heredoc rather than through `Write`
|
|
88
114
|
|
|
89
115
|
```bash
|
|
90
116
|
claude --bg --model <model> -n "planner-<project>-<slug>" "Run /canon:role-planner, then /canon:plan-feature <task>. Your controller is the session whose sessionId is <dispatcher-id>. Resolve its current name from that id through canon sessions list --json, which carries sessionId per row, at the moment you send, and never resolve an addressee by name prefix. Message it when the plan lands, carrying the path and what the task file got wrong, and message it again if you stop on a question."
|
|
91
117
|
```
|
|
92
118
|
|
|
93
|
-
`<task>` is the row's task file path and `<slug>` the slug its plan will take, resolved off the row
|
|
119
|
+
`<task>` is the row's task file path and `<slug>` the slug its plan will take, resolved off the row. `<dispatcher-id>`, `<model>`, and `<project>` resolve as above, and the prefix reads `planner-` because it marks the role of the session it names.
|
|
94
120
|
|
|
95
|
-
|
|
121
|
+
### Which checks bind
|
|
96
122
|
|
|
97
|
-
|
|
123
|
+
None of the three checks in `orchestrator-dispatch.md` binds this shape.
|
|
98
124
|
|
|
99
|
-
|
|
125
|
+
- The branch check has no candidate to read
|
|
126
|
+
- The conflict check has nothing to compare, since a planner writes one file no track in flight can hold
|
|
127
|
+
- The plan-answer gate reaches no plan, since the planner writes the file a build later reads, so running it would refuse every planning dispatch
|
|
100
128
|
|
|
101
|
-
|
|
129
|
+
What a planning dispatch owes instead is the reverse reading, since a row planned during a wave is planned against a tree that wave is changing. `role-planner` composes the session roster with the pull request list itself, which is why the brief carries no branch list.
|
|
130
|
+
|
|
131
|
+
### One row per dispatch
|
|
102
132
|
|
|
103
|
-
A
|
|
133
|
+
A session reused across a batch pays the context load once and ages its picture of the tree while it works, which is why the in-flight read sits on the task rather than the batch. One that compacts mid-batch loses the reasoning behind its earlier plans with nothing reporting it.
|
|
134
|
+
|
|
135
|
+
Cap a reused session where the saving is worth it and say what the cap was.
|
|
136
|
+
|
|
137
|
+
## Dispatch a talk session
|
|
104
138
|
|
|
105
|
-
|
|
139
|
+
A planner or worker the operator will talk with takes the same launch as its cold shape above, with a `-talk` suffix on its name and one sentence added to its brief. A cold session works alone and reports back, and a talk session stays open after its plan or pull request lands so the operator can keep shaping the row.
|
|
106
140
|
|
|
107
141
|
```bash
|
|
108
142
|
claude --bg --model <model> -n "planner-<project>-<slug>-talk" "Run /canon:role-planner, then /canon:plan-feature <task>. This is a talk session: the operator will talk with you here, so run your role's talk clause, and message your controller when the operator ends the conversation. Your controller is the session whose sessionId is <dispatcher-id>. ..."
|
|
@@ -112,13 +146,15 @@ This is a talk session: the operator will talk with you here, so run your role's
|
|
|
112
146
|
|
|
113
147
|
The ellipsis stands for the rest of the cold template's message clauses, unchanged. The build variant keeps `/canon:auto-ship <plan>` at position zero with nothing before it, per the rule above.
|
|
114
148
|
|
|
115
|
-
Keep the role prefix and add the suffix
|
|
149
|
+
- Keep the role prefix and add the suffix, since `orchestrator-handoff.md` separates dispatched sessions by `worker-` and `planner-` and a new prefix reads as a hand launch
|
|
150
|
+
- A talk session is retired only on the operator's word, stated once in `orchestrator-handoff.md`, so do not restate it in a launch report
|
|
151
|
+
- Reviewers get no talk shape, since a reviewer's pass holds no operator dialogue
|
|
116
152
|
|
|
117
|
-
|
|
153
|
+
### Recording the talk session
|
|
118
154
|
|
|
119
|
-
|
|
155
|
+
Read the session's `sessionId` off the launch output, carry it in this session's own context, and write it into the map's `## Talk sessions held open` at the next handoff. The client can rename a session and drop the suffix, so the id is the durable marker and the suffix is only for display.
|
|
120
156
|
|
|
121
|
-
|
|
157
|
+
The map exists only once the handoff writes it, so this session's own launches, read with the prior map, are what the first wind-down reads talk sessions from.
|
|
122
158
|
|
|
123
159
|
## Dispatch a reviewer
|
|
124
160
|
|
|
@@ -37,11 +37,16 @@ Next: <the single most useful action>
|
|
|
37
37
|
|
|
38
38
|
Omit any section with nothing in it. Recommend a handoff only for a plan the conflict check in `orchestrator-dispatch.md` holds behind no track already in flight, and name any paths it shares with one.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
- The block opens on the board rather than a version, since no committed file states one and a version line would restate the rows, dated by nothing
|
|
41
|
+
- Leave a plan out of `Ready to build` once a row in flight names it, since its file stays in `.canon/plans/` for the whole build
|
|
42
|
+
- Listing it would recommend handing off work underway, and the conflict check withdraws that only for a reader who knows what is running
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
### In flight
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
`In flight` covers the state between the other two, which lasts ten to thirty minutes and is most of what an operator sees once this session dispatches its own workers.
|
|
47
|
+
|
|
48
|
+
- Read the progress figures off each worker's worktree, since a busy status says a session is alive and nothing about whether it is moving
|
|
49
|
+
- Name the model, because a dispatcher now picks one per row
|
|
45
50
|
|
|
46
51
|
## Every later turn
|
|
47
52
|
|
|
@@ -56,6 +61,9 @@ Decisions:
|
|
|
56
61
|
Next: <the single most useful action>
|
|
57
62
|
```
|
|
58
63
|
|
|
59
|
-
Keep the detail below the block and keep it skippable. A decision reached at the bottom of three paragraphs has been buried, which is the failure this shape exists to prevent.
|
|
64
|
+
Keep the detail below the block and keep it skippable. A decision reached at the bottom of three paragraphs has been buried, which is the failure this shape exists to prevent.
|
|
65
|
+
|
|
66
|
+
- Reuse the vocabulary above rather than inventing a second one
|
|
67
|
+
- Keep a file set on the row claiming it, so the reader can check a hold or a shared-path claim instead of taking it
|
|
60
68
|
|
|
61
69
|
Write no shape for a correction. A correction is a sentence, and a format for admitting error invites ceremony where plainness is the whole value.
|
|
@@ -5,69 +5,109 @@ description: Re-testing every parked blocker against the current tree, the two t
|
|
|
5
5
|
|
|
6
6
|
Re-test every parked row as orchestrator. A blocker cell is a measurement taken the day the row was parked and nothing re-takes it, so a row can wait on a condition that stopped holding weeks earlier with no surface reporting the gap.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## Triggers
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Two triggers start this pass, and they differ in scope rather than in procedure.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
| Trigger | Scope |
|
|
13
|
+
| ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
14
|
+
| `orchestrator-sweep.md` sends the rows `canon tasks validate` listed untested | Those rows alone, since a merge changes the tree under every parked row and the validator already re-took the two kinds it settles |
|
|
15
|
+
| An idle session, with nothing merged, workers building, and no pull request awaiting a first pass | Every parked row, since no event narrowed them, plus every `backlog.md` row, which carries no blocker cell for the validator to name |
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
- Neither trigger is a scheduler. `orchestrator-poll.md` owns the one recurring trigger, and a second loop firing into a static board is the always-on failure it warns about.
|
|
18
|
+
- The sweep asks which parked row to promote next, taking the blocker cell as read, and this pass asks whether the cell is still true
|
|
19
|
+
- A session collapsing the two runs whichever it remembers and re-tests nothing
|
|
15
20
|
|
|
16
21
|
## Scope
|
|
17
22
|
|
|
18
|
-
Every row under `## Up next` and `## Needs a plan` in `.canon/tasks/priority.md
|
|
23
|
+
Every row under `## Up next` and `## Needs a plan` in `.canon/tasks/priority.md`, plus every row in `.canon/tasks/backlog.md` on the idle trigger when the file exists. A `## Run now` row carries no blocker, so the pass skips it. Resolve the board, the backlog, and each task file at the main worktree root, the way `session-worktree` does.
|
|
19
24
|
|
|
20
|
-
Take the board rows in board order and finish one before opening the next
|
|
25
|
+
- Take the board rows in board order and finish one before opening the next, since clearing a row changes what the next row holds behind
|
|
26
|
+
- A pass that measures every row first and writes afterwards writes against a board it has already invalidated
|
|
27
|
+
- On the idle trigger, walk the backlog after the board in filename order, since `${CLAUDE_SKILL_DIR}/../task-board/references/board.md` fixes it as unordered
|
|
21
28
|
|
|
22
29
|
## Re-testing a row
|
|
23
30
|
|
|
24
31
|
The blocker cell states what the row waits on, and each kind is tested differently. `canon tasks validate` already re-takes the first two and reports the rest as untested, so run it first and re-take by hand only what it names.
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
### A hold behind a track in flight
|
|
34
|
+
|
|
35
|
+
The validator tests the file the cell cites against the Touches column of every `## Run now` row. A track that merged since the row was parked is no longer in flight, whatever the sets still share.
|
|
36
|
+
|
|
37
|
+
- Re-test the cell under the conflict check in `orchestrator-dispatch.md` too, since a row parked on a shared file alone holds on nothing and moves up
|
|
38
|
+
- A cell naming the file in prose rather than backticks cites nothing, so rewrite the hold in the board's spelling and the next run picks it up
|
|
39
|
+
|
|
40
|
+
### A dependency on another task
|
|
41
|
+
|
|
42
|
+
The validator opens the task a link in the cell names. One whose outcomes are all `[x]`, one already archived, or one already declined holds nothing. A cell naming the task in prose resolves to no file, so open it by hand and rewrite the cell as a link.
|
|
43
|
+
|
|
44
|
+
### The other three kinds
|
|
45
|
+
|
|
46
|
+
These the validator reports untested, and each takes its own handling.
|
|
47
|
+
|
|
28
48
|
- A condition about the tree, such as a count of some shape or the presence of a construct: measure it again, per Two ways a re-test goes wrong below.
|
|
29
49
|
- Waiting on a plan: nothing external holds the row, so the pass writes the plan rather than testing anything. See The plan half below.
|
|
30
|
-
- Waiting on an operator action, such as a run
|
|
50
|
+
- Waiting on an operator action, such as a run from a shell: record it as untestable this pass and name what the operator has to do, since re-measuring it is waste
|
|
31
51
|
|
|
32
|
-
|
|
52
|
+
### Writing the result
|
|
33
53
|
|
|
34
|
-
|
|
54
|
+
Every measurement this pass takes decides whether a row can start rather than how big it is. Sizing a row is the filing boundary `role-orchestrator` states under `## Boundaries`, which leaves the extent and the cause to whoever plans it.
|
|
55
|
+
|
|
56
|
+
Write the result into the row, since a re-test reported in chat is lost at the next compaction and measured again.
|
|
57
|
+
|
|
58
|
+
- Rewrite a blocker cell whose test no longer holds, and move the row to the group its new state puts it in
|
|
59
|
+
- Record the measurement in the task's `## Findings` as a line labeled with this session and the date, per `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md`
|
|
60
|
+
- `### Writing the board` in `role-orchestrator` owns the method, and `canon tasks validate` runs once the board is rewritten and before the report
|
|
35
61
|
|
|
36
62
|
## Re-testing a backlog row
|
|
37
63
|
|
|
38
|
-
A backlog row carries no blocker cell, since `${CLAUDE_SKILL_DIR}/../task-board/references/board.md` fixes `backlog.md` as a flat list of links with no state of its own.
|
|
64
|
+
A backlog row carries no blocker cell, since `${CLAUDE_SKILL_DIR}/../task-board/references/board.md` fixes `backlog.md` as a flat list of links with no state of its own. This pass asks the standard's board-or-backlog question instead, whether the work in front of the row landed or the world changed under it.
|
|
65
|
+
|
|
66
|
+
- Read the answer from the task file's `## Findings` and its origin line, `Plan:`, `Groundwork:`, `Intake:`, or `Issue:`
|
|
67
|
+
- Clearing a row answers yes, never a count of how long it waited, since age is refused as evidence here on the same ground as for a board row
|
|
68
|
+
- This pass only clears a row upward. Declining or archiving a backlog row is `backlog-triage`.
|
|
39
69
|
|
|
40
|
-
|
|
70
|
+
### Moving a cleared row
|
|
41
71
|
|
|
42
|
-
A row
|
|
72
|
+
A cleared row moves out of `backlog.md` onto the bottom of `## Needs a plan`, with a `Waiting on` cell stating what changed and ending with the word `last`.
|
|
43
73
|
|
|
44
|
-
|
|
74
|
+
- `canon tasks validate`'s ordering check reads `last` as the ordinal the bottom placement claims
|
|
75
|
+
- A cell stating only what changed matches neither the ordinal nor the rank reading, raising a finding against the pass's own row
|
|
76
|
+
- The next refill sweep's promotion step still orders the row against the rest of that heading, per step 5 under `## Refilling the ready queue` in `role-orchestrator`
|
|
45
77
|
|
|
46
78
|
## Two ways a re-test goes wrong
|
|
47
79
|
|
|
48
80
|
Both return a confident wrong answer rather than an error, which is why each gets a step of its own.
|
|
49
81
|
|
|
50
|
-
|
|
82
|
+
### Reading the condition looser than the code
|
|
83
|
+
|
|
84
|
+
A row parked on a count of some shape names a shape its consumer defines precisely, and a count by eye or by an approximate pattern lands elsewhere. The row that motivated this runbook counted 19 instances of a shape whose real count under the consumer's definition was zero.
|
|
51
85
|
|
|
52
86
|
Find the code that consumes the shape, read the definition off it, and measure with that. A count taken any other way is not evidence about the blocker.
|
|
53
87
|
|
|
54
|
-
|
|
88
|
+
### Measuring against the wrong tree
|
|
55
89
|
|
|
56
|
-
|
|
90
|
+
A command that ships to targets is at risk in corpora this repository never formats, so a condition measured here reads as unreachable while it stays live where the command runs. Ask which tree the condition is about before asking what the count is.
|
|
57
91
|
|
|
58
|
-
|
|
92
|
+
A local formatter removing the shape on contact says nothing about a target running no such formatter.
|
|
59
93
|
|
|
60
|
-
|
|
94
|
+
## The plan half
|
|
61
95
|
|
|
62
|
-
|
|
96
|
+
Plan what the pass clears, and any `## Needs a plan` row whose only blocker is the missing plan. This pass runs while workers build and the session is idle, when planning costs the critical path nothing, and a row cleared with no plan is looked at again next pass.
|
|
63
97
|
|
|
64
|
-
|
|
98
|
+
- Run `plan-feature` for each, carrying the constraint per in-flight track that `## The loop` in `role-orchestrator` requires
|
|
99
|
+
- Verify each plan against the tree the way that step does, since several branches are already changing it
|
|
100
|
+
- Stop where `## Parallelism` stops, since a plan the conflict check holds behind every track in flight is one nobody can dispatch
|
|
101
|
+
- Do not restate the refill procedure. `orchestrator-refill.md` owns it, so this pass promotes through that method.
|
|
65
102
|
|
|
66
103
|
## Two results that are not a re-test
|
|
67
104
|
|
|
68
|
-
|
|
105
|
+
Neither result below justifies moving a row.
|
|
69
106
|
|
|
70
|
-
|
|
107
|
+
- Age is not evidence. `role-orchestrator` refuses to promote a task to fill the queue, so a row whose blocker still holds stays, reported as still parked against this pass's measurement.
|
|
108
|
+
- A scoping defect can wear a blocker. A task conflicting with every other through a contract everything consumes or a sweep over everything is oversized, not blocked.
|
|
109
|
+
- Split such a task so each piece holds behind fewer tracks, since planning it again produces the same undispatchable plan
|
|
110
|
+
- A task that merely shares files with everything is not this case
|
|
71
111
|
|
|
72
112
|
## Output
|
|
73
113
|
|