@erclx/canon 5.27.0 → 5.29.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/draft-ready/SKILL.md +3 -1
- package/claude/skills/git-pr/references/evidence.md +1 -1
- package/claude/skills/review-address/REQUIREMENT.md +4 -2
- package/claude/skills/review-address/SKILL.md +16 -7
- package/claude/skills/review-address/references/rebase-conflicts.md +4 -2
- package/claude/skills/review-craft/references/ui.md +4 -4
- package/claude/skills/review-ui/REQUIREMENT.md +2 -2
- package/claude/skills/review-ui/SKILL.md +13 -11
- package/claude/skills/review-ui/references/driving.md +8 -8
- package/claude/skills/review-ui/references/post.md +19 -7
- package/claude/skills/review-ui/references/tick.md +22 -0
- package/claude/skills/role-orchestrator/REQUIREMENT.md +15 -15
- package/claude/skills/role-orchestrator/SKILL.md +24 -26
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +18 -16
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +12 -2
- package/claude/skills/role-orchestrator/references/orchestrator-inbound.md +1 -1
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +1 -1
- package/claude/skills/role-orchestrator/references/orchestrator-output.md +4 -4
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +5 -5
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +11 -2
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +6 -6
- package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +2 -2
- package/claude/skills/role-orchestrator/scripts/poll.ts +304 -10
- package/claude/skills/role-planner/REQUIREMENT.md +1 -1
- package/claude/skills/role-planner/SKILL.md +2 -2
- package/claude/skills/role-reviewer/SKILL.md +1 -1
- package/claude/skills/role-worker/SKILL.md +3 -2
- package/claude/skills/ui-checklist/SKILL.md +1 -1
- package/docs/agents/canvas.md +12 -4
- package/docs/agents/gate.md +3 -1
- package/docs/agents/index.md +2 -1
- package/docs/agents/pr-evidence.md +15 -14
- package/docs/agents/pr-tick.md +72 -0
- package/docs/agents/sandbox.md +2 -2
- package/docs/agents/tasks-plans.md +1 -1
- package/docs/agents/tasks-validate.md +18 -18
- package/docs/agents/tasks.md +1 -1
- package/docs/workflow/operating-model.md +10 -15
- package/docs/workflow/parallel-features.md +7 -7
- package/package.json +1 -1
- package/src/audits/baseline.ts +1 -1
- package/src/audits/run.ts +1 -1
- package/src/canvas/capture.ts +1 -1
- package/src/canvas/client/app.tsx +105 -4
- package/src/canvas/client/inspector/field.tsx +61 -2
- package/src/canvas/client/inspector/fields.css +78 -0
- package/src/canvas/client/inspector/token-select.tsx +109 -0
- package/src/canvas/client/inspector/values.ts +74 -2
- package/src/canvas/client/inspector.tsx +134 -15
- package/src/canvas/client/keys.ts +71 -0
- package/src/canvas/client/pages-panel.tsx +5 -1
- package/src/canvas/client/panel-handle.tsx +90 -0
- package/src/canvas/client/selection.tsx +3 -1
- package/src/canvas/client/shell.css +194 -4
- package/src/canvas/client/state.ts +255 -11
- package/src/canvas/client/surface.tsx +231 -18
- package/src/canvas/client/tools.tsx +153 -0
- package/src/canvas/content.ts +66 -1
- package/src/canvas/edit.ts +207 -25
- package/src/canvas/history.ts +116 -0
- package/src/canvas/server.ts +119 -13
- package/src/canvas/tokens.ts +1 -1
- package/src/claude/seeds.ts +2 -2
- package/src/claude/skills-reach.ts +1 -1
- package/src/{exec.ts → cli/exec.ts} +2 -2
- package/src/{help.ts → cli/help.ts} +1 -1
- package/src/cli.ts +1 -1
- package/src/commands/audits.ts +9 -1
- package/src/commands/autoship.ts +1 -1
- package/src/commands/canvas.ts +2 -2
- package/src/commands/capture.ts +1 -1
- package/src/commands/census.ts +1 -1
- package/src/commands/claude.ts +5 -5
- package/src/commands/comments.ts +1 -1
- package/src/commands/context.ts +1 -1
- package/src/commands/demo.ts +9 -1
- package/src/commands/deps.ts +1 -1
- package/src/commands/design.ts +12 -4
- package/src/commands/docs.ts +2 -2
- package/src/commands/driver.ts +9 -1
- package/src/commands/feedback.ts +3 -3
- package/src/commands/gate.ts +10 -3
- package/src/commands/gov.ts +3 -3
- package/src/commands/indexes.ts +1 -1
- package/src/commands/init.ts +11 -3
- package/src/commands/intake.ts +1 -1
- package/src/commands/inventory.ts +9 -1
- package/src/commands/labels.ts +1 -1
- package/src/commands/markdown.ts +1 -1
- package/src/commands/migrate.ts +2 -2
- package/src/commands/pr.ts +324 -9
- package/src/commands/records.ts +1 -1
- package/src/commands/repo.ts +1 -1
- package/src/commands/sandbox.ts +11 -14
- package/src/commands/secrets.ts +9 -1
- package/src/commands/sessions.ts +1 -1
- package/src/commands/slides.ts +2 -2
- package/src/commands/standards.ts +1 -1
- package/src/commands/sync.ts +3 -3
- package/src/commands/targets.ts +1 -1
- package/src/commands/tasks.ts +20 -3
- package/src/commands/teach.ts +1 -1
- package/src/commands/tooling.ts +2 -2
- package/src/commands/transcripts.ts +2 -2
- package/src/commands/upgrade.ts +2 -2
- package/src/commands/wiki.ts +2 -2
- package/src/commands/worktrees.ts +1 -1
- package/src/context/architecture.ts +1 -1
- package/src/context/citations.ts +2 -2
- package/src/context/classify/extract.ts +1 -1
- package/src/context/folders.ts +2 -2
- package/src/context/requirements.ts +1 -1
- package/src/docs/read.ts +1 -1
- package/src/feedback/github.ts +1 -1
- package/src/gate/measures.ts +2 -2
- package/src/gate/sequencer.ts +55 -3
- package/src/gate/stages.ts +8 -0
- package/src/gate/suite-lock.ts +214 -0
- package/src/init/run.ts +1 -1
- package/src/intake/folder.ts +1 -1
- package/src/labels/map.ts +1 -1
- package/src/labels/phase.ts +3 -3
- package/src/migrate/record-layout.ts +1 -1
- package/src/migrate/records.ts +11 -11
- package/src/migrate/rename.ts +1 -1
- package/src/migrate/scratch-evidence.ts +1 -1
- package/src/migrate/surface-roots.ts +6 -6
- package/src/pr/evidence.ts +188 -16
- package/src/pr/tick.ts +56 -0
- package/src/process/harness.ts +1 -1
- package/src/records/backup.ts +1 -1
- package/src/records/ordinal.ts +1 -1
- package/src/records/prune.ts +1 -1
- package/src/records/size.ts +1 -1
- package/src/records/stale-canonical.ts +1 -1
- package/src/records/stale.ts +1 -1
- package/src/records/validate.ts +2 -2
- package/src/{project-root.ts → roots/project.ts} +2 -2
- package/src/{record-root.ts → roots/record.ts} +1 -1
- package/src/sandbox/coverage.ts +11 -12
- package/src/sandbox/equivalence.ts +57 -26
- package/src/sandbox/headless/run.ts +1 -1
- package/src/sandbox/hooks.ts +1 -1
- package/src/sandbox/provision.ts +79 -29
- package/src/sandbox/scenario.ts +588 -0
- package/src/serve/report.ts +1 -1
- package/src/sessions/live.ts +4 -1
- package/src/sessions/transfer/bundle.ts +1 -1
- package/src/slides/decks.ts +1 -1
- package/src/standards/read.ts +1 -1
- package/src/sync/engine.ts +2 -2
- package/src/sync/git.ts +1 -1
- package/src/sync/layout.ts +2 -2
- package/src/sync/stamp.ts +1 -1
- package/src/sync/workflow.ts +1 -1
- package/src/targets/validate.ts +2 -2
- package/src/tasks/answers.ts +1 -1
- package/src/tasks/archive.ts +1 -1
- package/src/tasks/label.ts +1 -1
- package/src/tasks/reach.ts +1 -1
- package/src/tasks/validate.ts +38 -14
- package/src/teach/nav.ts +1 -1
- package/src/teach/workspace.ts +1 -1
- package/src/tooling/inject.ts +2 -2
- package/src/tooling/read.ts +1 -1
- package/src/tooling/scan.ts +1 -1
- package/src/tooling/verify-stack.ts +1 -1
- package/src/version/installed.ts +1 -1
- package/src/version/skew.ts +1 -1
- package/standards/board.md +3 -3
- package/standards/plan.md +13 -7
- package/tsconfig.json +1 -1
- /package/src/{cli-run.ts → cli/run.ts} +0 -0
- /package/src/{ui.ts → cli/ui.ts} +0 -0
- /package/src/{legacy-path.ts → roots/legacy.ts} +0 -0
- /package/src/{surface-root.ts → roots/surface.ts} +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Orchestrator dispatch runbook
|
|
3
|
-
description: The plan-answer gate, the collision check before a self-dispatch, the
|
|
3
|
+
description: The plan-answer gate, the collision check before a self-dispatch, the conflict check against the tracks in flight and the evidence it rests on, the branch and model the launch names, the fallback to a human launch, and the loop's stopping condition
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Run this at loop step 4, for a `## Run now` row whose plan is verified, in place of handing the worktree to a human. The
|
|
6
|
+
Run this at loop step 4, for a `## Run now` row whose plan is verified, in place of handing the worktree to a human. The conflict check below is where that row is tested against every track in flight, and it is the one statement of what holds a row there.
|
|
7
7
|
|
|
8
8
|
## Contents
|
|
9
9
|
|
|
@@ -11,7 +11,7 @@ Run this at loop step 4, for a `## Run now` row whose plan is verified, in place
|
|
|
11
11
|
- [Check the plan waits on nobody](#check-the-plan-waits-on-nobody)
|
|
12
12
|
- [Check the branch is unclaimed](#check-the-branch-is-unclaimed)
|
|
13
13
|
- [Hold what this pass already launched](#hold-what-this-pass-already-launched)
|
|
14
|
-
- [Check the
|
|
14
|
+
- [Check for a conflict with the tracks in flight](#check-for-a-conflict-with-the-tracks-in-flight)
|
|
15
15
|
- [Pick the model](#pick-the-model)
|
|
16
16
|
- [Pick local or cloud](#pick-local-or-cloud)
|
|
17
17
|
- [Dispatch](#dispatch)
|
|
@@ -47,7 +47,7 @@ Branch on `launchable` rather than on the exit code, which a shell function wrap
|
|
|
47
47
|
|
|
48
48
|
This gate runs ahead of the two collision checks because it is the cheapest reading of the three, needing no roster and no ref, and because it is the only one asking about the row itself rather than about what else is in flight. A row nobody can launch does not need testing against the tracks already out.
|
|
49
49
|
|
|
50
|
-
It also reads the plan rather than a cell describing one, which is the input the gate below it does not have. The
|
|
50
|
+
It also reads the plan rather than a cell describing one, which is the input the gate below it does not have. The conflict check reads the sets a dispatcher wrote into the constraints and the Touches column, so a cell omitting a renamed or relocated path clears a check the tree would fail, and what catches it then is a worker's message rather than any check.
|
|
51
51
|
|
|
52
52
|
A blank `- Answer:` is not an unanswered question. `${CLAUDE_SKILL_DIR}/../../standards/plan.md` fixes an empty slot as accepting the `- Suggested:` line above it, which is what makes a plan decision-ready in one pass. The narrow case this reads is `- Suggested: needs your call, <why>` and its two demonstrated paraphrases, `needs operator's call` and `needs the operator's call`, over an empty slot, the form that same standard writes where the answer turns on preference rather than on a technical default. A gate reading every blank slot as open would refuse every plan in the folder.
|
|
53
53
|
|
|
@@ -58,7 +58,7 @@ What it prevents is a halt nobody is watching for. `role-worker` instructs a ses
|
|
|
58
58
|
Run `canon sessions list --branch <type>/<slug> --json` and read `claimed` off the record.
|
|
59
59
|
|
|
60
60
|
- `claimed: true`: the row is not free. Report what holds it, `worktree` when it names a path, `sessions` when it carries a row, and `refs` when the branch already exists. Move to the next candidate rather than colliding.
|
|
61
|
-
- `claimed: false`, `sessionsReadable: true`, and `refsReadable: true`: proceed to the
|
|
61
|
+
- `claimed: false`, `sessionsReadable: true`, and `refsReadable: true`: proceed to the conflict check.
|
|
62
62
|
- `claimed: false` with either flag false, or the command refuses, or the record carries no `claimed` key (`reason` reads `no-registry` or `no-repository`): treat the candidate as unverified rather than clear. Report which reading could not be taken and fall back to the human-launch line below. Dispatching on a check that could not be read reproduces the exact collision this exists to prevent.
|
|
63
63
|
|
|
64
64
|
Reading `claimed` off the record is what keeps this a check rather than a rule a session can talk itself out of. The field is already the composed answer across the worktree listing, the live session roster, and the refs that name the branch, so nothing here re-derives the OR.
|
|
@@ -77,21 +77,23 @@ A worker registers with `branch: main` and the main worktree as its `cwd` until
|
|
|
77
77
|
|
|
78
78
|
Keep the branch of every row this pass has launched and treat a candidate matching one as claimed, without re-running the check. That closes the window for this dispatcher and only for it. A second dispatcher in another session reads git and the roster alone, sees none of this record, and can still take the same row. Say so when reporting, rather than implying the window is shut.
|
|
79
79
|
|
|
80
|
-
## Check the
|
|
80
|
+
## Check for a conflict with the tracks in flight
|
|
81
81
|
|
|
82
|
-
No count binds this
|
|
82
|
+
No count binds this, and a shared file does not either. Hold a candidate behind a track in flight when any of these five holds, naming the hold and the track, and dispatch it otherwise:
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
1. Dependency. The row or plan cites the track as something it waits on or builds over, including a stacked slice based on the other's branch.
|
|
85
|
+
2. Contract. One plan changes a contract the other consumes, such as an exported signature, a CLI verb's flags or JSON record, a skill step another skill cites, or a config or frontmatter key, read off the changing plan's `**Risks:**`.
|
|
86
|
+
3. Relocation. One plan moves, renames, splits, or deletes a path the other writes or reads, which a rebase cannot settle mechanically. Both sides of a rename sit before the colon of a `**Files to touch:**` entry, per `${CLAUDE_SKILL_DIR}/../../standards/plan.md`.
|
|
87
|
+
4. Sweep. One plan rewrites a file or folder wholesale, such as a terminology pass or a `canon/context/` reflow, and the other writes inside it.
|
|
88
|
+
5. A stated reason, written on the hold: a singleton resource, or tracks interacting where no file reading shows, as a row creating a skill does with one counting that catalog. Nothing verifies the reason, so this hold stands only while the dispatcher applies it.
|
|
85
89
|
|
|
86
|
-
|
|
90
|
+
A shared file with none of the five is not a hold. Dispatch both and name the shared paths, so the merge order and the second branch's rebase are planned rather than discovered. The branch merging second resolves after the first merges, never against a sibling still building, by running `review-address` in the session that built it, whose Step 5 rebases the branch once it no longer merges. A hunk needing a decision the tree does not carry goes to the controller, and a branch no live session holds gets the review-address shape in `orchestrator-launch.md`.
|
|
87
91
|
|
|
88
|
-
|
|
92
|
+
No practitioner source serializes on a shared file. Each builds in parallel and tests at integration, where the merge surfaces a textual conflict and the suite run over the merged result surfaces a semantic one. Fowler's [branching patterns](https://martinfowler.com/articles/branching-patterns.html) have whoever integrates second pull mainline in and check health "even if it's a clean merge", his [Semantic Conflict](https://martinfowler.com/bliki/SemanticConflict.html) names self-testing code as the first defense, [DORA](https://dora.dev/capabilities/trunk-based-development/) keeps branches to a few hours, and GitHub's [merge queue](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue) tests each pull request against everything queued ahead of it. A candidate has no commits to trial-merge, so `git merge-tree` runs at integration and this check reads what a plan declares.
|
|
89
93
|
|
|
90
|
-
|
|
94
|
+
Read `canon sessions list --json` for the branches in flight as well as the board, since a track a person launched by hand carries no row, and read the plan of any branch no row names. `canon tasks validate` and `canon tasks plan-reach` report the paths two rows share, which is a candidate list for the five holds and the paths the dispatch names. A shared folder means a Touches cell claimed it bare, so narrow that cell rather than reading the folder as a sweep.
|
|
91
95
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
What binds past that is review attention rather than a count, and `## Parallelism` in the skill body states it along with the cap an operator can set for a session. The one number this skill carries is the review dispatch's count of three in `orchestrator-review-dispatch.md`, which moves a review rather than binding a track, and this runbook carries none.
|
|
96
|
+
A declared set predicts what a branch writes rather than bounding it, since `canon:context-fold`, `canon:docs-sync`, and the regenerated drift stages write past every plan. Such a crossing changes what the second branch rebases over rather than whether a row holds, and `canon tasks plan-reach` at `canon:git-ship` step 5 names it before the pull request opens. What binds past the five holds is review attention, which `## Parallelism` in the skill body states. The one number this skill carries is the review dispatch's count of three in `orchestrator-review-dispatch.md`, which moves a review rather than binding a track, and this runbook carries none.
|
|
95
97
|
|
|
96
98
|
## Pick the model
|
|
97
99
|
|
|
@@ -111,9 +113,9 @@ Read `${CLAUDE_SKILL_DIR}/references/orchestrator-launch.md` once every check ab
|
|
|
111
113
|
|
|
112
114
|
## Fall back to the human
|
|
113
115
|
|
|
114
|
-
Hand the row to the human-launch line in step 4 instead of dispatching when any of these hold, and name which one: the plan still waits on the operator, the plan-answer read could not be taken, the collision check refused, the row
|
|
116
|
+
Hand the row to the human-launch line in step 4 instead of dispatching when any of these hold, and name which one: the plan still waits on the operator, the plan-answer read could not be taken, the collision check refused, or the row holds behind a track already out under the conflict check, on a dependency, a contract, a relocation, a sweep, or a stated reason. A shared file alone is not on that list.
|
|
115
117
|
|
|
116
|
-
The first of those
|
|
118
|
+
The first of those four is the one that reaches a person rather than the board. A row held on its branch or under the conflict check waits on the wave clearing, where a row held on its plan waits on an answer only the operator can give, so hand that one over with the question label and its stated reason attached rather than as a name and a refusal.
|
|
117
119
|
|
|
118
120
|
Hand the person one command: `/canon:auto-ship <plan>`, naming the row, the plan path, and the branch together, with no worktree call ahead of it. A leading worktree call adds nothing beyond what `auto-ship` Step 0 already reaches for itself. A second command also risks a client folding two commands into one message, which reads everything after the first command's name as its own argument and drops the second, per `### Position zero` in `orchestrator-launch.md`.
|
|
119
121
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Orchestrator handback runbook
|
|
3
|
-
description: Addressing the session that answers a posted review, what to report when none is live, and where a worker's reply is placed by what it changes
|
|
3
|
+
description: Addressing the session that answers a posted review, the rebase handback a stale or conflicted branch earns, what to report when none is live, and where a worker's reply is placed by what it changes
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Read this at loop step 6, once a review pass has posted anything owed and the session holding that branch is to run `review-address`.
|
|
6
|
+
Read this at loop step 6, once a review pass has posted anything owed or the poll reports a branch stale or conflicted, and the session holding that branch is to run `review-address`.
|
|
7
7
|
|
|
8
8
|
## Sending the handback
|
|
9
9
|
|
|
@@ -13,6 +13,16 @@ Read this at loop step 6, once a review pass has posted anything owed and the se
|
|
|
13
13
|
- Name the skill for the reader to run rather than writing an invocation, which arrives as text
|
|
14
14
|
- Read the pull request's own draft flag rather than the state a worker reports, and report what the read returned and when rather than the state alone. `canon docs pr-reads` states why a reported field can lag and say nothing about it. The flag settles the question only once the worker's chain has run its undo, and nothing marks that moment, so a read taken between the pull request opening and that call sees a genuinely ready pull request about to become a draft and has told an operator the opposite of what the worker had said.
|
|
15
15
|
|
|
16
|
+
## The rebase handback
|
|
17
|
+
|
|
18
|
+
A `STALE` or `CONFLICT` from the poll goes to the branch's own session the same way, with `review-address` as the skill to run, since its staleness test rebases a branch `main` moved under even when the merge is clean. Name what merged under the branch, being the pull request that landed and the files the poll listed, so the worker reads those hunks first rather than re-deriving them from `git log`.
|
|
19
|
+
|
|
20
|
+
Say that a check failing after a clean rebase is a semantic conflict to fix on the branch, and that a hunk needing a decision the tree does not carry comes back as a message rather than as a guess. A pull request carrying review findings as well earns one message naming both, since one `review-address` run answers them together.
|
|
21
|
+
|
|
22
|
+
The worker that built the branch rebases it, not this session. It holds the plan behind each hunk, and a rebase made here would also write a branch this session does not own.
|
|
23
|
+
|
|
24
|
+
## Re-review and reachability
|
|
25
|
+
|
|
16
26
|
A re-review goes back to the reviewer that took the first pass. Find a live `reviewer-<project>-<number>` for that pull request through `canon sessions list --json` by name and message it to re-run `review-pr`. When none is live, launch a fresh reviewer through the reviewer shape in `orchestrator-reviewer-launch.md` or review in place, under the same trigger `orchestrator-review-dispatch.md` states, rather than messaging a name that no longer answers.
|
|
17
27
|
|
|
18
28
|
A session is reachable when it appears in a live listing, which reads what each session registered on disk rather than probing it, and a message carries plain text and no authority. When no live session holds the branch, report the invocation for the human, naming the branch, the pull request, and the skill to run, then stop. Retrying or waiting leaves the loop believing it is open while nothing acts on it.
|
|
@@ -5,7 +5,7 @@ description: What each message from another session costs the orchestrator's con
|
|
|
5
5
|
|
|
6
6
|
# What an inbound turn costs
|
|
7
7
|
|
|
8
|
-
Part of `role-orchestrator`'s `## Parallelism`. The session reads this file before widening a wave, since
|
|
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
10
|
Inbound turns are the third input to that judgment. Claude Code delivers a
|
|
11
11
|
message from another session as a new turn whenever this one sits idle, and the
|
|
@@ -83,7 +83,7 @@ claude --bg --model <model> -n "planner-<project>-<slug>" "Run /canon:role-plann
|
|
|
83
83
|
|
|
84
84
|
`<task>` is the row's task file path and `<slug>` the slug its plan will take, resolved off the row the way the build shape resolves one off a plan. `<dispatcher-id>`, `<model>`, and `<project>` resolve the same way they do above. The prefix reads `planner-` for the reason the worker's reads `worker-`, which is that it marks the role of the session it names rather than the one that launched it.
|
|
85
85
|
|
|
86
|
-
None of the three checks in `orchestrator-dispatch.md` binds this shape. The branch check has no candidate to read, and the
|
|
86
|
+
None of the three checks in `orchestrator-dispatch.md` binds this shape. The branch check has no candidate to read, and the conflict check has nothing to compare, since a planner writes one file no track in flight can hold. The plan-answer gate reaches no plan at all, because the planner is dispatched to write the file a build would later read, so running it here would refuse every planning dispatch over a plan nobody has written yet.
|
|
87
87
|
|
|
88
88
|
What a planning dispatch owes instead is the reverse reading, because the plan it produces carries a constraint per track in flight and 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 for that read rather than reading pull requests alone, which is why the brief carries no branch list for it: the planner takes this reading itself either way.
|
|
89
89
|
|
|
@@ -30,16 +30,16 @@ In review (your turn):
|
|
|
30
30
|
PR #<n> <title>
|
|
31
31
|
→ /review-pr
|
|
32
32
|
|
|
33
|
-
Merge order: #<a> before #<b> (shared
|
|
33
|
+
Merge order: #<a> before #<b> (shared paths: <files>).
|
|
34
34
|
|
|
35
35
|
Next: <the single most useful action>
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Omit any section with nothing in it. Recommend a handoff only for a plan
|
|
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
|
`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. Read the progress figures off each worker's worktree rather than from the worker, since a busy status says a session is alive and nothing about whether it is moving, and name the model because a dispatcher now picks one per row.
|
|
41
41
|
|
|
42
|
-
Leave a plan out of `Ready to build` once a row in flight names it. The plan file stays in `.canon/plans/` for the whole build, so listing it there recommends handing off work already underway, and the
|
|
42
|
+
Leave a plan out of `Ready to build` once a row in flight names it. The plan file stays in `.canon/plans/` for the whole build, so listing it there recommends handing off work already underway, and the conflict check withdraws the recommendation only for a reader who already knows what is running.
|
|
43
43
|
|
|
44
44
|
The block opens on the board rather than on a version, because no committed file states one, and a version line would restate what a reader can already see on the rows, dated by nothing.
|
|
45
45
|
|
|
@@ -56,6 +56,6 @@ Decisions:
|
|
|
56
56
|
Next: <the single most useful action>
|
|
57
57
|
```
|
|
58
58
|
|
|
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. Reuse the vocabulary above rather than inventing a second one, and keep a file set on the row claiming it so the reader can check a
|
|
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. Reuse the vocabulary above rather than inventing a second one, and 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
60
|
|
|
61
61
|
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.
|
|
@@ -17,13 +17,13 @@ The sweep's own question stays distinct from this one. It asks which parked row
|
|
|
17
17
|
|
|
18
18
|
Every row under `## Up next` and `## Needs a plan` in `.canon/tasks/priority.md`. A `## Run now` row carries no blocker by definition, so the pass skips it. On the idle trigger, also every row in `.canon/tasks/backlog.md` when the file exists, per the trigger split above. Resolve the board, the backlog, and each task file at the main worktree root, the way `session-worktree` does.
|
|
19
19
|
|
|
20
|
-
Take the board rows in board order and finish one before opening the next. Clearing a row changes what the next row
|
|
20
|
+
Take the board rows in board order and finish one before opening the next. Clearing a row changes what the next row holds behind, so a pass that measures every row first and writes afterwards writes against a board it has already invalidated. On the idle trigger, walk the backlog after the board, in the file's own filename order, since `${CLAUDE_SKILL_DIR}/../../standards/board.md` fixes that file as unordered and nothing about a row's position there means anything to preserve mid-pass.
|
|
21
21
|
|
|
22
22
|
## Re-testing a row
|
|
23
23
|
|
|
24
24
|
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
25
|
|
|
26
|
-
-
|
|
26
|
+
- A hold behind a track in flight: 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. 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. A cell naming the file in prose rather than in backticks cites nothing, so write the hold the way the board format spells it and the check picks the row up on the next run.
|
|
27
27
|
- A dependency on another task: 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.
|
|
28
28
|
- 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
29
|
- Waiting on a plan: nothing external holds the row, so the pass writes the plan rather than testing anything. See The plan half below.
|
|
@@ -59,7 +59,7 @@ Plan what the pass clears, and plan any `## Needs a plan` row whose only blocker
|
|
|
59
59
|
|
|
60
60
|
Run `plan-feature` for each, carrying the constraint per in-flight track that `## The loop` in `role-orchestrator` requires. Verify each plan against the tree the way that step does, since a plan written now is written against a tree several branches are already changing.
|
|
61
61
|
|
|
62
|
-
Stop where `## Parallelism` stops rather than planning every row the pass cleared. A plan
|
|
62
|
+
Stop where `## Parallelism` stops rather than planning every row the pass cleared. A plan the conflict check holds behind every track in flight is one nobody can dispatch.
|
|
63
63
|
|
|
64
64
|
Do not restate the refill procedure. `orchestrator-refill.md` owns it and `orchestrator-sweep.md` wraps it for a batch of merges, so this pass promotes through that method rather than a second one.
|
|
65
65
|
|
|
@@ -67,7 +67,7 @@ Do not restate the refill procedure. `orchestrator-refill.md` owns it and `orche
|
|
|
67
67
|
|
|
68
68
|
Age is not evidence. A row untouched for weeks invites promotion, and the waiting is not an argument for it. `role-orchestrator` refuses to promote a task to fill the queue and this pass inherits that refusal, so a row whose blocker still holds stays where it is. Reporting it as still parked, against a measurement taken this pass, is a result.
|
|
69
69
|
|
|
70
|
-
A scoping defect can wear a blocker. A task
|
|
70
|
+
A scoping defect can wear a blocker. A task conflicting with every other by construction, through a contract everything consumes or a sweep over everything, is oversized rather than blocked, and planning it again produces the same plan nobody can dispatch. Split it so each piece holds behind fewer tracks, and the board stops carrying a row that re-measures the same way every pass. A task that merely shares files with everything is not this case.
|
|
71
71
|
|
|
72
72
|
## Output
|
|
73
73
|
|
|
@@ -77,7 +77,7 @@ Cleared: <row>, now <group>, plan at <path>
|
|
|
77
77
|
Declined: <row>, waited on <task> which was declined, now <group>
|
|
78
78
|
Still parked: <row>, <blocker> re-confirmed against <what was measured>
|
|
79
79
|
Untestable: <row>, waits on <operator action>
|
|
80
|
-
Split: <task> into <tasks>,
|
|
80
|
+
Split: <task> into <tasks>, conflicted with everything by contract or sweep
|
|
81
81
|
Backlog cleared: <row>, now bottom of ## Needs a plan, waiting on <what changed>
|
|
82
82
|
Still backlogged: <row>, <what was checked> found unchanged
|
|
83
83
|
```
|
|
@@ -39,10 +39,11 @@ Poll GitHub for pull request movement by running `bun <POLL_SCRIPT>`, then act o
|
|
|
39
39
|
- OPENED, or a pull request with no prior review pass: take its first pass where the review dispatch runbook of the canon:role-orchestrator skill places it, running the canon:review-pr skill here or launching a reviewer. A draft counts, since every pull request here opens as one and skipping drafts skips everything.
|
|
40
40
|
- SEEN: report it and stop. A pass already covers that head, whether it arrived out of band or before the poll first saw the pull request, so no review follows.
|
|
41
41
|
- STALLED: read the last pass and report what it carried. The pass has sat open for hours with nothing following it, so a worker mid-task is already ruled out and the dispatch either never went out or the session holding it is gone. Confirm and re-send it under the dispatch rule below, whatever grades the pass carried. Do not re-run a review to correct the heading, since a pass on an unchanged head with no response behind it stops by design.
|
|
42
|
-
- CONFLICT:
|
|
42
|
+
- CONFLICT or STALE: send the session holding that branch the rebase handback in the canon:role-orchestrator skill's handback runbook, resolving it the way the handback rule below does. The branch owner rebases, not this session. The poll prints one of the two for a pull request, never both, so it earns one message. Hold the draft lift on it until `bun <POLL_SCRIPT> --check <number>` prints CLEAR, since its green run tested a main that no longer exists.
|
|
43
|
+
- OVERLAP: report the pair and the files, and settle their merge order now under the Parallelism rule of the canon:role-orchestrator skill. Dispatch nobody. The second to merge reads STALE or CONFLICT once the first lands, and the handback goes out then.
|
|
43
44
|
- UNMATCHED: report it and stop. A comment posted under a heading outside the known set reaches nobody automatically, so a person decides whether to answer it by hand or the set needs a ninth heading.
|
|
44
45
|
- UI-OPEN: dispatch the canon:review-address skill under the rule below, the same as an open code pass. A later RESPONSE re-sends the UI reviewer too.
|
|
45
|
-
- UI-CLOSED: report it, and lift the draft mark only once the code review is closed too.
|
|
46
|
+
- UI-CLOSED: report it, and lift the draft mark only once the code review is closed too and `bun <POLL_SCRIPT> --check <number>` prints CLEAR.
|
|
46
47
|
- UI-STALE: the UI verdict trails the head. Message the live UI reviewer to drive the new head, or launch one, and lift no mark on it.
|
|
47
48
|
- GONE: report it, then sweep the board by invoking the canon:role-orchestrator skill and following its queue-refill sweep.
|
|
48
49
|
- A line starting `poll:`: report it verbatim and treat that pull request as unread this run. It is a failed query, not a state.
|
|
@@ -69,6 +70,14 @@ The eight headings the script knows are written by `review-pr`, `review-address`
|
|
|
69
70
|
|
|
70
71
|
The state reaches every stalled dispatch, since one threshold governs the heading and the dispatch alike and a pass carrying anything posts the open heading. A minors-only pass therefore reports here on the same terms as a blocking one, which widens the state from what it caught while the two were split. It stays a heading test rather than a count test, so nothing here pins the summary line, which is a second string this script does not own.
|
|
71
72
|
|
|
73
|
+
### Base movement
|
|
74
|
+
|
|
75
|
+
A pull request's run tests the merge with the base as of its last push, so once a sibling merges, that green describes a merge nobody will make. `STALE` closes that gap by hand where a ruleset requiring branches to be current, or a merge queue, would close it on the host. It fires when the base changed a file the pull request writes since the commit it branched from, and names the files. A base that moved only on files the branch does not write reads as nothing, since re-testing after every merge is a merge queue's cost without its batching.
|
|
76
|
+
|
|
77
|
+
`STALE` and `CONFLICT` each report on their transition and again on every push that leaves the reading standing, then live only in the baseline, which is as old as the last run. Read a standing one with `--check <number>`, which fetches the base and reads the head at call time, so a sibling merging after the last run still shows, and prints `CONFLICT`, `STALE`, `CLEAR`, or `UNKNOWN`, writing nothing. A pull request whose written set could not be read, being a fork or a deleted head, reads as `UNKNOWN` rather than clear, so its lift waits on a person.
|
|
78
|
+
|
|
79
|
+
`OVERLAP` names two open pull requests that conflict with each other, read by merging their heads locally. Only pairs sharing a written path are tried, which keeps a wave of ten to a handful of merges. It reports once per pair, carried in the tenth baseline field, so the merge order is settled before the second branch has to rebase rather than after.
|
|
80
|
+
|
|
72
81
|
### The count behind the review dispatch
|
|
73
82
|
|
|
74
83
|
The report is also where the load count in `orchestrator-review-dispatch.md` is legible, and that count decides where a first pass runs, here or in a dispatched reviewer. That threshold trips on open pull requests awaiting a first pass, which is what `OPENED` and a pull request with no prior pass name here and what `SEEN` excludes, so read the count off these lines rather than off the open list, which counts a branch closed out and waiting on a merge the same as one nobody has read. It is a separate condition from the poll-start fallback above, which decides when this loop runs rather than where a review runs.
|
|
@@ -19,16 +19,16 @@ It counts unclaimed plans against workers rather than reading the reserve in ste
|
|
|
19
19
|
4. Read `.canon/tasks/priority.md` and count entries under its `## Run now` heading that carry a written plan. Keep one in reserve beyond what is running.
|
|
20
20
|
5. Promote from the top of `## Needs a plan`, which is where the last sweep recorded what to plan next. Depart from that order when something has changed under it and say what changed, since a position nobody honors is the ordering going stale on the surface built to hold it. What sets the order in the first place is whether a task establishes functionality rather than how old it is, so prefer a task that adds or proves a mechanism over one that trims, tidies, or audits an existing surface.
|
|
21
21
|
- Re-take the demotion half of the board-or-backlog call while the file is open. A row that has stopped being near-term moves to `backlog.md`, one line removed from `priority.md` and written there, per the standard's test. The promotion half is `orchestrator-parked.md`'s to run as a full walk over every backlog row, so this step does not repeat it. A row that pass clears already sits at the bottom of `## Needs a plan` before this sweep reads the heading.
|
|
22
|
-
6. Before promoting a candidate,
|
|
23
|
-
- A candidate held by something outside the tree stays where it is whatever
|
|
22
|
+
6. Before promoting a candidate, test it against every task already running under the conflict check in `orchestrator-dispatch.md`. Serialize it behind a task only on one of that check's holds, and name the hold. A path the two merely share is promoted beside it, named so the merge order plans the rebase.
|
|
23
|
+
- A candidate held by something outside the tree stays where it is whatever the check shows. A conflict is one of the reasons a task cannot start, so clearing the check clears that reason alone and leaves an external condition standing.
|
|
24
24
|
7. Write a plan for each newly promoted task with `plan-feature`, carrying the in-flight constraint that `## The loop` in the skill body states, then report:
|
|
25
25
|
|
|
26
26
|
```plaintext
|
|
27
27
|
Capture: owed since <the last handoff, or session start when none has run>
|
|
28
28
|
Findings placed: <finding> → <destination>
|
|
29
29
|
Archived: <task>
|
|
30
|
-
Promoted: <task>, touches <surfaces>, parallel with <task
|
|
31
|
-
Serialized: <task> behind <task>,
|
|
30
|
+
Promoted: <task>, touches <surfaces>, parallel with <task>, sharing <paths or none>
|
|
31
|
+
Serialized: <task> behind <task>, held on <dependency, contract, relocation, sweep, or reason>
|
|
32
32
|
Backlogged: <task>, because <what stopped being near-term>
|
|
33
33
|
Ready now: <tasks with plans, and what each waits on>
|
|
34
34
|
```
|
|
@@ -37,7 +37,7 @@ The capture row states a standing debt rather than a per-run result. Running cap
|
|
|
37
37
|
|
|
38
38
|
That block is the detail. Lead the reply with the three slots under `## Every later turn` in `orchestrator-output.md`, so the human reads what they own before the evidence for it.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
A task that edits `canon/context/` entries wholesale is a sweep under the conflict check, and holds every other task, because the root instruction file requires each task to update its own domain entry as it lands.
|
|
41
41
|
|
|
42
42
|
Do not promote a task to fill the queue when nothing qualifies. A thin queue is a real answer and it beats a plan nobody needed.
|
|
43
43
|
|
|
@@ -49,7 +49,7 @@ Promoting, demoting, and archiving a row all write `.canon/tasks/priority.md`, a
|
|
|
49
49
|
- Write both halves of a move before reporting it. A row removed from one surface and not written to the other leaves a task file nothing names, and the folder is gitignored with no history to recover the row from. `canon tasks validate` reports that state, so run it after any move.
|
|
50
50
|
- Put the reason a row sits where it does in its Waiting on cell. Position is the ordering and the cell is where the ordering's rationale lives, so a row promoted with the cell left alone carries an order the next sweep cannot check.
|
|
51
51
|
- Put a pointer in the Plan column, never prose. `## Run now` claims a written plan covers every open outcome, and `auto-ship` refuses at its guard when it follows the column and finds no plan, which spends a worker dispatch to learn what the row should have said.
|
|
52
|
-
- Name the file set in the Touches column.
|
|
52
|
+
- Name the file set in the Touches column. It feeds the merge order and the shared paths a dispatch names, and the hold call in step 6 is only checkable later when the sets are written down rather than reasoned once and discarded.
|
|
53
53
|
- Re-resolve every Plan pointer after anything archives a plan
|
|
54
54
|
- Read the file back after writing it, since the row that lands is the row a worker acts on
|
|
55
55
|
|
|
@@ -12,10 +12,10 @@ Sweep the board as orchestrator after merging. Run this once per batch of merges
|
|
|
12
12
|
|
|
13
13
|
Run `canon worktrees list` after the pull, which is the first point at which the merges this sweep followed are readable. It owns the reclaim rule and it removes nothing, so read its rows and act on the ones you mean to. Never substitute a git ancestry check for it.
|
|
14
14
|
|
|
15
|
-
Run `canon tasks validate` once the board is rewritten and before reporting it. It resolves every plan pointer, accounts every task file against the board and the backlog both,
|
|
15
|
+
Run `canon tasks validate` once the board is rewritten and before reporting it. It resolves every plan pointer, accounts every task file against the board and the backlog both, reports the paths `## Run now` rows share as a candidate list for the conflict check, and re-takes the two blocker kinds a command can settle. It reports and never writes, so fix each row it names and run it again. A finding it reports is a board defect rather than a task finding, so it goes nowhere but the board.
|
|
16
16
|
|
|
17
17
|
Then run `orchestrator-parked.md` over the rows the validator listed as untested. Those carry the three blocker kinds no command settles, and the merge this sweep followed changed the tree under every one of them at once while the refill above re-read none. Take the untested rows alone rather than the whole board, since the validator already answered the rest.
|
|
18
18
|
|
|
19
19
|
Place every finding the merged work produced before promoting anything. A finding that changes a rule goes to the standard or the rule that states it, one that changes another task goes to that task's Findings, and one that overturns a groundwork lean gets marked answered in that folder. A pull request body counts as nowhere, since the thread stops being read the moment it merges.
|
|
20
20
|
|
|
21
|
-
Report what closed, what moved, and what is ready to hand a worker. Name the file set each ready task touches, so the reader can check the
|
|
21
|
+
Report what closed, what moved, and what is ready to hand a worker. Name the file set each ready task touches and the hold or shared paths it carries, so the reader can check the conflict call rather than take it.
|