Ga naar hoofdinhoud
AcademytutorialHydra leerlijn — Deel 6: Troubleshooting & escalatie

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.

TutorialHydraTroubleshootingRecoveryTutorial series
11 min read

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 pass maar 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

#SituatieInterventieKostenWat behoud je
1Development is doorgegroeid, PR staat stale (nieuwe lint-rules, ADRs, fixtures op development)gh pr update-branch <N> (of de cron pakt het op)GratisAlle build/review/applier-werk. Alleen dependencies vernieuwen.
2Review-contracten zijn aangepast en je wilt reviewers opnieuw laten oordelen zonder rebuildReviewer-labels resetten: stage-labels strippen, code-review:queued opnieuw zetten. PR blijft.2× reviewer + applierDe builder-output. Alleen het review-deel rewindt.
3Reviewers/applier flagden concrete findings en de builder hoeft alleen even bij te schavenretry:queued op het issue plakken1× builder + 2× reviewer + applierBranch + 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.
4Builder-output was fundamenteel verkeerd (verkeerde aanpak, stub-implementatie, fundamentele requirements gemist)rebuild:queued op het issue plakkenVolledige cyclusOrchestrator sluit de open PR, hard-reset feature/<issue>/* naar development, strip alle cycle-labels, zet build:queued. Volgende cyclus begint van scratch.
5Je hebt zelf de PR al gesloten en stale labels staan nog op het issueWachten op reconcile.sh (om de 10 min)Volgende reconcile-runcheck_stage_without_open_pr ziet de inconsistentie en zet automatisch build:queued. Self-healing.
6Pipeline-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 hierbovenTijd

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

  1. Jij (of een automated rule) plakt retry:queued op het issue. Met label-prefix wordt dat <prefix>-retry:queuedscripts/hydra-label.sh regelt dat automatisch.
  2. Supervisor pakt het op als reguliere queue-job.
  3. Orchestrator vindt de open PR op feature/<issue>/*.
  4. Orchestrator cloned development, kopieert openspec/changes/<slug>/hydra.json en draait scripts/lib/build-feedback-brief.py → schrijft feedback.md met (a) applier-blockers, (b) unfixed reviewer-findings, (c) reeds-gefixed items, (d) Scope-lijst van alle geflagde files.
  5. Orchestrator flipped retry:queuedretry:running, dispatcht de builder met HYDRA_MODE=fix en feedback.md gemount op /workspace/feedback.md.
  6. 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.
  7. Succes: orchestrator strip alle review/applier-labels + retry:running + needs-input, zet code-review:queued. Reviewers draaien opnieuw tegen de gefixede code.
  8. Faal: retry:runningneeds-input, comment op het issue legt uit waarom en wijst naar rebuild:queued als 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:

  1. 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.sh of de gate-skill.
  2. 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.
  3. 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:

  1. gh pr update-branch — gratis. Alle build/review/applier-werk blijft staan, alleen dependencies vernieuwen.
  2. Reviewer-labels resetten — kost 2× reviewer + applier. Builder-output blijft.
  3. retry:queued — kost 1× builder + 2× reviewer + applier. Branch + PR blijven; builder fixed gescoped via feedback.md.
  4. rebuild:queued — volledige cyclus. PR sluit, branch reset, vanaf scratch.
  5. 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:queued opnieuw 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, in HYDRA_MODE=fix, met feedback.md (uit hydra.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?