d6c4faa3c0f8b456cd3ccb20f776eb4a8d8adc73
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d6c4faa3c0 |
fix(implement-loop): require positive edit evidence before DONE
The #11 vacuous-green shape on the main path: `outcome = DONE` was set purely from the absence of a BLOCKED task, with no check that the iteration actually wrote anything. `files_touched` was even computed by the finalize agent but never asserted > 0, `e2e.status` was never read, and in mini mode the handed-off RED test was never independently re-run (GREEN was asserted from the implementer's self-report, never observed). Add a positive-evidence precondition on DONE, taken from git ground truth — never a self-report, which must not be able to fail a run that actually did the work: - Standard mode: a dedicated `tree-check` agent runs `git status --porcelain | wc -l` after the per-task loop but BEFORE E2E/finalize. Zero (or a non-returning agent) downgrades DONE to BLOCKED. `git status --porcelain` (not `git diff HEAD`) so a brand-new untracked file — the implementer leaves edits unstaged — still counts; running pre-E2E/finalize keeps fixtures and the stats/BLOCKED.md artefacts from inflating it. - Mini mode: an independent `mini-verify` agent re-runs the RED test by name and the suite and checks the tree is dirty; a still-red test, a regression, or a clean tree is BLOCKED (route back to debug). - Per-task `applied_changes` (OR-ed across the initial dispatch and every repair) feeds only a neutral concern, never the outcome. - `e2e.status` is now read: a non-DONE status or a zero-fixture run surfaces as a concern. A clean-tree no-op is BLOCKED with no BLOCKED.md (nothing to clean up); the status + reason ride the end-report. SKILL.md documents the precondition, the no-BLOCKED.md carve-out, and the Step-4 handling. closes #12 |
||
|
|
89cc4bb9a8 |
fix(compiler-driven-edit): require positive edit evidence before DONE
The done-signal `build_clean && suite_green_unchanged` was vacuously true on a clean working tree, so a no-op edit (the edit agent touched nothing and reported sites: 0) read as DONE. An orchestrator trusting that verdict would "commit the unstaged changes" — committing nothing under a DONE banner. Add positive evidence that an edit actually landed, checked at two independent points: - Phase 1 (cheap, pre-suite): the edit agent reports `applied_changes` as ground truth from `git status --porcelain` / `git diff HEAD`. No hole + clean tree -> distinct BLOCKED (kind: no-op-edit), skipping a pointless suite run against an empty tree. - Phase 3 (authoritative backstop): DONE now also requires the verify agent's independent `working_tree_dirty` observation. The verify agent never sees the edit agent's self-report, so a false applied_changes is still caught. A green build+suite over a clean tree routes to the same BLOCKED, not to debug (a clean tree is no regression — nothing to reproduce RED-first). The precondition keys on tree-dirty, not sites > 0: a legitimate behaviour-preserving edit can touch only the definition site (sites: 0) and still dirty the tree. Also fix the DONE note to report a legitimate sites: 0 as 0 rather than coercing it to null. closes #11 |
||
|
|
52db1abe10 |
fix(implement-loop): hold plan-contradicting quality findings instead of oscillating to a false BLOCKED
The per-task quality re-loop treated every `changes_requested` as "deviate to satisfy", and the quality-repair dispatch was not even given the task text. When a finding's only remedy contradicted a plan-prescribed name/signature, the implementer renamed off-plan, the next review flagged "diverges from plan", and the loop oscillated name-misleads <-> diverges-from-plan until the retry cap, emitting a false BLOCKED on code that was green the whole time. Fix (issue's option 2 — the plan knowledge lives with the implementer, which holds the task text; the quality-reviewer is deliberately blind to it, so option 1 would have breached that separation): - The quality-repair dispatch now receives the task text and a HOLD CLAUSE. A cosmetic finding (plan kept => build+tests green) is KEPT and recorded in a new `held` field; the loop surfaces it as a concern instead of chasing a deviation. A finding the implementer judges correctness-breaking escalates to BLOCKED, never a silent hold. - The hold is keyed on two structural signals, never on a self-reported status enum (which the implementer contract overloads): the `held` array, and a no-op backstop over a required `diff_fingerprint` (a changes_requested verdict over an already-seen diff-state means the repair was a no-op or cycled back — re-running quality is futile). Fingerprints are tracked in a Set so A-B-A edit-then-revert is caught. - A no-op-backstop concern is labelled neutrally (a byte-identical diff cannot tell a principled plan-hold from an ignored bug); implement SKILL.md Step 3 now routes a held/unresolved quality finding to orchestrator hand-verification before committing, even under /boss. The held/no-op partition is the implementer's judgement, not enforced in code — the residual fail-open is bounded to cosmetic-on-green findings and disclosed, with the orchestrator's Step-3 inspection as the backstop, the same trust placed in its other self-reports. Verified across three rounds of adversarial review (held-the-plan paths, fail- open laundering, schema/Set mechanics) — all closed. closes #10 |
||
|
|
7a58a530b1 |
feat(pipeline): route to the lightest correct methodology; move execution loops onto the Workflow substrate
The selector forced every task through the heaviest methodology's
critical path: a behaviour-preserving, type-enumerable change paid the
same specify -> planner -> implement front-half as a novel feature,
because it was neither new behaviour (tdd) nor an observed bug (debug)
and so fell to specify by elimination. Two coupled defects — a selector
with no verification axis, and an all-or-nothing executor — kept the
existing lighter path unreachable and uneconomical. This fixes both.
Part A — verification-keyed selector (boss/SKILL.md):
- Replace the three-way "design line" with an ordered cascade that adds
a verification/enumeration axis ahead of the settled-vs-fork question.
Each lighter arm carries a positive trigger matched by signature, not
reached by elimination.
- New `compiler-driven` arm: a type/signature edit at a definition site
that propagates mechanically. Observe-then-bounce — make the edit,
build, run the suite; clean build AND suite green unchanged commits;
a hole bounces up (specify for a design choice, tdd for discovered
test-specifiable new behaviour); a regression bounces to debug.
- The observed-bug RED-first gate is first in the cascade, so a
mechanical-looking fix cannot bypass it.
- The straddle rule ("add an enum variant") is codified as a rule:
mechanical/forwarding -> compiler-driven; encodes new behaviour ->
tdd/spec; doubt routes up.
- The executor is the elevated inline carve-out plus a shipped workflow,
not a heavy new skill ("the largest concrete win is small").
Part B — Workflow substrate (implement/workflows/):
- implement-loop.js: the per-task loop as a deterministic script. Each
phase (implementer -> spec-compliance -> quality, + tester for E2E) is
a separate top-level agent() call, so a single phase is independently
invokable and inter-phase aggregation/re-loop is code. Retires the
implement-orchestrator agent's inline-role-switch workaround (the four
phase agents survive as the agent-types the script dispatches).
- compiler-driven-edit.js: the observe-then-bounce loop.
- install.sh / uninstall.sh symlink shipped workflows into
~/.claude/workflows/.
- specify and brainstorm stay prose + interactive (human-intent oracle);
only the autonomous/mechanical loops moved. try-and-error is deferred.
Docs (pipeline taxonomy, design, agent-template, migration, README) and
all selector<->executor cross-references updated; the arm and its
executor are co-located so a future re-route through the full loop is a
visible regression.
Verified by an adversarial multi-agent pass: PASS on all six acceptance
criteria; two coherence concerns fixed. The shipped scripts are
syntax-validated but exercised only in a downstream target project (the
skills repo is not itself a pipeline target).
closes #7
|