@erclx/canon 5.13.0 → 5.14.1
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/SKILL.md +3 -2
- package/claude/skills/deprecation-migration/REQUIREMENT.md +62 -0
- package/claude/skills/deprecation-migration/SKILL.md +115 -0
- package/claude/skills/deprecation-migration/references/adopted.md +50 -0
- package/claude/skills/git-followup/REQUIREMENT.md +1 -0
- package/claude/skills/git-followup/SKILL.md +3 -0
- package/claude/skills/git-pr/REQUIREMENT.md +1 -0
- package/claude/skills/git-pr/SKILL.md +1 -1
- package/claude/skills/git-pr/references/evidence.md +2 -2
- package/claude/skills/git-ship/REQUIREMENT.md +3 -0
- package/claude/skills/git-ship/SKILL.md +12 -1
- package/claude/skills/review-pr/SKILL.md +1 -1
- package/claude/skills/review-pr/references/close-out.md +1 -1
- package/claude/skills/review-pr/references/post.md +1 -1
- package/claude/skills/review-ui/REQUIREMENT.md +5 -2
- package/claude/skills/review-ui/SKILL.md +12 -4
- package/claude/skills/review-ui/references/driving.md +5 -3
- package/claude/skills/review-ui/references/post.md +3 -2
- package/claude/skills/role-orchestrator/SKILL.md +1 -1
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +10 -10
- package/claude/skills/role-orchestrator/scripts/poll.ts +628 -0
- package/claude/skills/role-orchestrator/scripts/repo.ts +69 -0
- package/claude/skills/role-orchestrator/scripts/watch.ts +267 -0
- package/docs/agents/commands.md +1 -1
- package/docs/agents/index.md +1 -0
- package/docs/agents/markdown-audit.md +1 -1
- package/docs/agents/pr-evidence.md +5 -0
- package/docs/agents/pr-frames.md +112 -0
- package/docs/agents/pr-reads.md +1 -1
- package/docs/agents/sandbox.md +3 -3
- package/docs/agents/state-scoped-risk.md +2 -2
- package/docs/workflow/skill-map.md +15 -14
- package/package.json +4 -5
- package/scripts/core/check-color-source.sh +11 -1
- package/scripts/core/install-check.sh +13 -4
- package/scripts/lib/sandbox-dispatch.sh +1 -1
- package/scripts/lib/sandbox-fixtures.sh +2 -2
- package/scripts/lib/sandbox-path.sh +1 -1
- package/scripts/manage-sandbox.sh +2 -2
- package/src/claude/cases/misc.ts +5 -0
- package/src/claude/skills-audit.ts +1 -0
- package/src/commands/pr.ts +452 -0
- package/src/commands/sandbox.ts +2 -2
- package/src/context/architecture.ts +5 -2
- package/src/context/citations.ts +1 -1
- package/src/gate/boundaries.ts +509 -0
- package/src/gate/measures.ts +8 -19
- package/src/gate/stages.ts +12 -28
- package/src/pr/frames.ts +323 -0
- package/src/sandbox/census.ts +1 -1
- package/src/sandbox/coverage.ts +1 -1
- package/src/sandbox/expect.ts +0 -1
- package/src/shipped/references.ts +8 -10
- package/src/targets/pulls.ts +2 -2
- package/src/tooling/manifest.ts +2 -3
- package/src/tooling/seeds.ts +37 -0
- package/tooling/claude/manifest.toml +3 -3
- package/tsconfig.json +1 -1
- package/claude/skills/role-orchestrator/scripts/poll.sh +0 -504
- package/claude/skills/role-orchestrator/scripts/watch.sh +0 -181
- package/scripts/core/check-capability-seeding.sh +0 -134
- package/scripts/core/check-ignore-parity.sh +0 -141
- package/scripts/core/check-plugin-boundary.sh +0 -45
- package/scripts/core/check-seed-independence.sh +0 -62
- package/scripts/core/check-skill-paths.sh +0 -24
- package/scripts/core/list-seed-roots.sh +0 -18
- package/scripts/lib/tooling.sh +0 -37
|
@@ -42,10 +42,10 @@ Every observable behavior becomes a dependency once there are enough callers, wh
|
|
|
42
42
|
## Change additively
|
|
43
43
|
|
|
44
44
|
- Add a field, a flag, or a parameter as optional, with a default that keeps the old behavior.
|
|
45
|
-
- Never rename or remove anything in place. Add the new name beside the old one, keep both working, and remove the old one only once no caller reads it
|
|
45
|
+
- Never rename or remove anything in place. Add the new name beside the old one, keep both working, and remove the old one only once no caller reads it, proving that and moving the callers through `deprecation-migration`.
|
|
46
46
|
- Never change what an existing field means or what type it carries. A new meaning takes a new name.
|
|
47
47
|
- When a caller cannot pin a version, such as a module everything in one repository imports, keep one version of the surface live and migrate every caller in the change that alters it, the One-Version Rule. Two versions live side by side split the callers between them.
|
|
48
|
-
- Record each deprecation where a caller looks, naming the replacement and what happens next, rather than in a commit message nobody reads again.
|
|
48
|
+
- Record each deprecation where a caller looks, naming the replacement and what happens next, rather than in a commit message nobody reads again. Whether to deprecate, and when a deprecation turns compulsory, is `deprecation-migration`.
|
|
49
49
|
|
|
50
50
|
## Make a retried write safe
|
|
51
51
|
|
|
@@ -100,3 +100,4 @@ Check each line against the surface the change produced. A line answering no is
|
|
|
100
100
|
- Listing the consumers a finished change breaks, and the docs it made false, during review: `review-craft`
|
|
101
101
|
- A visual interface, its layout, and its look: `design-taste`
|
|
102
102
|
- Interface depth and the internals behind a boundary: `code-craft`
|
|
103
|
+
- Retiring a surface, migrating its callers, and proving none remain before removal: `deprecation-migration`
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deprecation-migration
|
|
3
|
+
description: Why a session retiring code needs stated rules for deciding to deprecate, migrating callers, and proving none remain before removal, and where that discipline stops short of additive interface change, file placement, and schema migrations
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Deprecation and migration requirement
|
|
7
|
+
|
|
8
|
+
## Gap
|
|
9
|
+
|
|
10
|
+
Without this skill, nothing in the toolkit tells a session how to retire a function, a flag, a file, or a command. No skill folder carries the topic, and the terms strangler and expand-then-contract appear in no skill, rule, or standard. The persistence rule covers only the destructive half of a schema change, and `api-design` stops at adding a new name beside an old one and removing the old one once no caller reads it, without saying how a session proves that or who moves the callers.
|
|
11
|
+
|
|
12
|
+
The toolkit retires its own surfaces often, and three observed cases show the failure the gap allows:
|
|
13
|
+
|
|
14
|
+
- A record folder moved from a flat sibling to a nested layout while one known consumer still sat on the old layout with no checkout reachable to migrate it. The expand step shipped and the contract step had no owner or date.
|
|
15
|
+
- A skill kept a fallback beside a new command "until a release retires it", a compatibility path with no stated removal condition.
|
|
16
|
+
- A sync engine reported entries a source had stopped shipping as retired, leaving each consumer to decide what to do with them, which is a deprecation announced without the owner migrating anyone.
|
|
17
|
+
|
|
18
|
+
Each excuse row in the body traces to one of these cases or to a source in the ledger:
|
|
19
|
+
|
|
20
|
+
- Fallback row: the second case
|
|
21
|
+
- Migrate-later and one-machine rows: the first and third cases
|
|
22
|
+
- Notice row: the deprecation chapter of Software Engineering at Google
|
|
23
|
+
- No-owner row: the upstream skill's zombie-code section
|
|
24
|
+
- Search row: the upstream skill's red flag against removing code without verifying zero consumers
|
|
25
|
+
- Add-and-drop row: the upstream skill's rationalization for adding a column and dropping the old one in one migration
|
|
26
|
+
|
|
27
|
+
## Must
|
|
28
|
+
|
|
29
|
+
- State the decision to deprecate as four questions, being what keeping it costs, who calls it, what replaces it, and who migrates the callers, and keep the surface when they do not add up
|
|
30
|
+
- Separate advisory from compulsory, and allow compulsory only once a replacement has shipped and a removal date is stated where a caller looks
|
|
31
|
+
- State the Churn Rule: the owner of a surface migrates its callers rather than announcing and waiting
|
|
32
|
+
- Require a zero-consumers check across every caller kind before removal, being imports, string references, configuration, documentation, and copies outside the repository, and require the report to name the kinds the search could not reach rather than reporting zero
|
|
33
|
+
- Name the adapter and the strangler as the two bridges, with when each fits
|
|
34
|
+
- State expand, migrate, and contract as three separate changes, never letting the contract step share a change with the expand step
|
|
35
|
+
- Treat zombie code as a decision between removal and ownership, settled by the same zero-consumers check
|
|
36
|
+
- Record the external sources adopted and declined with the reason for each
|
|
37
|
+
- Close with a table of the excuses a session gives for removing early or leaving a deprecation open, the red flags it can see mid-task, and a checklist each line of which answers yes or no against the change
|
|
38
|
+
|
|
39
|
+
## Must not
|
|
40
|
+
|
|
41
|
+
- Name a toolkit command, a toolkit-local path, or a project from the evidence, since the body ships to targets
|
|
42
|
+
- State a numeric deprecation window, since a number fits one project's release cadence and not another's
|
|
43
|
+
- Restate additive change or the One-Version Rule, which `api-design` owns
|
|
44
|
+
- Restate the persistence rule's schema bullets
|
|
45
|
+
|
|
46
|
+
## Guards
|
|
47
|
+
|
|
48
|
+
- Code introduced on the same branch that nothing has shipped against skips the skill
|
|
49
|
+
- A removal whose zero-consumers check left a caller kind unreached is reported with that kind named, never as clean
|
|
50
|
+
|
|
51
|
+
## Out of scope
|
|
52
|
+
|
|
53
|
+
- Database schema migrations and their down paths: the project's persistence rule
|
|
54
|
+
- Release versioning and changelog format, which a release process owns
|
|
55
|
+
- Whether a tooling sync removes a path a stack stopped shipping, which needs measuring before any rule is written
|
|
56
|
+
- Moving or renaming a file with no caller change: `codebase-layout`
|
|
57
|
+
- Adding a field, flag, or parameter beside an old one: `api-design`
|
|
58
|
+
- Whether the guidance changes what a session ships, which needs a measured with-and-without run rather than a rule here
|
|
59
|
+
|
|
60
|
+
## Measured
|
|
61
|
+
|
|
62
|
+
Not yet run. The seeded arm holds a deprecated helper with one caller by import and one by string reference, and asserts the session finds both before deleting and leaves the helper while either remains. The with-and-without run waits on the operator authorizing the spend.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deprecation-migration
|
|
3
|
+
description: Carries how a session retires a function, a flag, a field, a file, or a command without stranding whoever still calls it, from deciding whether to deprecate at all through proving no caller remains, migrating callers through an adapter or a strangler, and removing the old surface in its own change after the new one has carried every caller. Use when deleting or replacing code something may still call, when a deprecated path has lingered with no date, when finding dead or unowned code, or when asked "can I delete this", "how do I retire this", "how do I migrate callers off X", or "is anything still using this". Do NOT use to move or rename a file with no caller change, which is `codebase-layout`, to migrate a database schema, which the project's persistence rule governs, or to shape a new field or flag added beside an old one, which is `api-design`.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Deprecation and migration
|
|
7
|
+
|
|
8
|
+
A session asked to remove something tends to grep for its name, find nothing it recognizes, and delete it. What it misses calls the thing by a string, a config key, or a copy shipped somewhere the search never looked, and the first anyone hears of it is a break in a place the diff never touched. The reverse failure is as common: a replacement ships, the old path gets a deprecation note, and nobody ever moves the callers, so both live on with no owner. This skill carries the discipline that ends with the old surface gone and every caller working.
|
|
9
|
+
|
|
10
|
+
Load it before deleting or replacing anything a caller outside the current change could reach. Skip it for code introduced on the same branch that nothing has shipped against yet.
|
|
11
|
+
|
|
12
|
+
## Decide whether to deprecate at all
|
|
13
|
+
|
|
14
|
+
Answer four questions before writing a deprecation notice, and keep the surface when the answers do not add up.
|
|
15
|
+
|
|
16
|
+
- **What does keeping it cost?** Name the concrete cost, such as a duplicate path to test, a dependency that blocks an upgrade, or a behavior that confuses readers. "It is old" is not a cost.
|
|
17
|
+
- **Who calls it?** Count the callers you can see and name the kinds you cannot, by the method in the zero-consumers section below.
|
|
18
|
+
- **What replaces it?** A deprecation with no shipped replacement only tells callers they are on their own. Build the replacement first, or keep the old surface.
|
|
19
|
+
- **Who migrates the callers?** Name an owner. A deprecation nobody owns stalls at the notice.
|
|
20
|
+
|
|
21
|
+
## Choose advisory or compulsory
|
|
22
|
+
|
|
23
|
+
- Start advisory: mark the surface deprecated, name the replacement, and leave it working. Callers move when they next touch the code.
|
|
24
|
+
- Move to compulsory only once the replacement has shipped and a removal date is stated where a caller looks, such as the warning text, the changelog, or the docs page for the surface.
|
|
25
|
+
- Make every warning actionable and well timed. Name the replacement and the change a caller makes, and raise it where the caller uses the old surface rather than in a log nobody reads.
|
|
26
|
+
- Never leave an advisory deprecation open with no date and no owner. Either schedule the move to compulsory or withdraw the deprecation.
|
|
27
|
+
|
|
28
|
+
## Migrate the callers yourself
|
|
29
|
+
|
|
30
|
+
The owner of a surface moves its callers, the Churn Rule. Announcing a deprecation and waiting for callers to migrate pushes the work onto everyone downstream, and most of them never do it.
|
|
31
|
+
|
|
32
|
+
- Migrate every caller you can reach in the repository you own, as part of the deprecation work rather than after it.
|
|
33
|
+
- For a caller you cannot edit, such as another team's code or a published consumer, ship a backward-compatible path or migration notes they can apply, and track them as a caller still on the old surface.
|
|
34
|
+
- Never add a feature to the deprecated surface. New behavior goes on the replacement, which gives callers a reason to move.
|
|
35
|
+
|
|
36
|
+
## Prove zero consumers before removal
|
|
37
|
+
|
|
38
|
+
A clean search for one spelling of the name proves only that this spelling is absent from the files searched. Check every caller kind before removing anything.
|
|
39
|
+
|
|
40
|
+
- **Imports and direct calls**, including re-exports and aliases that call it by another name.
|
|
41
|
+
- **String references**, such as a handler looked up by name, a command dispatched from a table, a reflection call, or a test fixture naming it.
|
|
42
|
+
- **Configuration**, including build files, CI workflows, environment defaults, and data files that name the surface.
|
|
43
|
+
- **Documentation and examples**, which callers copy from long after the code moves.
|
|
44
|
+
- **Copies outside the repository**, such as a published package, an installed copy in another project, a shipped binary, a script someone runs from their own machine, or a saved request in an API client.
|
|
45
|
+
|
|
46
|
+
Say which kinds your search could not reach and why, rather than reporting zero. "No callers in this repository, but a published release still exports it" is a finding a reader can act on, since it names where the remaining risk sits. A bare "no callers" is a guess.
|
|
47
|
+
|
|
48
|
+
## Bridge with an adapter or a strangler
|
|
49
|
+
|
|
50
|
+
- **Adapter.** Keep the old interface as a thin layer over the new implementation, so callers keep working while the implementation moves underneath them. The adapter holds no logic of its own and goes once its last caller moves.
|
|
51
|
+
- **Strangler.** Route callers to the new path a group at a time, leaving the old path serving the rest. The old path is done when it serves nothing, and only then is it removed.
|
|
52
|
+
- Prefer the adapter when the interface stays and the implementation changes. Prefer the strangler when callers have to change how they call.
|
|
53
|
+
|
|
54
|
+
## Expand, migrate, contract as three changes
|
|
55
|
+
|
|
56
|
+
Never add a replacement and remove the original in one change. Three separate changes keep every step reversible:
|
|
57
|
+
|
|
58
|
+
1. **Expand.** Add the replacement beside the original. Both work, and nothing calls the new one yet.
|
|
59
|
+
2. **Migrate.** Move callers to the replacement, in one change or several. The original still works for anything missed.
|
|
60
|
+
3. **Contract.** Remove the original once the zero-consumers check passes, in a change of its own.
|
|
61
|
+
|
|
62
|
+
Reverting any one step leaves a working tree. A change that expands and contracts together leaves no point where a missed caller still works, and reverting it reverts the migration too.
|
|
63
|
+
|
|
64
|
+
This sits beside the One-Version Rule `api-design` states rather than against it. Two versions live only between the expand and the contract, and the migrate step moves every caller rather than splitting them between the two.
|
|
65
|
+
|
|
66
|
+
## Treat zombie code as a decision to make
|
|
67
|
+
|
|
68
|
+
Zombie code is unowned and uncalled yet still built, tested, and shipped. It costs build time and reader attention, and it hides which code is live.
|
|
69
|
+
|
|
70
|
+
- Run the zero-consumers check on it like anything else, since "nothing calls it" is the claim to prove.
|
|
71
|
+
- When the check comes back clean, remove it. With no replacement there is nothing to expand or migrate, so the removal runs alone as the contract change.
|
|
72
|
+
- When something does still call it, it is not zombie code. Give it an owner, or deprecate it through the steps above.
|
|
73
|
+
|
|
74
|
+
Read `${CLAUDE_SKILL_DIR}/references/adopted.md` only when extending this guidance or arguing against a rule in it. It records which external sources were adopted, which declined, and why.
|
|
75
|
+
|
|
76
|
+
## Excuses and rebuttals
|
|
77
|
+
|
|
78
|
+
| Excuse | Rebuttal |
|
|
79
|
+
| -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
80
|
+
| I searched for the name and nothing calls it | A search finds one spelling in the files it read. A handler looked up by string, a config key, or a published copy stays hidden. |
|
|
81
|
+
| I'll keep the fallback until callers move | With no date and no owner, the fallback outlives every caller it was kept for. State when it goes and who removes it. |
|
|
82
|
+
| The callers can migrate when they get to it | They will not. The owner of the surface moves its callers, or the deprecation never finishes. |
|
|
83
|
+
| It's cleaner to add the new one and drop the old one now | One change that adds and removes leaves no state where a missed caller still works, and a revert undoes the migration too. |
|
|
84
|
+
| This only matters on one machine | One caller is still a caller. Migrate it, or record it as the reason the old path stays. |
|
|
85
|
+
| Nobody owns this, so I can just delete it | No owner is not no caller. Run the zero-consumers check before deciding, since unowned code is often the code nobody dares move. |
|
|
86
|
+
| I'll mark it deprecated and move on | A notice with no shipped replacement and no removal date tells callers nothing they can act on. |
|
|
87
|
+
|
|
88
|
+
## Red flags
|
|
89
|
+
|
|
90
|
+
- You are about to delete a surface after one search for its exact name.
|
|
91
|
+
- A deprecation notice names no replacement or no removal date.
|
|
92
|
+
- The diff adds a replacement and deletes the original in the same change.
|
|
93
|
+
- A fallback or compatibility path has no stated condition for its removal.
|
|
94
|
+
- You are adding behavior to the surface being deprecated.
|
|
95
|
+
- Your report says "no callers" without naming the caller kinds the search could not reach.
|
|
96
|
+
- A caller outside the repository was found and the plan still deletes the original.
|
|
97
|
+
|
|
98
|
+
## Before handing over
|
|
99
|
+
|
|
100
|
+
Check each line against what the change produced. A line answering no is fixed or reported, never left with a note.
|
|
101
|
+
|
|
102
|
+
- The surface is deprecated only if it has a stated cost, a shipped replacement, and a named owner.
|
|
103
|
+
- Every compulsory deprecation states its removal date where a caller looks.
|
|
104
|
+
- Every caller reachable in the repository was migrated, or is named with the reason it was not.
|
|
105
|
+
- The zero-consumers check covered every caller kind, and the report names the kinds it could not reach.
|
|
106
|
+
- No change both adds the replacement and removes the original.
|
|
107
|
+
- Every fallback left in place states when it goes and who removes it.
|
|
108
|
+
|
|
109
|
+
## What this delegates
|
|
110
|
+
|
|
111
|
+
- Adding a field, flag, or parameter beside an old one, and the One-Version Rule for a surface callers cannot pin: `api-design`
|
|
112
|
+
- Moving or renaming a file with no caller change, and where a replacement file sits: `codebase-layout`
|
|
113
|
+
- Database schema changes and their migrations: the project's persistence rule
|
|
114
|
+
- Sequencing expand, migrate, and contract into committed slices on one branch: `build-in-slices`
|
|
115
|
+
- Listing the consumers a finished change breaks, during review: `review-craft`
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Adopted and declined
|
|
3
|
+
description: Which external sources on deprecation and migration this skill adopted, which it declined, and why, so a later session extends the position instead of re-deriving it
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Adopted and declined
|
|
7
|
+
|
|
8
|
+
External sources were read and filtered rather than imported. This file is the record. A later session extending the skill adds to it rather than re-arguing an item already settled here.
|
|
9
|
+
|
|
10
|
+
## Adopted
|
|
11
|
+
|
|
12
|
+
### From the default shelf
|
|
13
|
+
|
|
14
|
+
**Deprecation.** [Software Engineering at Google, chapter 15](https://abseil.io/resources/swe-book/html/ch15.html). Adopted from it:
|
|
15
|
+
|
|
16
|
+
- Advisory and compulsory deprecation as the two types, with compulsory carrying a removal date. The body allows compulsory only once a replacement has shipped, which the chapter implies and the four questions make explicit.
|
|
17
|
+
- Warnings that are actionable and relevant: a warning names what the caller does, and surfaces where the caller uses the old surface.
|
|
18
|
+
- Deprecation as a process with an owner, since the chapter observes that unowned deprecation work makes no progress. Adopted as the fourth decision question and the rule against an advisory deprecation left open with no owner.
|
|
19
|
+
- Finding consumers before removal, which the chapter does with static analysis across one repository. Generalized into the zero-consumers check across caller kinds, since a target project rarely has a whole-company code index and its callers often live outside the repository.
|
|
20
|
+
|
|
21
|
+
**The Churn Rule.** [Software Engineering at Google, chapter 1](https://abseil.io/resources/swe-book/html/ch01.html), under "Policies That Don't Scale": infrastructure teams move their internal users to new versions themselves, or update in place in a backward-compatible way. Adopted as the group on migrating callers yourself, with the backward-compatible path kept for callers the owner cannot edit.
|
|
22
|
+
|
|
23
|
+
### The decision and the bridges
|
|
24
|
+
|
|
25
|
+
**Deprecation and migration.** Addy Osmani's `agent-skills`, pinned at addyosmani/agent-skills@2686b620, [`skills/deprecation-and-migration/SKILL.md`](https://github.com/addyosmani/agent-skills/blob/2686b620/skills/deprecation-and-migration/SKILL.md). Adopted from it:
|
|
26
|
+
|
|
27
|
+
- The five-question deprecation decision, cut to four. Its unique-value and maintenance-cost questions merge into one question about what keeping the surface costs. Its per-consumer migration-cost question drops, since the Churn Rule puts that cost on the owner rather than weighing it per caller. The owner question from the book takes the freed place.
|
|
28
|
+
- The rule never to deprecate without a replacement, as the third decision question.
|
|
29
|
+
- The strangler and adapter patterns, stated as when each fits rather than as worked code tied to one stack.
|
|
30
|
+
- Expand, migrate, contract, lifted out of its schema section and stated for any surface as three separate changes.
|
|
31
|
+
- Zombie code, narrowed to code that is unowned, uncalled, and still built, and settled by the same zero-consumers check rather than a list of staleness signals.
|
|
32
|
+
- The rationalizations and red flags that carry across stacks, reworded for any surface rather than a service or a column. Two excuse rows come from here:
|
|
33
|
+
- The row on a search that found nothing, from its red flag against removing code without verifying zero active consumers.
|
|
34
|
+
- The row on adding the new one and dropping the old one now, generalized from its rationalization about adding a column and dropping the old one in the same migration.
|
|
35
|
+
|
|
36
|
+
## Declined
|
|
37
|
+
|
|
38
|
+
**Its database schema section.** The column rename worked example, the tested down path, batched backfills, and concurrent index builds. Declined because a project's persistence rule owns schema changes, and restating them here puts two owners on one rule. Only the expand, migrate, contract shape was lifted, generalized beyond schemas.
|
|
39
|
+
|
|
40
|
+
**Feature flag migration.** Declined because it is one way to run a strangler, and naming a flag mechanism ties the body to a runtime a target may not have.
|
|
41
|
+
|
|
42
|
+
**The traffic percentages in its strangler phases.** Declined because they describe a service behind a router, and most surfaces a session retires, such as a function, a flag, or a file, have callers rather than traffic.
|
|
43
|
+
|
|
44
|
+
**"Default to advisory" as a standing default with no exit.** Kept advisory as the starting state, and declined leaving it open, since an advisory deprecation with no date and no owner is the stalled case the body exists to prevent.
|
|
45
|
+
|
|
46
|
+
**The thresholds in its zombie signs and rebuttals.** No commits in six months, and comparing costs over two or three years. Declined for the same reason the body states no deprecation window: a number fits one project's cadence and not another's.
|
|
47
|
+
|
|
48
|
+
**"Code is a liability" and design-time deprecation planning as sections.** Declined as framing a session already accepts by loading the skill. The cost question carries the first, and designing a new surface for removal belongs to the skill shaping that surface.
|
|
49
|
+
|
|
50
|
+
**The celebration step and the deprecation notice template.** Declined because neither changes what a session does, and the template's example names a package runner and a migration script tied to one stack.
|
|
@@ -21,6 +21,7 @@ A fix commit answering a review is the sharpest case of the first paragraph, sin
|
|
|
21
21
|
- Sync the body when the new commit moves the scope, and the title when the shift makes it inaccurate
|
|
22
22
|
- Reply on the pull request when it carries review comments, and scan that reply for the banned characters and internal phase labels before posting. The hook watches files and never sees a comment body on its way to the remote.
|
|
23
23
|
- Suppress the reply when the caller owns it, and still run the push and the body sync
|
|
24
|
+
- Read `canon pr evidence <number> --check --json` after posting the evidence and mint the preview when it is owed, since a followup that posts the evidence and stops leaves the preview for a relay
|
|
24
25
|
- Force the push under a lease when the tracking branch no longer reaches the head, so a caller's rebase lands and a commit this session never read is not overwritten
|
|
25
26
|
|
|
26
27
|
## Must not
|
|
@@ -33,6 +33,9 @@ A missing tracking ref is no longer a guard. An open pull request proves the bra
|
|
|
33
33
|
- `no-evidence`: nothing changed under an `evidence/` segment this push. Say nothing and move on.
|
|
34
34
|
- `ok`: write `body` to `.canon/tmp/pr/evidence/body-<number>.md` at the main worktree root (resolved the way `session-worktree` does), then post the comment with `gh pr comment <number> --body-file <main-root>/.canon/tmp/pr/evidence/body-<number>.md` when the record carries no `commentId`, or edit the existing one in place with `gh api -X PATCH repos/{owner}/{repo}/issues/comments/<commentId> -F body=@<main-root>/.canon/tmp/pr/evidence/body-<number>.md` when it does. Clean up the tmp file only after the call reports success.
|
|
35
35
|
- Any other reason is one of the mirrored git refusals (`gh-missing`, `gh-failed`, `no-base`, `unreadable-changes`, `would-empty`). Report it and continue without stopping the chain.
|
|
36
|
+
|
|
37
|
+
After an `ok` post, read what the pull request is still owed with `canon pr evidence <number> --check --json`, branching on `reason` and `owed` rather than the exit. When `owed` lists `preview`, mint it through the preview section of `canon:git-pr`'s `references/evidence.md`, then re-read once. Report anything but `settled` after that re-read and continue, since a refused deploy would otherwise loop. A binary lacking `--check` reports the thread unread rather than settled. A preview already on the comment counts as settled whatever head built it, so a later push does not re-mint one.
|
|
38
|
+
|
|
36
39
|
6. Check for existing review comments: `gh api 'repos/{owner}/{repo}/pulls/<number>/comments' --jq 'length'`, resolving `<number>` from `gh pr view --json number`.
|
|
37
40
|
7. Sync the body and title on every invocation, before the routing below decides on the reply.
|
|
38
41
|
- Run `gh pr view --json url,title,body` and update the body with `gh pr edit --body` when the new commit changes scope, and the title with `gh pr edit --title` when the scope shifted enough to make it inaccurate.
|
|
@@ -28,6 +28,7 @@ A lookup that resolves by head branch alone carries its own failure. A branch na
|
|
|
28
28
|
- Label from the paths the branch changed, against a map the project declares, so the label set belongs to the project rather than to the skill
|
|
29
29
|
- Apply labels after the pull request exists, so a label the remote does not carry costs a warning rather than the pull request
|
|
30
30
|
- Report a refused label, since a warning nothing surfaces leaves the run indistinguishable from one that labelled
|
|
31
|
+
- Run the evidence verb on every pull request the skill opens, and let its `no-evidence` answer be the skip, since a session cannot see a regenerated image it did not author and a gate asking it to look lets that image ship with no comment
|
|
31
32
|
- Put a preview address on a pull request that changes a rendered surface when the project's deploy can mint one, since screenshots and a checklist leave a reviewer nothing to click into before merging
|
|
32
33
|
- Bound the wait on that preview and finish the chain without the link on a timeout, since a slow deploy must not hold the ship
|
|
33
34
|
- Put the branch's running local server on the same pull request when this worktree is serving one, and remove it when the pull request closes, since a reviewer on the operator's machine can interact with the branch and a link that outlives it points at whatever runs there next
|
|
@@ -152,7 +152,7 @@ The last output line carries `head=` so a caller relaying the number holds a bra
|
|
|
152
152
|
|
|
153
153
|
### Post the rendered-surface evidence
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
Run this step on every pull request this skill opens or edits. Read `${CLAUDE_SKILL_DIR}/references/evidence.md` for finding the checklist and the local server, posting the evidence comparison, posting the checklist alone, and posting the preview address, each against the `<number>` the final command printed. Never judge from the diff whether an evidence image changed, since the verb answers `no-evidence` for a branch that changed none and a session cannot see an image it did not author.
|
|
156
156
|
|
|
157
157
|
### Record the number on the task
|
|
158
158
|
|
|
@@ -5,7 +5,7 @@ description: How git-pr finds the UI checklist and the local server, posts the e
|
|
|
5
5
|
|
|
6
6
|
# Rendered-surface evidence
|
|
7
7
|
|
|
8
|
-
The rendered-surface step of `git-pr`, reached after the final command printed the pull request number. The
|
|
8
|
+
The rendered-surface step of `git-pr`, reached after the final command printed the pull request number. The step runs on every pull request, with no test on the diff ahead of it. `no-evidence` is the silent branch, so a pull request that changes no rendered surface posts nothing.
|
|
9
9
|
|
|
10
10
|
## Find the UI checklist
|
|
11
11
|
|
|
@@ -92,7 +92,7 @@ Deleting the file is what makes the later re-render safe. `git-followup` re-runs
|
|
|
92
92
|
|
|
93
93
|
## Post the preview address
|
|
94
94
|
|
|
95
|
-
Run this step
|
|
95
|
+
Run this step when the evidence step above returned `ok`, a checklist was posted by the fallback, or `canon pr evidence <number> --check --json` lists `preview` in `owed`. The first two mean the pull request changes a rendered surface, and a reviewer holding a checklist with no screenshots needs the live page most. The third is how `git-ship` reaches this step alone when an earlier run's deploy timed out, so no evidence step ran in the current one. Otherwise skip it silently.
|
|
96
96
|
|
|
97
97
|
The evidence comment is already posted, so the reviewer has the screenshots while the deploy runs. Mint the preview against the same `<number>`:
|
|
98
98
|
|
|
@@ -22,6 +22,7 @@ The sequence also reaches the remote on work nothing re-checked. This skill is t
|
|
|
22
22
|
- Name the one point a wrapping caller may act at, so a chain built on this one is not left to pick a gap of its own
|
|
23
23
|
- Name the condition under which the closing block is not emitted, since a caller that closes on its own block leaves two instructions about the last line and nothing deciding between them
|
|
24
24
|
- Watch continuous integration to a terminal state in the background, so the session stays reachable while CI runs, and stop on a failure naming the check
|
|
25
|
+
- Read the evidence thread with `canon pr evidence <number> --check --json` once CI passes, run what it reports owed, and report done only on `settled`, since a chain that never reads the thread ships a regenerated image with no comment and no preview and leaves the controller to repair it
|
|
25
26
|
- Stop memory work at the Propose phase
|
|
26
27
|
|
|
27
28
|
## Must not
|
|
@@ -36,6 +37,8 @@ The sequence also reaches the remote on work nothing re-checked. This skill is t
|
|
|
36
37
|
## Guards
|
|
37
38
|
|
|
38
39
|
- A failing verify stops the run before the sync skills write, so the tree is left as the user left it
|
|
40
|
+
- A binary lacking `--check` reports the thread unread, never settled, since reading the absence as a pass repeats the failure the read exists to close
|
|
41
|
+
- Re-read the thread once after running what was owed and stop on anything but `settled`, so a refused preview cannot loop the chain
|
|
39
42
|
- A failing check stops the sequence. A stop report and the line announcing the background watch are the two places text is allowed between steps.
|
|
40
43
|
|
|
41
44
|
## Out of scope
|
|
@@ -49,7 +49,7 @@ Emit `⏳ Watching CI on #<number> in the background` and end the turn. Print no
|
|
|
49
49
|
|
|
50
50
|
On the wake, branch on the final record's fields rather than on the exit:
|
|
51
51
|
|
|
52
|
-
- `state: passing`: continue to After completion
|
|
52
|
+
- `state: passing`: read the evidence thread under `### Settling the evidence thread` below, then continue to After completion on `settled`.
|
|
53
53
|
- `state: failing`: stop the sequence and report the failing check with its URL.
|
|
54
54
|
- `conflicted: true`: stop the sequence and report that the branch conflicts with its base, since no run will start for it. A rebase is the repair.
|
|
55
55
|
- A `reason` and no `state`: the read was refused, such as `no-remote-branch` for a branch deleted on the remote. Stop and report that `reason`. A missing `state` is never a pass.
|
|
@@ -58,6 +58,17 @@ On the wake, branch on the final record's fields rather than on the exit:
|
|
|
58
58
|
|
|
59
59
|
Do not auto-fix any of these. The watch line and a stop report from any branch above are the two exceptions to the no-text-between-steps rule.
|
|
60
60
|
|
|
61
|
+
### Settling the evidence thread
|
|
62
|
+
|
|
63
|
+
On a `passing` wake, run `canon pr evidence <number> --check --json` against the number step 8 returned. It reads the pull request's comments and edits none, so the comment a reviewer already ticked stays as it is. Branch on `reason` and `owed` rather than the exit.
|
|
64
|
+
|
|
65
|
+
- `settled`: nothing is owed, which is also what a branch that changed no rendered surface reads. Continue to After completion.
|
|
66
|
+
- `owed`: run each step the record's `owed` list names, from `canon:git-pr`'s `references/evidence.md`, evidence first and then preview. Re-read once with the same command. Continue to After completion only on `settled`. Any other reading stops the sequence and reports the `reason` with the `owed` list, and the sequence never loops back for a second pass. A preview step that refuses, or a deploy that failed, leaves `preview` owed on the re-read, so that is the stop and not a retry.
|
|
67
|
+
- Any other `reason`, such as `gh-failed`: the thread went unread. Stop and report the `reason`, since an unread thread is not a settled one.
|
|
68
|
+
- No record at all, or an unknown flag error: the installed binary predates `--check`. Report the thread unread rather than settled, and continue to After completion without emitting a claim that it was checked.
|
|
69
|
+
|
|
70
|
+
The read is a closing step and the draft mark stays the only thing between steps 8 and 9. A caller that closes on its own block, as `auto-ship` does, waits on the same CI wake, so the read lands here and not in that body.
|
|
71
|
+
|
|
61
72
|
### Why the reach reads at step 5
|
|
62
73
|
|
|
63
74
|
The branch is whole there and nowhere earlier. Steps 2 and 3 write past whatever the plan declared, so a reading taken ahead of them misses the chain's own additions, and no pull request exists until step 8 to carry the answer anywhere.
|
|
@@ -73,7 +73,7 @@ Read each test file the branch added or changed against the final filter in `can
|
|
|
73
73
|
|
|
74
74
|
Then read the description's `## Testing` section, which is the one part of a pull request body this session is positioned to falsify. The branch author cannot see what a sibling branch drove the same day, and the arm list is what settles the claim rather than the diff.
|
|
75
75
|
|
|
76
|
-
Test every unchecked box against the testing discipline in `${CLAUDE_SKILL_DIR}/../../standards/pr.md`, which reserves an unchecked box for a capability the agent lacks. Raise the box when it names no human at all, when the human it names is a live agent session, or when it names a person for a step the repository ships a harness for, such as `
|
|
76
|
+
Test every unchecked box against the testing discipline in `${CLAUDE_SKILL_DIR}/../../standards/pr.md`, which reserves an unchecked box for a capability the agent lacks. Raise the box when it names no human at all, when the human it names is a live agent session, or when it names a person for a step the repository ships a harness for, such as `sandbox/run.sh`. Cost alone is not an answer, since authorizing a spend is the operator's and performing the run is not. A refusal the author actually met is an answer, and it names which one.
|
|
77
77
|
|
|
78
78
|
Test every ticked box too, bounded to one naming a file or a command. Confirm what it names still exists at `<headRefOid>`, `git show <headRefOid>:<path>` for a file or `git grep <command> <headRefOid>` for a command, rather than re-running what it claims. A box naming neither stays untested, since nothing here can confirm a claim carrying no artifact. A box ticked before a later commit removed or replaced what it names is a `should-fix` finding on the body itself, filed under a `**PR body**` block ahead of the file blocks, since what it corrupts is the merge record rather than a file in the diff.
|
|
79
79
|
|
|
@@ -25,6 +25,6 @@ gh api -X PUT repos/{owner}/{repo}/pulls/<number>/reviews/<review-id> -F body=@<
|
|
|
25
25
|
|
|
26
26
|
The guard fires on `## Review closed` alone. Two open passes carry different findings and both are worth reading, so a repeated `## Review` posts normally. A pass carrying anything owed posts normally too, under `## Review`, which is what keeps a finding raised after a close-out from being swallowed by the guard that exists for a silent one.
|
|
27
27
|
|
|
28
|
-
The rewrite used to cost the review's `commit.oid`, which `PUT` leaves pinned at the commit the standing close-out was first submitted against. Step 2's `<prior-oid>` and the prior commit `poll.
|
|
28
|
+
The rewrite used to cost the review's `commit.oid`, which `PUT` leaves pinned at the commit the standing close-out was first submitted against. Step 2's `<prior-oid>` and the prior commit `poll.ts` derives both read that field, so the next pass read a range wider than its delta, and the poll's `SEEN` branch, which fires on `prior` equalling the head, could never be reached at all: an out-of-band pass reported as `MOVED` for the rest of the pull request's life.
|
|
29
29
|
|
|
30
30
|
The marker closes both, because `PUT` replaces the body and the marker is in it. The rewritten close-out carries the commit this pass read rather than the one the comment was first submitted against, and every reader now takes that in preference to the pinned field. The one thing `PUT` still cannot move is `submittedAt`, which stays at the original submission and is what the poll's age test reads, so a rewritten close-out ages from when it first landed rather than from when it was last rewritten. That is the correct reading for a thread waiting on a human, which is the question the age test asks.
|
|
@@ -59,7 +59,7 @@ A Testing box the Step 3 check raised goes in a `**Testing**` block placed after
|
|
|
59
59
|
```markdown
|
|
60
60
|
**Testing**
|
|
61
61
|
|
|
62
|
-
- `- [ ] <the box as written>` names no capability the agent lacks. `
|
|
62
|
+
- `- [ ] <the box as written>` names no capability the agent lacks. `sandbox/run.sh <arm>` drives it. Was there a reason to leave it?
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
Keep it to the boxes the check raised. Restating a box whose stated requirement holds teaches the branch author to skip the block.
|
|
@@ -23,7 +23,9 @@ A verdict also goes stale without saying so. A push after the pass changes what
|
|
|
23
23
|
- Report an address that does not answer as not driven rather than as a fail, and leave the review closed on a box no commit on the branch can settle, so an absent preview never holds the draft mark at every head
|
|
24
24
|
- Sweep console errors, sideways overflow at each named width, and the focus and details probes over the states reached, and nothing beyond them
|
|
25
25
|
- Post its own comment as a pull request review under `## UI review` while anything is owed and `## UI review closed` once nothing is, ending on a marker naming the head it drove
|
|
26
|
-
-
|
|
26
|
+
- Embed a frame only for a state the worker's evidence record lacks, pushed through `canon pr frames` to a branch that never merges and linked by its path there under this pass's own stamp, so the image lasts until its own pull request is dropped and no later pass replaces it, and cite the evidence stem for a state the record already shows, so the review adds no image the worker's evidence already carries
|
|
27
|
+
- Push only a frame of the address the pass drove, since the branch is as public as the repository
|
|
28
|
+
- Describe a frame in words when the push refuses, naming the reason, and cite no local path, since a path under `.canon/` fails the label scan the review-event run applies to the posted body
|
|
27
29
|
- Read the review-event checks for the head after the post, bounded, and report a failure in the result line, or the checks as unread when they never settle
|
|
28
30
|
- Report the heading it posted by reading the posted file's first line, so the result line and the body come from one source
|
|
29
31
|
- Name the renderer the browser reported, and render on the GPU only when the launch names a config for it
|
|
@@ -55,4 +57,5 @@ A verdict also goes stale without saying so. A push after the pass changes what
|
|
|
55
57
|
- Writing the checklist and its drivable format, which `ui-checklist` owns
|
|
56
58
|
- Dispatching the pass, polling its verdict, and lifting the draft mark, which `role-orchestrator` owns
|
|
57
59
|
- A subagent inside the code reviewer, dropped because its cost stays invisible until it returns
|
|
58
|
-
-
|
|
60
|
+
- Writing a tracked file or checking anything out to host a frame. The push goes through the GitHub API onto the frames branch alone, so the reviewer still enters no worktree and touches no branch a pull request holds.
|
|
61
|
+
- Dropping a closed pull request's frames, which a scheduled workflow runs, and purging a dropped frame GitHub still serves by commit, which needs a platform request
|
|
@@ -26,7 +26,7 @@ rather than inside it, so the two passes finish on their own clocks.
|
|
|
26
26
|
|
|
27
27
|
## Step 1: resolve the pull request
|
|
28
28
|
|
|
29
|
-
Resolve the number with `gh pr view --json number,headRefName,headRefOid`, or take the one the launch names. Take `<head>` off `canon pr head <number> --json`, reading its `tip`, and fall back to `headRefOid` when no record comes back. The first seven characters are `<short-sha>`.
|
|
29
|
+
Resolve the number with `gh pr view --json number,headRefName,headRefOid`, or take the one the launch names. Take `<head>` off `canon pr head <number> --json`, reading its `tip`, and fall back to `headRefOid` when no record comes back. The first seven characters are `<short-sha>`. Record `<pass>` once, as the instant this pass starts, with `date -u +%Y%m%dT%H%M%SZ`. Every frame Step 5 pushes files under it, so a later pass at the same head never replaces an image this one's comment shows.
|
|
30
30
|
|
|
31
31
|
Read the newest UI verdict for the head guard:
|
|
32
32
|
|
|
@@ -44,7 +44,7 @@ Read nothing else about the change. The diff, the plan, the task, and the descri
|
|
|
44
44
|
canon pr evidence <number> --json
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
Take three fields off the record, each present only when the posted evidence comment holds it: `checklist`, `preview`, and `local`. They come from the comment already on the thread, so `reason` reading `ok` or `no-evidence` makes no difference here, and the rendered `body` is not this pass's to read. Branch on the record rather than on the exit code, which a shell function wrapping `canon` can flatten to zero. Only `ok` and `no-evidence` read the thread. Every other `reason` is a refusal that never reached the comment, so report it verbatim and stop rather than reading the missing fields as an absent checklist.
|
|
47
|
+
Take three fields off the record, each present only when the posted evidence comment holds it: `checklist`, `preview`, and `local`. They come from the comment already on the thread, so `reason` reading `ok` or `no-evidence` makes no difference here, and the rendered `body` is not this pass's to read. Keep `states` as well when `reason` reads `ok`, being each evidence state's name and the stems under it, which Step 5 matches a frame against. A record carrying no `states`, on `no-evidence` or from an older binary, covers no state, so every frame is pushed. Branch on the record rather than on the exit code, which a shell function wrapping `canon` can flatten to zero. Only `ok` and `no-evidence` read the thread. Every other `reason` is a refusal that never reached the comment, so report it verbatim and stop rather than reading the missing fields as an absent checklist.
|
|
48
48
|
|
|
49
49
|
A binary older than 5.4.0 reports none of the three fields whatever the thread holds, so a record carrying none is ambiguous. Read `canon --version` before taking the no-checklist stop, and on an older release report the release this pass needs and stop rather than parsing the comment by hand.
|
|
50
50
|
|
|
@@ -86,6 +86,14 @@ Give every box exactly one verdict, in checklist order. A box the pass could not
|
|
|
86
86
|
|
|
87
87
|
Never judge a box ending in `(taste)`. Drive to the state, capture the frame, and mark it needs eyes. Drive a ticked box the same as an unchecked one, since a tick is the author's claim and this pass exists to check it.
|
|
88
88
|
|
|
89
|
+
A frame the verdict rests on is published only when the worker's evidence lacks it. Compare the box's route, width, and theme against the `states` Step 2 kept, and when a state and stem show the same thing, cite that stem and push nothing. The match is this pass's judgment over the box's wording, so the verb never makes it. Otherwise push the frame and keep the `link` the record returns:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
canon pr frames <number> --add frames/<box-number>.png --box <box-number> --head <head> --pass <pass> --json
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Push only a frame of the address this pass drove, since the branch is as public as the repository. Branch on `reason` rather than on the exit code. Every reason but `ok` is a refusal, `read-only` among them on a fork's token, so describe that frame in words and name the reason in its evidence rather than failing the pass.
|
|
96
|
+
|
|
89
97
|
## Step 6: sweep
|
|
90
98
|
|
|
91
99
|
Run three checks over every route the boxes reached, and nothing beyond them:
|
|
@@ -100,7 +108,7 @@ Close the browser with `${CLAUDE_SKILL_DIR}/scripts/pw.sh -s=<project>-<number>
|
|
|
100
108
|
|
|
101
109
|
## Step 7: post
|
|
102
110
|
|
|
103
|
-
Read `${CLAUDE_SKILL_DIR}/references/post.md` for the heading rule, the body shape, the marker every body ends on, and the post command.
|
|
111
|
+
Read `${CLAUDE_SKILL_DIR}/references/post.md` for the heading rule, the body shape, the marker every body ends on, and the post command. Each Evidence cell embeds the `link` its Step 5 push returned, as given, or names the evidence stem it matched.
|
|
104
112
|
|
|
105
113
|
## Step 8: read the review-event checks
|
|
106
114
|
|
|
@@ -130,4 +138,4 @@ Add `S sweep finding(s).` when the sweep raised any. Report no merge recommendat
|
|
|
130
138
|
- Drive the checklist and the sweep, and nothing else. Open exploration has no end a dispatcher can predict.
|
|
131
139
|
- Never check out, build, or serve the head. An address is handed to this pass or the pass refuses.
|
|
132
140
|
- Never read a value off the snapshot file whole. Search it for the ref a box needs, and read text, styles, and geometry with `eval`.
|
|
133
|
-
- Write only under `.canon/tmp/pr/review-ui/`, at the main worktree root.
|
|
141
|
+
- Write only under `.canon/tmp/pr/review-ui/`, at the main worktree root, and to the frames branch through `canon pr frames`, which goes through the API and checks nothing out.
|
|
@@ -41,10 +41,12 @@ Each box takes exactly one.
|
|
|
41
41
|
| Verdict | When | Evidence it carries |
|
|
42
42
|
| ------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
43
43
|
| pass or fail, read | The result is a fact the page reports | The value read, quoted, such as `scrollWidth 436 against clientWidth 320` |
|
|
44
|
-
| pass or fail, frame | The result has a stated criterion only an image settles |
|
|
45
|
-
| needs eyes | The box ends in `(taste)` |
|
|
44
|
+
| pass or fail, frame | The result has a stated criterion only an image settles | The pushed frame's link or the matching evidence stem, and what the frame shows, in words |
|
|
45
|
+
| needs eyes | The box ends in `(taste)` | The pushed frame's link or the matching evidence stem, and what the frame showed, with nothing about whether it looks right |
|
|
46
46
|
| not driven | The state could not be reached | The reason, such as an unreachable address, a `(local only)` box on a hosted preview, or a target the snapshot does not hold |
|
|
47
47
|
|
|
48
|
-
A frame
|
|
48
|
+
A frame verdict carries one image at most, and never one the worker's evidence already shows. When a state and stem in the evidence record match the box's route, width, and theme, the evidence names that stem and nothing is pushed. Otherwise the frame goes up through `canon pr frames` and the evidence carries the `link` the record returned, which names the frame's path on the frames branch. Either way the words stay, describing the value or region judged, such as the element, its position, and the colors or text read, so a reader whose image fails to load can still check it.
|
|
49
|
+
|
|
50
|
+
A push that refuses leaves the words alone, with the reason named. Never cite the local frame path. A path under `.canon/` is a board identifier the label scan rejects, and it resolves only on this machine.
|
|
49
51
|
|
|
50
52
|
A fail names what was expected beside what was read. A not driven never reads as a fail, since it says the pass could not look rather than that the page is wrong. Its reason says whether the cause sits on the page or off it, since only a cause on the page opens the heading Step 7 picks.
|
|
@@ -28,7 +28,8 @@ P passed, F failed, E need eyes, N not driven. Drove <address> at <short-sha>, r
|
|
|
28
28
|
| Box | Verdict | Evidence |
|
|
29
29
|
| ---------------------------------- | ---------- | --------------------------------------------- |
|
|
30
30
|
| 1. <the box as written, shortened> | fail | <the value read against what the box expects> |
|
|
31
|
-
| 2. <box> | needs eyes | <what the frame showed, in words
|
|
31
|
+
| 2. <box> | needs eyes |  <what the frame showed, in words> |
|
|
32
|
+
| 3. <box> | pass | Evidence `<stem>` <what it showed, in words> |
|
|
32
33
|
|
|
33
34
|
**Sweep**
|
|
34
35
|
|
|
@@ -43,7 +44,7 @@ P passed, F failed, E need eyes, N not driven. Drove <address> at <short-sha>, r
|
|
|
43
44
|
<!-- review-ui: head=<head> -->
|
|
44
45
|
```
|
|
45
46
|
|
|
46
|
-
A frame
|
|
47
|
+
An Evidence cell resting on a frame takes one of three forms. A frame Step 5 pushed embeds as ``, with the link exactly as `canon pr frames` returned it. It names the frame's path on the frames branch, which stays put while other pull requests' frames are dropped and carries this pass's stamp, so a later pass never changes the image. A state the worker's evidence already shows names the evidence stem in backticks and embeds nothing, since the evidence comment carries that image. A push that refused leaves the words alone and names the reason. Never cite the local frame path, since a path under `.canon/` is a board identifier the label scan rejects.
|
|
47
48
|
|
|
48
49
|
A pass where every box needs eyes and nothing else is owed takes the closed heading:
|
|
49
50
|
|
|
@@ -45,7 +45,7 @@ On a request to write the handoff or save the session, read `${CLAUDE_SKILL_DIR}
|
|
|
45
45
|
|
|
46
46
|
On a request to resume after a compaction, read `${CLAUDE_SKILL_DIR}/references/orchestrator-resume.md`, which reads that file back with the board and the groundwork behind the live work.
|
|
47
47
|
|
|
48
|
-
The review trigger takes the same shape. `references/orchestrator-poll.md` holds the loop prompt and the condition under which the poll runs, and `scripts/poll.
|
|
48
|
+
The review trigger takes the same shape. `references/orchestrator-poll.md` holds the loop prompt and the condition under which the poll runs, and `scripts/poll.ts` is what the prompt invokes. A session holding a recurring-prompt scheduler starts and cancels that loop itself, and no hook or check does, so the condition holds only while whoever holds the loop applies it.
|
|
49
49
|
|
|
50
50
|
A board that is not moving is a third such moment. On a request to re-test the parked rows, read `${CLAUDE_SKILL_DIR}/references/orchestrator-parked.md` and follow it. It re-tests every `## Up next` and `## Needs a plan` blocker against the current tree, walks `backlog.md` on the same pass, writes what each test showed into the row, and plans what it clears. Its trigger is the inverse of the refill sweep's below, which fires on a merge and asks what to promote next rather than whether a row already parked is still parked for a reason.
|
|
51
51
|
|