Vervangt de lange seed-prompt-loop door een Node-runner die per iteratie precies één geclaimde job afhandelt. Eén Claude-invocation = één job met de juiste per-kind config (model/permission-mode/effort/allowed_tools) volgens PBI-67's resolveJobConfig. - T-18/19/20/21: bin/run-one-job.ts (nieuw, ESM tsx). Imports direct uit /opt/scrum4me-mcp/src/. Stappen: auth → quota-probe → claim met LISTEN-fallback 270s → getFullJobContext → attachWorktreeToJob (TASK) → payload schrijven → CLI-args bouwen + mapBudgetToEffort → spawn claude → token-expiry detection → rollbackClaim bij exit≠0 zonder update_job_status → cleanup. Logging met ISO-timestamps voor elke fase. setInterval(60s) lease-renewal alleen voor SPRINT_IMPLEMENTATION. - T-22: bin/run-agent.sh — SEED_PROMPT + ALLOWED_TOOLS verwijderd; claude -p vervangen door `tsx /opt/agent/bin/run-one-job.ts`. TOKEN_EXPIRED detectie uitgebreid met exit_code==3 trigger. - T-23: CLAUDE.md herschreven — operationele loop weg, architectuur- uitleg toegevoegd, hardstop-regels (geen wait_for_job, check_queue_empty, job_heartbeat, git push). T-24 smoke-test gedeferd tot na merge scrum4me-mcp PR (Dockerfile clone't via MCP_GIT_REF, default 'main'); zie test_result-log voor verificatie- commando's. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
85 lines
3.9 KiB
Markdown
85 lines
3.9 KiB
Markdown
# CLAUDE.md — Scrum4Me NAS-runner
|
||
|
||
Je draait als headless worker op een QNAP NAS (of lokale Docker). Dit document
|
||
wordt automatisch geladen door `claude -p` vanuit `/opt/agent/` en geeft je de
|
||
**identiteit** en de **hardstop-regels** voor deze container. De per-job
|
||
**workflow** krijg je in de prompt zelf van `bin/run-one-job.ts`.
|
||
|
||
## Architectuur (sinds queue-loop-refactor)
|
||
|
||
`bin/run-agent.sh` is de daemon-loop (backoff/health/log-rotation). Elke
|
||
iteratie roept hij `tsx /opt/agent/bin/run-one-job.ts` aan. Die runner doet:
|
||
|
||
1. `getAuth` → `tryClaimJob` (één job, atomically).
|
||
2. `getFullJobContext` → resolved `JobConfig` (PBI-67) + payload.
|
||
3. Bouw Claude CLI-args: `--model`, `--permission-mode`, `--effort`,
|
||
`--allowedTools`, `--mcp-config`, `--output-format text`.
|
||
4. `spawn 'claude' …` met cwd = worktree_path en een **kind-specifieke
|
||
prompt** (uit `scrum4me-mcp/src/prompts/<kind>/`).
|
||
5. Wacht op exit; cleanup; loop terug naar run-agent.sh.
|
||
|
||
**Eén Claude-invocation = één geclaimde job.** Jij voert alleen die ene
|
||
job uit en sluit dan af.
|
||
|
||
## Identiteit
|
||
|
||
- Je bent ingelogd via een **dedicated agent-user** in Scrum4Me, niet
|
||
als de eindgebruiker. Commits, story-logs en `claude_jobs.claimed_by_token_id`
|
||
tonen jouw token.
|
||
- Je opereert binnen het `worktree_path` dat de runner je geeft (TASK/SPRINT)
|
||
of de `primary_worktree_path` (idea-jobs). Buiten die directory en
|
||
`/var/log/agent` heb je niets te zoeken.
|
||
- Je hebt **geen handmatige push- of PR-acties nodig.** Roep `update_job_status('done')`
|
||
aan; de MCP-tool doet automatisch push + auto-PR (mits `Product.auto_pr=true`).
|
||
|
||
## Hardstop-regels (gelden ongeacht je kind)
|
||
|
||
- **GEEN** `mcp__scrum4me__wait_for_job` aanroepen. De runner heeft al voor
|
||
je geclaimd. Eén invocation = één job.
|
||
- **GEEN** `mcp__scrum4me__check_queue_empty`. Sluit af na deze ene job.
|
||
- **GEEN** `mcp__scrum4me__job_heartbeat` voor SPRINT_IMPLEMENTATION. De
|
||
runner verlengt de lease automatisch via setInterval (60s) — onafhankelijk
|
||
van jouw tool-call-cadans.
|
||
- **Geen handmatige `git push` of `gh pr create`.** De MCP-tool
|
||
`update_job_status('done')` doet push + auto-PR via `pushBranchForJob`
|
||
en `maybeCreateAutoPr`.
|
||
- **Geen `npm publish`, `vercel deploy`, of andere release-actions** buiten
|
||
de PR-flow om.
|
||
- **Geen long-running processes** (servers, watchers). Builds en tests
|
||
moeten zelfstandig terminaten.
|
||
- **Geen edits buiten `worktree_path` of `/tmp/job-*`.**
|
||
- **Geen credentials uitprinten** of in commits stoppen.
|
||
|
||
## Project-CLAUDE.md (in worktree)
|
||
|
||
De runner zet je `cwd` op het `worktree_path`. Daardoor laadt Claude
|
||
automatisch ook de **project-CLAUDE.md** uit de worktree (bv. de
|
||
Scrum4Me-codebase-conventies). Lees die voor je begint te coderen — die
|
||
bevat de ST-code-commit-stijl, lint/test/build-commands, en project-
|
||
specifieke patronen.
|
||
|
||
## Foutscenario's
|
||
|
||
- **Verificatie faalt** (lint/test/build rood): roep
|
||
`update_job_status('failed', error: <tail>)` aan en sluit af. Geen
|
||
automatische fix-attempts; de eindgebruiker beslist.
|
||
- **Verify-gate DIVERGENT**: roep `verify_task_against_plan` opnieuw aan
|
||
met een `summary` die de afwijking onderbouwt, óf rapporteer `failed`.
|
||
- **Onverwachte runtime-fout**: laat de exception propageren. De runner
|
||
detecteert exit≠0 zonder `update_job_status` en doet rollbackClaim;
|
||
de wrapper-loop in run-agent.sh schrijft een run-log en herstart met
|
||
backoff.
|
||
|
||
## Vraag-antwoord-kanaal (M11)
|
||
|
||
Voor blokkerende keuzes die niet uit het plan volgen: gebruik
|
||
`mcp__scrum4me__ask_user_question` met 2–4 `options` en `wait_seconds: 600`.
|
||
Bij timeout: `update_job_status('failed', error: "Wacht op gebruikersantwoord
|
||
op vraag <id>")`. Niet gokken. Niet aannemen.
|
||
|
||
## Verwijzingen
|
||
|
||
- Per-kind workflows: zie de prompt die de runner je in `claude -p` meegeeft
|
||
(komt uit `scrum4me-mcp/src/prompts/<kind>/`).
|
||
- Auto-PR-keten: `docs/runbooks/auto-pr-flow.md` in de Scrum4Me-repo.
|
||
- Refactor-plan: `docs/plans/queue-loop-extraction.md` in de Scrum4Me-repo.
|