feat(bootstrap): GH_TOKEN-based clone of Scrum4Me + scrum4me-mcp

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>
This commit is contained in:
Janpeter Visser 2026-05-02 19:48:57 +02:00
parent 47b1de93db
commit c090e6c349
5 changed files with 147 additions and 6 deletions

View file

@ -71,6 +71,13 @@ fouten.
# b. SCRUM4ME_TOKEN → log in als de dedicated agent-user in
# Scrum4Me, /settings/tokens, label "NAS-runner"
# c. DATABASE_URL/DIRECT_URL → Neon dashboard
# d. GH_TOKEN → github.com → Settings → Developer settings →
# Personal access tokens → Fine-grained.
# Repository access op madhura68/Scrum4Me +
# madhura68/scrum4me-mcp; Permissions:
# Contents (RW), Pull requests (RW),
# Metadata (R). Wordt gebruikt voor clone,
# push en `gh pr create` (auto_pr).
# 2. Repo op de NAS plaatsen
ssh admin@nas
@ -126,10 +133,30 @@ laatste heartbeat ouder is dan 5 minuten.
## Filesystem-grenzen
De agent-user heeft geen SSH-keys, geen `~/.gitconfig` met push-credentials,
en geen toegang tot andere shares dan `/share/Agent/*`. Commits worden
lokaal in de per-job clone gemaakt; pushen gebeurt door jou op je
werkstation na review (CLAUDE.md regel: *"`git push` is altijd expliciet"*).
De agent-user heeft geen SSH-keys en geen toegang tot andere shares dan
`/share/Agent/*`. Wel een `~/.git-credentials` met de `GH_TOKEN` voor
HTTPS-clone/push (zie volgende sectie) — die token is scoped tot de twee
configured repos en mag worden gerouleerd door rebuild + redeploy.
## Repo bootstrap (clone-on-start)
Bij elke container-start runt `bin/repo-bootstrap.sh` (als de
`agent`-user, ná drop-privileges) en zet zo'n setup neer:
1. Configureert git's credential-helper met `GH_TOKEN` zodat
`git clone`/`push` naar `https://github.com/...` zonder prompt werkt.
2. Voor elke repo in `GH_PRECLONE_REPOS` (komma-gescheiden owner/name):
- Bestaat `~/Projects/<name>/.git` al? → `git fetch origin --prune`
- Anders → fresh `git clone`
Daarna vindt scrum4me-mcp's `resolveRepoRoot` (in `wait_for_job`) de
clone via z'n convention-fallback `~/Projects/<name>/.git`. Worktrees
voor jobs landen vervolgens onder `~/.scrum4me-agent-worktrees/<jobId>/`
zodat de hoofd-clone niet wordt aangeraakt.
Push gaat over dezelfde token: `git push -u origin feat/story-<id>`
slaagt zonder prompt. `gh pr create` (voor producten met `auto_pr=true`)
gebruikt dezelfde `GH_TOKEN` via de `gh` CLI's standaard env-detect.
## Bekende grenzen