@ikon85/agent-workflow-kit 0.27.1 → 0.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/.agents/skills/ask-matt/SKILL.md +2 -2
- package/.agents/skills/board-to-waves/SKILL.md +13 -3
- package/.agents/skills/grill-me/SKILL.md +1 -1
- package/.agents/skills/grill-with-docs/SKILL.md +1 -1
- package/.agents/skills/kit-update/SKILL.md +12 -0
- package/.agents/skills/orchestrate-wave/SKILL.md +68 -21
- package/.agents/skills/orchestrate-wave/references/builder-contract.md +6 -4
- package/.agents/skills/retro/SKILL.md +24 -1
- package/.agents/skills/scale-check/SKILL.md +2 -2
- package/.agents/skills/setup-workflow/SKILL.md +44 -1
- package/.agents/skills/setup-workflow/workflow-overview.md +5 -5
- package/.agents/skills/tdd/SKILL.md +68 -14
- package/.agents/skills/to-issues/SKILL.md +104 -29
- package/.agents/skills/to-prd/SKILL.md +13 -3
- package/.agents/skills/to-waves/SKILL.md +16 -4
- package/.agents/skills/verify-spike/SKILL.md +1 -1
- package/.agents/skills/wrapup/SKILL.md +14 -3
- package/.claude/hooks/drift-guard.py +5 -2
- package/.claude/hooks/kit-origin-edit-hint.py +64 -0
- package/.claude/skills/ask-matt/SKILL.md +2 -2
- package/.claude/skills/board-to-waves/SKILL.md +13 -3
- package/.claude/skills/codex-build/SKILL.md +69 -23
- package/.claude/skills/codex-review/SKILL.md +47 -37
- package/.claude/skills/grill-me/SKILL.md +1 -1
- package/.claude/skills/grill-me-codex/SKILL.md +45 -34
- package/.claude/skills/grill-with-docs/SKILL.md +1 -1
- package/.claude/skills/grill-with-docs-codex/SKILL.md +46 -34
- package/.claude/skills/kit-update/SKILL.md +12 -0
- package/.claude/skills/orchestrate-wave/SKILL.md +68 -21
- package/.claude/skills/orchestrate-wave/references/builder-contract.md +6 -4
- package/.claude/skills/retro/SKILL.md +23 -0
- package/.claude/skills/scale-check/SKILL.md +2 -2
- package/.claude/skills/setup-workflow/SKILL.md +44 -1
- package/.claude/skills/setup-workflow/workflow-overview.md +5 -5
- package/.claude/skills/skill-manifest.json +1 -1
- package/.claude/skills/tdd/SKILL.md +68 -14
- package/.claude/skills/to-issues/SKILL.md +104 -29
- package/.claude/skills/to-prd/SKILL.md +13 -3
- package/.claude/skills/to-waves/SKILL.md +16 -4
- package/.claude/skills/verify-spike/SKILL.md +1 -1
- package/.claude/skills/wrapup/SKILL.md +14 -3
- package/README.md +70 -7
- package/agent-workflow-kit.package.json +99 -43
- package/docs/adr/0001-consumer-divergence-policy.md +49 -0
- package/docs/agents/wave-anchor-template.md +1 -1
- package/docs/research/wave-152-consumer-acceptance.md +98 -0
- package/package.json +1 -1
- package/scripts/board-sync.py +187 -12
- package/scripts/build-kit.test.mjs +42 -1
- package/scripts/codex-exec-scenarios/fake-codex.mjs +152 -0
- package/scripts/codex-exec.sh +566 -0
- package/scripts/codex-exec.test.mjs +815 -0
- package/scripts/codex_proc.py +602 -0
- package/scripts/find-by-marker.py +68 -0
- package/scripts/marker_lib.py +88 -0
- package/scripts/pr-body-check.py +34 -6
- package/scripts/pr_body_e2e.py +83 -0
- package/scripts/render-anchor.py +111 -0
- package/scripts/test_board_sync.py +208 -0
- package/scripts/test_census_backstop.py +56 -3
- package/scripts/test_marker_lib.py +154 -0
- package/scripts/test_orchestrate_wave_contract.py +116 -0
- package/scripts/test_pr_body_check.py +245 -0
- package/scripts/test_render_anchor.py +267 -0
- package/scripts/test_retro_wrapup_contract.py +117 -0
- package/scripts/test_skill_codex_exec_lifecycle.py +123 -0
- package/scripts/test_tdd_contract.py +78 -0
- package/src/cli.mjs +44 -8
- package/src/commands/diff.mjs +5 -2
- package/src/commands/init.mjs +12 -0
- package/src/commands/own.mjs +16 -0
- package/src/commands/uninstall.mjs +8 -1
- package/src/commands/update.mjs +37 -9
- package/src/lib/bundle.mjs +14 -0
- package/src/lib/consumerPath.mjs +30 -0
- package/src/lib/manifest.mjs +18 -0
- package/src/lib/ownedDiff.mjs +88 -0
- package/src/lib/updateCandidate.mjs +14 -0
- package/src/lib/updateReconcile.mjs +45 -6
|
@@ -51,12 +51,14 @@ invocation for each in this prompt so the builder cannot guess a wrong one.
|
|
|
51
51
|
2. Commit your ONE commit on the slice branch FIRST — before any longer verify
|
|
52
52
|
(verify-then-forget-to-commit leaves the orchestrator hand-committing your
|
|
53
53
|
worktree). Do NOT push. Do NOT `--no-verify` (pre-commit hooks must pass).
|
|
54
|
-
3. Run the commands above
|
|
55
|
-
|
|
54
|
+
3. Run the commands above IN THE FOREGROUND — never background a test/gate
|
|
55
|
+
command. Use a generous foreground timeout for a long suite and wait for every
|
|
56
|
+
completed command result. Never end your turn while a command is still running.
|
|
56
57
|
|
|
57
58
|
## Report back (concise)
|
|
58
|
-
Files touched · decisions taken · test results (exact
|
|
59
|
-
STOP items · what the orchestrator should visually
|
|
59
|
+
Files touched · decisions taken · test results (exact completed command results
|
|
60
|
+
and exit status) · commit SHA · STOP items · what the orchestrator should visually
|
|
61
|
+
verify.
|
|
60
62
|
```
|
|
61
63
|
|
|
62
64
|
Orchestrator notes:
|
|
@@ -114,6 +114,25 @@ For **every** friction point (user-reported AND self-found), the agent analyzes:
|
|
|
114
114
|
|
|
115
115
|
If the user's description in step 2a is ambiguous, the agent may ask **ONE** clarifying outcome question — e.g. "where was it most annoying — during setup, mid-work, or during cleanup?". Never multiple-choice with memory names, hook paths, or config classes.
|
|
116
116
|
|
|
117
|
+
### 3a. Mechanical enforcement check (before target + weight)
|
|
118
|
+
|
|
119
|
+
Before placing a finding on the target/weight ladder, ask for every finding:
|
|
120
|
+
|
|
121
|
+
> **"Could a machine decide this — with a grep, parser, test, hook, or CI gate?"**
|
|
122
|
+
|
|
123
|
+
- **Yes, within the current patch:** implement the enforcement. Supporting prose
|
|
124
|
+
may explain the rule, but prose alone does not resolve a machine-checkable
|
|
125
|
+
finding.
|
|
126
|
+
- **Yes, but enforcement is too expensive for the current patch:** propose the
|
|
127
|
+
prose change **plus a tracked enforcement issue** and state the **explicit
|
|
128
|
+
trade-off** (why enforcement is deferred, what failure remains possible, and
|
|
129
|
+
when the issue should fire). Do not present the prose-only half as complete.
|
|
130
|
+
- **No:** record why judgment is required, then continue to the target/weight
|
|
131
|
+
ladder.
|
|
132
|
+
|
|
133
|
+
This check prevents detection without enforcement: a rule that a machine can
|
|
134
|
+
decide should not depend on a future reader remembering a sentence.
|
|
135
|
+
|
|
117
136
|
### 3b. Determine target + weight (threshold ladder)
|
|
118
137
|
|
|
119
138
|
Before formulating a patch in step 4, place **every** friction point on the threshold ladder. **Weight** = how durable/far-reaching the rule is (drives the visible patch line in step 4 + the user's approval depth). **Target** = where the patch physically goes.
|
|
@@ -137,6 +156,10 @@ Before formulating a patch in step 4, place **every** friction point on the thre
|
|
|
137
156
|
|
|
138
157
|
**A GitHub issue is NOT a weight tier.** A real follow-up = work to track → `python3 scripts/board-sync.py create` (step-4 table), **orthogonal** to the ladder; its "weight" follows the follow-up scope. The ladder classifies **config patches**, not "turn it into a ticket".
|
|
139
158
|
|
|
159
|
+
**Kit-repo routing target (always ask; never automatic).** When a finding lands on a kit-shipped file (a consumer-manifest entry with kit origin), ask whether the improvement is generic or project-specific. For a generic improvement, offer to file a lightweight issue against the public kit repo: a title plus a short body that states the finding, affected file, and why it is generic. For a project-specific improvement, recommend `own` (keep it consumer-owned). The consumer user does not need to be the kit maintainer.
|
|
160
|
+
|
|
161
|
+
Before any `gh issue create --repo <owner>/agent-workflow-kit` runs, show the user a **sanitized preview** of the exact title and body with consumer identifiers and secrets stripped. Create the issue only after the user explicitly approves that exact text; if the title or body changes, show the revised preview and ask again. This approval is additional to the per-patch approval in step 5.
|
|
162
|
+
|
|
140
163
|
**Target missing in the project — separate two cases cleanly:**
|
|
141
164
|
- **(a) Tier skill missing entirely** (e.g. a foreign project without `spec-self-critique`): no durable spec-time gate exists. **Memory is NOT a substitute** — passive recall doesn't catch a recurring spec defect before building. Report honestly: *"this project has no durable target for this tier"* + propose a `/setup-workflow` follow-up. **No fake guard via memory.**
|
|
142
165
|
- **(b) Skill exists, project-layer file missing** (`docs/agents/skills/<skill>.md`): **create / append** — that is the normal retro-sink behavior that `spec-self-critique` step 0 expects anyway. **No** downgrade.
|
|
@@ -119,7 +119,7 @@ One behavior, already clear enough to build — no PRD, no slicing.
|
|
|
119
119
|
|
|
120
120
|
```
|
|
121
121
|
Small change: <one-sentence behavior>.
|
|
122
|
-
`
|
|
122
|
+
`implement` — build directly, one behavior at a time (red → green → refactor). No PRD, no decomposition.
|
|
123
123
|
```
|
|
124
124
|
|
|
125
125
|
### Bug (something that used to work)
|
|
@@ -134,7 +134,7 @@ Bug: <what's broken — expected vs. actual>.
|
|
|
134
134
|
```
|
|
135
135
|
scale-check: verdict=<Program | Feature | Direct-Slice | Bug>
|
|
136
136
|
criteria tripped=<C1,C2,… | none | n/a (bug/direct)>
|
|
137
|
-
route=<program grill → to-prd → to-waves (all waves execute-ready by default) | grill-with-docs → to-prd → to-issues |
|
|
137
|
+
route=<program grill → to-prd → to-waves (all waves execute-ready by default) | grill-with-docs → to-prd → to-issues | implement | diagnose>
|
|
138
138
|
start-prompt: <the paste-ready block above, filled in>
|
|
139
139
|
```
|
|
140
140
|
|
|
@@ -27,6 +27,7 @@ This is a prompt-driven skill, not a deterministic script. Explore, present what
|
|
|
27
27
|
| `.github/workflows/agent-workflow-kit-update.yml` | optional tested Kit update pull request for GitHub consumers (Section A2) |
|
|
28
28
|
| `docs/agents/census.md` | optional-census choice, paths, state, and safe disable contract seeded from [census.md](./census.md) (Section A3) |
|
|
29
29
|
| `docs/agents/workflow-capabilities.json` + capability assets | consumer-owned Worktree Lifecycle, Memory Lifecycle, Workflow Advisories, and Safety Guardrails choices (Sections A4–A7) |
|
|
30
|
+
| `.claude/settings.json` | additive activation of the advisory kit-origin Edit/Write hint (Section A8) |
|
|
30
31
|
|
|
31
32
|
## Idempotency contract — read before writing anything
|
|
32
33
|
|
|
@@ -57,7 +58,7 @@ Read the current state; don't assume. For every target file, read its first line
|
|
|
57
58
|
- `CONTEXT.md`, `CONTEXT-MAP.md`, `docs/adr/` — domain-doc layout.
|
|
58
59
|
- `docs/agents/`, `docs/agents/skills/`, `docs/conventions/` — prior output of this skill.
|
|
59
60
|
- `docs/agents/census.md`, `.census/profile.json`, `.census/active.json` — an existing census choice or consumer-owned census to adopt.
|
|
60
|
-
- `docs/agents/workflow-capabilities.json`, `.claude/settings.json`, `git config --get core.hooksPath` — existing capability choices/profile plus Worktree Lifecycle, Workflow Advisories,
|
|
61
|
+
- `docs/agents/workflow-capabilities.json`, `.claude/settings.json`, `git config --get core.hooksPath` — existing capability choices/profile plus Worktree Lifecycle, Workflow Advisories, Safety Guardrails, and kit-origin hint wiring to adopt.
|
|
61
62
|
- `.memory/active/`, `.memory/archive/`, and `.memory/receipts/` — consumer-owned Memory Lifecycle policies or recovery evidence to adopt without normalization.
|
|
62
63
|
- `gh auth status` (if GitHub) — is `gh` authenticated, and with which scopes?
|
|
63
64
|
|
|
@@ -243,6 +244,42 @@ The seed's reference consumer uses the parity-on profile. Other consumers are
|
|
|
243
244
|
opt-in/manual: never copy its package-manager, path, shim, surface, or outage
|
|
244
245
|
decisions without repository evidence and user confirmation.
|
|
245
246
|
|
|
247
|
+
### 2g. Section A8 — Advisory kit-origin edit hint (non-interactive)
|
|
248
|
+
|
|
249
|
+
> The shipped kit-origin hook asks the upstream-or-own question before an agent
|
|
250
|
+
> Edit/Write changes a file recorded with `origin: "kit"` in the consumer
|
|
251
|
+
> manifest. It is advisory only: it never blocks, reads the manifest once, uses
|
|
252
|
+
> no network, and silently fails open when the manifest cannot be read. Shell
|
|
253
|
+
> redirection, formatters, and IDE edits are knowingly outside its coverage; the
|
|
254
|
+
> skills remain the rule's primary carrier.
|
|
255
|
+
|
|
256
|
+
Activate the shipped hook by reconciling this exact entry into
|
|
257
|
+
`.claude/settings.json`:
|
|
258
|
+
|
|
259
|
+
```json kit-origin-edit-hook-settings
|
|
260
|
+
{
|
|
261
|
+
"matcher": "Edit|Write",
|
|
262
|
+
"hooks": [
|
|
263
|
+
{
|
|
264
|
+
"type": "command",
|
|
265
|
+
"command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/kit-origin-edit-hint.py\""
|
|
266
|
+
}
|
|
267
|
+
]
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
This is an additive, idempotent settings edit, not a settings rewrite:
|
|
272
|
+
|
|
273
|
+
1. Missing settings → create `{ "hooks": { "PreToolUse": [<entry>] } }`.
|
|
274
|
+
2. Existing valid settings → preserve every consumer key, matcher, command,
|
|
275
|
+
hook event, ordering, and formatting byte-for-byte; append only `<entry>` to
|
|
276
|
+
`hooks.PreToolUse`.
|
|
277
|
+
3. If any existing hook already contains the exact command above, do nothing,
|
|
278
|
+
regardless of its surrounding matcher. A rerun must be byte-identical.
|
|
279
|
+
4. Unreadable/invalid settings, or a non-object `hooks` / non-array
|
|
280
|
+
`PreToolUse`, are consumer-owned conflicts: leave the file untouched and
|
|
281
|
+
report the skipped activation. Never replace or normalize them.
|
|
282
|
+
|
|
246
283
|
### 3. Section B — Triage labels
|
|
247
284
|
|
|
248
285
|
> When `triage` processes an incoming issue it applies labels (or your tracker's equivalent). It needs strings you've actually configured, or it creates duplicates.
|
|
@@ -341,6 +378,12 @@ Do not copy templates with shell commands or edit the capability profile by
|
|
|
341
378
|
hand. Report `seeded · adopted · skipped`; do not print memory contents or
|
|
342
379
|
receipt contents.
|
|
343
380
|
|
|
381
|
+
For `.claude/settings.json`, run the Section A8 reconciliation on fresh and
|
|
382
|
+
already-initialized consumers. Report `activated · already active · skipped
|
|
383
|
+
(consumer-owned conflict)`. Do not make the hook conditional on an optional
|
|
384
|
+
capability choice: its self-filtering, fail-open behavior keeps it inert except
|
|
385
|
+
for matching kit-origin Edit/Write events.
|
|
386
|
+
|
|
344
387
|
For the **`## Workflow`**, **`## Agent skills`**, and **`## Prod`** blocks, reconcile per section in **both** CLAUDE.md and AGENTS.md that exist:
|
|
345
388
|
|
|
346
389
|
- If **both** files exist → write/update the block in **both** (keep them coherent — Codex is a first-class surface).
|
|
@@ -11,12 +11,12 @@ Use this section as the entry-point map for agent-assisted work. The individual
|
|
|
11
11
|
- **Existing plan, PRD, or ready issue:** use `to-issues` to split it into independently buildable tracer-bullet slices.
|
|
12
12
|
- **A Program-PRD with a wave plan:** use `to-waves` to unfold it into named wave stubs + slice leaves on the board, after a chat preview gate that shows the whole plan before any write.
|
|
13
13
|
- **A backlog of open issues needs clustering into themed waves:** use `board-to-waves`.
|
|
14
|
-
- **A whole wave anchor (file-disjoint slices, specs already locked) to build, verify and land end-to-end — often AFK:** use `orchestrate-wave` — it dispatches implementers per slice, integrates serially, verifies centrally, and lands. (A single slice just goes to `
|
|
14
|
+
- **A whole wave anchor (file-disjoint slices, specs already locked) to build, verify and land end-to-end — often AFK:** use `orchestrate-wave` — it dispatches implementers per slice, integrates serially, verifies centrally, and lands. (A single slice just goes to `implement`.)
|
|
15
15
|
- **Bugs or requests piling up that you didn't create:** use `triage` to move them into agent-ready issues.
|
|
16
16
|
- **Bug or regression:** use `diagnose` to reproduce, minimize, hypothesize, instrument, fix, and regression-test.
|
|
17
17
|
- **A design question needs a runnable answer (state, business logic, a UI you have to see):** spike it with `prototype`, then fold what you learned back in.
|
|
18
|
-
- **Multi-session build from a PRD or issue:** use `implement` to drive
|
|
19
|
-
- **Implementation slice:** use `
|
|
18
|
+
- **Multi-session build from a PRD or issue:** use `implement` to drive the build end-to-end, one red-green slice at a time.
|
|
19
|
+
- **Implementation slice:** use `implement` for one behavior at a time: RED, GREEN, then refactor.
|
|
20
20
|
- **Build or refresh a project-local census:** use `census-update` to scan facts, resolve ambiguous decisions one at a time, and transactionally activate a counted census.
|
|
21
21
|
- **Preview or restore consumer-owned memories:** use `memory-lifecycle` to classify every configured path without writing, then apply an explicitly approved collision-safe restore with a content-free receipt.
|
|
22
22
|
- **Finished slice:** use `wrapup` to prepare the branch, PR, and cleanup steps your repo expects.
|
|
@@ -27,11 +27,11 @@ Use this section as the entry-point map for agent-assisted work. The individual
|
|
|
27
27
|
|
|
28
28
|
## Routing Rule
|
|
29
29
|
|
|
30
|
-
Prefer the smallest workflow that produces a clear next action. A tiny fix can go straight to `
|
|
30
|
+
Prefer the smallest workflow that produces a clear next action. A tiny fix can go straight to `implement`; a cross-cutting feature should become a PRD and then slices before implementation. When a skill reports missing project context, run `setup-workflow` again and fill only the missing stub.
|
|
31
31
|
|
|
32
32
|
## Depth Ladder
|
|
33
33
|
|
|
34
|
-
- **Light:** direct `
|
|
34
|
+
- **Light:** direct `implement` for a small, well-understood change.
|
|
35
35
|
- **Medium:** `to-issues` for a ready artefact that needs slicing.
|
|
36
36
|
- **Deep:** `grill-with-docs` followed by `to-prd` and `to-issues` when terminology, contracts, rollout order, or ownership are still uncertain.
|
|
37
37
|
- **Gate:** insert `verify-spike` or `decision-gate` before any depth level when a slice hinges on an unresolved fact or trade-off.
|
|
@@ -60,6 +60,8 @@ Before writing any code:
|
|
|
60
60
|
|
|
61
61
|
- [ ] Confirm with user what interface changes are needed
|
|
62
62
|
- [ ] Confirm with user which behaviors to test (prioritize)
|
|
63
|
+
- [ ] Find the nearest existing tests for those behaviors
|
|
64
|
+
- [ ] Assign exactly one test-delta decision per behavior
|
|
63
65
|
- [ ] Identify opportunities for [deep modules](deep-modules.md) (small interface, deep implementation)
|
|
64
66
|
- [ ] Design interfaces for [testability](interface-design.md)
|
|
65
67
|
- [ ] List the behaviors to test (not implementation steps)
|
|
@@ -69,34 +71,81 @@ Ask: "What should the public interface look like? Which behaviors are most impor
|
|
|
69
71
|
|
|
70
72
|
**You can't test everything.** Confirm with the user exactly which behaviors matter most. Focus testing effort on critical paths and complex logic, not every possible edge case.
|
|
71
73
|
|
|
72
|
-
### 2.
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
### 2. Existing-Test-First Decision
|
|
75
|
+
|
|
76
|
+
TDD does not imply a new test file or a growing test count. Start at the nearest
|
|
77
|
+
existing behavioral test. For each planned behavior, record exactly one of these
|
|
78
|
+
test-delta decisions:
|
|
79
|
+
|
|
80
|
+
- **REUSE** — the existing public-behavior test already protects the change.
|
|
81
|
+
- **EXTEND** — add the missing boundary to the nearest suite or parameter table.
|
|
82
|
+
- **REPLACE** — establish equivalent protection at a smaller or more stable level,
|
|
83
|
+
then retire the duplicate.
|
|
84
|
+
- **NEW** — only for a distinct, previously unprotected risk; name the plausible
|
|
85
|
+
defect it catches.
|
|
86
|
+
- **RETIRE** — the behavior or contract is intentionally gone or already replaced;
|
|
87
|
+
delete its obsolete test.
|
|
88
|
+
- **NO-NEW-TEST** — a behavior-neutral refactor or removal without a durable
|
|
89
|
+
negative contract.
|
|
90
|
+
|
|
91
|
+
Do not create a new test file until the nearest existing owner has been inspected
|
|
92
|
+
and rejected with a reason. A feature, source file, component, method, or
|
|
93
|
+
acceptance-criterion line is not itself a test boundary.
|
|
94
|
+
|
|
95
|
+
Every executable new behavior and bug fix must begin with a failing assertion.
|
|
96
|
+
REUSE and NO-NEW-TEST never bypass this RED-first invariant. For a `REUSE`
|
|
97
|
+
candidate, run the existing assertion before implementation: if the requested
|
|
98
|
+
behavior is executable and the assertion is already green, an already-green
|
|
99
|
+
assertion does not prove the requested change; choose `EXTEND`, or choose `NEW`
|
|
100
|
+
after rejecting the nearest owner. `NO-NEW-TEST` is limited to behavior-neutral
|
|
101
|
+
work and removals without a durable absence contract.
|
|
102
|
+
|
|
103
|
+
For removals, delete the tests that specified the retired behavior. Add or keep a
|
|
104
|
+
negative assertion (`404`, forbidden, hidden) only when absence itself is a durable
|
|
105
|
+
security, API, or compatibility promise. Permanent skipped executable tests are
|
|
106
|
+
retired or moved to a runbook or issue, not parked in the green suite.
|
|
107
|
+
|
|
108
|
+
### Worked decision matrix
|
|
109
|
+
|
|
110
|
+
| Behavior situation | Decision | Feedback proof |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| An existing regression test reproduces the bug | REUSE | Existing assertion is RED, then the minimal fix makes it GREEN |
|
|
113
|
+
| The nearest suite lacks one requested boundary | EXTEND | Added assertion is RED, then the minimal change makes it GREEN |
|
|
114
|
+
| A broad duplicate can become a stable focused check | REPLACE | Equivalent protection is proven before the duplicate is removed |
|
|
115
|
+
| A distinct risk has no suitable owner after documented inspection | NEW | New assertion is RED and names the plausible defect it catches |
|
|
116
|
+
| The specified behavior is intentionally removed | RETIRE | Obsolete test is removed with the obsolete behavior |
|
|
117
|
+
| An internal refactor preserves all observable behavior | NO-NEW-TEST | Relevant existing suite is GREEN before and after the change |
|
|
118
|
+
|
|
119
|
+
### 3. First Feedback Cycle
|
|
120
|
+
|
|
121
|
+
Pick ONE behavior and use its decision's feedback loop:
|
|
75
122
|
|
|
76
123
|
```
|
|
77
|
-
|
|
78
|
-
|
|
124
|
+
REUSE, executable change: existing assertion → RED → minimal code → GREEN
|
|
125
|
+
EXTEND/NEW: assertion in nearest suite → RED → minimal code → GREEN
|
|
126
|
+
REUSE, neutral change: relevant suite GREEN → small refactor → stays GREEN
|
|
127
|
+
REPLACE: prove equivalent protection → remove duplicate → GREEN
|
|
128
|
+
RETIRE: remove obsolete behavior and its obsolete test → GREEN
|
|
129
|
+
NO-NEW-TEST: relevant suite GREEN → behavior-neutral change → stays GREEN
|
|
79
130
|
```
|
|
80
131
|
|
|
81
|
-
|
|
132
|
+
The RED-to-GREEN cycle is the tracer bullet for each executable new behavior or
|
|
133
|
+
bug fix. It proves the path end to end without automatically creating another
|
|
134
|
+
test file.
|
|
82
135
|
|
|
83
|
-
###
|
|
136
|
+
### 4. Incremental Loop
|
|
84
137
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
RED: Write next test → fails
|
|
89
|
-
GREEN: Minimal code to pass → passes
|
|
90
|
-
```
|
|
138
|
+
Repeat one behavior at a time, using the matching feedback loop above.
|
|
91
139
|
|
|
92
140
|
Rules:
|
|
93
141
|
|
|
94
142
|
- One test at a time
|
|
143
|
+
- Prefer extending the existing owner or parameter matrix over adding a sibling file
|
|
95
144
|
- Only enough code to pass current test
|
|
96
145
|
- Don't anticipate future tests
|
|
97
146
|
- Keep tests focused on observable behavior
|
|
98
147
|
|
|
99
|
-
###
|
|
148
|
+
### 5. Refactor
|
|
100
149
|
|
|
101
150
|
After all tests pass, look for [refactor candidates](refactoring.md):
|
|
102
151
|
|
|
@@ -114,7 +163,12 @@ After all tests pass, look for [refactor candidates](refactoring.md):
|
|
|
114
163
|
[ ] Test describes behavior, not implementation
|
|
115
164
|
[ ] Test uses public interface only
|
|
116
165
|
[ ] Test would survive internal refactor
|
|
166
|
+
[ ] Exactly one test-delta decision is recorded for this behavior
|
|
167
|
+
[ ] NEW names the distinct plausible defect; a new file has a justified owner boundary
|
|
117
168
|
[ ] Code is minimal for this test
|
|
118
169
|
[ ] No speculative features added
|
|
119
170
|
[ ] Wave slice: a flipped/new assumption affecting an unbuilt sibling issue → log it to ANNAHMEN.md (worktree root; wrapup Step 0c reads it)
|
|
120
171
|
```
|
|
172
|
+
|
|
173
|
+
At handoff, list every behavior and its one decision, then report the counted
|
|
174
|
+
test delta: `Reused X · Extended Y · New Z · Replaced/retired W`.
|
|
@@ -54,7 +54,7 @@ Even when the slices were already cut upstream (a grill/PRD slice table), do NOT
|
|
|
54
54
|
- **Seam ownership check (Fix A):** does any slice **replace/unify/retire a central mechanism**? If yes, it MUST be its own 🧊 grill-needed slice — NOT hidden in a behavior-preserving naming/tweak leaf. A byte-neutral slice does not discharge the seam.
|
|
55
55
|
- **Blast-radius threshold:** for each slice, estimate the blast radius (~N files, from recon/grep — not a guess; workflow slices count SKILL.md + adapter mirrors + tests). **≥ 10 estimated files OR not estimable → check for a split.** If the slice stays deliberately large, it MUST be 🧊 **grill-needed** (HITL) with a "why indivisible" justification **in the issue body** — a guideline, not a hard block, but the deviation lives in the body, not in the agent's head. (Incident: a slice cut too coarse ballooned to 34 prod files at execute-recon, an emergency in-build split — no gate at the cut existed.) (Terminology note: this blast radius is a **slice estimate** — ~N files for this one cut — not a project-owned rollout-completeness census (e.g. an-style, code-derived "X of Y" census over all surfaces of a cross-cutting concept, if your repo runs one).)
|
|
56
56
|
<!-- mirror-xform:start codex-escalation -->
|
|
57
|
-
- **Gate type + sequencing (Retro):** every slice that is **not** a clean AFK build gets a gate tag — 🧭 **Design Grill** (a decision with alternatives, hard-to-reverse, ADR-worthy → `grill-with-docs-codex`), 🔬 **Verify Spike** (a pure fact question, read-only), 📐 **Trade-off/Research** (a concrete trade-off choice OR "needs more research", **below** the grill threshold — read-only research + a documented trade-off in the issue), 📝 **Review Note** (a finding, **not** a build slice). A gate slice (🧭/🔬/📐) is cut as its **own slice**, sequenced **before** its dependent build slice, and blocks it (gate-before-build — published as a **native blocking edge** (§5a step 5), visible in the mirrored "Blocked by" section + table order). "Needs a decision / open call / research gap" while cutting → gate slice, **never** a blind AFK `/
|
|
57
|
+
- **Gate type + sequencing (Retro):** every slice that is **not** a clean AFK build gets a gate tag — 🧭 **Design Grill** (a decision with alternatives, hard-to-reverse, ADR-worthy → `grill-with-docs-codex`), 🔬 **Verify Spike** (a pure fact question, read-only), 📐 **Trade-off/Research** (a concrete trade-off choice OR "needs more research", **below** the grill threshold — read-only research + a documented trade-off in the issue), 📝 **Review Note** (a finding, **not** a build slice). A gate slice (🧭/🔬/📐) is cut as its **own slice**, sequenced **before** its dependent build slice, and blocks it (gate-before-build — published as a **native blocking edge** (§5a step 5), visible in the mirrored "Blocked by" section + table order). "Needs a decision / open call / research gap" while cutting → gate slice, **never** a blind AFK `/implement`. (🔬 **Verify Spike** runs via the `verify-spike` skill — read-only fact question, throwaway harness, verdict as ADR/comment, the throwaway deleted. 📐 **Trade-off/Research** runs via the `decision-gate` skill — options + criteria, read-only research/measurement, a documented trade-off table, a reasoned decision as ADR/comment; throwaway measurement code deleted.)
|
|
58
58
|
<!-- mirror-xform:end -->
|
|
59
59
|
- **🧭-vs.-📐 discriminator:** if the decision replaces/unifies/retires a **central seam**, is a **one-way door** (hard/costly to reverse), or a **schema migration** → 🧭 Design Grill (ADR-worthy, see Seam Ownership above). Otherwise — a **bounded choice between concrete options**, easily revised → 📐 Trade-off/Research.
|
|
60
60
|
- **Absence-before-build (Retro):** a slice cut as "build feature/page/endpoint/flow X" (or a gate "X gap unclear") MUST cite an **existence grep** — *absent* (`grep <pattern> = 0` across route **and** UI **and** repo) OR *partial* (`exists @<file>, gap = <Y>`). A hedge ("current state unclear → verify during build") is **not** a valid slice state: the check is cheap (minutes), so it happens **at the cut**, not deferred into a gate. (Incident: a gate was cut for a feature that greps already showed built — the gap was deferred instead of resolved.)
|
|
@@ -143,33 +143,108 @@ else
|
|
|
143
143
|
WAVE="$CURRENT" # Stufe-1p Program-stub — reuse
|
|
144
144
|
fi
|
|
145
145
|
|
|
146
|
-
# 2.
|
|
147
|
-
# body header `**Welle $WAVE — <
|
|
148
|
-
#
|
|
149
|
-
#
|
|
150
|
-
#
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
146
|
+
# 2. Fill /tmp/anchor-template.md from docs/agents/wave-anchor-template.md (Tier 2):
|
|
147
|
+
# body header `**Welle $WAVE — <Topic>**`, anchor-owned markers at the head,
|
|
148
|
+
# filled Slices table, and the To-Do checklist collapsed to one line. Save the
|
|
149
|
+
# unchanged source PRD body as /tmp/source-prd.md. The renderer reads only those
|
|
150
|
+
# two files and writes only stdout: no GitHub/network call and no mutation.
|
|
151
|
+
python3 scripts/render-anchor.py --template /tmp/anchor-template.md \
|
|
152
|
+
--prd /tmp/source-prd.md --document anchor > /tmp/anchor.md
|
|
153
|
+
python3 scripts/render-anchor.py --template /tmp/anchor-template.md \
|
|
154
|
+
--prd /tmp/source-prd.md --document archive > /tmp/prd-archive.md
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The anchor output is the filled template byte-for-byte. The archive starts with
|
|
158
|
+
the stable `📄 Full PRD` marker and strips every canonical marker line
|
|
159
|
+
(`plan_revision`, `prd-source-id`, `prd-content-fp`, `<!-- prd: … -->`) only
|
|
160
|
+
from the source body's head block. Marker-looking text in a quote, fence, or
|
|
161
|
+
later section is content and remains untouched.
|
|
162
|
+
|
|
163
|
+
Promotion uses the remote issue itself as its journal. Classify four
|
|
164
|
+
observations before every resume. Before transition 1, `S=yes|no` compares a
|
|
165
|
+
freshly fetched remote body byte-for-byte with `/tmp/source-prd.md`, the source
|
|
166
|
+
snapshot that produced both rendered outputs. Once `B=yes`, that source
|
|
167
|
+
snapshot is no longer active and `S=n/a`. `B=yes|no` says whether the fetched
|
|
168
|
+
issue body is byte-identical to `/tmp/anchor.md`.
|
|
169
|
+
`C=0|exact-1|wrong-1|duplicates(<ids>)` classifies stable-marker comments:
|
|
170
|
+
none; exactly one whose whole body is byte-identical to
|
|
171
|
+
`/tmp/prd-archive.md`; exactly one with different bytes; or multiple matches
|
|
172
|
+
with every comment ID retained. `P=absent|complete|partial` classifies only
|
|
173
|
+
promotion-owned board state. `P=absent` accepts either an
|
|
174
|
+
ordinary pre-state (no `type:cluster`, Wave unset, no `Welle` title prefix) or a
|
|
175
|
+
valid Stufe-1p pre-state (`wave-stub` present, no `type:cluster`, and the
|
|
176
|
+
pre-stamped Wave/title match `$WAVE`). `P=complete` requires `type:cluster`, the
|
|
177
|
+
expected Wave/title, and no remaining `wave-stub`. Every other combination —
|
|
178
|
+
including a different Wave — is `P=partial`. Fetch comments with the paginated
|
|
179
|
+
API, never the first page alone:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
gh api --paginate --slurp \
|
|
183
|
+
"repos/<owner>/<repo>/issues/<prd#>/comments?per_page=100"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Flatten every returned page, retain the comment `id`, and exact-match the
|
|
187
|
+
start-of-body marker. The four valid states and their sole resume action are:
|
|
188
|
+
|
|
189
|
+
<!-- promotion-board-observation-table:start -->
|
|
190
|
+
| Scenario | Observable board facts | P classification |
|
|
191
|
+
|---|---|---|
|
|
192
|
+
| `ordinary-prestate` | no cluster; Wave unset; no Wave title | `absent` |
|
|
193
|
+
| `stufe-1p-prestate` | wave-stub; no cluster; expected Wave/title | `absent` |
|
|
194
|
+
| `promoted` | cluster; expected Wave/title; no wave-stub | `complete` |
|
|
195
|
+
| `cluster-only` | cluster; Wave/title missing | `partial` |
|
|
196
|
+
| `wrong-wave` | any different Wave value | `partial` |
|
|
197
|
+
<!-- promotion-board-observation-table:end -->
|
|
198
|
+
|
|
199
|
+
<!-- promotion-state-table:start -->
|
|
200
|
+
| State | Observable predicates | Resume action |
|
|
201
|
+
|---|---|---|
|
|
202
|
+
| `initial` | `S=yes`, `B=no`, `C=0`, `P=absent` | render + write body |
|
|
203
|
+
| `body-written` | `S=n/a`, `B=yes`, `C=0`, `P=absent` | reconcile + write archive comment |
|
|
204
|
+
| `comment-written` | `S=n/a`, `B=yes`, `C=exact-1`, `P=absent` | promote board state |
|
|
205
|
+
| `promoted` | `S=n/a`, `B=yes`, `C=exact-1`, `P=complete` | no-op; continue publish audit |
|
|
206
|
+
<!-- promotion-state-table:end -->
|
|
207
|
+
|
|
208
|
+
Each transition is idempotent and has an explicit contract:
|
|
209
|
+
|
|
210
|
+
1. **Write body (`initial → body-written`).** Pre: `S=yes`, `B=no`, `C=0`,
|
|
211
|
+
`P=absent`. Fetch the remote body again immediately before the command and
|
|
212
|
+
recompute `S`; a prior fetch is not sufficient.
|
|
213
|
+
Run `gh issue edit <prd#> --body-file /tmp/anchor.md`, refetch the body, and
|
|
214
|
+
require a byte match. Post: `S=n/a`, `B=yes`, `C=0`, `P=absent`.
|
|
215
|
+
2. **Write archive (`body-written → comment-written`).** Pre: `S=n/a`, `B=yes`,
|
|
216
|
+
`C=0`, `P=absent`. Re-run the pagination-aware lookup immediately before
|
|
217
|
+
create; if it now yields `C=exact-1`, classify as `comment-written` and do
|
|
218
|
+
not create. `C=wrong-1` or `C=duplicates(<ids>)` is drift and enters repair,
|
|
219
|
+
never create. Only `C=0` runs `gh issue comment <prd#> --body-file
|
|
220
|
+
/tmp/prd-archive.md`, then immediately paginate and reconcile again. Post:
|
|
221
|
+
`S=n/a`, `B=yes`, `C=exact-1`, `P=absent`.
|
|
222
|
+
3. **Promote (`comment-written → promoted`).** Pre: `S=n/a`, `B=yes`,
|
|
223
|
+
`C=exact-1`, `P=absent`. Run `python3 scripts/board-sync.py promote --issue <prd#> --wave
|
|
224
|
+
"$WAVE"`, refetch body, comments, labels, Wave, and title. Post: `S=n/a`,
|
|
225
|
+
`B=yes`, `C=exact-1`, `P=complete`. Re-running `promote` with the same Wave
|
|
226
|
+
is the repair for `P=partial`; a different Wave remains a hard stop.
|
|
227
|
+
|
|
228
|
+
Any other predicate combination is drift, not a fifth state. Repair it
|
|
229
|
+
explicitly, then reclassify. `S=no` before transition 1 means **STOP**: report
|
|
230
|
+
the diff between the fresh remote body and `/tmp/source-prd.md`, never write the
|
|
231
|
+
stale render, re-fetch the remote body into a reviewed source snapshot, and
|
|
232
|
+
rerender both outputs before recomputing `S`. `B=no` outside the valid `initial` tuple
|
|
233
|
+
means **STOP**, report the body diff against `/tmp/anchor.md`, and require
|
|
234
|
+
an explicit operator decision to restore the rendered anchor or adopt the remote
|
|
235
|
+
edit and rerender both outputs; never overwrite remote journal evidence automatically.
|
|
236
|
+
Only transition 1 performs the approved source-to-anchor body write without
|
|
237
|
+
this drift gate. `C=wrong-1` → report its ID and explicitly update it to the
|
|
238
|
+
rendered archive; `P=complete` with `C=0` → create/reconcile the archive without
|
|
239
|
+
demoting. For `P=partial`, a different Wave is a hard stop; otherwise rerun
|
|
240
|
+
same-Wave `promote`. `C=duplicates(<ids>)` always means **STOP and report every
|
|
241
|
+
comment ID**. An operator must choose and explicitly delete/update the
|
|
242
|
+
duplicates, then rerun the paginated lookup; never select the first match or
|
|
243
|
+
silently discard one. No local operation journal is written: these
|
|
244
|
+
observations are the journal.
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# 3. Continue only from the `promoted` state.
|
|
173
248
|
|
|
174
249
|
# 4. create each child (dependency order), then link it under the anchor — BEFORE the §7 exit audit,
|
|
175
250
|
# so the checker sees the anchor's children (a childless type:cluster anchor mis-reads as a leaf)
|
|
@@ -302,7 +377,7 @@ Reference the blocking ticket(s), or "None - can start immediately".
|
|
|
302
377
|
<!-- mirror-xform:start codex-escalation -->
|
|
303
378
|
```
|
|
304
379
|
Welle <N> · Slice <X> (<closes #x | refs #<prd#>, Parent #<prd#>>). Read #<prd#> for decisions.
|
|
305
|
-
Start skill: 🧭 Design Grill → /grill-with-docs-codex · 🔬 Verify Spike → /verify-spike · 📐 Trade-off/Research → /decision-gate · AFK → /
|
|
380
|
+
Start skill: 🧭 Design Grill → /grill-with-docs-codex · 🔬 Verify Spike → /verify-spike · 📐 Trade-off/Research → /decision-gate · AFK → /implement · HITL → /grill-me → /implement. Recommended model: <Model [Effort]>.
|
|
306
381
|
Worktree: your project's worktree helper, or `git worktree add`
|
|
307
382
|
Scope (<N> files) — REQUIRED FIELD, blast-radius estimate at cut time; the build session checks it against its own recon findings, >2x deviation → STOP:
|
|
308
383
|
- <concrete file + change>
|
|
@@ -49,11 +49,21 @@ gh project item-list 1 --owner <owner> --limit 500 --format json # check targe
|
|
|
49
49
|
- **Mode A — idempotency via two separate markers in the body:**
|
|
50
50
|
- **Stable source identity** `<!-- prd-source-id: <id> -->` — **never** changes across plan content edits (otherwise search-before-create misses the changed re-run → duplicate). **Default rule** for `<id>` (identity ≠ content; set on the **first** to-prd run, **never** changed after — the slug then lives in the issue body and is discoverable via search-before-create): kebab-case slug of the plan topic. Priority: **(1)** explicitly passed ID / durable issue number → **(2)** existing slug from a prior run (found via search-before-create) → **(3)** new kebab-case slug from the plan/title topic. The `PLAN.md` path is only a **secondary hint** (not stable across worktrees; external specs have none), **never** the identity itself.
|
|
51
51
|
- **Separate content fingerprint** `<!-- prd-content-fp: <hash> -->` — only for diff/audit/bump decisions, **not** for identity.
|
|
52
|
-
- **search-before-create:**
|
|
52
|
+
- **search-before-create:** use the shared all-state exact-marker lookup (it uses
|
|
53
|
+
`gh api --paginate`, discards REST pull-request items, and never relies on
|
|
54
|
+
GitHub Search or a capped issue list):
|
|
53
55
|
```bash
|
|
54
|
-
|
|
55
|
-
# filter locally on `prd-source-id: <id>` → 1 match ⇒ update; >1 ⇒ STOP+report; 0 ⇒ create
|
|
56
|
+
python3 scripts/find-by-marker.py --kind prd-source-id --slug "<id>"
|
|
56
57
|
```
|
|
58
|
+
Branch on its JSON contract (`count`, `issues[].number`, `issues[].state`,
|
|
59
|
+
`verdict`): `0` / `create` → create; exactly one `open` / `update` → update
|
|
60
|
+
that issue; exactly one `closed` / `user-decision` → ask the user whether to
|
|
61
|
+
reopen, use a new identity, or stop; `>1` / `STOP` → stop and report every
|
|
62
|
+
number/state. Never auto-delete or silently replace a closed/duplicate identity.
|
|
63
|
+
Immediately after a Mode-A create, run the same lookup with
|
|
64
|
+
`--created <new-issue-number>`. Continue only when it returns exactly the
|
|
65
|
+
newly-created open issue; duplicate reconciliation is a loud `STOP` that
|
|
66
|
+
reports both/all numbers for user-decided resolution.
|
|
57
67
|
|
|
58
68
|
## 4. Write the Draft PRD (deliverable)
|
|
59
69
|
|
|
@@ -192,10 +192,22 @@ A re-run of to-waves on the same program is **delta-apply** and doubles as
|
|
|
192
192
|
bottom-up `wave-stub-source` marker; `<prd-source-id>` is the PRD's own source
|
|
193
193
|
slug). These never change across revisions — they are the identity for
|
|
194
194
|
search-before-create.
|
|
195
|
-
- **Delta apply.**
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
195
|
+
- **Delta apply.** Resolve every planned identity through the shared all-state,
|
|
196
|
+
exact-marker CLI (it uses `gh api --paginate`, discards REST pull-request
|
|
197
|
+
items, and does not rely on GitHub Search or a capped issue list):
|
|
198
|
+
```bash
|
|
199
|
+
python3 scripts/find-by-marker.py --kind program-stub-source --slug "<prd-source-id>/w<N>"
|
|
200
|
+
python3 scripts/find-by-marker.py --kind program-leaf-source --slug "<prd-source-id>/<local-id>"
|
|
201
|
+
```
|
|
202
|
+
Branch on each JSON result (`count`, `issues[].number`, `issues[].state`,
|
|
203
|
+
`verdict`): `0` / `create` → create; exactly one `open` / `update` → update in
|
|
204
|
+
place; exactly one `closed` / `user-decision` → ask the user whether to reopen,
|
|
205
|
+
use a new identity, or stop; `>1` / `STOP` → stop and report every number/state.
|
|
206
|
+
Never auto-delete or silently replace a closed/duplicate identity. Immediately
|
|
207
|
+
after every create, run the same lookup with `--created <new-issue-number>` and
|
|
208
|
+
continue only when exactly the newly-created open issue is returned; a duplicate
|
|
209
|
+
reconciliation stops loudly with both/all numbers for user-decided resolution.
|
|
210
|
+
A live issue carrying a
|
|
199
211
|
`program-*-source` for this program that the current plan no longer references →
|
|
200
212
|
report as **orphaned** (do not auto-close — closing is the abort convention, §8).
|
|
201
213
|
Cross-check the native children (`children-of <prd#>` and each stub) against the
|
|
@@ -17,7 +17,7 @@ This is the "Verify First" rule with a runnable harness behind it: when you cann
|
|
|
17
17
|
| "Which of these options, given these trade-offs?" / "I need to research this before I can choose." (bounded, sub-grill) | `decision-gate` |
|
|
18
18
|
| "Does this design / state model / UI feel right?" (open-ended) | `prototype` |
|
|
19
19
|
| "Why is this broken / slow?" (root-cause of a known defect) | `diagnose` |
|
|
20
|
-
| "Build this behaviour, test-first." (new feature/fix) | `
|
|
20
|
+
| "Build this behaviour, test-first." (new feature/fix) | `implement` |
|
|
21
21
|
|
|
22
22
|
If the question is really "what should this be", it is not a verify-spike — those are open, not yes/no.
|
|
23
23
|
|
|
@@ -39,9 +39,21 @@ Hard stop (the only pure precondition): not in a feature worktree / on `main`
|
|
|
39
39
|
|
|
40
40
|
### 2 · Retro gate (blocking, optional retro-exit — before anything is committed)
|
|
41
41
|
One reminder, not a merge confirmation:
|
|
42
|
-
> "Already ran a retro? **(a)** yes / continue → landing now. **(b)** you want one first →
|
|
42
|
+
> "Already ran a retro? **(a)** yes / continue → landing now. **(b)** you want one first → the retro starts now; afterwards, invoke `/wrapup` again — repo-file patches then travel in this PR."
|
|
43
43
|
|
|
44
|
-
(b) →
|
|
44
|
+
(b) → **invoke the `retro` skill immediately in this run.** Retro is
|
|
45
|
+
model-invocable and non-deploying, and every mutation still has its own approval
|
|
46
|
+
gate. After retro finishes, **land nothing in this run**. Require a **fresh
|
|
47
|
+
explicit `/wrapup` invocation** because retro may have changed the exact diff
|
|
48
|
+
that the next merge authorization covers.
|
|
49
|
+
|
|
50
|
+
General chaining rule: automatically chain only into a **model-invocable**,
|
|
51
|
+
**non-deploying** workflow. If the named target is user-only, deploys, or
|
|
52
|
+
depends on an external action, **return control to the user** and **state the
|
|
53
|
+
reason**. A forward chain never carries wrapup's merge/deploy authorization
|
|
54
|
+
into another run.
|
|
55
|
+
|
|
56
|
+
The answer materializes as the mandatory `**Retro:**` PR-body line in step 4 — that's recording, not a second question. Why the gate lives here: in a foreign project this is the only portable retro touchpoint; a project-local "offer retro before PR" convention usually answers it already.
|
|
45
57
|
|
|
46
58
|
### 3 · Commit (only if the tree is dirty)
|
|
47
59
|
Judgment first, then the guarded commit:
|
|
@@ -77,5 +89,4 @@ STOP → diagnose in the main conversation, fix, re-run `land` (an already-merge
|
|
|
77
89
|
|
|
78
90
|
## Out of scope
|
|
79
91
|
- Live-verify / DoD: must happen **before** `/wrapup` — this skill lands, it does not verify.
|
|
80
|
-
- `/retro`: offered before landing (step 2), never run by this skill.
|
|
81
92
|
- Other worktrees / their servers stay untouched.
|