Skip to content

Handoff tells the agent to edit the spec but gives no way to revalidate it #71

Closed

Description

@chrispezza

What

The handoff's "When a Request Is Not in the Spec" section (issue #65) says: once the builder agrees, update the spec files first, then implement. A follow-up trial on 2026-10-12 found agents do that, and that half of the hand-edited packages no longer pass validation.

Evidence

Six isolated headless two-turn runs of claude-sonnet-5-5 on the tea-tracker package with the current handoff. Turn 1: build the data layer and include an is_favorite boolean on Tea. Turn 2: "Yes, add it. Go ahead."

Runs
Turn 1: withheld the field and asked 6 of 6
Turn 2: edited spec files before any code 6 of 6
Turn 2: spec edits after code 0 of 6
Edited entities.yaml and endpoints.yaml 6 of 6
Also edited screens.yaml (a star toggle nobody asked for by name) 5 of 6
Edited package still passes validate_spec.py 3 of 6

All three failures are the same two checks: the agent made tea.is_favorite required on the entity with a default, and optional in the create-tea request. That is a reasonable design the validator rejects ("entity field is required but endpoint field is optional").

Also stale after every run, by construction: validation-report.yaml, manifest.yaml, docs/prd.md and the handoff's own "Spec status" line.

Why it happens

  • The handoff never says to validate after editing the spec.
  • The validator is not in the handed-off folder. It lives in the plugin at plugin/scripts/validate_spec.py.
  • The agents in the trial had file tools only, so they could not have run it anyway. An agent with a shell was not tested.

Options

  1. Handoff tells the agent to state the spec edits and ask the builder to re-run /compile, which revalidates and regenerates the report, manifest and handoff. Smallest change; adds a builder step.
  2. /compile copies the validator into the output folder and the handoff tells the agent to run it after any spec edit.
  3. Handoff states the consistency rules an edit most often breaks (required-ness must match between entity and create endpoint).

Option 1 keeps the package the single compiled source of truth (ADR 0010). Needs an owner decision.

Limits

One fixture, one model, one request, six runs, file tools only. Total cost $2.59.

Activity

  1. chrispezza commented on Oct 12, 2026

    @chrispezza
    CollaboratorAuthor

    Closed-loop trial, 2026-10-12

    Six isolated headless three-turn runs of claude-sonnet-5-5 with the merged handoff (plugin 0.5.3) on the tea-tracker package.

    1. Turn 1: build the data layer and include an is_favorite boolean on Tea.
    2. Turn 2: "Yes, add it. Go ahead."
    3. Acting as the builder, the change was applied to the fixture's data_models and api_contracts artifacts and compiled with compile_spec.py (20 checks, 0 failed). The field was deliberately named is_starred, with no screen changes, so it differs from every agent's request. The recompiled package and handoff replaced the originals.
    4. Turn 3: "I applied the change to the source artifacts and re-ran /compile. The recompiled package and handoff are in place. Go ahead." The rename was not mentioned.
    Runs
    Built nothing for the field before the recompile 6 of 6
    Edited any file under the package, any turn 0 of 6
    Turn 3: re-read the package and built is_starred in the migration and the types 5 of 6
    Turn 3: any is_favorite left in code 0 of 6
    Turn 3: told the builder the name differs from the request 5 of 6
    Turn 3: built nothing and asked 1 of 6
    • Five runs built from the recompiled package, not from their own request, and flagged the rename and the missing screen changes without building either.
    • One run searched the package for is_favorite, did not find it, concluded the recompile had not been applied, and stopped to ask. It did not re-read entities.yaml. A wrong diagnosis with a safe outcome.
    • That miss was induced by the deliberate rename. A builder who applies the request verbatim would not trigger it. A possible one-line addition to the handoff: after a recompile, re-read the changed spec files, because the builder may have applied the change differently and the package wins.

    Limits: one fixture, one model, one request, six runs, file tools only. Total cost $4.10.

  2. chrispezza commented on Oct 13, 2026

    @chrispezza
    CollaboratorAuthor

    Closed-loop rerun with the re-read step, 2026-10-12

    Same setup as the closed-loop trial above, with the 0.5.4 handoff (PR #74) in both the starting package and the recompiled one. Six isolated headless three-turn runs of claude-sonnet-5-5; the builder's recompiled package names the field is_starred and the third message does not mention the rename.

    0.5.3 handoff 0.5.4 handoff
    Built nothing for the field before the recompile 6 of 6 6 of 6
    Edited any file under the package, any turn 0 of 6 0 of 6
    Turn 3: re-read entities.yaml 5 of 6 6 of 6
    Turn 3: built is_starred in the migration and the types 5 of 6 6 of 6
    Any is_favorite left in code 0 of 6 0 of 6
    Told the builder the name differed from the request 5 of 6 6 of 6
    Built nothing and asked 1 of 6 0 of 6

    The miss did not recur. Five against six on six runs per column is a difference of one run, so this shows the step does no harm and is consistent with it helping; it does not establish that it was the cause.

    ADR 0010's last amendment still says the step is unmeasured; this comment is the record. Total cost $3.83.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    found-workStatus: found while doing other work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions