Skip to content

Commit 0723438

Browse files
jwaldripclaude
andcommitted
feat(workflow): rework /followup to create linked iteration intents
Instead of adding units to completed intents, /followup now creates a new intent with iterates_on: frontmatter linking to the previous intent. Elaboration automatically loads prior context when this field is present. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c0349b7 commit 0723438

File tree

2 files changed

+465
-0
lines changed

2 files changed

+465
-0
lines changed

plugin/skills/elaborate/SKILL.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,116 @@ Then proceed to Phase 1.
185185

186186
---
187187

188+
## Phase 0.5: Detect Iteration Intent (`iterates_on`)
189+
190+
> **CALLOUT:** If the intent being elaborated has an `iterates_on` field in its frontmatter, it is an **iteration intent** — a follow-up that builds on a previous intent. This changes how several subsequent phases behave. The agent MUST check for this field early and carry the prior context through the entire elaboration.
191+
192+
If elaborating an existing intent (slug provided), check its frontmatter for `iterates_on`:
193+
194+
```bash
195+
INTENT_SLUG="{slug}"
196+
197+
# Check if intent.md exists and has iterates_on
198+
if [ -f ".ai-dlc/${INTENT_SLUG}/intent.md" ]; then
199+
ITERATES_ON=$(han parse yaml iterates_on -r --default "" < ".ai-dlc/${INTENT_SLUG}/intent.md")
200+
fi
201+
```
202+
203+
If `ITERATES_ON` is non-empty, this is an iteration intent. Load the previous intent's full context:
204+
205+
**Load from filesystem first, then fall back to git branch:**
206+
207+
```bash
208+
PREVIOUS_SLUG="$ITERATES_ON"
209+
210+
# Try filesystem
211+
if [ -f ".ai-dlc/${PREVIOUS_SLUG}/intent.md" ]; then
212+
PREVIOUS_INTENT=$(cat ".ai-dlc/${PREVIOUS_SLUG}/intent.md")
213+
PREVIOUS_SOURCE="filesystem"
214+
else
215+
# Fallback: read from intent branch
216+
PREVIOUS_INTENT=$(git show "ai-dlc/${PREVIOUS_SLUG}/main:.ai-dlc/${PREVIOUS_SLUG}/intent.md" 2>/dev/null)
217+
PREVIOUS_SOURCE="git-branch"
218+
fi
219+
220+
# Load previous units
221+
if [ "$PREVIOUS_SOURCE" = "filesystem" ]; then
222+
PREVIOUS_UNITS=""
223+
for unit_file in .ai-dlc/${PREVIOUS_SLUG}/unit-*.md; do
224+
[ -f "$unit_file" ] && PREVIOUS_UNITS="${PREVIOUS_UNITS}$(cat "$unit_file")\n---\n"
225+
done
226+
else
227+
PREVIOUS_UNITS=""
228+
git ls-tree --name-only "ai-dlc/${PREVIOUS_SLUG}/main" ".ai-dlc/${PREVIOUS_SLUG}/" 2>/dev/null | \
229+
grep 'unit-' | while read -r f; do
230+
git show "ai-dlc/${PREVIOUS_SLUG}/main:$f" 2>/dev/null
231+
done
232+
fi
233+
234+
# Load previous discovery.md if available
235+
if [ "$PREVIOUS_SOURCE" = "filesystem" ]; then
236+
PREVIOUS_DISCOVERY=$(cat ".ai-dlc/${PREVIOUS_SLUG}/discovery.md" 2>/dev/null)
237+
else
238+
PREVIOUS_DISCOVERY=$(git show "ai-dlc/${PREVIOUS_SLUG}/main:.ai-dlc/${PREVIOUS_SLUG}/discovery.md" 2>/dev/null)
239+
fi
240+
```
241+
242+
**Present prior context to the user:**
243+
244+
```markdown
245+
## Iteration Context
246+
247+
This intent iterates on **{previous title}** (`{previous-slug}`).
248+
249+
### What was built previously
250+
{Summary of previous intent's problem, solution, and domain model}
251+
252+
### Previous Units
253+
| Unit | Status | Description |
254+
|------|--------|-------------|
255+
| {unit-slug} | {status} | {brief description} |
256+
...
257+
258+
### Previous Domain Knowledge
259+
{Key findings from discovery.md if available}
260+
```
261+
262+
**Store this context** — it will be referenced in Phase 2, Phase 2.5, and Phase 5. Use `han keep save` to persist:
263+
264+
```bash
265+
han keep save previous-intent-context "{JSON summary of previous intent}"
266+
```
267+
268+
**When `iterates_on` is set, the following phases are modified:**
269+
- **Phase 1**: Skip the "What do you want to build?" question — the intent scaffold already has a Problem/Solution from `/followup`. Instead, present the existing description and ask if the user wants to refine it.
270+
- **Phase 2**: Use previous intent context to ask more targeted clarifying questions. Focus on what's *different* from the previous intent, not re-establishing the full domain.
271+
- **Phase 2.5**: Shorten or skip domain discovery — the previous intent already explored the domain. Focus discovery on *new* areas or changes only.
272+
- **Phase 5**: Reference previous units to understand what exists. Suggest units that modify, extend, or fix what was previously built.
273+
274+
---
275+
188276
## Phase 1: Gather Intent
189277

