diff --git a/scripts/work/decompose.mjs b/scripts/work/decompose.mjs index 5f9b911..bf0d02e 100644 --- a/scripts/work/decompose.mjs +++ b/scripts/work/decompose.mjs @@ -160,6 +160,12 @@ export async function executeDecompose(prdId, prdPath, prdText) { promptFile: decomposerPrompt, promptArgs: { PRD_FILE_CONTENT: prdText }, cwd: REPO_ROOT, + // Sandcastle's default maxIterations: 1 cut the agent off after its + // first response — files were written inside the sandbox but never + // captured as commits. Decompose is a small authoring task (read + // context, write epic + stories, commit); 10 iterations is enough + // room. Tune via env SANDCASTLE_DECOMPOSE_ITERATIONS. + maxIterations: Number(process.env.SANDCASTLE_DECOMPOSE_ITERATIONS ?? 10), }); } catch (e) { console.error("✗ Decomposer dispatch failed:", e.message); diff --git a/scripts/work/dispatch.mjs b/scripts/work/dispatch.mjs index 0c07889..743f938 100644 --- a/scripts/work/dispatch.mjs +++ b/scripts/work/dispatch.mjs @@ -231,6 +231,12 @@ async function executeDispatch() { promptFile: implementerPrompt, promptArgs: { TASK_FILE_CONTENT: taskSpec }, cwd: REPO_ROOT, + // Implementer runs a full TDD slice (read context, red test, green + // impl, run all five gates, commit). 30 iterations matches typical + // slice shape. Tune via env SANDCASTLE_IMPLEMENTER_ITERATIONS. + maxIterations: Number( + process.env.SANDCASTLE_IMPLEMENTER_ITERATIONS ?? 30, + ), }); } catch (e) { console.error("✗ Implementer dispatch failed:", e.message); @@ -280,6 +286,10 @@ async function executeDispatch() { promptFile: reviewerPrompt, promptArgs: { TASK_FILE_CONTENT: taskSpec, DIFF: diff }, cwd: REPO_ROOT, + // Reviewer reads the diff + task spec and decides (approve/reject). + // Smaller surface than the implementer; 10 iterations is plenty. + // Tune via env SANDCASTLE_REVIEWER_ITERATIONS. + maxIterations: Number(process.env.SANDCASTLE_REVIEWER_ITERATIONS ?? 10), }); console.log(`Reviewer returned. stdout follows:\n${reviewResult.stdout}`);