run-one-job.ts importeerde releaseLocksOnTerminal uit
'/opt/scrum4me-mcp/src/tools/wait-for-job.js' maar die module re-exporteert
deze symbol niet (alleen lokaal geïmporteerd uit ../git/job-locks.js).
Resultaat: bij elke rollbackClaim-pad (worktree-fout, getFullJobContext-
fout, claude exit≠0 zonder update_job_status) crasht run-one-job met:
TypeError: (0 , import_wait_for_job.releaseLocksOnTerminal) is not a function
Fix: importeer direct uit /opt/scrum4me-mcp/src/git/job-locks.js (zelfde
pad als wait-for-job.ts en cancel/pbi-cascade.ts intern doen).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drie kleine fixes voor de runner uit PBI-4 die in een lokale smoke-test
naar boven kwamen:
1. NODE_PATH=/opt/scrum4me-mcp/node_modules in Dockerfile ENV — anders
vindt tsx de top-level `pg` import in bin/run-one-job.ts niet (resolve
start vanaf /opt/agent/bin/, zoekt geen scrum4me-mcp/node_modules).
2. ARG MCP_CACHE_BUST in Dockerfile vóór de scrum4me-mcp clone-laag.
BuildKit cached anders de clone op MCP_GIT_REF=main, ook als main
intussen nieuwere commits heeft. Rebuild met
`--build-arg MCP_CACHE_BUST=$(date +%s)` invalidate't deze laag
deterministisch.
3. quotaProbe in run-one-job.ts soft-failt nu bij niet-zero exit, geen
pct-veld, of geen rate-limit-headers in response. De Anthropic API
retourneert niet altijd headers; dit zou de runner niet hard moeten
crashen. Komt overeen met CLAUDE.md stap 0.4 ("anders: ga door").
Lokale smoke-test bevestigt nu dat een IDEA_GRILL job correct geclaimd
wordt met `--model=claude-sonnet-4-6 --permission-mode=plan --effort=high`
en de juiste 10 allowed_tools.
Apart probleem ontdekt (NIET in deze PR): IDEA_GRILL/IDEA_MAKE_PLAN/
PLAN_CHAT draaien default in --permission-mode plan. In autonomous batch-
mode kan Claude in plan-mode mogelijk geen update_job_status aanroepen
(plan-mode wacht op human approval), waardoor jobs FAILED raken na
2x lease-expiry. Verdient eigen issue/PR voor permission_mode review.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
Drukt M13 pre-flight quota-gate op de batch-loop:
- ALLOWED_TOOLS in run-agent.sh uitgebreid met
mcp__scrum4me__get_worker_settings + worker_heartbeat (anders mag
Claude ze niet aanroepen ondanks dat ze geregistreerd zijn).
- CLAUDE.md operationele loop krijgt stap 0 vóór wait_for_job:
get_worker_settings → bin/worker-quota-probe.sh →
worker_heartbeat → sleep-tot-reset bij low quota.
Hierna draait de complete keten end-to-end: worker meet quota,
rapporteert aan server, NavBar toont stand-by-badge wanneer pct <
user.min_quota_pct.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lost terugkerende pijn op: na cross-build op Mac vergeet je makkelijk
de .env mee te nemen of vanuit de juiste directory te starten, met
"FAIL: ... is not set" als gevolg in pre-flight.
Script doet in volgorde:
1. docker buildx build --platform linux/amd64 --load
2. docker save | gzip → scrum4me-agent-runner-amd64.tar.gz
3. scp tarball + compose + (eerste keer) .env naar NAS
4. ssh: docker load + sanity-check op .env + compose up --force-recreate
5. ssh: docker compose logs -f (Ctrl-C om te stoppen)
Bestaande NAS-.env wordt niet overschreven. Eerste deploy patcht de
NAS-paden via sed. Sanity-check faalt expliciet als anthropic-,
SCRUM4ME_- of DATABASE_URL-vars ontbreken — ipv stille pre-flight-fail.
Config via .env.deploy (zit in .gitignore). Voor eerste deploy en
volledige procedure: README "Deploy — cross-build" sectie.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- entrypoint.sh: chown → chmod a+rwX → fail-fast met diagnostiek voor
AGENT_STATE_DIR en AGENT_LOG_DIR. Lost stille state.json permission
denied op QNAP-share op (NAS-ACL blokkeert chown vanuit container).
- bin/log-cleanup.sh: nieuwe hard-delete >2d (env-tunable) naast de
conservatievere rotate-logs.sh (gzip 24u, delete 30d).
- run-agent.sh: roept log-cleanup.sh aan bij startup en elke iteratie.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CLAUDE.md: nieuwe stap 8 in operationele loop — agent roept
check_queue_empty aan na update_job_status('done'). Bij empty=true
exit batch direct ipv 600s wait_for_job-poll.
bin/run-agent.sh: voeg mcp__scrum4me__check_queue_empty toe aan
ALLOWED_TOOLS zodat de agent de tool ook daadwerkelijk mag aanroepen.
Vereist: scrum4me-mcp v0.3.0+ in MCP_GIT_REF (na merge bumpen + rebuild).
Re-doet werk uit `bd6b91e` dat in eerdere agent-run verloren ging
omdat verify_task_against_plan errorde (origin/main hard-coded; bug
in scrum4me-mcp opgevangen in PBI cmoq1j2e2001dvt17scif1flj).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Voeg cacheBytesFree() toe via df -PB1 en retourneer 503 met
{ status: 'unhealthy', reason: 'cache-low' } als < 100 MB vrij.
Bij voldoende ruimte wordt cache_free_bytes toegevoegd aan de
200-response.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Faalt direct als /var/cache tmpfs is (ontbrekende bind-mount) of niet
schrijfbaar is. Geeft een WARNING voor /var/log/agent en /var/run/agent
als die op tmpfs staan.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Vercel rejected the smoke-test deploy with "The deployment was blocked
because the commit author email (agent@scrum4me.local) is not valid.
Ensure your git email matches your GitHub account."
The default `agent@scrum4me.local` in repo-bootstrap.sh was a phony
local domain not tied to any GitHub account. Vercel's deploy-protection
checks the latest commit's author email and blocks unknown ones.
Fix: error out with a helpful message if GIT_AUTHOR_EMAIL is unset, and
document the GitHub noreply form (`<user-id>+<username>@users.noreply.github.com`)
in `.env.example` as the recommended choice.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fixes the 'no GitHub credentials' deadlock observed in the first
NAS-Docker batch run (2 May 2026): scrum4me-mcp's `wait_for_job`
expects a local clone at `~/Projects/<repo-name>` (convention-fallback
in resolveRepoRoot) but the container had no credentials and no clone.
Agent asked the user how to proceed; turn closed without claim.
Changes:
- `.env.example`: GH_TOKEN (fine-grained PAT, repo+PR scope) and
GH_PRECLONE_REPOS (comma-separated owner/name list, default covers
Scrum4Me + scrum4me-mcp).
- `bin/repo-bootstrap.sh` (new): runs as agent-user; configures git
credential-helper with HTTPS oauth2 token, then clones-or-fetches
each entry in GH_PRECLONE_REPOS into ~/Projects/<name>. Idempotent.
- `bin/entrypoint.sh`: hooks repo-bootstrap before run-agent.sh.
- `Dockerfile`:
- installs `gh` CLI (used for auto_pr `gh pr create`; reads GH_TOKEN
from env directly).
- pre-creates `~agent/Projects` and `~agent/.scrum4me-agent-worktrees`
so directory-ownership is right from the first boot.
- `README.md`: 'Repo bootstrap (clone-on-start)' section + GH_TOKEN
step in the deploy checklist; corrects the obsolete 'no push
credentials' note (agent now pushes feature-branches, gh creates PRs).
Same token covers clone, push and PR-creation — one secret to rotate.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drie fixes om de container lokaal (en op de NAS) te kunnen builden en draaien:
- Dockerfile: clone scrum4me-mcp zonder --recurse-submodules. De Prisma-
schema zit al gecommit in het scrum4me-mcp repo; de vendor/scrum4me
submodule is alleen nodig voor schema-updates en wijst naar een
privaat repo dat tijdens docker build niet bereikbaar is.
- Dockerfile: voeg /usr/sbin en /sbin toe aan PATH zodat gosu (in
/usr/sbin/gosu na apt-install) gevonden wordt door entrypoint.sh.
Zonder dit faalt de container in een restart loop.
- Verplaats alle runner scripts naar bin/ en maak etc/ aan, zodat
COPY bin/ en COPY etc/ in de Dockerfile bestanden vinden.
Verder:
- .gitattributes om CRLF-corruptie van shell scripts op Windows te
voorkomen (core.autocrlf=true is default actief).
- .gitignore: docker-compose.override.yml uitsluiten zodat lokale
dev-overrides niet worden gecommit.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>