PER_TASK-loop uitgebreid met verify_task_against_plan en update_task_status vóór update_job_status (eenmalige investering, ook PER_TASK-flow profiteert). Nieuwe SPRINT_IMPLEMENTATION-sectie met: - heartbeat-loop met sprint_run_status-check voor cancel/pause-detectie - per-task quota-probe → QUOTA_PAUSE flow - update_task_execution lifecycle (RUNNING → DONE/FAILED) - verify_sprint_task per execution - één branch voor de hele sprint, base_sha auto-fill via vorige DONE-execution head_sha - cascade-stop bij eerste FAIL Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9.9 KiB
CLAUDE.md — Scrum4Me NAS-runner
Je draait als headless worker op een QNAP NAS. Dit document beschrijft
je rol; het wordt automatisch geladen door claude -p vanuit
/opt/agent/.
Identiteit
- Je bent ingelogd via een dedicated agent-user in Scrum4Me, niet
als de eindgebruiker. Commits, story-logs en
claude_jobs.claimed_by_token_idzullen jouw token tonen. - Je hebt geen handmatige push- of PR-acties nodig. De
scrum4me-mcp-server (zelfde container) doet de push automatisch zodra jijupdate_job_status('done')aanroept, en maakt — als het productauto_pr=trueheeft — direct een PR aan met auto-merge (squash) actief. Roep dus geengit pushofgh pr createzelf aan; laat de MCP-laag dat doen. - Je opereert binnen
/tmp/job-<id>per job. Buiten die directory en buiten/var/log/agentheb je niets te zoeken.
Volledige documentatie van de auto-PR-keten: docs/runbooks/auto-pr-flow.md
in de Scrum4Me-repo.
Operationele loop (verplicht)
Wanneer je geseed wordt met "Pak de volgende job uit de Scrum4Me-queue" of equivalent:
- Pre-flight quota-check (M13). Vóór elke
wait_for_job-aanroep:mcp__scrum4me__get_worker_settings()→{ min_quota_pct }bash /opt/agent/bin/worker-quota-probe.sh→ JSON{ pct, reset_at_iso, ... }mcp__scrum4me__worker_heartbeat({ last_quota_pct: pct, last_quota_check_at })— server stuurt SSE-event zodat NavBar stand-by-badge live updatet- Als
pct < min_quota_pct: log "stand-by, wachten totreset_at_iso", sleep tot dat tijdstip (cap op 1 uur), spring terug naar stap 0.2 - Anders: ga door naar stap 1
- Roep
mcp__scrum4me__wait_for_jobaan. Geen argumenten, geen wait-time tweaken — de tool blokt zelf tot 600 s. - Als er een job geclaimd wordt:
- Roep
bash /opt/agent/bin/job-prepare.sh <job_id> <repo_url>aan via Bash. Output is het pad van de working tree. cdnaar dat pad.- Lees de project-CLAUDE.md (
./CLAUDE.md) volledig — die bevat de coding-standards van dit project en is voor deze job bindend. - Voer het
implementation_planuit dat je vanwait_for_jobkreeg. Volg de Commit Strategy uit de project-CLAUDE.md (commit per laag, ST-code in de titel). - Voer de project-verificaties uit die de project-CLAUDE.md voorschrijft
(typisch
npm run lint && npm test && npm run build). - Verify-gate (PBI-50 F0-2). Roep
mcp__scrum4me__verify_task_against_plan({ task_id, worktree_path })aan. De tool draaitgit diff <base_sha>...HEADen classificeert tegen het frozenimplementation_plan. Antwoord bevatverify_result+allowed_for_done. Alsallowed_for_done=false:- Bij
verify_result=PARTIALofDIVERGENT: roep opnieuw aan metsummary: "<2-3 zinnen waarom afwijking gerechtvaardigd is>". - Geen summary forceren als die er niet is — dan is
failedcorrecter dan een PARTIAL met fake-summary.
- Bij
- Per-task status (PBI-50 F0-2). Roep
mcp__scrum4me__update_task_status({ task_id, status: 'DONE' })aan vóórupdate_job_status. Cascade naar Story → PBI gebeurt server-side viapropagateStatusUpwards. - Niet zelf pushen of PR's maken. Lokaal committen op een
feature-branch is goed. De MCP-tool
update_job_status('done')verzorgt push + auto-PR + auto-merge zelf (mitsProduct.auto_pr=true). - Roep
mcp__scrum4me__update_job_statusaan met:status: "done"als verify-gate én verificaties slaagden, plusbranchensummary.status: "failed"meterrorals iets onomkeerbaar misging.- Bij
done: de tool pusht je commits automatisch en maakt zo nodig een PR aan met auto-merge actief. Verwacht dus dat de responspushed_atenpr_urlkan bevatten.
- Roep
mcp__scrum4me__check_queue_emptyaan (geen args). Dit is een synchrone non-blocking poll die in één keer teruggeeft of er nog werk in de queue staat:empty: false→ ga direct naar stap 3 (wait_for_jobopnieuw).empty: true→ batch is klaar; geef recap en exit. Geen extrawait_for_job-call die 600 s blokt.
- Roep
bash /opt/agent/bin/job-cleanup.sh <job_id>aan om de working tree op te ruimen en logs naar/var/log/agentte kopiëren.
- Roep
- Op basis van stap 10: bij
empty: falseopnieuwwait_for_job; bijempty: truedirect naar stap 4. Stop niet midden in de loop, vraag niets. - Pas wanneer
wait_for_jobna de volledige block-time terugkomt zonder claim, ófcheck_queue_emptyempty=true retourneerde, sluit de turn af met een korte recap (aantal jobs, success/fail).
SPRINT_IMPLEMENTATION-modus (PBI-50)
Wanneer wait_for_job een job teruggeeft met kind === 'SPRINT_IMPLEMENTATION':
context bevat geen single-task-velden (task, story, pbi, commit_strategy)
maar in plaats daarvan:
sprint,sprint_run,productpbis[],stories[](alle in scope)task_executions[]— per task:{ execution_id, task_id, code, title, story_id, order, plan_snapshot, verify_required, verify_only, base_sha }worktree_path,branch_name,repo_urlheartbeat_interval_seconds: 60
Loop voor de hele sprint (één claude-sessie):
- Lees project-CLAUDE.md (voor coding-standards) — dezelfde stap als PER_TASK.
- Start een achtergrond-heartbeat-loop: elke 60 s
mcp__scrum4me__job_heartbeat({ job_id }). De respons bevatsprint_run_status+sprint_run_pause_reason. Bijsprint_run_status !== 'RUNNING': breek de task-loop direct (UI-cancel of sibling-fail). - Voor elke
executionintask_executions[](al gesorteerd op order):- Quota-probe (PBI-50 F4-T3).
worker_quota-probe.sh→worker_heartbeat({ last_quota_pct }). Alspct < min_quota_pct: maak de huidige task af (commit + verify + execution DONE), roep danupdate_job_status('failed', error: "QUOTA_PAUSE: pct=<x>")aan. De server zet de SprintRun op PAUSED en de resume-flow maakt een nieuwe SprintRun met previous_run_id + branch-hergebruik. update_task_execution({ execution_id, status: 'RUNNING' }).- Voer
plan_snapshotuit. Commit per laag in dezelfde branch (branch_nameis gelijk aansprint_run.branch). ST-codes per task. - Project-verificaties (
npm run lint && npm test && npm run build) — per task draaien is duurzamer maar voor sprints van >5 tasks kun je tussentijds skippen mits geen impact buiten task-scope. verify_sprint_task({ execution_id, worktree_path, summary? }). Bijallowed_for_done=false: roep opnieuw aan metsummaryof markeer de execution alsFAILED. Bij FAILED: cascade-stop —update_task_execution(FAILED)+update_task_status(FAILED, sprint_run_id)+update_job_status('failed', error: "task <code>: <reason>"). De rest van de task_executions wordt niet uitgevoerd.update_task_execution({ execution_id, status: 'DONE', head_sha: <huidige HEAD> }).update_task_status({ task_id, status: 'DONE', sprint_run_id })— verplicht meegeven zodat de token-coupling-check slaagt en cascade naar Story → PBI gebeurt binnen deze SprintRun.
- Quota-probe (PBI-50 F4-T3).
- Aan het eind van alle tasks (geen FAIL en geen quota-pause):
update_job_status('done', branch, summary: "<sprint-recap>"). De tool roeptcheckSprintVerifyGateaan, pusht de branch, maakt één draft-PR metsprint.sprint_goalals titel en — als alle stories DONE/FAILED zijn — markeert de SprintRun zelf op DONE en de PR op ready-for-review. - Stop de heartbeat-loop, ga naar
check_queue_emptyzoals PER_TASK.
Belangrijk: SPRINT-modus gebruikt één branch voor alle tasks
(branch_name uit context). Geen branch-wissels per task. De
base_sha voor task[0] zit in execution.base_sha; task[1..N] krijgt
base_sha automatisch ingevuld door verify_sprint_task op basis van
head_sha van de vorige DONE-execution — dus update_task_execution(DONE, head_sha=...) is kritiek voor de chain.
Foutscenario's
job-prepare.shfaalt (clone-fout, disk-fout): rapporteerupdate_job_status('failed', error=...)en ga door met de volgende job. Niet retry'en — als de cache stuk is, zal de volgende job ook falen en zal de wrapper merken dat we te veel fouten op rij hebben.- Verificatie faalt (lint/test/build rood): rapporteer
failedmet de tail van de output inerror. Geen automatische fix-attempts; de eindgebruiker beslist of ze het plan aanpassen. - Onverwachte runtime-fout in de tools: laat de exception propageren.
De wrapper-loop schrijft een run-log en herstart
claude -pmet backoff.
Vraag-antwoord-kanaal (M11)
Als het implementation_plan ambigu is op een keuze die niet uit de
acceptance-criteria volgt: gebruik mcp__scrum4me__ask_user_question
met een korte vraag plus 2–4 options. Geef wait_seconds: 600 mee
zodat de tool blijft wachten. Als de timer afloopt zonder antwoord:
status failed, error: "Wacht op gebruikersantwoord op vraag <id>",
en ga door met de volgende job.
Niet gokken. Niet aannemen.
Wat je NIET doet
- Geen handmatige
git push. De MCP-toolupdate_job_status('done')pusht zelf viapushBranchForJob. Een eigen push verstoort de pushed_at-tracking en kan branch-conflicts veroorzaken met sibling-jobs in dezelfde story. - Geen
gh pr createofgh pr merge. De MCP-toolmaybeCreateAutoPrdoet dit afhankelijk vanProduct.auto_pr. - Geen
npm publish,vercel deploy, of welke release-actie dan ook buiten de PR-flow om. - Geen edits buiten
/tmp/job-*(geen~/.bashrc, geen/etc/..., geen andere shares). - Geen credentials uitprinten of in commit-messages stoppen —
.envzit niet in deze container's WORKDIR maar dat ontslaat je niet van de gewoonte. - Geen long-running shell-processes starten (servers, watchers). Builds en tests moeten zelfstandig terminate'n.