Hydra leerlijn — Deel 6: Troubleshooting & escalatie
Wat te doen als de pijplijn vastloopt. Het keuzemenu tussen development-merge, label-reset, retry:queued, en rebuild:queued — geordend van goedkoop naar duur. Laatste van zes korte modules.
In deel 5 stond de pijplijn. Nu het laatste deel: wat doe je als hij niet groen wordt? Dit deel geeft je de keuzeboom — geordend van goedkoopste interventie naar duurste — en de patronen waarmee je needs-input-issues weer in beweging krijgt.
Wat betekent needs-input?
needs-input is geen failure-state in de zin van "Hydra heeft gefaald". Het is een expliciete escalatie: Hydra heeft gedaan wat hij kon, één run, en is tot een terminaal punt gekomen waar hij niet zelf verder kan zonder een menselijke beslissing.
Mogelijke oorzaken:
- Beide reviewers
passmaar de quality-recheck na hun fixes is rood (een fix introduceerde een nieuwe overtreding). - Eén van beide reviews
:fail. - Applier Axel Pliér
:fail. - Build crashed mid-stage (container OOM, rate-limit op alle accounts, …).
- Agent-maxed-out: een persona heeft zijn turn-budget opgemaakt.
Je rol als mens: bepaal welke van de vier opties hieronder het meest passend is en pas die toe. Niet een nieuwe retry:queued blind plakken in de hoop dat het deze keer wel werkt.
De interventie-ladder
| # | Situatie | Interventie | Kosten | Wat behoud je |
|---|---|---|---|---|
| 1 | Development is doorgegroeid, PR staat stale (nieuwe lint-rules, ADRs, fixtures op development) | gh pr update-branch <N> (of de cron pakt het op) | Gratis | Alle build/review/applier-werk. Alleen dependencies vernieuwen. |
| 2 | Review-contracten zijn aangepast en je wilt reviewers opnieuw laten oordelen zonder rebuild | Reviewer-labels resetten: stage-labels strippen, code-review:queued opnieuw zetten. PR blijft. | 2× reviewer + applier | De builder-output. Alleen het review-deel rewindt. |
| 3 | Reviewers/applier flagden concrete findings en de builder hoeft alleen even bij te schaven | retry:queued op het issue plakken | 1× builder + 2× reviewer + applier | Branch + PR blijven. Orchestrator bouwt feedback.md uit hydra.json (unfixed + applier-blockers + reeds gefixed) en dispatcht builder in HYDRA_MODE=fix. Single-shot — geen loop. |
| 4 | Builder-output was fundamenteel verkeerd (verkeerde aanpak, stub-implementatie, fundamentele requirements gemist) | rebuild:queued op het issue plakken | Volledige cyclus | Orchestrator sluit de open PR, hard-reset feature/<issue>/* naar development, strip alle cycle-labels, zet build:queued. Volgende cyclus begint van scratch. |
| 5 | Je hebt zelf de PR al gesloten en stale labels staan nog op het issue | Wachten op reconcile.sh (om de 10 min) | Volgende reconcile-run | check_stage_without_open_pr ziet de inconsistentie en zet automatisch build:queued. Self-healing. |
| 6 | Pipeline-infra is stuk (container crash, alle tokens op, image niet vindbaar) | Escaleer naar mens (jij of een teamlead), los infra op, en kies pas DAN één van 1-4 hierboven | Tijd | — |
Volgorde: altijd 1 → 2 → 3 → 4. Pak het goedkoopste herstel eerst. Reach voor rebuild:queued alleen als de build zelf fundamenteel verkeerd was.
retry:queued in detail
- Jij (of een automated rule) plakt
retry:queuedop het issue. Met label-prefix wordt dat<prefix>-retry:queued—scripts/hydra-label.shregelt dat automatisch. - Supervisor pakt het op als reguliere queue-job.
- Orchestrator vindt de open PR op
feature/<issue>/*. - Orchestrator cloned development, kopieert
openspec/changes/<slug>/hydra.jsonen draaitscripts/lib/build-feedback-brief.py→ schrijftfeedback.mdmet (a) applier-blockers, (b) unfixed reviewer-findings, (c) reeds-gefixed items, (d) Scope-lijst van alle geflagde files. - Orchestrator flipped
retry:queued→retry:running, dispatcht de builder metHYDRA_MODE=fixenfeedback.mdgemount op/workspace/feedback.md. - Builder leest de brief, fixed álle bevindingen in één pass, beperkt zich tot Scope-files (plus nieuwe files die expliciet door een blocker geëist worden), commit met
fix (retry):messages, pusht. - Succes: orchestrator strip alle review/applier-labels +
retry:running+needs-input, zetcode-review:queued. Reviewers draaien opnieuw tegen de gefixede code. - Faal:
retry:running→needs-input, comment op het issue legt uit waarom en wijst naarrebuild:queuedals de volgende hefboom.
Geen loop. Eén retry:queued = één iteratie. Als de fix-builder pusht en de volgende review weer faalt, kun je opnieuw retry:queued aanvragen — maar dat is dan een nieuwe single-shot, niet een auto-retry.
Wanneer is het de gate, en wanneer is het de builder?
Een terugkerende valkuil uit eigen retrospectives: het issue gaat 3 keer naar needs-input om dezelfde reden — typisch spdx-headers: fail of een gelijksoortige mechanische gate. Iedere retry:queued reproduceert hetzelfde patroon.
In dat geval is een vierde retry niet de juiste move. Wees discplineerd:
- Sanity-check de gate zelf. Is dit een fout-positief? (Zie deel 3.) Een klassieker: een grep zonder word-boundary die meer matcht dan bedoeld. Fix in dat geval
scripts/run-quality.shof de gate-skill. - Hand-fix de mechanische overtreding. Soms is het sneller om zelf de SPDX-headers toe te voegen, te committen op de feature branch en de reviewers opnieuw aan te roepen via label-reset (situatie 2 hierboven). Tijd: minuten.
- Overweeg een sterkere agent. Als hetzelfde klasse-fout op meerdere repos dezelfde "blind spot" vertoont, is dat een signaal dat de huidige builder-prompt of de mechanische gate niet voldoende is. Open een issue in
hydra/om de gate aan te scherpen of een "housekeeping"-agent te bouwen.
Watch-list patronen
Patronen die we al hebben gezien en die het waard zijn om eerst tegen je situatie te leggen:
Diagnostics: waar kijk je?
Snelle checklist als een issue naar needs-input gaat:
# 1. Welke labels staan er nu?
gh issue view <N> --repo ConductionNL/<app> --json labels --jq '[.labels[].name]'
# 2. Wat zegt hydra.json (mits aanwezig op de feature branch)?
gh api repos/ConductionNL/<app>/contents/openspec/changes/<slug>/hydra.json?ref=feature/<N>/<slug> \
--jq '.content' | base64 -d | jq '.cycles[-1] | {outcome, outcome_reason, pattern_tags}'
# 3. De supervisor-log van de relevante tijdspanne
grep "issue/<N>" logs/supervisor.log | tail -50
# 4. Pipeline-logs (per stage) op de feature branch
gh api repos/ConductionNL/<app>/contents/openspec/changes/<slug>/pipeline-logs?ref=feature/<N>/<slug>
hydra.json is je belangrijkste bron. De outcome_reason en pattern_tags van de laatste cycle leggen meestal in één regel uit wat er misging.
Wanneer is "menselijk overnemen" gewoon goed?
Niet elk needs-input-issue verdient een geautomatiseerd fix-pad. Soms is de meest pragmatische actie: mens neemt over, los het op in een eigen commit op de feature branch, push, mark resolved.
Voorbeelden:
- Een kleine semantische beslissing die de Builder niet kan maken zonder context buiten de change (bijv. "moet dit veld optional of required zijn?").
- Een interactie met een externe partij (open ticket bij een leverancier).
- Een gate die fout-positief is en een fix in
hydra/zelf vereist (waarover je niet binnen één retry-cyclus uit bent).
Hydra is een fabriek, geen ideologie. Pak de menselijke shortcut als die billijker is.
Test jezelf
Vier korte vragen om te checken of je dit deel begrepen hebt. Vastgelopen? Klik Hint. Curieus naar het antwoord? Klik Antwoord.
1. In welke volgorde probeer je de interventies in de ladder, en waarom?
Hint
Eén dimensie: kosten. De andere: hoeveel reeds-gedaan werk je verliest.
Antwoord
Van goedkoop naar duur, met als doel zo veel mogelijk reeds-gedaan werk te behouden:
gh pr update-branch— gratis. Alle build/review/applier-werk blijft staan, alleen dependencies vernieuwen.- Reviewer-labels resetten — kost 2× reviewer + applier. Builder-output blijft.
retry:queued— kost 1× builder + 2× reviewer + applier. Branch + PR blijven; builder fixed gescoped viafeedback.md.rebuild:queued— volledige cyclus. PR sluit, branch reset, vanaf scratch.- Handmatige fix — als de loop op een fout-positieve gate hangt of een mens een semantische beslissing moet maken.
Reach voor rebuild:queued alleen als de oorspronkelijke build fundamenteel verkeerd was; anders verspil je goed werk.
2. Wat is het verschil tussen "Reviewer-labels resetten" en retry:queued?
Hint
De vraag is: wordt de builder opnieuw aangeroepen, ja of nee?
Antwoord
- Reviewer-labels resetten (stage-labels strippen +
code-review:queuedopnieuw zetten): de builder wordt NIET opnieuw aangeroepen. PR + builder-output blijven exact zoals ze waren; alleen Juan en Clyde draaien opnieuw. Geschikt als de review-contracten zijn aangepast (nieuwe ADR, nieuwe gate-skill) en je wilt herbeoordelen zonder de code te veranderen. retry:queued: builder wordt wél opnieuw aangeroepen, inHYDRA_MODE=fix, metfeedback.md(uithydra.json) als input. Hij maakt nieuwe commits, dan draaien reviewers opnieuw. Geschikt als reviewers terechte findings hadden en de builder alleen even moet bijschaven.
3. Wanneer is het zinvoller om met de hand de fix te maken in plaats van opnieuw retry:queued?
Hint
Als hetzelfde patroon zich herhaalt op dezelfde mechanische gate is meer geld erin gooien niet de oplossing.
Antwoord
Als hetzelfde issue 3 keer of vaker naar needs-input is gegaan om dezelfde reden — typisch een mechanische gate zoals spdx-headers: fail. Iedere retry:queued reproduceert hetzelfde patroon: builder maakt dezelfde fout, reviewer ziet het als boilerplate, recheck slaat rood.
In dat geval:
- Check eerst of het een fout-positieve gate is (zie deel 3). Zo ja: gate-detectie aanscherpen.
- Zo nee: fix het met de hand (bijv. zelf SPDX-headers committen op de feature branch) en gebruik label-reset om de reviewers opnieuw te laten oordelen.
Tijd: minuten. Goedkoper dan nog een Sonnet-cyclus verspillen aan iets wat steeds opnieuw fout gaat.
4. Wat doe je als je 3+ identieke needs-input-comments ziet binnen korte tijd?
Hint
Dit zegt iets over de pijplijn-zélf, niet over één issue. Welk soort fix is dat?
Antwoord
Dit is een infra-bug, geen retry-vraag. Ergens in de completion-handler ontbreekt een terminal-state guard, waardoor een tight loop elke tick een nieuwe escalation-comment plaatst op een al-terminaal issue. Voorbeeld: 134 duplicate comments overnight op 23 april 2026 — fix was een terminal-state guard vóór alle side-effects (zie CLAUDE.md sectie "Terminal-state guards").
Wat doe je: open een infra-issue in hydra/, niet een nieuwe retry:queued. Een retry doet niets met de comment-storm en kan zelfs meer chaos toevoegen.
Klaar — wat nu?
Je hebt de hele leerlijn doorlopen. Wat is verstandig daarna?
