rk-skills 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +14 -0
- package/.claude-plugin/plugin.json +12 -0
- package/LICENSE +21 -0
- package/README.md +61 -0
- package/bin/install.mjs +41 -0
- package/package.json +39 -0
- package/skills/create-release/SKILL.md +25 -0
- package/skills/fable-new-issue/SKILL.md +72 -0
- package/skills/fable-new-issue-loop/SKILL.md +52 -0
- package/skills/fable-validate/SKILL.md +73 -0
- package/skills/fable-validate-loop/SKILL.md +80 -0
- package/skills/fableplan/SKILL.md +97 -0
- package/skills/fix-pr-review/SKILL.md +236 -0
- package/skills/fix-pr-review-loop/SKILL.md +105 -0
- package/skills/new-issue/SKILL.md +109 -0
- package/skills/new-issue-loop/SKILL.md +51 -0
- package/skills/sync-docs/SKILL.md +25 -0
- package/skills/sync-docs-release/SKILL.md +45 -0
- package/skills/validate-issue/SKILL.md +333 -0
- package/skills/validate-issue-fableplan-loop/SKILL.md +83 -0
- package/skills/validate-issue-loop/SKILL.md +64 -0
- package/skills/work-on-issue/SKILL.md +170 -0
- package/skills/work-on-issue-loop/SKILL.md +112 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: validate-issue
|
|
3
|
+
description: Use when the user asks to validate, review, or check whether a GitHub issue is valid. Takes a GitHub issue URL or number (defaults to the latest open issue in the current repo). Verifies every factual claim against the actual code with file:line citations rather than trusting the author's description; for non-trivial proposals, also checks architectural feasibility and proposal self-consistency.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# validate-issue
|
|
7
|
+
|
|
8
|
+
Validate a GitHub issue by tracing every factual claim to the code — never trust the author's description of current behavior, even the repo owner's. Validate **everything** the issue asserts, not just "Current Behavior": a named root cause, cited `file:line`, or recommended fix are *additional* claims, not shortcuts — a confident root cause can point at the wrong path, a citation can be stale, a fix can be infeasible even when the symptom is real, so run the proposal through 5a/5c however authoritative it reads. The deliverable is one end-to-end judgment — summary, behavior, root cause, citations, fix.
|
|
9
|
+
|
|
10
|
+
## Input
|
|
11
|
+
|
|
12
|
+
The user provides one of:
|
|
13
|
+
- Full URL: `https://github.com/<owner>/<repo>/issues/<N>`
|
|
14
|
+
- Short form: `#<N>` or just `<N>` (use the current repo)
|
|
15
|
+
- `owner/repo#N`
|
|
16
|
+
- **Nothing** — default to the latest (most recently created) open issue in the current repo.
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
### 0. Baseline: validate against the current default branch — NO worktree yet
|
|
21
|
+
|
|
22
|
+
**Do not create a worktree for validation or for `update issue` edits.** A worktree is created only when the user explicitly says to **work on** the issue (step 7.5) — validation and title/description edits run from the existing checkout.
|
|
23
|
+
|
|
24
|
+
So that claims trace against the repo's current default branch (`main`, `master`, or whatever the repo uses — never assume) rather than a stale or divergent local checkout, resolve it and refresh the baseline first:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
DEFAULT=$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)
|
|
28
|
+
git fetch origin "$DEFAULT"
|
|
29
|
+
git branch --show-current # which branch the working tree is on
|
|
30
|
+
git rev-list --left-right --count "origin/$DEFAULT...HEAD" # <behind> <ahead> vs origin
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Read files directly only when that count is `0 0`, or when the differing commits don't touch the paths you'll inspect (`git diff --name-only HEAD "origin/$DEFAULT"`). Otherwise trace via `git show "origin/$DEFAULT":<path>` instead of the working-tree copy. **Merely *behind* counts as stale:** `git fetch` updates only the remote-tracking ref, never your checkout, so an unpulled default branch silently traces outdated code. Note in the verdict which baseline you used.
|
|
34
|
+
|
|
35
|
+
### 1. Fetch the issue
|
|
36
|
+
|
|
37
|
+
Given a number/URL, view directly (`--repo` optional — omit to use the current repo). **Always include `--comments`** — corrections, "actually already fixed by …" notes, and scope changes live in the comment thread, and depth rule 3 depends on them:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
gh issue view <N> --repo <owner>/<repo> --comments
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If no issue was provided, resolve the latest first (newest-first by creation date), then view it; state which number you resolved to:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
N=$(gh issue list --limit 1 --json number --jq '.[0].number')
|
|
47
|
+
gh issue view "$N" --comments
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Then check for PRs already addressing it** — an in-flight or merged PR changes the verdict, and cross-referenced PRs do NOT appear in `--comments`:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
gh api "repos/<owner>/<repo>/issues/<N>/timeline" --paginate \
|
|
54
|
+
--jq '.[] | select(.event == "cross-referenced" and .source.issue.pull_request)
|
|
55
|
+
| .source.issue | "PR #\(.number) \(.state)\(if .pull_request.merged_at then " (merged)" else "" end) \(.title)"'
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
A **merged** PR that already implements the fix usually means the "before" baseline is gone (depth rule 3) — verify the claims against post-merge code and recommend closing or repurposing the issue in the verdict. An **open** PR means overlapping in-flight work — name it under Concerns so the fix isn't duplicated.
|
|
59
|
+
|
|
60
|
+
### 2. Extract factual claims
|
|
61
|
+
|
|
62
|
+
List every concrete claim about *current* behavior — e.g.:
|
|
63
|
+
- "Function X is called when Y happens"
|
|
64
|
+
- "Only A is sent to the external system, B and C are not"
|
|
65
|
+
- "Field F defaults to V"
|
|
66
|
+
- "On crash/error, behavior B occurs"
|
|
67
|
+
|
|
68
|
+
Claims about *desired* behavior (the proposal) aren't factual claims — skip them for step 3, but extract them for **5 and 5c**. Also extract **proposal design assertions** (mandatory for 5c):
|
|
69
|
+
- **Lifetime** — per request, per cycle, process lifetime, on load/reload, persisted across restarts
|
|
70
|
+
- **Population timing** — "on add", "on load", "on first access", "each cycle", "on demand"
|
|
71
|
+
- **Benefits** — dedup, SSoT, latency, fewer fetches (each implies a *current* baseline — rule 3)
|
|
72
|
+
- **Deploy surface** — new subprocess/service, argv/CLI/env contract, startup checks, migration
|
|
73
|
+
|
|
74
|
+
Flag the proposal for **5a + 5c** when it's more than a localized bugfix — new subsystem, cross-cutting refactor, dedup/SSoT, new layer/service, shared/global state, multi-consumer coordination, or analogies to existing infra ("like the X cache", "central calculator"). Keywords aren't enough; judge from scope.
|
|
75
|
+
|
|
76
|
+
### 3. Verify each claim
|
|
77
|
+
|
|
78
|
+
For each claim, find the code path that confirms or refutes it; cite `file:line`.
|
|
79
|
+
|
|
80
|
+
**Critical:** "Function X exists" ≠ "X fires for the scenario discussed." Trace conditionals fully — if X is gated on `flag > 0`, find what sets `flag` for the issue's case. If behavior depends on config, identify which config produces it and which doesn't.
|
|
81
|
+
|
|
82
|
+
**Depth rules (this is where validation actually fails — each rule opens with its trigger; apply every rule that fires):**
|
|
83
|
+
|
|
84
|
+
1. **Trigger: a claim names a wrapper/helper by its intent.** Read into the body, not the call site — a name states intent, not behavior. A wrapper named for one concern often delegates elsewhere or short-circuits (early-return, flag off, other branch) in a state the claim ignores; trace each named symbol one level deeper than feels necessary.
|
|
85
|
+
|
|
86
|
+
2. **Trigger: a claim covers a set ("all N of X", "every consumer", "each dispatch").** The grouping is itself a claim. Grep the real call sites, establish true membership from code, and **diff against the claimed set**. Usual failure: a listed member that's actually a separate path (never calls the function), or a missing one.
|
|
87
|
+
|
|
88
|
+
3. **Trigger: a benefit claim ("eliminates the lag", "removes duplicate work", "unifies the two paths").** A benefit asserts a *current* broken state as premise — itself a factual claim. Confirm the "before" still exists: a recent commit may have already fixed it (`git log`/comments), or it was never broken as described. If the baseline is gone, mark the benefit ❌/⚠️ and narrow the payoff.
|
|
89
|
+
|
|
90
|
+
4. **Trigger: a claim joins clauses ("and"/"but", "not X, just Y") or asserts a negative.** Split every conjunction and negation into atomic assertions, verify each against its own `file:line`, and grade by the weakest part. Negations are especially trap-prone: prove the absence on **all** paths — the value may be produced another way (direct assignment, fallback, sibling path), not via the one mechanism you checked.
|
|
91
|
+
|
|
92
|
+
5. **Trigger: the issue's headline conclusion is a negative over a window ("naked until next cycle", "deferred", "value is lost").** The conclusion is its own claim — about *everything that executes between event A and boundary B*, not just the mechanisms the issue names — so each cited fact can be ✅ while it's false. Read the dispatch A→B top-to-bottom and enumerate every call that could produce the effect; the producer is often a sibling step the issue never names.
|
|
93
|
+
|
|
94
|
+
6. **Trigger: a superlative ("closest / most / only"), a method-over-a-set, or a cited report/baseline.** Establish the full population yourself — never trust the subject's own row: compute the extremum across every member (near-ties → ⚠️, reword to the narrowest true scope); diff what the method NAMES against what the executing tooling actually COVERS (a named-but-unreached member silently never runs); `git log` a cited snapshot against the source it summarizes. Cite both the named set and the actual set, mark ⚠️, name the gap.
|
|
95
|
+
|
|
96
|
+
7. **Trigger: a claim — or your own proposed fix — leans on a prorate/dedupe/aggregate/shared-state facility.** Confirming the aggregation *happens* isn't enough: find the **partition boundary and key** it runs within (per-row, per-tenant, per-process) and check it against the scope the fix feeds it — a mismatched key over- or under-counts the moment it's fed rows spanning partitions. The boundary lives in the enclosing function's signature and scoping comments, not the formula. Applies doubly to the Optimal direction you propose in 5a.
|
|
97
|
+
|
|
98
|
+
8. **Trigger: a "missing / undocumented / not handled" claim (docs, copy, UI).** A two-part claim — keyword-absence proves neither part. Read the surrounding prose/copy/code, not just the grep hits. Two misses: (a) the content partly exists under different wording, so the deliverable is smaller than claimed; (b) existing copy describing the OLD behavior is now actively WRONG — invisible to a presence grep, a ❌ that *widens scope* and **flips Update → Yes** even when the "needs docs" claim is technically ✅. Also diff the issue's scope file-list against the surfaces its deliverables must edit — an omitted surface → ⚠️.
|
|
99
|
+
|
|
100
|
+
**Evidence outranks verdicts — whoever produced them.** A subagent's ✅/❌, a reviewer's or another model's findings, and your own earlier outputs all get the same treatment: re-derive each mark from code with your own `file:line`. An agent that cites contradicting code while marking ✅ has refuted itself — its evidence outranks its verdict. Endorsement is a verification act, not a relay; the failure mode is tracing one load-bearing claim hard, then transcribing the rest — every bullet gets traced, including the obvious ones. Also reconcile pairs of your **own** results before finalizing: two outputs that don't individually refute a ✅ can expose the gap in combination.
|
|
101
|
+
|
|
102
|
+
### 4. Mark each claim
|
|
103
|
+
|
|
104
|
+
| Status | Meaning |
|
|
105
|
+
|--------|---------|
|
|
106
|
+
| ✅ Verified | Code path confirms the claim, cite file:line |
|
|
107
|
+
| ❌ Refuted | Code does the opposite, cite file:line |
|
|
108
|
+
| ⚠️ Conditional | True for some configs/paths, false for others — name them |
|
|
109
|
+
| ❓ Unverified | Couldn't locate the code path; flag for the user |
|
|
110
|
+
|
|
111
|
+
Mark **every** claim. A path you couldn't locate is ❓, never silently dropped — it appears in the verdict. Verify claims **before** the proposal: if the claims are wrong, the proposal is moot.
|
|
112
|
+
|
|
113
|
+
### 5. Assess the proposal (if any)
|
|
114
|
+
|
|
115
|
+
Only after all factual claims are marked, evaluate the proposed fix. Split into **architecture** (right shape for *this* codebase?) and **general** (conflicts, safety, regressions).
|
|
116
|
+
|
|
117
|
+
First, write a one-shot **Goal** summary — what the issue is ultimately trying to accomplish (the outcome, not the mechanism), in plain language anyone could follow (ELI23), **≤55 words**. It is the lead line of the **Proposal** section in the output (step 7), shown even when the rest of that section is omitted, and independent of whether the proposal is sound.
|
|
118
|
+
|
|
119
|
+
#### 5a. Architectural feasibility & optimization (REQUIRED for non-trivial proposals)
|
|
120
|
+
|
|
121
|
+
The problem statement can be 100% correct while the **implementation sketch is wrong or suboptimal**. Validate architecture like behavior: trace the repo, cite `file:line`, name what's missing. **Goal:** does the proposal place each concern in the **right layer** with a **viable ownership model** — and when underspecified, what's the optimal pattern *for this repo* (not a generic lecture)?
|
|
122
|
+
|
|
123
|
+
**Workflow (in order):**
|
|
124
|
+
|
|
125
|
+
1. **Runtime topology** — draw the hot path from the entrypoint: processes/threads/containers/serverless, who spawns whom, what's long-lived vs per-request. Cite the spawn/dispatch site (`main`, worker pool, HTTP handler, `exec`, queue consumer).
|
|
126
|
+
|
|
127
|
+
2. **Concern decomposition** — separate **fetch/cache**, **compute/derive**, **store/SSoT**, **consume/route**; analogies often confuse these ("cached like X" when X only dedupes I/O, not derived results).
|
|
128
|
+
|
|
129
|
+
3. **Ownership checklist** — for each shared/authoritative piece of state the issue must make these explicit (else ⚠️, fill from the codebase):
|
|
130
|
+
|
|
131
|
+
| Question | Why it matters |
|
|
132
|
+
|----------|----------------|
|
|
133
|
+
| **Owner** | Which component has all consumers in scope, or which service is the writer of record? |
|
|
134
|
+
| **Lifetime** | Per request, per tick/cycle, process lifetime, persisted across restarts? |
|
|
135
|
+
| **Medium** | In-heap, DB, file, queue, RPC — must match topology |
|
|
136
|
+
| **Population** | When is it written? Who invalidates? |
|
|
137
|
+
| **Consumer contract** | Read-only inject, pull API, subscribe, recompute fallback? |
|
|
138
|
+
| **Failure policy** | Miss/stale/error → fail open, closed, retry, degrade? |
|
|
139
|
+
|
|
140
|
+
4. **Boundary rules** (when topology crosses isolation — process, machine, runtime, deploy unit):
|
|
141
|
+
- **In-memory in worker A is invisible to worker B** unless the issue defines IPC (file, DB, pipe, bus, parent inject).
|
|
142
|
+
- **On-disk / DB / shared service** coordinates across workers; **heap-only** cannot.
|
|
143
|
+
- **"Global" inside a leaf worker** is global only to that instance, not peers.
|
|
144
|
+
- **Silent fallback** (recompute locally on miss) often negates dedup/SSoT goals — ⚠️ unless intentional.
|
|
145
|
+
|
|
146
|
+
5. **Layer placement / optimization** — is work in the best place given existing conventions?
|
|
147
|
+
- **Orchestrator** (fan-in, dedup, cycle state, routing) vs **worker** (per-job handler, subprocess) vs **shared library** (pure logic, one impl) vs **persistence**.
|
|
148
|
+
- Prefer **one SSOT for business logic** (a library both live and offline paths import) + thin orchestration over duplicating rules in two languages or N workers.
|
|
149
|
+
- Prefer **existing inject/precompute patterns** (flags, stdin JSON, shared pre-fan-out phase) over new infrastructure unless justified.
|
|
150
|
+
- Name a **better placement** when the issue puts state/compute in a leaf that can't see all consumers — cite the component that can (parent loop, API server, scheduler).
|
|
151
|
+
|
|
152
|
+
6. **Touch-set completeness (REQUIRED — the proposal's site-list is an implicit set claim).** When the proposal adds or modifies a config field, flag, or any shared/persisted state, the issue's Approach names *which* sites it will touch — that named list is a claim, and the usual failure is a site it never names. So **grep the field/symbol across the package**, enumerate **every** site that reads / writes / defaults / validates / serializes / reload-copies it, classify each, and **diff the actual set against the Approach's named set**. Any unnamed site that mutates the same state — or that *must* change for the fix to work but isn't listed — is a finding (⚠️/❌), before architecture can be ✅. Verify ordering and completeness by reading the **whole load/apply sequence around the proposed edit point**, not just the neighbors the issue names: the recurring misses are an earlier step that pre-empts the proposed site (a default-injection/normalization pass that stamps the field first, so an "only when unset" guard never fires), and a second required site the issue never cites (a guard verified but the apply/copy step missing, so the change lands as a silent half-implementation). Cite every required site or mark ⚠️.
|
|
153
|
+
|
|
154
|
+
7. **Mark architecture:**
|
|
155
|
+
|
|
156
|
+
| Status | Meaning |
|
|
157
|
+
|--------|---------|
|
|
158
|
+
| ✅ **Viable** | Topology, owner, medium, timing, and consumer contract are explicit and match the repo |
|
|
159
|
+
| ⚠️ **Underspecified** | Right problem, wrong/missing placement or IPC — state the concrete edit |
|
|
160
|
+
| ❌ **Infeasible** | Violates isolation, duplicates SSOT with no sync story, or contradicts established patterns |
|
|
161
|
+
|
|
162
|
+
When ⚠️/❌, add one line: **Optimal direction (this repo):** `<pattern>` — derived from the workflow, not issue text.
|
|
163
|
+
|
|
164
|
+
#### 5c. Proposal self-consistency (REQUIRED whenever 5a runs)
|
|
165
|
+
|
|
166
|
+
The problem can be 100% code-accurate while the **proposal contradicts itself** or reuses words that mean different things across sections. Run **after** step 3, **in parallel with** 5a — don't wait for the user to spot it.
|
|
167
|
+
|
|
168
|
+
**Workflow (all required):**
|
|
169
|
+
|
|
170
|
+
1. **Lifetime × population matrix** — list every place the issue names *when* state is created or read:
|
|
171
|
+
|
|
172
|
+
| Source (quote or section) | When? | Medium | Survives restart? |
|
|
173
|
+
|---------------------------|-------|--------|-------------------|
|
|
174
|
+
|
|
175
|
+
Can one store satisfy every row? ❌ when two rows are incompatible (e.g. **"on add / loaded / register"** vs **"in-memory, recomputed each cycle"** — a load-time registry isn't an ephemeral per-cycle map). Cite the **existing** hook to use instead (config-load/validation vs main-loop/per-cycle — grep the repo).
|
|
176
|
+
|
|
177
|
+
2. **Verb audit** — search the text for `on add`, `on load`, `register`, `first access`, `each cycle`, `ephemeral`, `persist`, `cache`, `global`, `shared`. Same noun ("store", "calculator", "bundle") tied to two different verbs → ❌ unless the issue explicitly defines two layers with different lifetimes.
|
|
178
|
+
|
|
179
|
+
3. **Benefit vs existing facility** — rule 3 + 5a rule 2 applied to dedup: name what already dedupes that layer; "N fetches → 1" when a cache dedupes the I/O but not the derived compute is a ⚠️ overclaim.
|
|
180
|
+
|
|
181
|
+
4. **Consumer completeness** — if the issue says "the orchestrator reads it" or "no inline compute", grep **all** consumers (orchestrator *and* leaf workers/subprocesses). Partial migration (orchestrator updated, a leaf still computes the old way) is ⚠️ unless phased scope is explicit.
|
|
182
|
+
|
|
183
|
+
5. **Failure policy** — new fetch/subprocess without stated miss/timeout/error behavior → ⚠️; compare to today's inline path (fail open, reuse last value, skip the unit, hard error).
|
|
184
|
+
|
|
185
|
+
6. **Mark proposal consistency:**
|
|
186
|
+
|
|
187
|
+
| Status | Meaning |
|
|
188
|
+
|--------|---------|
|
|
189
|
+
| ✅ **Consistent** | Lifetime, population, benefits, and consumer story align across sections |
|
|
190
|
+
| ⚠️ **Gaps** | No internal contradiction, but missing failure policy, deploy/startup checks, or phased scope |
|
|
191
|
+
| ❌ **Contradicts** | Two sections describe incompatible ownership or timing — state the rewrite |
|
|
192
|
+
|
|
193
|
+
Any **❌** or material **⚠️** → **Update issue description? Yes** (same as bad architecture), edits phrased in step 7.
|
|
194
|
+
|
|
195
|
+
#### 5b. General proposal checks
|
|
196
|
+
|
|
197
|
+
- Does it conflict with recent work? (`git log --since=7.days` on touched paths)
|
|
198
|
+
- Safety: locking, migrations, hot-reload, idempotency, blast radius of failure
|
|
199
|
+
- Parity: are there parallel paths (simulation/offline, a secondary client, an admin/CLI surface) that must share the same SSOT?
|
|
200
|
+
- **Dual implementation risk** — same rule in two languages/runtimes without a single library or generated source
|
|
201
|
+
- Does it regress something just fixed?
|
|
202
|
+
|
|
203
|
+
5b findings route to the **Concerns** section of the output (`file:line` each). A material finding — safety gap, conflict with or regression of recent work, missing parity surface — means the proposal as written shouldn't be implemented, and flips **Update issue description? → Yes** just like 5a/5c.
|
|
204
|
+
|
|
205
|
+
### 6. Score complexity
|
|
206
|
+
|
|
207
|
+
Rate the work to implement the fix **correctly, including tests** — not the happy-path diff, not the author's estimate. Score five axes 0–4, sum ×5 for a 0–100 base, then apply the risk floor.
|
|
208
|
+
|
|
209
|
+
**Derive the axes from the change surface you traced, not the issue's prose.** List the concrete edits steps 3–5 imply — files/functions, configs/migrations, tests to add or rewrite — and size the axes from that list; a score not backed by it is a vibe. If a path is unresolved (5a/5c ⚠️/❌), raise **Uncertainty**, give a range (e.g. 55–75) not a point, and name the single unknown driving the spread.
|
|
210
|
+
|
|
211
|
+
**Count the surface that hides from the diff.** The usual undercount is Scope and Verification — account for tests to add/rewrite, parity/offline paths that must match, migrations or schema/config-version bumps, init/wizard/generate surfaces, probe/startup argv, and docs the change invalidates. A "one-file" fix often drags three of these.
|
|
212
|
+
|
|
213
|
+
**Cross-check against your own step-5 verdicts.** If architecture is ❌ (5a) or several checks are ⚠️ (5c), the work includes redesign and can't land low — a low score next to an ❌ verdict is self-contradiction.
|
|
214
|
+
|
|
215
|
+
| Axis (0–4) | 0 | 2 | 4 |
|
|
216
|
+
|---|---|---|---|
|
|
217
|
+
| **Scope** — files/layers/languages; new abstraction vs localized | one file, localized | a few files, one layer/language | many files across layers + a new abstraction |
|
|
218
|
+
| **Coupling** — state/locking, migration, hot-reload, config↔runtime parity, dual-language SSoT, IPC across process/machine | none; pure/local | one shared mechanism touched | multiple interacting subsystems / cross-boundary coordination |
|
|
219
|
+
| **Risk** — money, data integrity, security, irreversible or live side effects; regression on recently-changed code | read-only / offline | reversible writes, contained blast radius | live-exec / money / data-integrity / irreversible |
|
|
220
|
+
| **Uncertainty** — is the approach known? | spec'd, or a hard decision-gate over existing tooling | mechanism known, params/shape to be found | needs design; step 5a ⚠️/❌ |
|
|
221
|
+
| **Verification** — test/repro surface to prove it | pure helper, unit-testable | several units + fixtures | integration/parity/subprocess, or hard-to-reproduce state |
|
|
222
|
+
|
|
223
|
+
**Base** = sum × 5. **Risk floor (safety outranks effort):** Risk = 4 → final ≥ 60; Risk = 3 → final ≥ 45. Take `max(base, floor)`, cap 100 — irreversible/live-exec work is never low-complexity to ship correctly, however tiny the diff.
|
|
224
|
+
|
|
225
|
+
The axes encode the two calls a flat score botches: **bounded research** scores low even when sophisticated (the "code" is existing tooling), and a **tiny diff on a money/state path** is caught by the Risk floor. Work the axes in scratch; **report only** `N/100 — <highest axis> is the driver` with the traced edit list.
|
|
226
|
+
|
|
227
|
+
### 6.5. Scope disposition — is the issue too large to be ONE issue?
|
|
228
|
+
|
|
229
|
+
A high complexity score is not automatically a defect — a single hard change can be correctly scoped. The defect is when one issue **bundles work that should be tracked as several**. Decide from the traced edit list (step 6), not the prose: an issue is too large when **the deliverables are separable** — two or more parts each land in their own PR, pass their own tests, and deliver value alone — **or** it reads as an "and also" laundry list spanning unrelated subsystems with no single root cause tying them.
|
|
230
|
+
|
|
231
|
+
A genuinely-large-but-atomic change (one root cause, one inseparable diff) is **not** too large — the high score already tells the story; only flag when the parts are independently landable.
|
|
232
|
+
|
|
233
|
+
When it IS too large, recommend exactly one disposition (state which and why in the output):
|
|
234
|
+
|
|
235
|
+
| Disposition | Use when | Action to recommend |
|
|
236
|
+
|-------------|----------|---------------------|
|
|
237
|
+
| **Split into N issues** | Parts are independent — no shared design, no ordering dependency, each separately landable | File each as its own fully-specified issue, then close/repurpose this one. List the proposed splits with a one-line scope each. |
|
|
238
|
+
| **Umbrella / tracking issue** | Parts are related and need coordinated design or a shared sequence, but are still individually shippable | Keep THIS issue as the parent; convert its body to a checklist of child issues (`- [ ] #…`), move per-part detail into the children. List the proposed children. |
|
|
239
|
+
| **Narrow scope** | Much of the issue is speculative/optional/"nice to have" around one real core | Cut to the core deliverable; move the rest to a "Future / out of scope" note or a single follow-up. Name the core vs what's cut. |
|
|
240
|
+
|
|
241
|
+
**Each proposed split/child is itself fully specified — never recommend filing a stub.** Per the repo's issue rules, every spun-off issue needs its own complexity-prefixed ELI18 title (a clear, plain-language sentence understandable to an average 18-year-old), problem statement, and acceptance criteria before it's filed. If a part isn't ready to spec, recommend tracking it as a checklist line in the parent, not a separate issue yet. Don't actually file the children during validation — propose them; filing happens only if the user says to act on the disposition.
|
|
242
|
+
|
|
243
|
+
This decision is **independent of "Update issue description?"** — an issue can be factually accurate (verdict: No update) yet still need to be split. Surface both.
|
|
244
|
+
|
|
245
|
+
### 7. Output verdict
|
|
246
|
+
|
|
247
|
+
Be terse. No preamble, no closing remarks. The deliverable is the **decision** about whether the original issue description needs to be updated — it lands at the **end**, as the conclusion the findings build to, not a loose summary.
|
|
248
|
+
|
|
249
|
+
Format:
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
Claims:
|
|
253
|
+
- ✅ <claim> — <file:line>
|
|
254
|
+
- ⚠️ <claim> — <condition> (<file:line>)
|
|
255
|
+
- ❌ <claim> — <what code actually does> (<file:line>)
|
|
256
|
+
- ❓ <claim> — <where you looked; what's needed to verify>
|
|
257
|
+
|
|
258
|
+
Architecture: (omit if trivial proposal / no step 5a)
|
|
259
|
+
- <✅|⚠️|❌> <one-line verdict: placement + owner + medium> (<file:line> dispatch/spawn path)
|
|
260
|
+
- Optimal: <only when ⚠️/❌ — one line, repo-specific>
|
|
261
|
+
|
|
262
|
+
Concerns: (omit section if none)
|
|
263
|
+
- <concern> (<file:line>)
|
|
264
|
+
|
|
265
|
+
Proposal:
|
|
266
|
+
- Goal (ELI23, ≤55 words): <plain-language summary of what the issue is trying to accomplish — outcome, not mechanism>
|
|
267
|
+
- <✅|⚠️|❌> <lifetime/population/benefit/consumer/failure — one line each only when not ✅> (omit this verdict line if no step 5c / trivial fix)
|
|
268
|
+
|
|
269
|
+
Scope: (omit unless the issue is too large per step 6.5)
|
|
270
|
+
- <Split | Umbrella | Narrow> — <one-line why> · proposed parts:
|
|
271
|
+
- <part 1 — one-line scope>
|
|
272
|
+
- <part 2 — one-line scope>
|
|
273
|
+
|
|
274
|
+
**#<N>: Update issue description? <Yes | No>** · Complexity: <0-100>/100 — <main driver> · Scope: <OK | too large — split/umbrella/narrow>
|
|
275
|
+
|
|
276
|
+
<If Yes: a short bulleted list of specific edits the author should make to the title and/or description — wrong file:line, incorrect behavior, missing repro, ambiguous scope, a title that misstates the bug or scope, etc. One line each, phrased as edits ("Change X to Y", "Add Z", "Remove claim about W", "Retitle to …").>
|
|
277
|
+
|
|
278
|
+
→ Reply "work on issue" to proceed, "update issue" to apply the edits first<, or "split issue" / "decompose" to file the proposed parts — only when step 6.5 flagged it>.
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### 7.5. When the user replies "work on issue" — hand off to the work-on-issue skill
|
|
282
|
+
|
|
283
|
+
When the user opts to **work on** the issue (not merely validate or update it), **invoke the `work-on-issue` skill** — that is the default follow-on. It owns the full implementation flow: create and switch into a fresh isolated worktree off the latest default branch, implement the fix to the codebase's conventions, verify, commit and push, open a PR that `Closes #<N>`, and trigger an `@claude` review on it.
|
|
284
|
+
|
|
285
|
+
Pass the issue number through; the skill is idempotent about the worktree (reuses an existing one for this issue). Don't start editing code or creating a worktree here yourself — delegate so the implement → PR → review chain stays consistent.
|
|
286
|
+
|
|
287
|
+
**If step 6.5 flagged the issue as too large, surface the disposition before handing off** — implementing an oversized, multi-part issue as one PR reproduces the scope problem in the diff. Recommend splitting/decomposing first; proceed to work-on-issue only on the user's say-so, or scope the implementation to the single core part if they want to start there.
|
|
288
|
+
|
|
289
|
+
### 8. When the user replies "update issue"
|
|
290
|
+
|
|
291
|
+
This can mean editing the issue title and/or editing the issue body (apply the suggested edits) — both from the current checkout, per step 0. Do both as appropriate.
|
|
292
|
+
|
|
293
|
+
**Your own rewrite is claim-verified too — gate before you write.** The corrected description, fix plan, "Optimal direction", and suggested edits aren't exempt from steps 3–5 just because they're your prose: every **verb** (write, split, stamp, record) and **value** (which field a number lands in, zero vs derived-nonzero, lifetime, owner) is a code-grounded claim — trace each to `file:line`. Two traps:
|
|
294
|
+
- **Narrative compression erases a verified distinction.** If step 3 proved two paths differ (one writes a derived non-zero value, the other zero; one records, the other skips), don't flatten both under one tidy label; a tidier sentence that's now wrong is a regression.
|
|
295
|
+
- **A fix plan can propose violating a documented invariant.** Before recommending a fix that writes/derives a value, grep `CLAUDE.md`/guardrails and nearby comments for an invariant governing it ("only writer is Z", "fail closed", "never write X into field Y") — route the value to its authorized path, not the convenient one.
|
|
296
|
+
|
|
297
|
+
**MANDATORY final consistency pass — re-read the WHOLE assembled body before every `gh issue edit`, not just the section you changed.** Section-by-section edits drift: the early summary and the later detailed sections silently disagree, and since the correct fact is already *in your own document*, only an end-to-end read catches it. List every **value/distinction restated in more than one place** (zero in one section, non-zero in another; a path that writes vs skips; a benefit exists vs not) and confirm the summary says the *same thing* as the detailed buckets. Required after any edit pass touching ≥2 sections or spanning ≥2 turns.
|
|
298
|
+
|
|
299
|
+
**Editing the title** (`gh issue edit <N> --title "<new title>"`): update it whenever the validated findings make the current one wrong or misleading — it misstates the bug, names the wrong component or root cause, or its scope no longer matches what you traced, or it isn't a clear, plain-language sentence understandable to an average 18-year-old (ELI18) — precise about component and behavior, no unexplained jargon. Hold the corrected title to the same claim-verification gate as the body. If the repo follows the `[C<score>] <title>` prefix convention, set or correct it from step 6. Leave an accurate title untouched; combinable with the body edit in one call.
|
|
300
|
+
|
|
301
|
+
**Editing the issue body** (`gh issue edit <N> --body-file <file>`): apply the edits, then end the body with the **LLM Attribution Footer** — **stack, never replace**: keep the original `Created with LLM: …` line and add an `Updated with LLM: …` line directly below it (each later edit appends another `Updated …` if model/effort/harness differ; collapse exact duplicates). Preserve provenance, don't overwrite. The footer is the final lines of the body, preceded by a `---` separator on its own line:
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
---
|
|
305
|
+
Created with LLM: <model> | <effort> | Harness: <harness>
|
|
306
|
+
Updated with LLM: <current model> | <effort> | Harness: <harness>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Verb tracks the action: `Created` for the original body, `Updated` for title/description edits; when the body has no footer yet, append just the `Updated …` line. Fill in `<current model>` (e.g. `Fable 5`, `Opus 4.8`) and `<effort>` (`medium` / `high` / `xhigh` — default `high`, never low). `<harness>` is whatever produced the edit — `Claude Code` for an interactive session, the GitHub Action identifier when running in CI (e.g. `anthropics/claude-code-action@v1`; the workflow states this identifier in your system prompt — use that value, and treat its absence as an interactive session), or the specific tool (`Cursor`, `Codex`, `OpenClaw`, `Hermes`). When the repo's `CLAUDE.md` defines its own footer format, it overrides this default.
|
|
310
|
+
|
|
311
|
+
Rules:
|
|
312
|
+
- Close with the update-or-not decision, placed after the findings that justify it. That is the deliverable; the complexity score sits on the same line, after a `·` separator.
|
|
313
|
+
- Always include the complexity score, even when the verdict is **No** — it tells the user how much work the fix is.
|
|
314
|
+
- No restatement of the issue title or body.
|
|
315
|
+
- Each claim/concern fits on one line. If you need more, the claim is too broad — split it.
|
|
316
|
+
- Drop the Concerns section entirely when there are none. Don't write "None."
|
|
317
|
+
- **Yes** when any ❌/⚠️ **claim** affects the fix, the description states wrong behavior, repro/scope is missing, **step 5a is ⚠️/❌**, **step 5c is ⚠️/❌** (proposal contradicts itself or omits failure/deploy/consumer scope), or a **material 5b finding** (safety gap, conflict/regression with recent work, missing parity surface) means the proposal as written shouldn't be implemented. **No** when claims are ✅, architecture, proposal consistency, and general checks are clean (or trivial/local), the problem statement is accurate, and there's enough context to start work.
|
|
318
|
+
- Keep claim descriptions short — verb phrase only, no full sentences.
|
|
319
|
+
|
|
320
|
+
## Red Flags — STOP
|
|
321
|
+
|
|
322
|
+
Depth-rule and section triggers live on the rules/sections themselves (steps 3, 5a, 5c, 6.5, 8) — these are the remaining checks with no home there:
|
|
323
|
+
|
|
324
|
+
| Situation | Action |
|
|
325
|
+
|-----------|--------|
|
|
326
|
+
| Claim cites a function that doesn't exist | Mark ❌; note the actual function name if you find it |
|
|
327
|
+
| Claim is true *only* for one config branch | Mark ⚠️ — don't simplify to ✅ |
|
|
328
|
+
| Issue author is the repo owner | **Still verify.** Repo owners write from memory and get details wrong too — never anchor on "Current Behavior" |
|
|
329
|
+
| Code recently changed (last 7 days) | `git log --since=7.days <file>` to confirm current behavior |
|
|
330
|
+
| Claim depends on runtime state ("after N cycles") | Trace the state machine; don't approximate |
|
|
331
|
+
| Your own grep/read contradicts the issue's prose | Trust the code, not the author's grouping |
|
|
332
|
+
| "Shared / global / central" with no owner named | 5a — require owner, medium, timing, consumer contract |
|
|
333
|
+
| All claims ✅ but the proposal is cross-cutting | Run **5a + 5c** before scoring — accurate problem ≠ sound design |
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: validate-issue-fableplan-loop
|
|
3
|
+
description: Use when the user asks to validate a GitHub issue (without Fable), conditionally plan it with fableplan, then autonomously drive it to a reviewed PR in one shot — "validate-issue-fableplan-loop", "validate, plan, and work on #N", "validate and fableplan and fully automate #N". Runs validate-issue on your session model (not a Fable subagent), auto-applies its update-issue edits when the verdict calls for it, has fableplan produce and post a Fable 5 implementation plan (skipped for issues below C50 with no safety flags), then hands off to work-on-issue-loop — stopping instead when validation flags the issue as too large, architecturally infeasible, or already addressed by an existing PR. The non-Fable-validation counterpart to fable-validate-loop.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# validate-issue-fableplan-loop
|
|
7
|
+
|
|
8
|
+
Chain validate-issue → (conditional) update issue → (conditional) fableplan → work-on-issue-loop into one autonomous run: your session model validates the issue against the code, the main agent fixes the issue description if needed, Fable 5 plans the implementation for non-trivial issues (plan posted to the issue), and work-on-issue-loop implements the plan and drives the PR through review to convergence.
|
|
9
|
+
|
|
10
|
+
This is **validate-issue-loop with a Fable 5 planning phase inserted before implementation** — identical to fable-validate-loop except validation runs through the plain `validate-issue` (your session model) instead of a Fable 5 subagent. Only the *planning* is delegated to Fable 5, and only when the issue is complex enough to warrant it. Reach for this over fable-validate-loop when you want cheaper, session-model validation but still want a Fable-vetted plan for the harder issues.
|
|
11
|
+
|
|
12
|
+
**Do not skip or reorder the chain.** Validation gates planning (a plan built on refuted claims is wrong), and the plan gates implementation (that's the point of routing through fableplan). The only sanctioned skip is the step-4 complexity gate (low-complexity issues bypass fableplan). Every other step of each skill still runs; only the "wait for the user's reply" moments are replaced by the decision rules below.
|
|
13
|
+
|
|
14
|
+
## Input
|
|
15
|
+
|
|
16
|
+
Same defaults as validate-issue: issue URL, `#<N>` / `<N>` / `owner/repo#N`, or nothing (defaults to the latest open issue in the current repo).
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
### 1. Run validate-issue
|
|
21
|
+
|
|
22
|
+
Invoke the `validate-issue` skill for the target issue (Skill tool, `skill: validate-issue`). Let it run its full process — steps 0 through 7 — and produce its verdict block:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
**#<N>: Update issue description? <Yes|No>** · Complexity: <score>/100 — <driver> · Scope: <OK | too large — split/umbrella/narrow>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Treat the verdict block as structured output to parse yourself, not the interactive `→ Reply "work on issue"` prompt to wait on. Don't ask the user to confirm; decide from the table in step 2. Record the resolved issue number — every later step targets exactly this issue.
|
|
29
|
+
|
|
30
|
+
### 2. Scope gate — stop if the issue is unsafe to auto-implement
|
|
31
|
+
|
|
32
|
+
Check the verdict's **Scope** field, **Architecture** section, and **Concerns** (for an already-addressing PR from validate-issue's step 1 linked-PR check) before doing anything else:
|
|
33
|
+
|
|
34
|
+
| Condition | Action |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `Scope: too large` (validate-issue step 6.5 flagged split / umbrella / narrow) | **STOP.** Report the disposition and proposed parts; do not proceed to planning or work-on-issue-loop. Implementing a multi-part issue as one PR reproduces the scope problem in the diff — that needs a human call on how to split it. |
|
|
37
|
+
| Architecture marked ❌ **Infeasible** | **STOP.** Report the infeasibility and the "Optimal direction" note; planning and implementing a design the validation itself rejected would ship the wrong fix. |
|
|
38
|
+
| A **merged** PR already implements the fix (verdict recommends closing/repurposing the issue) | **STOP.** Report the PR and the close/repurpose recommendation — there's nothing left to implement. |
|
|
39
|
+
| An **open** PR is already addressing the issue (named under Concerns) | **STOP.** Report the overlapping PR; whether to supersede, join, or wait on in-flight work is a human call — auto-implementing duplicates it. |
|
|
40
|
+
|
|
41
|
+
Otherwise (Scope: OK; architecture ✅/⚠️ or not applicable; no PR already addressing it), continue.
|
|
42
|
+
|
|
43
|
+
### 3. Apply the update-issue edits, if called for
|
|
44
|
+
|
|
45
|
+
If the verdict says **Update issue description? Yes**, apply validate-issue's step 8 now — the suggested title/body edits plus the stacked `Updated with LLM: …` attribution line (harness suffix `validate-issue-fableplan-loop`) — from the current checkout (no worktree for issue edits, per validate-issue step 0).
|
|
46
|
+
|
|
47
|
+
If **No**, skip straight to step 4.
|
|
48
|
+
|
|
49
|
+
**Order matters:** the edits land before fableplan runs, so the Fable 5 planner fetches and plans against the corrected issue, not the flawed original.
|
|
50
|
+
|
|
51
|
+
### 4. Run fableplan — planning phase only (skip below C50)
|
|
52
|
+
|
|
53
|
+
**Complexity gate:** if the verdict's validated complexity score is **below 50**, skip fableplan and go straight to step 5 — work-on-issue-loop plans adequately for low-complexity changes on its own. **Safety carve-out (overrides the gate):** if the validation flags money, data integrity, security, or an auto-protective mechanism anywhere in its findings, run fableplan regardless of score.
|
|
54
|
+
|
|
55
|
+
Otherwise, invoke the `fableplan` skill for the same issue number (Skill tool, `skill: fableplan`), and **scope it to its planning phase — steps 1 through 5 only**: fetch the issue, dispatch the Fable 5 Plan subagent, sanity-check the plan against the code, post the vetted plan as an issue comment, and relay it. **Do NOT execute fableplan's steps 6–7 (worktree + build)** — implementation belongs to work-on-issue-loop in step 5, which owns the implement → PR → review chain; building here would duplicate it outside that chain.
|
|
56
|
+
|
|
57
|
+
Give the planning subagent the validation findings (the verdict block and validate-issue's report) alongside the issue — the plan must respect what validation established (verified/refuted claims, the Optimal-direction note when architecture was ⚠️, and any concerns it raised).
|
|
58
|
+
|
|
59
|
+
Keep the vetted plan's scratchpad file — step 5 passes it through. If fableplan fails after its internal retry, stop and report; don't fall back to planning yourself or implementing unplanned.
|
|
60
|
+
|
|
61
|
+
### 5. Hand off to work-on-issue-loop
|
|
62
|
+
|
|
63
|
+
Invoke the `work-on-issue-loop` skill for the same issue number (Skill tool, `skill: work-on-issue-loop`). Pass the issue number through explicitly — don't let it re-resolve "latest issue" — and instruct it that the implementation must follow the Fable 5 plan: point it at the plan's scratchpad file and the posted issue comment (`## Implementation plan (Fable 5)`), and tell it deviations from the plan are allowed only when the code contradicts the plan, and must be named in the PR body. (If step 4 was skipped by the complexity gate, there is no plan — hand off the issue alone and note the skip.)
|
|
64
|
+
|
|
65
|
+
It runs its full loop: work-on-issue implements in a worktree, opens the PR, triggers `@claude` review, and fix-pr-review cycles until convergence.
|
|
66
|
+
|
|
67
|
+
### 6. Report
|
|
68
|
+
|
|
69
|
+
Relay work-on-issue-loop's final summary (PR URL, review cycles, final verdict), prefixed with one line covering the head of the chain: scope gate passed, issue updated or not, plan posted (comment URL) or skipped by the complexity gate.
|
|
70
|
+
|
|
71
|
+
**Cap the whole report at 55 words, ELI18** — plain language, no jargon, as if explaining the outcome to a smart 18-year-old with no context on this codebase.
|
|
72
|
+
|
|
73
|
+
## Red Flags — STOP
|
|
74
|
+
|
|
75
|
+
| Situation | Action |
|
|
76
|
+
|---|---|
|
|
77
|
+
| Tempted to skip validation or planning and jump to implementation | Never reorder — validate-then-plan-then-build is the point of this skill; the only sanctioned skip is the step-4 complexity gate (<C50, no safety flags) |
|
|
78
|
+
| `Scope: too large`, Architecture ❌ Infeasible, or a PR already addressing the issue | Stop and report per step 2 — the cases the loop can't safely auto-resolve |
|
|
79
|
+
| Tempted to wait for a literal user reply to validate-issue's or fableplan's prompt | Parse the output yourself and proceed per the step rules |
|
|
80
|
+
| Verdict says Update issue description? Yes | Apply the edits **before** fableplan runs, so the plan targets the corrected issue |
|
|
81
|
+
| fableplan about to enter its build steps (6–7) | Don't — stop it at step 5; work-on-issue-loop owns implementation |
|
|
82
|
+
| fableplan's sanity-check finds the plan structurally wrong | Stop and report — don't hand a broken plan to work-on-issue-loop, and don't silently re-plan |
|
|
83
|
+
| Issue scored below C50 with no safety flags | Skip fableplan and hand the issue straight to work-on-issue-loop — note the skip in the report |
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: validate-issue-loop
|
|
3
|
+
description: Use when the user asks to validate a GitHub issue and then autonomously drive it to a reviewed PR in one shot — "validate and work on this issue", "validate-issue-loop", "fully automate issue #N". Runs validate-issue, auto-applies its update-issue edits when the verdict calls for it, then hands off to work-on-issue-loop — stopping instead when validation flags the issue as too large, architecturally infeasible, or already addressed by an existing PR.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# validate-issue-loop
|
|
7
|
+
|
|
8
|
+
Chain validate-issue → (conditional) update issue → work-on-issue-loop into one autonomous run, so an issue goes from "reported" to "PR through N rounds of review" without a human in the loop between steps. This is validate-issue's normal interactive handoff (`→ Reply "work on issue"`) made unattended: the loop reads its own verdict and decides what to do next, instead of waiting for the user to type a reply.
|
|
9
|
+
|
|
10
|
+
**Do not skip validation.** Auto-implementing an issue whose factual claims or proposal you haven't traced against the code just reproduces the issue's own mistakes in a PR. Every step of validate-issue still runs; only the "wait for the user's reply" step is replaced by a decision table.
|
|
11
|
+
|
|
12
|
+
## Input
|
|
13
|
+
|
|
14
|
+
Same defaults as validate-issue: issue URL, `#<N>` / `<N>` / `owner/repo#N`, or nothing (defaults to the latest open issue in the current repo).
|
|
15
|
+
|
|
16
|
+
## Steps
|
|
17
|
+
|
|
18
|
+
### 1. Run validate-issue
|
|
19
|
+
|
|
20
|
+
Invoke the `validate-issue` skill for the target issue (Skill tool, `skill: validate-issue`). Let it run its full process — steps 0 through 7 — and produce its verdict block:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
**#<N>: Update issue description? <Yes|No>** · Complexity: <score>/100 — <driver> · Scope: <OK | too large — split/umbrella/narrow>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Its final `→ Reply "work on issue"...` line is written for interactive use — in this loop, treat the verdict block as structured output to parse yourself, not a prompt to wait on. Don't ask the user to confirm; decide from the table in step 2.
|
|
27
|
+
|
|
28
|
+
### 2. Scope gate — stop if the issue is unsafe to auto-implement
|
|
29
|
+
|
|
30
|
+
Check the verdict's **Scope** field, **Architecture** section, and **Concerns** (for an already-addressing PR from validate-issue's step 1 linked-PR check) before doing anything else:
|
|
31
|
+
|
|
32
|
+
| Condition | Action |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `Scope: too large` (validate-issue step 6.5 flagged split / umbrella / narrow) | **STOP.** Report the disposition and proposed parts; do not proceed to work-on-issue-loop. Implementing a multi-part issue as one PR reproduces the scope problem in the diff — that needs a human call on how to split it. |
|
|
35
|
+
| Architecture marked ❌ **Infeasible** | **STOP.** Report the infeasibility and the "Optimal direction" note; auto-implementing a design the validation itself rejected would ship the wrong fix. |
|
|
36
|
+
| A **merged** PR already implements the fix (verdict recommends closing/repurposing the issue) | **STOP.** Report the PR and the close/repurpose recommendation — there's nothing left to implement. |
|
|
37
|
+
| An **open** PR is already addressing the issue (named under Concerns) | **STOP.** Report the overlapping PR; whether to supersede, join, or wait on in-flight work is a human call — auto-implementing duplicates it. |
|
|
38
|
+
|
|
39
|
+
Otherwise (Scope: OK; architecture ✅/⚠️ or not applicable; no PR already addressing it), continue.
|
|
40
|
+
|
|
41
|
+
### 3. Apply the update-issue edits, if called for
|
|
42
|
+
|
|
43
|
+
If the verdict says **Update issue description? Yes**, apply validate-issue's step 8 now — the suggested title/body edits plus the stacked `Updated with LLM: …` attribution line — from the current checkout (no worktree for issue edits, per validate-issue step 0).
|
|
44
|
+
|
|
45
|
+
If **No**, skip straight to step 4.
|
|
46
|
+
|
|
47
|
+
### 4. Hand off to work-on-issue-loop
|
|
48
|
+
|
|
49
|
+
Invoke the `work-on-issue-loop` skill for the same issue number (Skill tool, `skill: work-on-issue-loop`). Pass the issue number through explicitly — don't let it re-resolve "latest issue" and risk picking a different one.
|
|
50
|
+
|
|
51
|
+
### 5. Report
|
|
52
|
+
|
|
53
|
+
Relay work-on-issue-loop's final summary to the user (PR URL, review cycles run, final verdict). Prefix it with a one-line note of what happened in steps 2–3 (issue updated or not; scope check passed) so the user sees the whole chain, not just the tail.
|
|
54
|
+
|
|
55
|
+
**Cap the whole report (prefix + relayed summary) at 55 words, ELI18** — plain language, no jargon, as if explaining the outcome to a smart 18-year-old with no context on this codebase or its internals.
|
|
56
|
+
|
|
57
|
+
## Red Flags — STOP
|
|
58
|
+
|
|
59
|
+
| Situation | Action |
|
|
60
|
+
|---|---|
|
|
61
|
+
| Tempted to skip validation and go straight to work-on-issue-loop | Never reorder — validate-first is the point of this skill |
|
|
62
|
+
| `Scope: too large`, Architecture ❌ Infeasible, or a PR already addressing the issue | Stop and report per step 2 — the cases the loop can't safely auto-resolve |
|
|
63
|
+
| Tempted to wait for a literal user reply to validate-issue's prompt | Parse the verdict yourself and proceed per step 2 |
|
|
64
|
+
| Verdict says Update issue description? Yes | Apply the edits before handing off; don't defer |
|