Skip to content

v0.26.0

Choose a tag to compare

@ux287 ux287 released this 12 Jul 05:03

Greenfield first-code generation: the planner can now author file bodies from scratch.

FIXED — greenfield plans no longer die in an unwinnable retry loop.
On a fresh child with an empty RAG index, a story whose targets are all op: create never
produced code. The JSON-embedded planner emitted PROSE NARRATION in a step's content field
("Create a Calculator component that handles the four operations.") instead of an actual file
body, and two failures compounded:

  1. PREDICATE DIVERGENCE. The LLM-side executability check accepted any non-empty content
    string and called the plan executable; the server-side create-coverage gate was stricter
    and called the same target uncovered. The plan was simultaneously too complete to retry
    usefully and too empty to execute, so it round-tripped as output_invalid / has_note_steps
    until retries exhausted. No refinement could escape it — the planner cannot emit a whole file
    body through the JSON channel, so re-asking just re-narrates.

  2. NO SYNTHESIS PATH FOR SOURCE FILES. Test files had an escape hatch (a focused raw-code LLM
    call); source files had none. Greenfield is exactly the case where every file is a source
    file being born.

CHANGES

  • NEW isSynthesizedBody(content, filePath) in server/plan-quality.mjs — ONE shared predicate
    answering "is this a real file body?" for BOTH the LLM-side and server-side gates, so they can
    no longer diverge. Rejects empty bodies, placeholder/comment-ONLY bodies, and prose narration in
    code files. Deliberately conservative: it fail-safes to "this is a real body" when unsure,
    because a false negative is catastrophic (a real component downgraded to a note, or a covered
    target declared unauthorable → hard unrefinable failure) while a false positive is merely the
    status quo ante.

  • NEW enrichCreateFileContent in llm/planner.mjs — synthesizes real file bodies via a focused
    raw-code LLM call for any create_file step the JSON planner narrated instead of authoring,
    running UPSTREAM of every gate (critic, retry, coverage). Explicitly NOT gated on testExemplar
    the way the test-content enricher is: a fresh child has no exemplar, and the fresh child is
    precisely the case this rescues. When synthesis itself cannot author the file, the step is left
    untouched so the coverage gate fails LOUD and unrefinable — rather than swapping in another
    unauthorable body and re-entering the loop.

  • The placeholder rule is now a WHOLE-BODY test, not an unanchored substring match. A real
    200-line component containing one incidental // TODO: is no longer downgraded to a note.
    LLM-authored code carries TODOs routinely; that body is real and now stays executable.

  • De-fragilized the witness tests: replaced source-grep pins (which assert nothing about behavior
    and break on every refactor) with behavioral assertions against the real predicate, removed a
    duplicated local mirror of the coverage rule, and killed a src.slice(idx, idx + 2200) fixed
    window that empties silently when the code above it grows — making every assertion below it
    vacuously pass.