278+
**If `iterates_on` is set:** The intent was created by `/followup` and already has a Problem/Solution section. Present the existing description to the user and ask if they want to refine it:
279+
280+
```json
281+
{
282+
"questions": [{
283+
"question": "Here's the follow-up description from the intent scaffold. Does this capture what you need, or would you like to refine it?",
284+
"header": "Follow-up Description",
285+
"options": [
286+
{"label": "Looks good", "description": "Proceed with this description"},
287+
{"label": "Refine it", "description": "I want to adjust the problem or solution statement"}
288+
],
289+
"multiSelect": false
290+
}]
291+
}
292+
```
293+
294+
If they choose "Refine it", engage in dialogue to update the Problem/Solution sections. If "Looks good", proceed to Phase 2.
295+
296+
**If `iterates_on` is NOT set (normal flow):**
297+
190298
Ask the user: "What do you want to build or accomplish?"
191299

192300
Wait for their answer. Do not explain the process.
@@ -205,6 +313,8 @@ Use `AskUserQuestion` to explore the user's intent. Ask 2-4 questions at a time,
205313

206314
CRITICAL: Do NOT list questions as plain text. Always use the `AskUserQuestion` tool.
207315

316+
> **Iteration intents (`iterates_on` set):** When elaborating an iteration intent, you already have the previous intent's domain model, units, and decisions as context. Focus clarifying questions on what's **different or new** in this follow-up — do not re-establish the full domain from scratch. Ask about: what specifically changed, which parts of the previous implementation are affected, any new constraints or requirements that didn't exist before, and whether the previous domain model needs updates.
317+
208318
Focus your questions on understanding:
209319
- What **specific problem** this solves (not just "build X" but "build X because Y")
210320
- Who uses it and how (the user journey, not just "it's for developers")
@@ -309,6 +419,13 @@ This ensures:
309419

310420
**This phase is mandatory.** Domain discovery runs in a forked subagent to keep the main context lean. The subagent performs deep technical exploration autonomously, writing all findings to `discovery.md` on disk.
311421

422+
> **Iteration intents (`iterates_on` set):** When this intent iterates on a previous one, domain discovery should be **shortened, not skipped**. The previous intent already explored the domain — include the previous intent's `discovery.md` content in the discovery brief so the subagent can use it as a starting point. The subagent should focus on:
423+
> - **New areas** introduced by the follow-up that weren't covered before
424+
> - **Changes** to existing code/systems made by the previous intent (the codebase has evolved since the original discovery)
425+
> - **Affected components** — which parts of what was built need modification
426+
>
427+
> Include the previous intent's discovery findings and unit specs in the discovery brief (Step 2) under a `## Previous Intent Context` section so the subagent has full context.
428+
312429
### Step 1: Load provider config
313430

314431
```bash
@@ -599,6 +716,13 @@ Decompose the intent into **Units** — independent pieces of work. This is NOT
599716

600717
Do NOT ask the user whether to decompose. Assess the complexity from the domain model, success criteria, and data sources — then decompose accordingly.
601718

719+
> **Iteration intents (`iterates_on` set):** When decomposing an iteration intent, reference the previous intent's units to understand what already exists in the codebase. Use this context to:
720+
> - **Identify which previous units are affected** by the follow-up work and note them in the new unit specs
721+
> - **Suggest units that modify or extend** specific previous units rather than starting from scratch
722+
> - **Auto-populate `context` references** in unit descriptions pointing to previous unit files (e.g., "See `{previous-slug}/unit-02-auth-middleware` for the existing implementation")
723+
> - **Avoid duplicating work** — if a previous unit already handles a concern, the new unit should describe how it *changes* that work, not rebuild it
724+
> - **Carry forward domain knowledge** — reference the previous intent's domain model and data sources rather than re-describing them
725+
602726
**Hard rules for unit boundaries:**
603727

604728
1. **Units MUST NOT span dependency boundaries.** If a piece of work depends on another piece being done first, those are two separate units with an explicit `depends_on` edge. This applies regardless of change strategy (`unit` or `intent`). A unit that contains both "set up the database schema" and "build the API that uses it" is a bad unit — those are two units where the API unit depends on the schema unit.
@@ -921,6 +1045,7 @@ git:
9211045
announcements: [] # e.g., [changelog, release-notes, social-posts, blog-draft]
9221046
passes: [] # Optional: [design, product, dev] — omit or leave empty for single-pass (default dev)
9231047
active_pass: "" # Current pass being worked on (auto-managed by construct)
1048+
iterates_on: "" # Slug of the previous intent this iterates on (set by /followup, leave empty for new intents)
9241049
created: {ISO date}
9251050
status: active
9261051
epic: "" # Ticketing provider epic key (auto-populated if ticketing provider configured)

0 commit comments

Comments
 (0)