Skip to content

Intent assistant validates proposals only with the parser - extend the repair loop through a dry-run generation #6956

Description

@delchev

Problem

The intent assistant validates a proposal with the parser and nothing else: IntentAgentService.validationIssues runs IntentParser.parse and returns. Everything the parser accepts reaches the developer unexamined — including models that generate nothing for an authored requirement, or generate references the generation pass itself would refuse. The repair loop (ProposalRepairLoop) can only ever correct parse errors, so a proposal that "parsed fine, generated wrong" is handed over looking finished.

The generation layer already collects exactly the right issues: IntentGenerationContext.addIssue / getIssues is where reportDroppedGlue, the cross-model resolution failures and the lifecycle warnings land. What is missing is a way to run generation without writing.

Fix

  1. A dryRun mode on the generation pass. A flag on IntentGenerationContext guarding every write/claim surface — writeModelFile, writeModelFileIfAbsent, keepExistingModelFile — plus the stale-output scrub, which lives in IntentGenerationService (the flag must be consulted there too, not only on the context). Reads stay live: cross-model resolution needs the repository.
  2. A dry-run entry point on IntentGenerationService returning the collected issues. Note the current generate(...) signature requires projectRoot / projectName / workspaceName — and AgentRequest is {yaml, message, history}, carrying no project coordinates — so the dry-run entry point needs a synthetic-context shape, not just a flag.
  3. validationIssues runs parse, then the dry run, and concatenates — the repair loop then sees the generation-layer issues too.
  4. Wire the Builder shell's gate. The Builder's client-side re-validation of an agent proposal calls POST /services/ide/intent/parse — parse-only, the same blind spot. It should consume the extended check (a dry-run parameter on the parse endpoint, or a dedicated endpoint), so its auto-apply gate stops accepting generation-invalid models.
  5. Raise MAX_REPAIR_ROUNDS from 2 to 4 — one constant, worthless alone, sensible once the validator can see more than a parse error. Land it after the upstream call is streamed (Intent AI client: stream the upstream call, send adaptive thinking, raise the max-tokens default #6955): each repair round is a full re-emission of the document, and more rounds before streaming only multiplies exposure to the 120-second wall.

The load-bearing risk — review this hardest

The agent has no repository context for the proposed YAML (see the AgentRequest shape above). Cross-model references (uses: aliases) resolve against the owner's .model in the repository; with no project context they fall back to conventions and would report false "unresolvable reference" issues. A false positive is worse than no check: it burns one of the few repair rounds correcting something that is not wrong, and teaches the model to "fix" correct YAML. Cross-model resolution issues must therefore be filtered out of the dry-run result for the agent path (the Builder path, which knows the project, can keep them). That filter is the part to get right.

Acceptance

  • A proposal that parses but whose generation would drop glue / fail a cross-model-independent check comes back to the repair loop with those issues, and the repaired proposal reaches the developer.
  • A dry run writes nothing and scrubs nothing (assert the workspace is byte-identical before/after).
  • A valid multi-model intent proposed with no project context produces zero cross-model false positives.
  • IntentAgentServiceTest gains the parse-ok-generation-fails path against a scripted upstream.

Complements #6953 (which moves the map-key class of defect all the way forward to parse time); this issue catches the band the parser legitimately cannot see.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions