Agent Pipeline Read-only Audit
How to use
Provide the project path and optional product goal, known concerns, and constraints. Run this before creating a PRD or tickets.
Prompt
Projekt: <CESTA NEBO ODKAZ NA PROJEKT>
Produktový cíl: <VOLITELNÝ POPIS CÍLE>
Známé problémy nebo obavy: <VOLITELNÉ>
Omezení: <VOLITELNÉ — ČAS, KOMPATIBILITA, DATA, DEPLOY, ROZPOČET>
Proveď důkladnou read-only analýzu projektu a připrav ověřený návrh pracovních proudů, problémů a priorit. V této fázi nic neimplementuj, neměň soubory, nevytvářej tickety, necommituj a nepushuj.
Cílem není maximalizovat počet nálezů. Cílem je najít skutečné, aktuální a doložitelné problémy, určit jejich dopad a vytvořit spolehlivý podklad pro PRD a implementační tickety.
Použij /caveman full pro komunikaci a /ponytail full jako rozhodovací filtr: odstranit nebo nepřidávat práci, která nemá doloženou hodnotu.
1. Nejdřív zjisti pravidla projektu
Přečti celé:
- repository instrukce jako
AGENTS.md,CLAUDE.md,CONTRIBUTING.md; - hlavní README a architektonický přehled;
- domain glossary nebo
CONTEXT.md; - relevantní ADR;
- current-state nebo handoff dokumentaci;
- issue-tracker a commit workflow;
- package manifesty, workspace config, build/test config;
- relevantní memories nebo ekvivalent projektu.
Urči:
- které dokumenty jsou současná autorita;
- které dokumenty jsou historické;
- které dokumenty si odporují;
- zda pracovní strom obsahuje uživatelské změny;
- zda existují další repozitáře, worktrees nebo datové zdroje s vlastními pravidly;
- jaké operace jsou read-only a jaké by později měnily externí stav.
Historický dokument nepovažuj automaticky za backlog. Každý jeho nález ověř proti současnému kódu a testům.
Pokud chybí issue-tracker, triage nebo domain-doc routing, použij /setup-matt-pocock-skills. Pokud už jsou správně nastavené, skill nespouštěj.
Pokud projekt obsahuje vlastní audit workflow, přečti jej. Použij jej pouze
tehdy, když zachovává read-only hranici této fáze a připravuje evidence pro
issue tracker. Workflow, které automaticky opravuje, publikuje issues nebo
commituje, v této fázi nespouštěj.
2. Skill routing
Použij jen relevantní skills. Nespouštěj skill pouze proto, že existuje.
Na začátku analýzy
/zoom-out- použij, pokud architekturu nebo doménu neznáš;
- cílem je pochopit hranice systému, datové toky a odpovědnosti;
- nepoužívej, pokud je projekt malý a struktura zřejmá.
/graphify- použij jen pro velký, neznámý, cross-repo nebo dokumentačně složitý systém, kde knowledge graph skutečně zlepší orientaci;
- nikdy nepoužívej
pnpm dlx graphify; npm balíček není codebase Graphify; - pokud existuje aktuální
graphify-out/, použij report, wiki a queries pouze jako navigační index; - vytvoření nebo update grafu zapisuje artefakty a může instalovat runtime, proto vyžaduje samostatnou autorizaci před tímto read-only auditem;
EXTRACTEDhrany používej pro navigaci;INFERREDaAMBIGUOUShrany jsou hypotézy;- každý problém z grafu znovu ověř v raw kódu a testech;
- Graphify není důkaz bugu, dead code, bezpečnosti ani splněného kontraktu.
Deterministická strukturální evidence pro TS/JS
- Fallow
- použij jako doplňkový evidence source pro dead code, circular dependencies, duplicity, complexity, architecture boundaries a design-system drift;
- preferuj repository-pinned
pnpm exec fallow; - pokud Fallow není dependency, nespouštěj
pnpm dlx fallowbez explicitního povolení, protože stáhne balíček a zapíše package-manager cache; - Fallow může zapisovat
.fallow/cachea changed-file audit může vytvořit dočasný Git worktree; porovnej Git status před a po běhu, profallow auditpoužij--no-cachea nástroj nespouštěj, pokud nelze zachovat project tree a Git metadata; - pro celý projekt použij read-only pipeline
pnpm exec fallow --format json --quiet; - volitelně použij
pnpm exec fallow recommend --format jsonpro ověření framework entry points a potřebné konfigurace; - exit
0a1znamená dokončenou analýzu;1znamená findings,2chybu nástroje; - nespouštěj
fix,init,hooks install,watch, config writes ani baseline writes; - Fallow finding je kandidát, ne automaticky potvrzený problém;
- před backlogem ověř framework entry points, generated files, veřejnou dosažitelnost a současný kód.
Architektura a kvalita návrhu
/improve-codebase-architecture- použij pro hledání špatných hranic modulů, duplicitních autorit, silného couplingu, obtížné testovatelnosti a nejasných doménových odpovědností;
- návrhy musí vycházet z aktuálního kódu a domain vocabulary.
/grill-with-docs- použij, když kód odporuje dokumentaci;
- použij při nejasné doménové semantice;
- použij před doporučením zásadního architektonického nebo produktového rozhodnutí;
- výsledek může být HITL rozhodnutí, ne automatická implementace.
/ponytail-audit- použij jako samostatný pohled na over-engineering;
- hledej zbytečné abstraction layers, dependencies, konfiguraci, vlastní implementace standardních funkcí a spekulativní flexibilitu;
- nález nezahrnuj do backlogu, pokud jeho odstranění nepřinese konkrétní snížení rizika, složitosti nebo nákladů.
Potvrzené chyby
/diagnose- použij až pro konkrétní podezření na bug, selhání nebo regresi;
- postup: reprodukce → minimalizace → hypotéza → instrumentace → příčina;
- pouhý podezřelý kód není potvrzený bug.
Webové projekty
/modern-web-guidance- spusť jako první skill před analýzou HTML, CSS nebo client-side JavaScriptu;
- ověř aktuální webové API a doporučené browser patterns;
- nepoužívej pro čistý backend, CLI nebo datovou knihovnu.
/chrome-devtools- použij pro runtime chování, network, rendering, layout, browser state nebo performance timeline;
- pouze pokud lze aplikaci bezpečně spustit bez změny produkčních dat.
/a11y-debugging- použij pro semantic HTML, ARIA, keyboard flow, focus management, contrast a tap targets;
- automatický audit neoznačuj za úplnou WCAG certifikaci.
/debug-optimize-lcp- použij pouze při potvrzené otázce kolem načítání, LCP nebo Core Web Vitals;
- nejdřív změř baseline, potom navrhuj optimalizaci.
/memory-leak-debugging- použij pouze při důkazu rostoucí paměti, OOM, dlouho žijících objektů nebo neukončených subscriptions/listeners.
Nejasné řešení
/prototype- použij jen když malý zahoditelný experiment levně ověří datový model, stavový automat nebo UI variantu;
- prototyp není produkční implementace ani důkaz dokončení.
Pozdější fáze
V této analytické fázi zatím nepoužívej:
/to-prd— až po schválení analytického závěru;/to-issues— až po schválení PRD nebo pracovních proudů;/tdd— až při implementaci behaviorálních tiketů;/triage— pouze pokud bude potřeba rozhodnout, zda neúplný nález potřebuje další informace, lidské rozhodnutí nebo zamítnutí.
3. Agent a model routing
Pokud jsou dostupní subagenti, použij je paralelně pouze pro nezávislé read-only oblasti.
explorer- mapování domény, modulů, testů, historie a logů;
- každý explorer dostane jednu jasně ohraničenou oblast;
- nesmí měnit soubory.
reviewer- nezávislé adversarial ověření P0/P1 nálezů;
- hledá chybnou interpretaci, false positive, bezpečnostní důsledky a chybějící důkazy.
worker- v analytické fázi nepoužívej, protože je určen pro implementaci.
Model vybírej podle povahy práce, ne náhodně:
- rychlejší model pro inventuru a mechanické mapování;
- silnější reasoning model pro architekturu, bezpečnost, doménovou semantiku a adversarial review;
- specializovaný browser nástroj pro runtime UI důkazy.
Read-only subagenti nepotřebují worktrees. Worktrees začni řešit až při paralelní implementaci.
4. Vytvoř mapu systému
Popiš současný systém pomocí projektového domain vocabulary.
Zmapuj:
- vstupní rozhraní;
- hlavní use cases;
- frontend, backend, CLI a background processing;
- persistence a zdroje pravdy;
- filesystem, DB, cache a externí služby;
- autentizaci, autorizaci a privacy hranice;
- build, assembly, deploy a release;
- synchronní a asynchronní datové toky;
- recovery a rollback;
- testovací vrstvy;
- provozní observability;
- kritická uživatelská a administrátorská rozhraní.
Pro každou oblast určuj její autoritu. Hledej zejména případy, kdy stejný stav nezávisle zapisují nebo odvozují dvě části systému.
5. Coverage mapa
Každou relevantní doménu označ jedním stavem:
covered— současný kontrakt je doložen kódem a citlivým testem;active— existuje potvrzená mezera;parked— práce vyžaduje budoucí produktové rozhodnutí nebo nový scope;wontfix— vědomě přijatý stav s odůvodněním;unaudited— nebylo možné získat dost důkazů.
Minimálně zvaž:
- produktové use cases;
- data integrity;
- persistence a recovery;
- security a privacy;
- authentication a authorization;
- API a integrační kontrakty;
- concurrency a idempotence;
- frontend state a race conditions;
- accessibility;
- responsive a touch;
- localization;
- performance;
- build a deploy;
- observability a logging;
- test isolation;
- developer workflow;
- dokumentaci;
- dependency a supply-chain rizika.
Nevynucuj nerelevantní domény. U čisté knihovny například nemusí existovat UI, deploy ani uživatelská lokalizace.
6. Hledání problémů
U každého podezření ověř:
- Existuje tato cesta v aktuálním kódu?
- Je chování veřejně dosažitelné?
- Existuje test, který by na regresi skutečně selhal?
- Je dokumentovaný kontrakt stále autoritativní?
- Jde o chybu, produktové rozhodnutí, technický dluh, testovací mezeru nebo pouze stylistickou preferenci?
- Jaký je nejhorší realistický dopad?
- Lze problém reprodukovat read-only nebo v izolované fixture?
- Neřeší jej už jiný mechanismus?
- Není návrh řešení složitější než samotný problém?
- Je nález stále platný na současném HEAD?
Nepoužívej samotný počet řádků, stáří kódu, chybějící abstrakci nebo osobní styl jako důkaz problému.
7. Klasifikace nálezů
Použij priority:
P0 — bezpečnost a ztráta dat
- možná ztráta nebo nevratná korupce dat;
- špatný tenant, projekt, dataset nebo environment;
- únik credentials nebo soukromého obsahu;
- bypass authorization;
- nebezpečný deploy nebo recovery kontrakt.
P0 musí mít silný důkaz a nezávislé adversarial ověření.
P1 — chybné veřejné chování
- potvrzený funkční bug;
- nondeterminismus;
- race condition;
- nefunkční persistence;
- chybný API/UI kontrakt;
- významná accessibility nebo responsive překážka;
- testy závislé na produkčních datech nebo konkrétním stroji.
P2 — dlouhodobá kvalita a provoz
- nejasná doménová autorita;
- významná testovací mezera;
- měřitelný performance problém;
- komplikovaný nebo chybový developer workflow;
- duplicita, která prokazatelně způsobuje drift;
- dokumentace odporující současnému chování.
Parked
- hypotetický problém bez reprodukce;
- feature bez produktového rozhodnutí;
- optimalizace bez baseline;
- migrace bez cílového systému;
- nový dependency nebo architecture layer bez konkrétní potřeby.
Nevytvářej pevný cílový počet nálezů.
8. Evidence pro každý nález
Každý potvrzený nález popiš jednotnou strukturou:
- ID;
- krátký název;
- priorita;
- typ:
bug,security,data-safety,test-gap,architecture,UX,a11y,performance,decision; - dotčená doména;
- veřejné chování;
- důkaz v aktuálním kódu s přesným
file:line; - reprodukce nebo read-only tracer;
- existující testy a proč problém nezachytí;
- realistický dopad;
- confidence:
confirmed,strong,tentative; - minimální směr opravy;
- vhodný veřejný regresní test;
- dependencies;
- doporučený typ budoucího ticketu:
AFKneboHITL; - co výslovně není součástí scope.
Nález bez dostatečného důkazu přesuň do unaudited nebo parked; nevydávej jej za potvrzený problém.
9. Adversarial ověření
Nezávislý reviewer musí u všech P0 a P1 nálezů ověřit:
- zda je cesta skutečně dosažitelná;
- zda nedošlo k záměně historického a současného kontraktu;
- zda existující guard problém již neřeší;
- zda navrhovaný test opravdu selže při původní chybě;
- zda doporučená oprava nezpůsobí větší regresi;
- zda scope nevyžaduje produktové rozhodnutí.
False positives odstraň. Sporné body označ jako HITL, needs-info, parked nebo unaudited.
10. Návrh pracovních proudů
Potvrzené nálezy seskup do pracovních proudů podle doménové odpovědnosti, ne podle adresářů.
U každého proudu uveď:
- cíl;
- zahrnuté nálezy;
- prioritu;
- dependencies;
- bezpečnostní hranice;
- co lze analyzovat nebo později implementovat paralelně;
- co vyžaduje jediného writera;
- co vyžaduje HITL rozhodnutí;
- definition of done;
- co zůstává parked nebo mimo scope.
Pracovní proud ještě není implementační ticket. Neprováděj předčasný detailní návrh všech souborových změn.
11. Povinný výstup
Vrať jeden soudržný report:
A. Executive summary
- současný stav projektu;
- největší potvrzená rizika;
- počet nálezů podle priority;
- nejdůležitější nejistoty.
B. Architecture and domain map
- hranice systému;
- zdroje pravdy;
- hlavní datové toky;
- kritické write paths.
C. Coverage mapa
Tabulka všech relevantních domén se stavem covered, active, parked, wontfix nebo unaudited.
D. Potvrzené nálezy
Seřazené P0 → P1 → P2, každý s úplnou evidence strukturou.
U každého nálezu uveď existující issue reference, nebo NEW CANDIDATE.
Nevytvářej duplicity. Připrav issue-ready title, behavior statement, acceptance
criteria, dependencies, AFK/HITL a evidence links, ale nic nepublikuj.
E. Odmítnuté nebo nepotvrzené hypotézy
Uveď, co bylo prověřeno a proč to není backlog.
F. Navržené pracovní proudy
Logické seskupení budoucí práce, dependencies a možné paralelní vlny.
G. HITL rozhodnutí
Pouze skutečná produktová nebo doménová rozhodnutí, která nelze bezpečně odvodit z kódu.
H. Parked a wontfix
Explicitně, aby se později nezaměnily za zapomenutou práci.
I. Doporučené pořadí
- P0 unblock;
- závislosti;
- P1 behaviorální důkazy;
- P2 kvalita;
- možné paralelní větve práce.
J. Audit limitations
Co nebylo možné ověřit a proč.
K. Podklad pro další fázi
Na konci vytvoř krátký schvalovací blok, který mohu potvrdit a následně předat /to-prd a /to-issues.
Po odevzdání reportu zastav. Nic neimplementuj ani nepublikuj bez mého dalšího schválení.
Attachments
I don't know this area of code well. Go up a layer of abstraction. Give me a map of all the relevant modules and callers, using the project's domain glossary vocabulary.
# Improve Codebase Architecture
Surface architectural friction and propose **deepening opportunities** — refactors that turn shallow modules into deep ones. The aim is testability and AI-navigability.
This command is _informed_ by the project's domain model and built on a shared design vocabulary:
- Run the `/codebase-design` skill for the architecture vocabulary (**module**, **interface**, **depth**, **seam**, **adapter**, **leverage**, **locality**) and its principles (the deletion test, "the interface is the test surface", "one adapter = hypothetical seam, two = real"). Use these terms exactly in every suggestion — don't drift into "component," "service," "API," or "boundary."
- The domain language in `CONTEXT.md` gives names to good seams; ADRs in `docs/adr/` record decisions this command should not re-litigate.
## Process
### 1. Explore
**Scope before you scan — YAGNI.** Deepening a module pays off by making future changes to it easier, so put extra weight on the parts of the codebase that have recently changed. Decide *where* to look before you look:
- If the user named a direction — a module, a subsystem, a pain point — take it, and skip the inference below.
- Otherwise, walk back a good stretch of the commit history (`git log --oneline`) to find the codebase's hot spots — the files and areas that keep coming up — and let those paths pull your attention first. If the changes are scattered with no clear hot spot, widen the net.
Read the project's domain glossary (`CONTEXT.md`) and any ADRs in the area you're touching first.
Then use the Agent tool with `subagent_type=Explore` to walk the codebase. Don't follow rigid heuristics — explore organically and note where you experience friction:
- Where does understanding one concept require bouncing between many small modules?
- Where are modules **shallow** — interface nearly as complex as the implementation?
- Where have pure functions been extracted just for testability, but the real bugs hide in how they're called (no **locality**)?
- Where do tightly-coupled modules leak across their seams?
- Which parts of the codebase are untested, or hard to test through their current interface?
Apply the **deletion test** to anything you suspect is shallow: would deleting it concentrate complexity, or just move it? A "yes, concentrates" is the signal you want.
### 2. Present candidates as an HTML report
Write a self-contained HTML file to the OS temp directory so nothing lands in the repo. Resolve the temp dir from `$TMPDIR`, falling back to `/tmp` (or `%TEMP%` on Windows), and write to `<tmpdir>/architecture-review-<timestamp>.html` so each run gets a fresh file. Open it for the user — `xdg-open <path>` on Linux, `open <path>` on macOS, `start <path>` on Windows — and tell them the absolute path.
The report uses **Tailwind via CDN** for layout and styling, and **Mermaid via CDN** for diagrams where a graph/flow/sequence reliably communicates the structure. Mix Mermaid with hand-crafted CSS/SVG visuals — use Mermaid when relationships are graph-shaped (call graphs, dependencies, sequences), and hand-built divs/SVG when you want something more editorial (mass diagrams, cross-sections, collapse animations). Each candidate gets a **before/after visualisation**. Be visual.
For each candidate, render a card with:
- **Files** — which files/modules are involved
- **Problem** — why the current architecture is causing friction
- **Solution** — plain English description of what would change
- **Benefits** — explained in terms of locality and leverage, and how tests would improve
- **Before / After diagram** — side-by-side, custom-drawn, illustrating the shallowness and the deepening
- **Recommendation strength** — one of `Strong`, `Worth exploring`, `Speculative`, rendered as a badge
End the report with a **Top recommendation** section: which candidate you'd tackle first and why.
**Use CONTEXT.md vocabulary for the domain, and the `/codebase-design` vocabulary for the architecture.** If `CONTEXT.md` defines "Order," talk about "the Order intake module" — not "the FooBarHandler," and not "the Order service."
**ADR conflicts**: if a candidate contradicts an existing ADR, only surface it when the friction is real enough to warrant revisiting the ADR. Mark it clearly in the card (e.g. a warning callout: _"contradicts ADR-0007 — but worth reopening because…"_). Don't list every theoretical refactor an ADR forbids.
See [HTML-REPORT.md](HTML-REPORT.md) for the full HTML scaffold, diagram patterns, and styling guidance.
Do NOT propose interfaces yet. After the file is written, ask the user: "Which of these would you like to explore?"
### 3. Grilling loop
Once the user picks a candidate, run the `/grilling` skill to walk the decision tree with them — constraints, dependencies, the shape of the deepened module, what sits behind the seam, what tests survive.
Side effects happen inline as decisions crystallize — run the `/domain-modeling` skill to keep the domain model current as you go:
- **Naming a deepened module after a concept not in `CONTEXT.md`?** Add the term to `CONTEXT.md`. Create the file lazily if it doesn't exist.
- **Sharpening a fuzzy term during the conversation?** Update `CONTEXT.md` right there.
- **User rejects the candidate with a load-bearing reason?** Offer an ADR, framed as: _"Want me to record this as an ADR so future architecture reviews don't re-suggest it?"_ Only offer when the reason would actually be needed by a future explorer to avoid re-suggesting the same thing — skip ephemeral reasons ("not worth it right now") and self-evident ones.
- **Want to explore alternative interfaces for the deepened module?** Run the `/codebase-design` skill and use its design-it-twice parallel sub-agent pattern.
Run a `/grilling` session, using the `/domain-modeling` skill.
# Diagnose
A discipline for hard bugs. Skip phases only when explicitly justified.
When exploring the codebase, use the project's domain glossary to get a clear mental model of the relevant modules, and check ADRs in the area you're touching.
## Phase 1 — Build a feedback loop
**This is the skill.** Everything else is mechanical. If you have a fast, deterministic, agent-runnable pass/fail signal for the bug, you will find the cause — bisection, hypothesis-testing, and instrumentation all just consume that signal. If you don't have one, no amount of staring at code will save you.
Spend disproportionate effort here. **Be aggressive. Be creative. Refuse to give up.**
### Ways to construct one — try them in roughly this order
1. **Failing test** at whatever seam reaches the bug — unit, integration, e2e.
2. **Curl / HTTP script** against a running dev server.
3. **CLI invocation** with a fixture input, diffing stdout against a known-good snapshot.
4. **Headless browser script** (Playwright / Puppeteer) — drives the UI, asserts on DOM/console/network.
5. **Replay a captured trace.** Save a real network request / payload / event log to disk; replay it through the code path in isolation.
6. **Throwaway harness.** Spin up a minimal subset of the system (one service, mocked deps) that exercises the bug code path with a single function call.
7. **Property / fuzz loop.** If the bug is "sometimes wrong output", run 1000 random inputs and look for the failure mode.
8. **Bisection harness.** If the bug appeared between two known states (commit, dataset, version), automate "boot at state X, check, repeat" so you can `git bisect run` it.
9. **Differential loop.** Run the same input through old-version vs new-version (or two configs) and diff outputs.
10. **HITL bash script.** Last resort. If a human must click, drive _them_ with `scripts/hitl-loop.template.sh` so the loop is still structured. Captured output feeds back to you.
Build the right feedback loop, and the bug is 90% fixed.
### Iterate on the loop itself
Treat the loop as a product. Once you have _a_ loop, ask:
- Can I make it faster? (Cache setup, skip unrelated init, narrow the test scope.)
- Can I make the signal sharper? (Assert on the specific symptom, not "didn't crash".)
- Can I make it more deterministic? (Pin time, seed RNG, isolate filesystem, freeze network.)
A 30-second flaky loop is barely better than no loop. A 2-second deterministic loop is a debugging superpower.
### Non-deterministic bugs
The goal is not a clean repro but a **higher reproduction rate**. Loop the trigger 100×, parallelise, add stress, narrow timing windows, inject sleeps. A 50%-flake bug is debuggable; 1% is not — keep raising the rate until it's debuggable.
### When you genuinely cannot build a loop
Stop and say so explicitly. List what you tried. Ask the user for: (a) access to whatever environment reproduces it, (b) a captured artifact (HAR file, log dump, core dump, screen recording with timestamps), or (c) permission to add temporary production instrumentation. Do **not** proceed to hypothesise without a loop.
Do not proceed to Phase 2 until you have a loop you believe in.
## Phase 2 — Reproduce
Run the loop. Watch the bug appear.
Confirm:
- [ ] The loop produces the failure mode the **user** described — not a different failure that happens to be nearby. Wrong bug = wrong fix.
- [ ] The failure is reproducible across multiple runs (or, for non-deterministic bugs, reproducible at a high enough rate to debug against).
- [ ] You have captured the exact symptom (error message, wrong output, slow timing) so later phases can verify the fix actually addresses it.
Do not proceed until you reproduce the bug.
## Phase 3 — Hypothesise
Generate **3–5 ranked hypotheses** before testing any of them. Single-hypothesis generation anchors on the first plausible idea.
Each hypothesis must be **falsifiable**: state the prediction it makes.
> Format: "If <X> is the cause, then <changing Y> will make the bug disappear / <changing Z> will make it worse."
If you cannot state the prediction, the hypothesis is a vibe — discard or sharpen it.
**Show the ranked list to the user before testing.** They often have domain knowledge that re-ranks instantly ("we just deployed a change to #3"), or know hypotheses they've already ruled out. Cheap checkpoint, big time saver. Don't block on it — proceed with your ranking if the user is AFK.
## Phase 4 — Instrument
Each probe must map to a specific prediction from Phase 3. **Change one variable at a time.**
Tool preference:
1. **Debugger / REPL inspection** if the env supports it. One breakpoint beats ten logs.
2. **Targeted logs** at the boundaries that distinguish hypotheses.
3. Never "log everything and grep".
**Tag every debug log** with a unique prefix, e.g. `[DEBUG-a4f2]`. Cleanup at the end becomes a single grep. Untagged logs survive; tagged logs die.
**Perf branch.** For performance regressions, logs are usually wrong. Instead: establish a baseline measurement (timing harness, `performance.now()`, profiler, query plan), then bisect. Measure first, fix second.
## Phase 5 — Fix + regression test
Write the regression test **before the fix** — but only if there is a **correct seam** for it.
A correct seam is one where the test exercises the **real bug pattern** as it occurs at the call site. If the only available seam is too shallow (single-caller test when the bug needs multiple callers, unit test that can't replicate the chain that triggered the bug), a regression test there gives false confidence.
**If no correct seam exists, that itself is the finding.** Note it. The codebase architecture is preventing the bug from being locked down. Flag this for the next phase.
If a correct seam exists:
1. Turn the minimised repro into a failing test at that seam.
2. Watch it fail.
3. Apply the fix.
4. Watch it pass.
5. Re-run the Phase 1 feedback loop against the original (un-minimised) scenario.
## Phase 6 — Cleanup + post-mortem
Required before declaring done:
- [ ] Original repro no longer reproduces (re-run the Phase 1 loop)
- [ ] Regression test passes (or absence of seam is documented)
- [ ] All `[DEBUG-...]` instrumentation removed (`grep` the prefix)
- [ ] Throwaway prototypes deleted (or moved to a clearly-marked debug location)
- [ ] The hypothesis that turned out correct is stated in the commit / PR message — so the next debugger learns
**Then ask: what would have prevented this bug?** If the answer involves architectural change (no good test seam, tangled callers, hidden coupling) hand off to the `/improve-codebase-architecture` skill with the specifics. Make the recommendation **after** the fix is in, not before — you have more information now than when you started.
This skill takes the current conversation context and codebase understanding and produces a PRD. Do NOT interview the user — just synthesize what you already know.
The issue tracker and triage label vocabulary should have been provided to you — run `/setup-matt-pocock-skills` if not.
## Process
1. Explore the repo to understand the current state of the codebase, if you haven't already. Use the project's domain glossary vocabulary throughout the PRD, and respect any ADRs in the area you're touching.
2. Sketch out the major modules you will need to build or modify to complete the implementation. Actively look for opportunities to extract deep modules that can be tested in isolation.
A deep module (as opposed to a shallow module) is one which encapsulates a lot of functionality in a simple, testable interface which rarely changes.
Check with the user that these modules match their expectations. Check with the user which modules they want tests written for.
3. Write the PRD using the template below, then publish it to the project issue tracker. Apply the `ready-for-agent` triage label - no need for additional triage.
<prd-template>
## Problem Statement
The problem that the user is facing, from the user's perspective.
## Solution
The solution to the problem, from the user's perspective.
## User Stories
A LONG, numbered list of user stories. Each user story should be in the format of:
1. As an <actor>, I want a <feature>, so that <benefit>
<user-story-example>
1. As a mobile bank customer, I want to see balance on my accounts, so that I can make better informed decisions about my spending
</user-story-example>
This list of user stories should be extremely extensive and cover all aspects of the feature.
## Implementation Decisions
A list of implementation decisions that were made. This can include:
- The modules that will be built/modified
- The interfaces of those modules that will be modified
- Technical clarifications from the developer
- Architectural decisions
- Schema changes
- API contracts
- Specific interactions
Do NOT include specific file paths or code snippets. They may end up being outdated very quickly.
Exception: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it within the relevant decision and note briefly that it came from a prototype. Trim to the decision-rich parts — not a working demo, just the important bits.
## Testing Decisions
A list of testing decisions that were made. Include:
- A description of what makes a good test (only test external behavior, not implementation details)
- Which modules will be tested
- Prior art for the tests (i.e. similar types of tests in the codebase)
## Out of Scope
A description of the things that are out of scope for this PRD.
## Further Notes
Any further notes about the feature.
</prd-template>
# To Issues
Break a plan into independently-grabbable issues using vertical slices (tracer bullets).
The issue tracker and triage label vocabulary should have been provided to you — run `/setup-matt-pocock-skills` if not.
## Process
### 1. Gather context
Work from whatever is already in the conversation context. If the user passes an issue reference (issue number, URL, or path) as an argument, fetch it from the issue tracker and read its full body and comments.
### 2. Explore the codebase (optional)
If you have not already explored the codebase, do so to understand the current state of the code. Issue titles and descriptions should use the project's domain glossary vocabulary, and respect ADRs in the area you're touching.
### 3. Draft vertical slices
Break the plan into **tracer bullet** issues. Each issue is a thin vertical slice that cuts through ALL integration layers end-to-end, NOT a horizontal slice of one layer.
Slices may be 'HITL' or 'AFK'. HITL slices require human interaction, such as an architectural decision or a design review. AFK slices can be implemented and merged without human interaction. Prefer AFK over HITL where possible.
<vertical-slice-rules>
- Each slice delivers a narrow but COMPLETE path through every layer (schema, API, UI, tests)
- A completed slice is demoable or verifiable on its own
- Prefer many thin slices over few thick ones
</vertical-slice-rules>
### 4. Quiz the user
Present the proposed breakdown as a numbered list. For each slice, show:
- **Title**: short descriptive name
- **Type**: HITL / AFK
- **Blocked by**: which other slices (if any) must complete first
- **User stories covered**: which user stories this addresses (if the source material has them)
Ask the user:
- Does the granularity feel right? (too coarse / too fine)
- Are the dependency relationships correct?
- Should any slices be merged or split further?
- Are the correct slices marked as HITL and AFK?
Iterate until the user approves the breakdown.
### 5. Publish the issues to the issue tracker
For each approved slice, publish a new issue to the issue tracker. Use the issue body template below. These issues are considered ready for AFK agents, so publish them with the correct triage label unless instructed otherwise.
Publish issues in dependency order (blockers first) so you can reference real issue identifiers in the "Blocked by" field.
<issue-template>
## Parent
A reference to the parent issue on the issue tracker (if the source was an existing issue, otherwise omit this section).
## What to build
A concise description of this vertical slice. Describe the end-to-end behavior, not layer-by-layer implementation.
Avoid specific file paths or code snippets — they go stale fast. Exception: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it here and note briefly that it came from a prototype. Trim to the decision-rich parts — not a working demo, just the important bits.
## Acceptance criteria
- [ ] Criterion 1
- [ ] Criterion 2
- [ ] Criterion 3
## Blocked by
- A reference to the blocking ticket (if any)
Or "None - can start immediately" if no blockers.
</issue-template>
Do NOT close or modify any parent issue.
# Triage
Move issues on the project issue tracker through a small state machine of triage roles.
If this repo treats external pull requests as a request surface (see the issue-tracker config), triage covers them too: **a PR is an issue with attached code** — same roles, same states, same machine, with a few deltas marked "for a PR" below. Resolve a bare `#42` to an issue or PR per the tracker config.
Every comment or issue posted to the issue tracker during triage **must** start with this disclaimer:
```
> *This was generated by AI during triage.*
```
## Reference docs
- [AGENT-BRIEF.md](AGENT-BRIEF.md) — how to write durable agent briefs
- [OUT-OF-SCOPE.md](OUT-OF-SCOPE.md) — how the `.out-of-scope/` knowledge base works
## Roles
Two **category** roles:
- `bug` — something is broken
- `enhancement` — new feature or improvement
Five **state** roles:
- `needs-triage` — maintainer needs to evaluate
- `needs-info` — waiting on reporter for more information
- `ready-for-agent` — fully specified, ready for an AFK agent
- `ready-for-human` — needs human implementation
- `wontfix` — will not be actioned
For a PR, the same states read against the attached code: `ready-for-agent` means a brief is attached and an agent should take the next step on the diff; `ready-for-human` means it's ready for a human to merge.
Every triaged issue should carry exactly one category role and one state role. If state roles conflict, flag it and ask the maintainer before doing anything else.
These are canonical role names — the actual label strings used in the issue tracker may differ. The mapping should have been provided to you - run `/setup-matt-pocock-skills` if not.
State transitions: an unlabeled issue normally goes to `needs-triage` first; from there it moves to `needs-info`, `ready-for-agent`, `ready-for-human`, or `wontfix`. `needs-info` returns to `needs-triage` once the reporter replies. The maintainer can override at any time — flag transitions that look unusual and ask before proceeding.
## Invocation
The maintainer invokes `/triage` and describes what they want in natural language. Interpret the request and act. Examples:
- "Show me anything that needs my attention"
- "Let's look at #42" (issue or PR)
- "Move #42 to ready-for-agent"
- "What's ready for agents to pick up?"
## Show what needs attention
Query the issue tracker and present three buckets, oldest first:
1. **Unlabeled** — never triaged.
2. **`needs-triage`** — evaluation in progress.
3. **`needs-info` with reporter activity since the last triage notes** — needs re-evaluation.
When PRs are in scope, include external PRs in these buckets and tag each line `[PR]` or `[issue]`. Discovery surfaces only *external* PRs (the tracker config defines who counts as external) — a collaborator's in-flight PR is not triage work. This filter is discovery-only; an explicitly named PR is always triaged regardless of author.
Show counts and a one-line summary per item. Let the maintainer pick.
## Triage a specific issue or PR
1. **Gather context.** Read the full issue or PR (body, comments, labels, author, dates; for a PR, the diff too). Parse any prior triage notes so you don't re-ask resolved questions. Explore the codebase using the project's domain glossary, respecting ADRs in the area. Run two checks against the codebase: (a) **redundancy** — search for an existing implementation of the requested behavior by domain concept (not just the request's wording), and report where you looked. If found, it's an already-implemented `wontfix` (step 5). (b) **prior rejection** — read `.out-of-scope/*.md` and surface any that resembles this request.
2. **Recommend.** Tell the maintainer your category and state recommendation with reasoning, plus a brief codebase summary relevant to the request — including whether it's already implemented. Wait for direction.
3. **Verify the claim.** Before any grilling, check that the claim holds up. For a bug, reproduce it from the reporter's steps. For a PR, confirm the diff does what it claims — check it out, run the relevant tests or commands. Report what happened: confirmed (with code path), failed, or insufficient detail (a strong `needs-info` signal). A confirmed verification makes a much stronger agent brief.
4. **Grill (if needed).** If the request needs fleshing out, run the `/grilling` and `/domain-modeling` skills together — grill it into shape one question at a time, sharpening domain terms and updating `CONTEXT.md`/ADRs inline as decisions land.
5. **Apply the outcome:**
- `ready-for-agent` — post an agent brief comment ([AGENT-BRIEF.md](AGENT-BRIEF.md)).
- `ready-for-human` — same structure as an agent brief, but note why it can't be delegated (judgment calls, external access, design decisions, manual testing).
- `needs-info` — post triage notes (template below).
- `wontfix` — close, with the comment depending on *why*:
- **Already implemented** — the change already exists in the codebase. Point to where it lives; do **not** write to `.out-of-scope/` (that KB is for *rejected* requests, not built ones).
- **Rejected (bug)** — polite explanation, then close.
- **Rejected (enhancement)** — write to `.out-of-scope/`, link to it from a comment, then close ([OUT-OF-SCOPE.md](OUT-OF-SCOPE.md)).
- `needs-triage` — apply the role. Optional comment if there's partial progress.
## Quick state override
If the maintainer says "move #42 to ready-for-agent", trust them and apply the role directly. Confirm what you're about to do (role changes, comment, close), then act. Skip grilling. If moving to `ready-for-agent` without a grilling session, ask whether they want to write an agent brief.
## Needs-info template
```markdown
## Triage Notes
**What we've established so far:**
- point 1
- point 2
**What we still need from you (@reporter):**
- question 1
- question 2
```
Capture everything resolved during grilling under "established so far" so the work isn't lost. Questions must be specific and actionable, not "please provide more info".
## Resuming a previous session
If prior triage notes exist on the issue or PR, read them, check whether the reporter has answered any outstanding questions, and present an updated picture before continuing. Don't re-ask resolved questions.
# Test-Driven Development
TDD is the red → green loop. This skill is the reference that makes that loop produce tests worth keeping: what a good test is, where tests go, the anti-patterns, and the rules of the loop. Every section applies on every cycle — consult them before and during the loop, not after.
When exploring the codebase, read `CONTEXT.md` (if it exists) so test names and interface vocabulary match the project's domain language, and respect ADRs in the area you're touching.
## What a good test is
Tests verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't. A good test reads like a specification — "user can checkout with valid cart" tells you exactly what capability exists — and survives refactors because it doesn't care about internal structure.
See [tests.md](tests.md) for examples and [mocking.md](mocking.md) for mocking guidelines.
## Seams — where tests go
A **seam** is the public boundary you test at: the interface where you observe behavior without reaching inside. Tests live at seams, never against internals.
**Test only at pre-agreed seams.** Before writing any test, write down the seams under test and confirm them with the user. No test is written at an unconfirmed seam. You can't test everything — agreeing the seams up front is how testing effort lands on the critical paths and complex logic instead of every edge case.
Ask: "What's the public interface, and which seams should we test?"
## Anti-patterns
- **Implementation-coupled** — mocks internal collaborators, tests private methods, or verifies through a side channel (querying the database instead of using the interface). The tell: the test breaks when you refactor but behavior hasn't changed.
- **Tautological** — the assertion recomputes the expected value the way the code does (`expect(add(a, b)).toBe(a + b)`, a snapshot derived by hand the same way, a constant asserted equal to itself), so it passes by construction and can never disagree with the code. Expected values must come from an independent source of truth — a known-good literal, a worked example, the spec.
- **Horizontal slicing** — writing all tests first, then all implementation. Bulk tests verify _imagined_ behavior: you test the _shape_ of things rather than user-facing behavior, the tests go insensitive to real changes, and you commit to test structure before understanding the implementation. Work in **vertical slices** instead — one test → one implementation → repeat, each test a **tracer bullet** that responds to what the last cycle taught you.
## Rules of the loop
- **Red before green.** Write the failing test first, then only enough code to pass it. Don't anticipate future tests or add speculative features.
- **One slice at a time.** One seam, one test, one minimal implementation per cycle.
- **Refactoring is not part of the loop.** It belongs to the review stage (see the `code-review` skill), not the red → green implementation cycle.
# Setup Matt Pocock's Skills
Scaffold the per-repo configuration that the engineering skills assume:
- **Issue tracker** — where issues live (GitHub by default; local markdown is also supported out of the box)
- **Triage labels** — the strings used for the five canonical triage roles
- **Domain docs** — where `CONTEXT.md` and ADRs live, and the consumer rules for reading them
This is a prompt-driven skill, not a deterministic script. Explore, present what you found, confirm with the user, then write.
## Process
### 1. Explore
Look at the current repo to understand its starting state. Read whatever exists; don't assume:
- `git remote -v` and `.git/config` — is this a GitHub repo? Which one?
- `AGENTS.md` and `CLAUDE.md` at the repo root — does either exist? Is there already an `## Agent skills` section in either?
- `CONTEXT.md` and `CONTEXT-MAP.md` at the repo root
- `docs/adr/` and any `src/*/docs/adr/` directories
- `docs/agents/` — does this skill's prior output already exist?
- `.scratch/` — sign that a local-markdown issue tracker convention is already in use
- Is the `triage` skill installed? (a `triage` skill folder alongside this one, or `triage` in your available skills.) This decides whether Section B runs at all.
- Monorepo signals — a `pnpm-workspace.yaml`, a `workspaces` field in `package.json`, or a populated `packages/*` with its own `src/`. Present only in a genuinely large multi-package repo; their absence means single-context, which is almost every repo.
### 2. Present findings and ask
Summarise what's present and what's missing. Then take the sections in order — one section, one answer, then the next.
Lead each section with the recommended answer so the user can accept it in a word. Give a one-line explainer only when the choice genuinely branches; skip the section entirely when exploration already settled it (Section B when `triage` isn't installed, Section C when there's no monorepo).
**Section A — Issue tracker.**
> Explainer: The "issue tracker" is where issues live for this repo. Skills like `to-tickets`, `triage`, `to-spec`, and `qa` read from and write to it — they need to know whether to call `gh issue create`, write a markdown file under `.scratch/`, or follow some other workflow you describe. Pick the place you actually track work for this repo.
Default posture: these skills were designed for GitHub. If a `git remote` points at GitHub, propose that. If a `git remote` points at GitLab (`gitlab.com` or a self-hosted host), propose GitLab. Otherwise (or if the user prefers), offer:
- **GitHub** — issues live in the repo's GitHub Issues (uses the `gh` CLI)
- **GitLab** — issues live in the repo's GitLab Issues (uses the [`glab`](https://gitlab.com/gitlab-org/cli) CLI)
- **Local markdown** — issues live as files under `.scratch/<feature>/` in this repo (good for solo projects or repos without a remote)
- **Other** (Jira, Linear, etc.) — ask the user to describe the workflow in one paragraph; the skill will record it as freeform prose
Record the choice in `docs/agents/issue-tracker.md`. The GitHub and GitLab templates carry a "PRs as a request surface" flag, defaulted **off** — leave it off and don't raise it; a user who wants external PRs in the triage queue can flip the flag in the file later.
**Section B — Triage label vocabulary.** Skip this section entirely if the `triage` skill isn't installed (exploration told you) — an uninstalled skill needs no labels.
If it is installed, ask exactly one question:
> Do you want to keep the default triage labels? (recommended: **yes**)
The defaults are the five canonical roles, each label string equal to its name: `needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`. On **yes**, write them as-is. Only if the user says no — usually because their tracker already uses other names (e.g. `bug:triage` for `needs-triage`) — collect the overrides so `triage` applies existing labels instead of creating duplicates.
**Section C — Domain docs.** Default to **single-context** — one `CONTEXT.md` + `docs/adr/` at the repo root. This fits almost every repo; write it without asking.
Offer **multi-context** — a root `CONTEXT-MAP.md` pointing to per-context `CONTEXT.md` files — only when exploration found monorepo signals. Then confirm which layout they want.
### 3. Confirm and edit
Show the user a draft of:
- The `## Agent skills` block to add to whichever of `CLAUDE.md` / `AGENTS.md` is being edited (see step 4 for selection rules)
- The contents of `docs/agents/issue-tracker.md`, `docs/agents/domain.md`, and `docs/agents/triage-labels.md` (the last only when `triage` is installed)
Let them edit before writing.
### 4. Write
**Pick the file to edit:**
- If `CLAUDE.md` exists, edit it.
- Else if `AGENTS.md` exists, edit it.
- If neither exists, ask the user which one to create — don't pick for them.
Never create `AGENTS.md` when `CLAUDE.md` already exists (or vice versa) — always edit the one that's already there.
If an `## Agent skills` block already exists in the chosen file, update its contents in-place rather than appending a duplicate. Don't overwrite user edits to the surrounding sections.
The block:
```markdown
## Agent skills
### Issue tracker
[one-line summary of where issues are tracked]. See `docs/agents/issue-tracker.md`.
### Triage labels
[one-line summary of the label vocabulary]. See `docs/agents/triage-labels.md`.
### Domain docs
[one-line summary of layout — "single-context" or "multi-context"]. See `docs/agents/domain.md`.
```
Include the `### Triage labels` sub-block, and write `docs/agents/triage-labels.md`, only when `triage` is installed and Section B ran. When it isn't, both are omitted.
Then write the docs files using the seed templates in this skill folder as a starting point:
- [issue-tracker-github.md](./issue-tracker-github.md) — GitHub issue tracker
- [issue-tracker-gitlab.md](./issue-tracker-gitlab.md) — GitLab issue tracker
- [issue-tracker-local.md](./issue-tracker-local.md) — local-markdown issue tracker
- [triage-labels.md](./triage-labels.md) — label mapping (only if `triage` is installed)
- [domain.md](./domain.md) — domain doc consumer rules + layout
For "other" issue trackers, write `docs/agents/issue-tracker.md` from scratch using the user's description.
### 5. Done
Tell the user the setup is complete and which engineering skills will now read from these files. Mention they can edit `docs/agents/*.md` directly later — re-running this skill is only necessary if they want to switch issue trackers or restart from scratch.
# Prototype
A prototype is **throwaway code that answers a question**. The question decides the shape.
## Pick a branch
Identify which question is being answered — from the user's prompt, the surrounding code, or by asking if the user is around:
- **"Does this logic / state model feel right?"** → [LOGIC.md](LOGIC.md). Build a tiny interactive terminal app that pushes the state machine through cases that are hard to reason about on paper.
- **"What should this look like?"** → [UI.md](UI.md). Generate several radically different UI variations on a single route, switchable via a URL search param and a floating bottom bar.
The two branches produce very different artifacts — getting this wrong wastes the whole prototype. If the question is genuinely ambiguous and the user isn't reachable, default to whichever branch better matches the surrounding code (a backend module → logic; a page or component → UI) and state the assumption at the top of the prototype.
## Rules that apply to both
1. **Throwaway from day one, and clearly marked as such.** Locate the prototype code close to where it will actually be used (next to the module or page it's prototyping for) so context is obvious — but name it so a casual reader can see it's a prototype, not production. For throwaway UI routes, obey whatever routing convention the project already uses; don't invent a new top-level structure.
2. **One command to run.** Whatever the project's existing task runner supports — `pnpm <name>`, `python <path>`, `bun <path>`, etc. The user must be able to start it without thinking.
3. **No persistence by default.** State lives in memory. Persistence is the thing the prototype is _checking_, not something it should depend on. If the question explicitly involves a database, hit a scratch DB or a local file with a clear "PROTOTYPE — wipe me" name.
4. **Skip the polish.** No tests, no error handling beyond what makes the prototype _runnable_, no abstractions. The point is to learn something fast.
5. **Surface the state.** After every action (logic) or on every variant switch (UI), print or render the full relevant state so the user can see what changed.
6. **Capture it when done.** Fold any validated decision into the real code, then capture the prototype itself as a **primary source**: commit it to a throwaway branch, out of main, and leave a context pointer to that branch on the implementation issue. Capture the answer too — the verdict and the question it settled — in the issue or a commit. The main branch keeps only the validated decision.