Skip to content

Proposal: measure planning readiness, not just planning-artifact existence #1519

Description

@clay-good

Summary

OpenSpec tracks two very different notions of "done" for a change, but only one of them is actually measured:

  • Implementation complete — is the work built? Measured concretely from tasks.md checkboxes.
  • Planning complete / ready to implement — is the plan good enough to start building? Currently inferred only from file existence.

openspec status now cleanly separates these two ideas at the field level (isPlanningComplete vs. implementation progress). What it does not yet do is measure planning readiness with the same rigor it measures implementation. This issue captures the gap and a proposed happy path. Because "what makes a plan ready" is a product/architecture decision, this needs a maintainer design call before implementation.

Current behavior (grounded in main)

Implementation completion — measured by content.
tasks.md checkboxes are parsed and counted by a shared parser, so list, view, archive, and instructions apply all agree on how much is built.

  • src/utils/task-progress.ts (shared checkbox parser)
  • Archive gates on incomplete tasks; list/view show real progress.

Planning completion — inferred from file existence only.
An artifact is "completed" if its output file exists — nothing about the file's content is checked.

  • src/core/artifact-graph/state.ts:7-28detectCompletedArtifacts adds an artifact id to the completed set purely via fs.existsSync.
  • src/core/artifact-graph/instruction-loader.ts:486-492 — artifact status: 'done' when its id is in completed.
  • src/core/artifact-graph/instruction-loader.ts:517,526-527isPlanningComplete (and its compat alias isComplete) = "every non-skipped planning artifact exists."
  • src/commands/workflow/status.ts — prints "All planning artifacts complete!" off that boolean.

Validation exists, but is not wired into readiness.
openspec validate already checks structural correctness of proposals/specs/deltas, but nothing connects a passing validation to the planning-complete signal. A change can report planning-complete while validate would fail — or while an artifact is a one-line stub.

The gap

isPlanningComplete answers "do the planning files exist?" — not "is the plan ready to implement?" Consequences:

  • An empty or stub proposal.md / design.md flips isPlanningComplete to true exactly like a substantive one.
  • An agent (or a human reading status) can reasonably treat planning-complete as "ready to build" and hand off prematurely.
  • The two halves of the lifecycle are measured with different rigor: implementation readiness is content-based (tasks.md), planning readiness is presence-based (file exists).

The recent field split (isPlanningComplete vs. isComplete) is honest about what it measures today — the docs say "artifacts exist," not "plan is ready." This issue is about closing the remaining gap so the planning side gets a content-based readiness signal comparable to the implementation side.

Proposed happy path (for discussion)

Introduce an explicit planning readiness signal distinct from planning artifacts exist, and surface both:

  1. Keep isPlanningComplete meaning exactly what it means today (all non-skipped planning artifacts exist). Don't overload it.
  2. Add a readiness signal — e.g. isPlanningReady — that is true only when planning artifacts exist and openspec validate passes for the change. This reuses the validator we already ship rather than inventing a second notion of correctness.
  3. Surface it in status text and status --json, and update the workflow/skill guidance so the handoff from planning → implementation keys off readiness, not mere existence.
  4. Optionally, a light content-sanity check for stub artifacts (non-trivial length / required sections present) if validation alone proves too weak a gate for freeform artifacts like design.md.

This mirrors the implementation side: tasks.md gives implementation a content-based gate; validate (± a content check) would give planning a content-based gate.

Open design questions (need a maintainer decision)

  • What does "ready" mean? Is passing openspec validate sufficient, or is a separate quality/completeness bar needed for freeform artifacts (proposal.md, design.md) that the validator only lightly constrains?
  • New field vs. redefinition. Add isPlanningReady alongside isPlanningComplete, or redefine planning-complete to already imply validity? (Backward-compatibility: isComplete is a documented alias many scripts/agents read — see docs/agent-contract.md.)
  • How strict at the gate? Should readiness be advisory (surfaced in status) or enforced (e.g. instructions apply / handoff refuses until ready)? Enforcement risks deadlocking agents on schemas whose artifacts validate loosely.
  • Custom schemas. Readiness must not hardcode spec-driven artifact names — it has to be computed from the active schema's declared artifacts so custom schemas keep working.
  • Skipped artifacts. Readiness should treat skip_specs-style skipped artifacts as satisfied, consistent with how isPlanningComplete already handles them.

Scope / non-goals

  • Not proposing to change implementation tracking (tasks.md) — that already works.
  • Not proposing to make validate stricter here; only to (optionally) consume it as a readiness input.
  • No user-facing default behavior should change until the design questions above are settled.

Why file this now

The concepts are stable and the code is easy to point at, but the answer is a core product-design decision about what "a plan is ready" means in OpenSpec. Filing as a proposal so the design can be settled deliberately before any implementation.

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