Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
a6e112cbae docs: branch-per-story flow + heartbeat self-heal in CLAUDE.md
- Worktree-flow section now describes resolveBranchForJob (sibling
  reuse), feat/story-<id> naming, deferred cleanup while siblings are
  active, and the 1-PR-per-story result.
- File table corrects the heartbeat description (PR #14 made it
  self-healing instead of self-terminating).

Closes the docs task in story 'Voorkom doublure-PRs' under PBI 'Veilige
Claude-agent-workflow'.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:25:08 +02:00

View file

@ -8,16 +8,24 @@ MCP server that exposes the Scrum4Me dev-flow as native tools for Claude Code.
### How it works ### How it works
1. On successful claim, `wait_for_job` calls `createWorktreeForJob`: 1. On successful claim, `wait_for_job` calls `resolveBranchForJob` first:
- Looks for a sibling job in the same story that already has a branch
- If found → reuse that branch (`reused_branch: true` in the response)
- Otherwise → fresh branch `feat/story-<last-8-chars-of-story-id>`
2. Then `createWorktreeForJob`:
- Worktree directory: `SCRUM4ME_AGENT_WORKTREE_DIR/<job-id>` (default: `~/.scrum4me-agent-worktrees/<job-id>`) - Worktree directory: `SCRUM4ME_AGENT_WORKTREE_DIR/<job-id>` (default: `~/.scrum4me-agent-worktrees/<job-id>`)
- Branch: `feat/job-<last-8-chars-of-job-id>` (timestamp-suffixed if branch already exists) - Base: `origin/main` for fresh branches; existing remote tip for reused branches
- Base: `origin/main` - When reusing: any stale sibling worktree still holding the branch is removed first (siblings are sequential)
2. Tool response includes `worktree_path` and `branch_name`. 3. Tool response includes `worktree_path`, `branch_name`, `reused_branch`.
3. **Work exclusively in `worktree_path`** — all file edits and commits go there. 4. **Work exclusively in `worktree_path`** — all file edits and commits go there.
4. On `update_job_status(done|failed)`, `removeWorktreeForJob` runs automatically: 5. On `update_job_status(done|failed)`, `removeWorktreeForJob` runs automatically — but is **deferred** while siblings in the same story are still QUEUED/CLAIMED/RUNNING (next sub-task will reuse the branch). Only the last terminal transition triggers actual cleanup:
- `keepBranch=true` if `done` and a `branch` was reported (agent pushed) - `keepBranch=true` if `done` and a `branch` was reported (agent pushed)
- `keepBranch=false` otherwise (branch deleted with worktree) - `keepBranch=false` otherwise (branch deleted with worktree)
### Branch-per-story result
A story with 3 sub-tasks lands as **1 branch** with 3 commits and **1 PR** (assuming `auto_pr=true`). Sibling sub-tasks share the same `pr_url``maybeCreateAutoPr` reuses an existing PR from a sibling job instead of opening duplicates. Story-level PR title (`<story-code>: <story-title>`) so the GitHub view reads as one logical change rather than per-task fragments.
### Required configuration ### Required configuration
Set env var per product: Set env var per product:
@ -49,7 +57,7 @@ Server-startup registers a `ClaudeWorker` record + starts a 5 s heartbeat; SIGTE
| File | Purpose | | File | Purpose |
|---|---| |---|---|
| `src/presence/worker.ts` | `registerWorker` (upsert + pg_notify worker_connected) + `unregisterWorker` | | `src/presence/worker.ts` | `registerWorker` (upsert + pg_notify worker_connected) + `unregisterWorker` |
| `src/presence/heartbeat.ts` | `startHeartbeat` — 5 s interval, stops on record-not-found | | `src/presence/heartbeat.ts` | `startHeartbeat` — 5 s interval, self-heals by re-registering when record disappears |
| `src/presence/shutdown.ts` | `registerShutdownHandlers` — SIGTERM/SIGINT → stop heartbeat + unregister | | `src/presence/shutdown.ts` | `registerShutdownHandlers` — SIGTERM/SIGINT → stop heartbeat + unregister |
| `src/index.ts` | Bootstrap: calls `getAuth``registerWorker``startHeartbeat``registerShutdownHandlers` | | `src/index.ts` | Bootstrap: calls `getAuth``registerWorker``startHeartbeat``registerShutdownHandlers` |