Skip to content

feat(work-driver): resolve intent from any spec — ground it against code and world, then proceed, assume, or park #378

Description

@randomm

Context

/work currently assumes an issue tells it what to build. Real backlogs do not honour that: issues are hand-written, terse, imported from other projects, or simply wrong. Measured externally, 38.3% of real GitHub issues are underspecified (SWE-bench Verified, 93 annotators over 1,699 samples), and 41.77% of multi-agent failures are specification and system design (MAST) — the largest single failure category.

Today the driver has no comprehension step. It fetches the body, inlines it into an explore prompt, and routes on a single VERDICT: token. Two structural problems:

  1. A missing verdict means "build it". work-driver-plan.ts:148 defaults an absent verdict to NEEDS_WORK. Silence is treated as permission.
  2. Nothing checks whether the issue is TRUE. No step asks whether the named symbols exist, whether the described behaviour matches the code, whether the work is already done, or whether the premise is sound. A confidently-wrong bug report gets built.

The intelligence to dissect a spec belongs on the /work side — /plan should keep producing the best spec it can, and /work must cope with whatever it is handed.

What to build

A. Normalised spec. A new step between explore and plan produces one internal artifact from ANY issue body:

{ intent, deliverables[{id, description, paths[]}], acceptanceCriteria[],
  outOfScope[], assumptions[{text, basis, confidence}], openQuestions[],
  confidence, evidence[{claim, source, verdict}] }

Persisted to .pi/work-state/<issue>/spec.json. Downstream steps read the artifact rather than re-deriving from prose. Grouping markers, where present, are consumed as high-confidence hints — never required.

B. Grounding, against the code AND the world. The intent is only useful if it is true:

  • code: do the named symbols/files exist? is it already implemented? is there an open PR? does the described behaviour match reality?
  • world: does a referenced third-party API exist with that shape?
    Each check lands in evidence[] with its source. A contradiction between the issue and the code is the highest-value signal this step can produce.

C. Three-way verdict.

Verdict When Action
proceed intent clear, grounded, deliverables derivable continue
proceed-with-assumptions gaps exist but each has a defensible default continue; every assumption recorded in the PR body
park unresolvable, contradicted, already done, too large, premise unsound write no code; post diagnosis; label; continue the queue

Park reasons are machine-readable: underspecified, contradicted-by-code, already-implemented, too-large, premise-unsound. A missing verdict parks — inverting today's default.

D. Read-only resolver. The resolving agent gets no edit tools. Per "Ask or Assume?" (69.4% on an underspecified SWE-bench variant), an agent that can build rationalises ambiguity away, because building is cheaper than asking.

E. Decomposition counted from the artifact. countEnumeratedFindings currently counts top-level - [ ], which in a /plan issue is exclusively ## Acceptance criteria. Measured: #287→7, #288→6, #289→7, #366→6 — every count is test assertions, and zero of #287's five real deliverables (**A.****E.**) are seen. So a correctly-planned single-workstream issue essentially always triggers a wasteful corrective re-dispatch. Count deliverables[] instead.

Acceptance criteria

  • A one-line hand-written bug report ("login is broken on mobile") produces either a grounded intent or a park with reason underspecified — never a guess turned into code
  • An issue whose central claim is contradicted by the code parks with contradicted-by-code and cites the contradicting evidence
  • An already-implemented issue parks with already-implemented
  • A well-formed /plan issue resolves to proceed and its deliverables are derived
  • park produces zero code-writing dispatches
  • A missing or unparseable verdict parks; it never proceeds
  • proceed-with-assumptions records each assumption where PR review will see it
  • Decomposition is checked against deliverables[]: feat(work-driver): repoRoot is never a dev tree — always-worktree branch mechanization + integration at repoRoot only #287 yields ~5 deliverables (not 7 criteria); fix(agents.json): ops grants blanket oo gh api* while gating the safe single-purpose commands #341 yields ~1 and does NOT trigger a corrective re-dispatch
  • Clarifying questions are budgeted (≤3) and only asked when the answer changes the outcome
  • Escape hatch restores pre-change behaviour
  • bun run build + cd extension && bunx tsc --noEmit && bun run check + all offline smoke tests pass

Technical context

  • extension/src/work-driver-explore.ts:195-240 — the current single-token verdict router
  • extension/src/work-driver-plan.ts:148 — where a missing verdict becomes NEEDS_WORK
  • extension/src/work-driver-plan.tscountEnumeratedFindings, planQualityReason
  • extension/src/workflow-state-schema.ts — additive pipelineState field
  • extension/src/work-queue.ts:108humanActionFor, for park reasons

Out of scope

  • Any change to /plan — it keeps producing the best spec it can
  • GitHub Issue Forms — would impose the format constraint this removes
  • Merge authority, resume, notification, memory — separate waves

This work must ship as its own separate PR, independent of any other open issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions