|
| 1 | +--- |
| 2 | +title: "Implement-Feature Loop — plan → gh tickets → code/verify/changelog/commit per ticket → human browser test → ship" |
| 3 | +lede: "The generic feature-execution cadence: a signed-off plan becomes gh tickets, each ticket lands as verified code + a changelog beat + a conventions-clean commit, and the run closes with a human browser test and a ship() commit." |
| 4 | +date_created: 2026-07-27 |
| 5 | +date_modified: 2026-07-27 |
| 6 | +authors: |
| 7 | + - Michael Staton |
| 8 | +augmented_with: |
| 9 | + - Claude Code on Claude Fable 5 |
| 10 | +semantic_version: 0.0.0.1 |
| 11 | +tags: |
| 12 | + - Loop |
| 13 | + - Augment-It |
| 14 | + - Feature-Execution |
| 15 | + - GH-Issues |
| 16 | + - Git-Conventions |
| 17 | + - Changelog-Conventions |
| 18 | + - Browser-Drive |
| 19 | +status: Awaiting-First-Run |
| 20 | +--- |
| 21 | + |
| 22 | +# Implement-Feature Loop |
| 23 | + |
| 24 | +> `context-v/loops/` is **experimental** (per the context-vigilance skill). |
| 25 | +> Unlike its sibling |
| 26 | +> [[Loop-through-Spec-Write-Plans-Implement-Test-Changelog-Commit]] — which |
| 27 | +> was codified retrospectively and asked that the next loop be authored |
| 28 | +> *before* running — this one is written first. The doc is the durable |
| 29 | +> definition; each session that runs it is an execution. |
| 30 | +
|
| 31 | +## What this loop is |
| 32 | + |
| 33 | +A per-**ticket** execution cadence for a feature whose plan already exists in |
| 34 | +`context-v/plans/`. The plan is the contract; gh issues are the visible work |
| 35 | +trail; every iteration lands one ticket as working, verified code with its |
| 36 | +changelog beat and its own commit. The run is bookended by two named commits — |
| 37 | +`init(feature, <feature-name>)` opens it, `ship(feature, <feature-name>)` |
| 38 | +closes it — with a **human browser test as the gate between "all tickets |
| 39 | +done" and "shipped."** |
| 40 | + |
| 41 | +Distinct from the sibling spec-loop: that one iterates *phases of a spec* |
| 42 | +(authoring a plan each turn); this one iterates *tickets of a plan* that is |
| 43 | +already written. Run that loop to produce plans; run this one to burn a plan |
| 44 | +down. |
| 45 | + |
| 46 | +## Parameters (set at loop start) |
| 47 | + |
| 48 | +- `<feature-name>` — kebab-case handle used in both bookend commits |
| 49 | + (e.g. `org-relations`). |
| 50 | +- `<plan-doc>` — the `context-v/plans/*.md` file being executed |
| 51 | + (e.g. [[../plans/Org-Relations-Parent-Child-Peer-Plus-Org-Tags]]). |
| 52 | +- `<changelog-file>` — minted in Phase 0 per changelog-conventions |
| 53 | + (`changelog/YYYY-MM-DD_NN_<Title>.md`). |
| 54 | + |
| 55 | +## Skills to load at loop start (exact names) |
| 56 | + |
| 57 | +1. **`context-vigilance`** — frontmatter, status discipline, where artifacts go |
| 58 | +2. **`pseudomonorepos`** — which repo you're actually in; branch-tier |
| 59 | + awareness (augment-it trunk is `rebuild/turbo-rsbuild`, not the documented |
| 60 | + tiers); never bump parent gitlinks as a side effect |
| 61 | +3. **`git-conventions`** — header syntax, body structure, pre-commit checklist |
| 62 | +4. **`gh-cli-projects-tasks-conventions`** — ticket bodies link the context-v |
| 63 | + file as a **GitHub URL in the file's own repo** (not a deep parent-monorepo |
| 64 | + path); prefill labels/milestones/types from what the repo actually has |
| 65 | +5. **`changelog-conventions`** — the stub's frontmatter (publish, lede, ISO |
| 66 | + dates) and the ship-note register |
| 67 | + |
| 68 | +Also confirm the **Playwright MCP** is connected (`.mcp.json` project scope; |
| 69 | +`claude mcp add -s project playwright -- npx @playwright/mcp@latest` if |
| 70 | +absent — remembering a newly added server loads in the **next** session). |
| 71 | +Browser-simulated checking is part of the loop, not an optional extra. |
| 72 | + |
| 73 | +## Phase 0 — setup (once per run) |
| 74 | + |
| 75 | +1. **Check the plan.** Read `<plan-doc>` end to end against the live working |
| 76 | + tree — plans go stale the moment code moves. Flag divergences in the plan |
| 77 | + doc (a `## Superseded by reality` note, sibling-loop style) rather than |
| 78 | + silently improvising. Flip the plan's `status:` → `Implementing` |
| 79 | + (+ `date_modified`, patch bump). |
| 80 | +2. **Write the tickets.** One gh issue per plan step/phase-slice, per the |
| 81 | + gh-cli-projects skill: body leads with the clickable GitHub URL to |
| 82 | + `<plan-doc>`, sidebar prefilled from the repo's real labels/milestones. |
| 83 | + The issue list IS the loop's work queue — order it by the plan's |
| 84 | + dependency order. |
| 85 | +3. **Initiate the changelog stub.** Create `<changelog-file>` with full |
| 86 | + frontmatter and a **narrative** opening — why this feature, what changes |
| 87 | + for the operator — plus an empty `## What landed` section the loop |
| 88 | + appends to. It ships as a stub on the first commit; it's polished at the |
| 89 | + end, not written at the end. |
| 90 | +4. **First commit:** |
| 91 | + |
| 92 | + ``` |
| 93 | + init(feature, <feature-name>): tickets opened, changelog stubbed, loop begins |
| 94 | + ``` |
| 95 | + |
| 96 | + Body per git-conventions: link `<plan-doc>` and enumerate the gh issue |
| 97 | + numbers. Push. This commit is the run's opening bracket. |
| 98 | + |
| 99 | +## The iteration (once per gh ticket, in queue order) |
| 100 | + |
| 101 | +``` |
| 102 | +pick ticket → code → verify (svelte-check / typecheck / logs / browser drive) |
| 103 | + → changelog beat → commit → close ticket with the hash → next |
| 104 | +``` |
| 105 | + |
| 106 | +1. **Pick the next open ticket** and note its number — the whole iteration |
| 107 | + hangs off it. |
| 108 | +2. **Write the code.** Match surrounding idiom; scope strictly to the ticket |
| 109 | + (scope creep spawns a *new* ticket, it doesn't widen this one). |
| 110 | +3. **Verify — the ladder, cheapest rung first:** |
| 111 | + - `pnpm exec svelte-check` in each touched `apps/*` (and |
| 112 | + `pnpm -r typecheck` when services changed) — code logic sound, nothing |
| 113 | + breaking. (`pnpm exec`, the current form of `pnpx`.) |
| 114 | + - **Monitor server logs** while exercising the change: |
| 115 | + `docker compose logs -f --tail=50 <touched-services>` — watch for |
| 116 | + errors/failures the type layer can't see (NATS timeouts, handler |
| 117 | + throws, refused boots). |
| 118 | + - **Browser drive** for any UI-facing ticket: Playwright MCP against the |
| 119 | + local shell — navigate, click the new affordance, assert via |
| 120 | + accessibility snapshot (screenshots only for visual questions). Reads |
| 121 | + unrestricted; **writes only against throwaway/test entities, never |
| 122 | + canonical data.** |
| 123 | + - Run the plan's proof script if the ticket lands capability surface. |
| 124 | +4. **Update the changelog** — append to `## What landed`: the step, a short |
| 125 | + code sample of the interesting part, and any gotcha hit. Beats are |
| 126 | + written while the context is hot; the polish pass only reorders and |
| 127 | + tightens. |
| 128 | +5. **Commit** per git-conventions (action verb + effort grouping, impact |
| 129 | + before implementation, `Refs #<ticket>` in the body). One ticket, one |
| 130 | + commit, as a rule; riders per the skill when a trivial fix tags along. |
| 131 | + Push. |
| 132 | +6. **Close the ticket with the receipt:** |
| 133 | + |
| 134 | + ```bash |
| 135 | + gh issue close <n> --comment "Landed in <short-hash>. <one-line note: what proved it / anything the next ticket should know>" |
| 136 | + ``` |
| 137 | + |
| 138 | + The commit hash in the closing comment is mandatory — it's what makes the |
| 139 | + issue trail auditable later. |
| 140 | + |
| 141 | +**Blocked ticket?** Comment the blocker on the issue, label it, skip it, and |
| 142 | +continue the queue — return after the others. Two consecutive passes with the |
| 143 | +same blocker = stop the loop and surface to the operator. |
| 144 | + |
| 145 | +## Exit conditions → the human gate → ship |
| 146 | + |
| 147 | +The loop's iterations end when **every gh ticket is closed** and the full |
| 148 | +ladder is green (svelte-check + typecheck clean, logs quiet, agent browser |
| 149 | +drives passed, proof script green if one exists). |
| 150 | + |
| 151 | +Then, in order: |
| 152 | + |
| 153 | +1. **Human browser test.** Hand the surface to the operator with a short |
| 154 | + click-path script (what to try, what changed). The agent's Playwright |
| 155 | + drives proved the buttons *work*; this rung judges whether the surface is |
| 156 | + *usable* — it is the gate, and it augments, never replaces, the drives |
| 157 | + that preceded it. Findings become fix-tickets and the loop re-enters the |
| 158 | + iteration above for them. |
| 159 | +2. **Polish the changelog.** Narrative pass over `<changelog-file>`: tighten |
| 160 | + the lede, order `## What landed` for a reader instead of a chronology, |
| 161 | + keep the best code samples, add the ship note. |
| 162 | +3. **Close the plan.** `<plan-doc>` `status:` → `Shipped` |
| 163 | + (+ `date_first_published`); check off any tracking issue's boxes |
| 164 | + (e.g. the source issue's worklist). |
| 165 | +4. **Ship commit:** |
| 166 | + |
| 167 | + ``` |
| 168 | + ship(feature, <feature-name>): <one-line what the operator can now do> |
| 169 | + ``` |
| 170 | + |
| 171 | + Body: link the changelog entry and `<plan-doc>`, enumerate the closed |
| 172 | + issue numbers, note the human test passed. Push. Closing bracket; loop |
| 173 | + over. |
| 174 | + |
| 175 | +## Commit-verb note (extends git-conventions for this loop) |
| 176 | + |
| 177 | +`init(feature, …)` and `ship(feature, …)` are this loop's bookend markers — |
| 178 | +kin to the sibling loop's `attempt()`/`milestone()` verbs. Everything between |
| 179 | +the bookends uses the standard git-conventions vocabulary (`feat`, `fix`, |
| 180 | +`progress`, …). If the bookends prove out across runs, propose them upstream |
| 181 | +into the git-conventions skill; until then they're loop-local. |
| 182 | + |
| 183 | +## Anti-patterns (learned house rules, restated so the loop can't forget) |
| 184 | + |
| 185 | +- **No time estimates** in tickets, changelog, or commits. |
| 186 | +- **Don't batch commits** across tickets "to keep history clean" — the |
| 187 | + ticket↔commit↔changelog-beat correspondence *is* the cleanliness. |
| 188 | +- **Don't polish the changelog mid-loop** — beats stay raw until the ship |
| 189 | + pass, or the polish work gets done twice. |
| 190 | +- **Don't let the agent's browser drive substitute for the human test**, and |
| 191 | + don't ask for the human test before the drives are green — the human's |
| 192 | + attention is the scarcest resource in the loop. |
| 193 | +- **Don't touch parent pseudomonorepo gitlinks** as part of any commit here. |
| 194 | + |
| 195 | +## See also |
| 196 | + |
| 197 | +- [[Loop-through-Spec-Write-Plans-Implement-Test-Changelog-Commit]] — the |
| 198 | + sibling loop that produces the plans this one consumes |
| 199 | +- `context-v/blueprints/Browser-Drive-Verification-For-Agent-Sessions.md` |
| 200 | + (anchor monorepo root) — the two-rung verification pattern |
| 201 | +- The five skills named above — this doc orchestrates them, it doesn't |
| 202 | + restate them |
0 commit comments