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>
This commit is contained in:
Madhura68 2026-05-05 12:45:18 +02:00
parent 63e095f756
commit dc43351831
2 changed files with 6 additions and 4 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "scrum4me-mcp", "name": "scrum4me-mcp",
"version": "0.6.0", "version": "0.6.1",
"description": "MCP server for Scrum4Me — exposes dev-flow tools and prompts via the Model Context Protocol", "description": "MCP server for Scrum4Me — exposes dev-flow tools and prompts via the Model Context Protocol",
"type": "module", "type": "module",
"bin": { "bin": {

View file

@ -249,12 +249,14 @@ export async function tryClaimJob(
): Promise<string | null> { ): Promise<string | null> {
// Atomic claim in a single transaction — also captures plan_snapshot from task // Atomic claim in a single transaction — also captures plan_snapshot from task
const rows = await prisma.$transaction(async (tx) => { const rows = await prisma.$transaction(async (tx) => {
// SELECT FOR UPDATE OF claude_jobs SKIP LOCKED — join tasks to read implementation_plan // SELECT FOR UPDATE OF claude_jobs SKIP LOCKED — LEFT JOIN tasks zodat
// idea-jobs (task_id IS NULL, M12) ook gevonden worden. plan_snapshot
// blijft dan NULL/'' voor idea-jobs — niet nodig (geen verify-flow).
const found = productId const found = productId
? await tx.$queryRaw<Array<{ id: string; implementation_plan: string | null }>>` ? await tx.$queryRaw<Array<{ id: string; implementation_plan: string | null }>>`
SELECT cj.id, t.implementation_plan SELECT cj.id, t.implementation_plan
FROM claude_jobs cj FROM claude_jobs cj
JOIN tasks t ON t.id = cj.task_id LEFT JOIN tasks t ON t.id = cj.task_id
WHERE cj.user_id = ${userId} WHERE cj.user_id = ${userId}
AND cj.product_id = ${productId} AND cj.product_id = ${productId}
AND cj.status = 'QUEUED' AND cj.status = 'QUEUED'
@ -265,7 +267,7 @@ export async function tryClaimJob(
: await tx.$queryRaw<Array<{ id: string; implementation_plan: string | null }>>` : await tx.$queryRaw<Array<{ id: string; implementation_plan: string | null }>>`
SELECT cj.id, t.implementation_plan SELECT cj.id, t.implementation_plan
FROM claude_jobs cj FROM claude_jobs cj
JOIN tasks t ON t.id = cj.task_id LEFT JOIN tasks t ON t.id = cj.task_id
WHERE cj.user_id = ${userId} WHERE cj.user_id = ${userId}
AND cj.status = 'QUEUED' AND cj.status = 'QUEUED'
ORDER BY cj.created_at ASC ORDER BY cj.created_at ASC