Commit graph

127 commits

Author SHA1 Message Date
Janpeter Visser
f5887da1f5
Merge pull request #25 from madhura68/feat/worker-quota-tools
feat(M13): get_worker_settings + worker_heartbeat tools (v0.7.0)
2026-05-06 04:24:47 +02:00
Madhura68
d50075d960 feat(M13): get_worker_settings + worker_heartbeat tools (v0.7.0)
T-519 — pre-flight quota-gate voor de worker-loop.

Twee nieuwe MCP-tools:
- get_worker_settings (read): retourneert User.min_quota_pct. Worker
  roept dit elke iteratie aan vóór de quota-probe.
- worker_heartbeat (write): worker rapporteert last_quota_pct +
  last_quota_check_at na een probe. Update ClaudeWorker en emit
  pg_notify 'worker_heartbeat' op scrum4me_changes-channel zodat
  NavBar stand-by-badge real-time updatet. requireWriteAccess
  (demo-blok).

Schema-resync: vendor/scrum4me bijgewerkt naar 555ed8f waarmee de
M13-velden (User.min_quota_pct, ClaudeWorker.last_quota_pct +
last_quota_check_at) beschikbaar zijn voor Prisma client.

Bestaande achtergrond-heartbeat (presence/heartbeat.ts, 5s tick op
last_seen_at) blijft ongewijzigd. Worker_heartbeat is een aparte
expliciete call met quota-info.

Versie naar 0.7.0 (minor — twee nieuwe tools).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 04:23:31 +02:00
Janpeter Visser
edb1da7081
Merge pull request #24 from madhura68/feat/create-task-repo-url
feat(create_task): optionele repo_url voor cross-repo tasks
2026-05-06 04:21:39 +02:00
Madhura68
f600237c8c feat(create_task): optionele repo_url voor cross-repo tasks
Schema heeft Task.repo_url al (override van product.repo_url voor
worktree/branch/push), maar de create_task MCP-tool exposeerde 'm
niet — gevolg: cross-repo tasks (bv. T-519 in scrum4me-mcp onder een
Scrum4Me-PBI) eindigden met repo_url=null en worker draaide ze in
het verkeerde repo.

PBI-34 introduceerde IdeaProduct (idea aan meerdere producten) als
multi-product-pattern. Voor PBI/Story is geen extensie nodig; per-task
override is genoeg om cross-repo werk correct te routeren.

Validatie: zod.string().url() — full https://github.com/owner/repo URL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 04:16:31 +02:00
Janpeter Visser
b48f2a5c74
Merge pull request #23 from madhura68/feat/auto-merge-after-pr
feat: enable auto-merge (squash) after gh pr create
2026-05-06 00:44:04 +02:00
Madhura68
c1abcb8f82 feat(pr): enable auto-merge (squash) na pr create
Best-effort gh pr merge --auto --squash direct na succesvolle
gh pr create. PR mergt zodra alle vereiste CI-checks groen zijn,
zonder handmatige actie van de gebruiker.

