Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Workflow/GenerateIssueWorkflow.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ protected function criticRules(): array
. "- Few steps. One step that implements and verifies is the intended shape for a small task.\n"
. "- Boilerplate: namespace, strict_types, the class declaration. Rejected at save if wrong.\n\n"
. "REJECT when any of these hold — and say which:\n"
. '- a step is too SIMPLE to earn its own existence. This is a judgement, not a count: read '
. 'each step and ask "if it does this little, is it a step at all, or ceremony?". A step '
. 'whose prompt carves out only a sliver — a lookup, a restatement, one trivial action a '
. 'neighbour would absorb without noticing — should be FOLDED into that neighbour. A step '
. 'must justify its own fresh context; a workflow that spends one on a triviality is badly '
. "split. (Having FEW steps is not the fault — a lone meaty step is ideal; a thin step is);\n"
. "- a step is a true placeholder: no ai()/tool() call at all;\n"
. '- the class builds the change as a PHP string and writes it (str_replace/preg_replace '
. 'surgery on source, a heredoc of the new file). It cannot see or fix its own mistakes '
Expand Down
23 changes: 23 additions & 0 deletions tests/Workflow/GenerateIssueWorkflowTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,29 @@ public function theSolverReviewCanRejectOnSubstanceAndSeesWhatTheAuthorSaw(): vo
}
}

/**
* A too-simple step is a decomposition defect the reviewer must catch — the "make meaty steps"
* rule lives in the generator prompt, which the model can ignore; the gate is the critic. It is an
* EVALUATION, not a turn count: read each step and ask whether one this small earns being a step.
*/
#[Test]
public function theSolverReviewRejectsAStepTooSimpleToJustifyItself(): void
{
$dir = self::tempDir();

try {
$agent = self::generate($dir, 'Issue13Solver', 'simple');
$review = self::textOf($agent, 5); // the critic's prompt

Assert::true(str_contains($review, 'too SIMPLE to earn its own existence'));
Assert::true(str_contains($review, 'is it a step at all, or ceremony?'));
// and the judgement is not mistaken for "too few steps" — a lone meaty step stays ideal
Assert::true(str_contains($review, 'a lone meaty step is ideal'));
} finally {
self::rmrf($dir);
}
}

/**
* A chosen approach reaches the model that writes the solver, and sits BESIDE the general recipe
* rather than replacing it.
Expand Down
Loading