Faal-tolerant: als auto-merge niet werkt (repo heeft "Allow
auto-merge" uit, of token-scope ontbreekt), wordt alleen een
warning gelogd. createPullRequest blijft de PR-URL teruggeven —
auto-merge kan handmatig aangezet worden.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 00:34:30 +02:00
Janpeter Visser
35460b09de
Merge pull request #22 from madhura68/fix/idea-job-done-skip-verify
fix: idea-jobs done blocked by verify-gate (v0.6.2)
2026-05-05 13:27:20 +02:00
Madhura68
536a27592c fix: idea-jobs cannot mark done — skip verify-gate (v0.6.2)
T-505 in v0.6.0 wired the idea-failure side-effects but missed the
'skip verify-gate for IDEA_*-kinds on done' branch from the M12 plan.

Reproduced live on IDEA-002: agent answered 5 questions, called
update_idea_grill_md (status → GRILLED, grill_md persisted), but
update_job_status('done') was rejected by the verify-gate because
idea-jobs have no task → no plan_snapshot → verify_task_against_plan
cannot run. Job got marked FAILED + idea reverted to GRILL_FAILED
even though the grill itself succeeded.

Fix: in update_job_status, when status='done' AND kind in
[IDEA_GRILL, IDEA_MAKE_PLAN]: skip checkVerifyGate AND
prepareDoneUpdate (no git push, no branch). The idea-status was
already moved to GRILLED/PLAN_READY by update_idea_*_md; the job
just needs to flip to DONE.

Tests: 153/153 still green.

Bump 0.6.1 → 0.6.2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 13:25:32 +02:00
Janpeter Visser
1ac87deb0e
Merge pull request #21 from madhura68/fix/idea-job-claim-leftjoin
fix: idea-jobs never claimed — LEFT JOIN tasks (v0.6.1)
2026-05-05 12:46:22 +02:00
Madhura68
dc43351831 fix: idea-jobs never claimed — JOIN tasks → LEFT JOIN (v0.6.1)
T-505 added the kind-discriminator to wait_for_job's response payload but
missed the claim-SQL: tryClaimJob does INNER JOIN tasks ON cj.task_id,
which matches NO rows for IDEA_*-jobs (task_id IS NULL by design — M12
schema). Result: idea-jobs sit forever in QUEUED, never picked up.

Reproduced live: IDEA-002 (cmoshh2ne...) had a IDEA_GRILL job queued at
10:26 that 2 active workers ignored for 14+ minutes.

Fix: LEFT JOIN tasks. plan_snapshot stays empty for idea-jobs (no
verify-flow needed for grill/make-plan).

Bump to 0.6.1 since 0.6.0 production deploy has the broken claim-SQL.

Tests: 153/153 still green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 12:45:18 +02:00
Janpeter Visser
63e095f756
Merge pull request #20 from madhura68/feat/m12-idea-jobs
M12 — Idea-job support (v0.6.0)
2026-05-05 12:02:31 +02:00
Madhura68
fa6e393465 vendor: bump scrum4me to main (post-M12) + re-sync schema
Scrum4Me PR #91 (feat/m12-ideas) merged at 09:58 UTC. Vendor pointer now
tracks origin/main (commit 2893573, includes the canonical M12 schema and
all M12 server/UI/REST/realtime work).

Re-synced prisma/schema.prisma from vendor as the authoritative source
(was previously synced from a local Scrum4Me feature-branch worktree).
Diff vs vendor: only the erd-generator block (vendored has it, mcp does
not — same as before M12).

Tests: 153/153 green; tsc + build clean. No tool-code changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 12:01:13 +02:00
Madhura68
fdf3dc4471 feat: M12 idea-job support — version 0.6.0
Adds the 4 new MCP-tools for the Scrum4Me M12 Idea-entity flow + extends
3 existing tools to handle the new ClaudeJobKind discriminator.

New tools:
- get_idea_context: full idea + product + open questions + recent logs
- update_idea_grill_md: save grill-result + status → GRILLED + IdeaLog
- update_idea_plan_md: server-side yaml parser validates frontmatter;
  ok → PLAN_READY, fail → PLAN_FAILED + line-info errors
- log_idea_decision: DECISION/NOTE entries on the timeline

Extended tools:
- ask_user_question: xor schema (story_id | idea_id); idea-questions are
  user-private with productId derived from idea.product_id
- wait_for_job: returns \`kind\` discriminator; IDEA_* payloads include
  idea + prompt_text (from src/prompts/idea/) and skip worktree creation
- update_job_status: failed on IDEA_* auto-transitions idea-status to
  GRILL_FAILED / PLAN_FAILED + IdeaLog{JOB_EVENT}; auto-PR + worktree-
  cleanup skipped for idea-jobs

Other changes:
- Health version now read dynamically from package.json (was hardcoded
  '0.1.0' which caused deploy-sync confusion)
- Schema synced to Scrum4Me M12 (Idea + IdeaLog + enums + ClaudeJob/
  Question nullable-FKs + check-constraints + pg_notify-trigger update)
- New @scrum4me-mcp/lib/idea-plan-parser duplicates Scrum4Me's parser
  (drift detected by vendor schema-watchdog)
- Embedded grill+make-plan prompts copied to src/prompts/idea/
- New userOwnsIdea access helper

Tests: 153/153 green; tsc + build clean.

Migration: requires Scrum4Me M12 migration (20260504172747_add_ideas_and_grill_jobs)
applied on the target DB. See vendor/scrum4me/docs/runbooks/mcp-integration.md
for the updated batch-loop with kind-switch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 22:12:36 +02:00
Madhura68
79eb13a210 MCP version bump 2026-05-04 16:45:48 +02:00
Madhura68
49defa9686 feat: auto-generate codes for PBI/Story/Task on create
Code field became required in schema (feat/entity-codes-required).
All three create tools now generate PBI-N / ST-001 / T-N via the same
SELECT-MAX + retry pattern used in the Scrum4Me app. Also bumps vendor
submodule to v1.0.0 and regenerates prisma/schema.prisma.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 16:14:36 +02:00
Janpeter Visser
85111f6dc7
Merge pull request #19 from madhura68/feat/story-o3ti9khw
feat(mcp): check_queue_empty tool — synchrone non-blocking queue-poll
2026-05-03 19:41:46 +02:00
Scrum4Me Agent
7db9881d85 docs: add lege-queue example to check_queue_empty README section 2026-05-03 17:58:52 +02:00
Scrum4Me Agent
d4522e8e53 feat: add check_queue_empty tool (v0.3.0)
Synchronous, non-blocking count of active ClaudeJobs per product or across
all accessible products. Registers check_queue_empty MCP tool with optional
product_id scope, productAccessFilter AuthZ, tests, and README docs.
2026-05-03 17:57:17 +02:00
Janpeter Visser
3ce2c044c4
feat(mcp): set_pbi_pr + mark_pbi_pr_merged tools voor PBI-PR-gating (#18)
* feat(ST-mhj9f2la): add set_pbi_pr MCP tool

- Add pr_url and pr_merged_at fields to Pbi model in schema
- Implement set_pbi_pr tool: writes pr_url, clears pr_merged_at (idempotent)
- AuthZ via requireWriteAccess + userCanAccessProduct through pbi.product_id
- 10 tests: happy path, not-found, no-access, demo-denied, schema validation
- Update README tools table and bump version to 0.2.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ST-mhj9f2la): add mark_pbi_pr_merged MCP tool

- Implement mark_pbi_pr_merged: sets pr_merged_at = now() on a PBI
- Requires pr_url to be set; returns error if not (geen gekoppelde PR)
- Idempotent: re-calling overwrites the timestamp
- AuthZ via requireWriteAccess + userCanAccessProduct through pbi.product_id
- 6 tests: happy path, no-pr_url, idempotent, no-access, not-found, demo-denied
- Update README tools table with mark_pbi_pr_merged entry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(ST-mhj9f2la): expand README with set_pbi_pr + mark_pbi_pr_merged docs

Add full signature/input/output/error documentation sections for both
new tools, following the verify_task_against_plan pattern.
Version already bumped to 0.2.0 in earlier commit.
Tag + MCP_GIT_REF pin in scrum4me-docker to be done by maintainer after merge.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 16:25:53 +02:00
2c85f4d239
feat(routing): cross-repo task routing + orphan-branch cleanup (#17)
Two related fixes for the agent-workflow defects exposed by the
2-May-2026 batch:

1. **Cross-repo task routing** (`task.repo_url` override).
   `resolveRepoRoot` now consults `task.repo_url` first; matches against
   per-repo env-var (`SCRUM4ME_REPO_ROOT_REPO_<name>`),
   `~/.scrum4me-agent-config.json` `repoRoots[<name>]`, and finally
   `~/Projects/<name>/.git`. Falls back to product-level resolution
   when null. Tasks tracked under one product but targeting another
   repo (e.g. MCP-server tasks under the main product's PBI) now work.
   `getFullJobContext` exposes `task.repo_url` to the agent.
   `attachWorktreeToJob` accepts and forwards it.

2. **Orphan-branch cleanup** in `createWorktreeForJob`.
   Previously a name-collision suffixed with a timestamp, leaving the
   agent on an unpredictable `feat/story-XXX-<ms>`-name. Worse, in the
   2-May batch the agent ended up reusing an orphan branch from an
   earlier story (`feat/story-x35n155c`) and pushed to a remote ref
   that did not exist, causing 'src refspec does not match any'.

   Now: detect orphan, attempt to remove its (stale) worktree if any,
   delete the local branch, and recreate with the predictable name.
   Timestamp-suffix is the last resort.

Vendor submodule bumped to pick up `Task.repo_url` from Scrum4Me #54.

Tests: 129/129 — `suffixes branch name with timestamp` updated to
`removes orphan branch and reuses the predictable name`.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 18:07:57 +02:00
1fe6ccf609
feat(gate): verify_required levels — ALIGNED/ALIGNED_OR_PARTIAL/ANY (#16)
Sluit story 'Verify-gate uitbreiden' in PBI 'Agent verify-flow hardening' af.

The previous gate weighed only EMPTY: any PARTIAL or DIVERGENT verify
slipped through. The Insights batch (2 May 2026) showed why that's
weak — agent-jobs claiming DONE while only delivering helpers, not
the requested UI components, with verify=DIVERGENT/PARTIAL accepted.

New decision matrix:

  null                       → reject (run verify_task_against_plan)
  EMPTY  + !verify_only      → reject
  EMPTY  + verify_only       → allowed
  ALIGNED                    → always allowed
  PARTIAL/DIVERGENT
    required=ALIGNED         → reject (strict task)
    required=ALIGNED_OR_PARTIAL (default) → allowed only if summary
                                            ≥20 chars (acknowledge drift)
    required=ANY             → allowed (refactor escape hatch)

`update_job_status('done')` now reads `task.verify_required` from the DB
(field added in Scrum4Me PR #53) and passes it + `summary` to the gate.
Tool description updated with the new rules.

Vendor submodule synced to pick up the schema enum.

Tests: 129/129 (was 120 + 9 new combinatorial gate tests).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 17:55:06 +02:00
0bcca15235
docs: branch-per-story flow + heartbeat self-heal in CLAUDE.md (#15)
- 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:26:21 +02:00
657f7a80c0
fix(presence): heartbeat self-heals when worker record disappears (#14)
Previously, if the ClaudeWorker record vanished (deleted by
prisma_workers_cleanup, manual cleanup, or a race during shutdown of a
parallel worker), the heartbeat would log a warning and stop itself
permanently. From that moment the NavBar showed 'Geen agent' for the
rest of the MCP-server process lifetime — even though the agent was
still alive and serving tools.

Fix: on result.count === 0, call registerWorker again so the record is
re-created. Heartbeat keeps ticking. Self-healing instead of self-
terminating.

startHeartbeat now also accepts userId (needed for re-registration);
caller in index.ts updated.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:17:07 +02:00
4736284f8d
fix: register worker presence BEFORE server.connect, not after (#13)
server.connect(transport) on the stdio transport awaits the first MCP
handshake from the client. If that handshake stalls (or the await keeps
the process pinned to the stdio event loop), the lines that follow
never run — registerWorker / startHeartbeat / shutdown-handlers are
silently skipped.

Symptom: NavBar shows 'Geen agent' while jobs are claiming and running
(observed in production after the M13 worker-presence release).
ClaudeWorker count stays at 0 even though tools are responding.

Fix: do the presence bootstrap before opening the transport. Tools are
already registered at this point — connecting the transport just makes
them reachable. Delaying the connect by ~10ms (one DB upsert + one
pg_notify) is harmless to the client handshake.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 19:53:27 +02:00
f01fab8c38
feat: branch-per-story + worktree-defer + verify EMPTY edge-cases (#12)
Implementeert vier open stories uit PBI 'Veilige Claude-agent-workflow':

**Branch per story (cmon11tbe001zbortx35n155c)**
- `resolveBranchForJob`: zoek sibling-job in dezelfde story; reuse z'n
  branch (1 PR per story i.p.v. per task).
- Branch-naam: `feat/story-<8-char>` voor nieuwe stories.
- `createWorktreeForJob` kent nu `reuseBranch=true`: detecteert stale
  sibling-worktree die de branch nog vasthoudt en verwijdert die eerst.
- `attachWorktreeToJob` neemt `storyId` mee.

**PR-hergebruik (zelfde story)**
- `maybeCreateAutoPr`: als sibling-job in story al een pr_url heeft,
  hergebruik die zonder nieuwe `gh pr create`-call. PR-titel komt nu
  van de story (was task) zodat het als 'story-PR' leest.

**Worktree-cleanup uitgesteld bij actieve siblings**
- `cleanupWorktreeForTerminalStatus`: count active sibling-jobs in
  dezelfde story; defer als > 0 (volgende sub-task gebruikt branch).

**Worktree-cleanup logging (cmon0jc14001ubortjxf2a2ck)**
- Warning bij ontbrekende repoRoot, met productId + jobId in message.
- Warning bij removeWorktreeForJob-failure met keepBranch in message.

**resolveRepoRoot fallback (cmon0jc14001ubortjxf2a2ck)**
- Convention-based fallback: `~/Projects/<repo-name>` afgeleid uit
  `product.repo_url` als noch env-var noch config-bestand iets oplevert.
- `repoNameFromUrl` helper geëxporteerd voor herbruikbaarheid.

**Verify EMPTY-detection edge-case (cmon0kdq6001xbort2kgbcqmr)**
- `classifyDiffAgainstPlan`: na file-paths-check ook content-lines
  checken; als alle +/- regels alleen headers of whitespace zijn,
  return EMPTY met duidelijke reasoning.

Tests: 120/120 groen (3 nieuwe), tsc clean, build clean.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 17:04:54 +02:00
f87b20744b
feat: worker presence layer + batch-loop docs (#7)
* feat: add next_action field to update_job_status response

* docs: add Batch-loop section to README

* feat: presence layer — registerWorker, startHeartbeat, registerShutdownHandlers

* feat: bootstrap worker presence at server startup, remove inline presence from wait-for-job

* docs: document worker presence layer in CLAUDE.md

* docs: refine Batch-loop intro — add 'Hier is de flow:' per implementation plan
2026-05-01 16:39:26 +02:00
c990d8547e
Merge pull request #6 from madhura68/fix/done-gate-reject-empty-verify
fix: DONE-gate in update_job_status (verify_result null/EMPTY rejection)
2026-05-01 14:00:18 +02:00
5cd792a8fe feat: DONE gate in update_job_status — reject if verify_result null or EMPTY without verify_only
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 13:58:28 +02:00
994f28f103
Merge pull request #5 from madhura68/feat/job-slv6i9xm
M13: Veilige Claude-agent-workflow (MCP-server-side)
2026-05-01 13:52:46 +02:00
1015264558 feat(M13): auto-PR via gh CLI after successful push (auto_pr=true)
New src/git/pr.ts helper wraps 'gh pr create'; returns { url } or { error }.
maybeCreateAutoPr() in update-job-status checks product.auto_pr, builds title
from story.code + task.title, writes pr_url to DB. Non-fatal: gh failure logs
a warning and leaves DONE status intact. Also syncs schema: auto_pr on Product,
pr_url on ClaudeJob.
2026-05-01 13:30:38 +02:00
dadcbc48d6 feat(M13): cleanup_my_worktrees tool — scan + remove stale worktrees for terminal-status jobs 2026-05-01 13:22:47 +02:00
095ebc40f8 feat(M13): retry-tracking — stale CLAIMED jobs → QUEUED (retry_count++) or FAILED (≥2 retries)
resetStaleClaimedJobs now uses $queryRaw with RETURNING so it can send pg_notify
claude_job_status events per transitioned job. Jobs under the retry limit are
re-queued with retry_count incremented; jobs at ≥2 retries are marked FAILED.
2026-05-01 13:18:59 +02:00
2343915a6a feat(M13): sync schema — retry_count on ClaudeJob, verify_only on Task, VerifyResult enum 2026-05-01 13:18:54 +02:00
e63ea7026b feat: verify_task_against_plan calls classifyDiffAgainstPlan + saves verify_result to DB
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 12:59:17 +02:00
24e933fc2f chore: sync VerifyResult enum + verify_only + verify_result from main Scrum4Me schema
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 12:59:08 +02:00
1e264ed521 feat: classifyDiffAgainstPlan — pure diff vs plan classifier (VerifyResult)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 12:55:47 +02:00
8ebf4ff895 feat: integrate push into update_job_status DONE transition
On status=done, calls pushBranchForJob before DB write:
- pushed=true → DONE + pushed_at + branch set + worktree cleanup (keepBranch=true)
- no-changes → DONE without pushed_at + worktree cleanup
- push failure → FAILED with error message + worktree preserved for manual inspection

Also adds pushed_at to vendored prisma schema + regenerates client.
6 unit tests for prepareDoneUpdate covering all push outcomes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 12:00:30 +02:00
fbfaf905c8 feat: add pushBranchForJob helper (src/git/push.ts)
Runs git push -u origin <branch> in the worktree. Detects no-changes
(HEAD = origin/main) before pushing. Classifies push failures into
no-credentials, conflict, or unknown via stderr pattern matching.
5 unit tests covering all paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 11:57:14 +02:00
48b67444cc docs: agent worktree-flow documentation + CLAUDE.md
README: updated wait_for_job/update_job_status tool descriptions,
added 'Agent worktree-flow' section with env vars, config-file fallback,
and smoke-test checklist. New CLAUDE.md with worktree-flow summary and
key source file index.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 11:53:45 +02:00
ce4afa1928 feat: cleanup worktree in update_job_status on terminal transitions
On DONE/FAILED, resolves repoRoot and calls removeWorktreeForJob (best-effort).
keepBranch=true when status=done and agent reported a branch (push assumed);
false otherwise. Cleanup failures are logged as warnings — DB status is preserved.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 11:52:16 +02:00
6ee55e79b6 feat: integrate createWorktreeForJob into wait_for_job tool
After claiming a job, resolves repoRoot (env SCRUM4ME_REPO_ROOT_<productId>
or ~/.scrum4me-agent-config.json), creates a git worktree, and returns
worktree_path + branch_name in the response. Rolls back claim to QUEUED
on failure. Tool description updated to instruct agent to work in worktree.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 11:50:51 +02:00
b20e297851 feat: add removeWorktreeForJob helper
Removes worktree dir via `git worktree remove --force` and deletes
the local branch by default; keepBranch=true preserves the branch.
Returns { removed: false } when the worktree path doesn't exist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 11:46:31 +02:00
e7bb3c82ba feat: createWorktreeForJob helper — isolate agent per job in git worktree
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 11:34:19 +02:00
3efebe21f3 chore: update vendor/scrum4me submodule to merged main (794f7af)
Points to the merge commit of PR #23 on Scrum4Me/main so the submodule
tracks origin instead of the local-only pre-merge commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 19:46:46 +02:00
c2ca29d52b
Merge pull request #4 from madhura68/feat/plan-snapshot-verify-tool
feat: plan_snapshot capture in wait_for_job + verify_task_against_plan tool
2026-04-30 19:42:33 +02:00
d9f3a7ea40 test+docs: verify-plan tests and README for verify_task_against_plan
23 unit tests covering parseAcceptanceCriteria, extractKeywords,
checkACStatus, computeDriftScore, lineDiff, and 4 end-to-end scenarios
(plan unchanged, edited, AC missed, no baseline). README documents the
tool with example output and heuristic limitations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 19:36:43 +02:00
f51b7a6178 feat: verify_task_against_plan MCP tool
Read-only tool that compares frozen plan_snapshot against current
task.implementation_plan + story logs + commits. Returns markdown report
with per-AC ✓/✗/? keyword heuristic, drift-score, and plan diff.
Demo users allowed (readOnlyHint: true).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 19:36:37 +02:00
de7803a370 chore: add plan_snapshot to local prisma schema copy
Keeps prisma/schema.prisma in sync with vendor/scrum4me so
prisma:generate produces the updated ClaudeJob client types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 19:36:30 +02:00
54ace839f8 test: snapshot capture + stale reset in wait_for_job
Verifies: claim writes plan_snapshot from task.implementation_plan;
NULL plan becomes '' snapshot; no job returns null; stale reset SQL
includes plan_snapshot = NULL; product_id scoping passes correct param.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 19:27:56 +02:00
ddc773d20a feat: capture plan_snapshot at job claim in wait_for_job
- resetStaleClaimedJobs: also sets plan_snapshot = NULL on reset
- tryClaimJob: JOINs tasks table to read implementation_plan in the
  same atomic transaction, writes it to claude_jobs.plan_snapshot
- Empty-plan edge case: NULL becomes '' (non-null) in snapshot
- Exports both functions for unit testing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 19:27:52 +02:00