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-28 — detectCompletedArtifacts 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-527 — isPlanningComplete (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:
- Keep
isPlanningComplete meaning exactly what it means today (all non-skipped planning artifacts exist). Don't overload it.
- 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.
- 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.
- 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.
Summary
OpenSpec tracks two very different notions of "done" for a change, but only one of them is actually measured:
tasks.mdcheckboxes.openspec statusnow cleanly separates these two ideas at the field level (isPlanningCompletevs. 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.mdcheckboxes are parsed and counted by a shared parser, solist,view,archive, andinstructions applyall agree on how much is built.src/utils/task-progress.ts(shared checkbox parser)list/viewshow 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-28—detectCompletedArtifactsadds an artifact id to thecompletedset purely viafs.existsSync.src/core/artifact-graph/instruction-loader.ts:486-492— artifactstatus: 'done'when its id is incompleted.src/core/artifact-graph/instruction-loader.ts:517,526-527—isPlanningComplete(and its compat aliasisComplete) = "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 validatealready checks structural correctness of proposals/specs/deltas, but nothing connects a passing validation to the planning-complete signal. A change can report planning-complete whilevalidatewould fail — or while an artifact is a one-line stub.The gap
isPlanningCompleteanswers "do the planning files exist?" — not "is the plan ready to implement?" Consequences:proposal.md/design.mdflipsisPlanningCompletetotrueexactly like a substantive one.status) can reasonably treat planning-complete as "ready to build" and hand off prematurely.tasks.md), planning readiness is presence-based (file exists).The recent field split (
isPlanningCompletevs.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:
isPlanningCompletemeaning exactly what it means today (all non-skipped planning artifacts exist). Don't overload it.isPlanningReady— that is true only when planning artifacts exist andopenspec validatepasses for the change. This reuses the validator we already ship rather than inventing a second notion of correctness.statustext andstatus --json, and update the workflow/skill guidance so the handoff from planning → implementation keys off readiness, not mere existence.design.md.This mirrors the implementation side:
tasks.mdgives implementation a content-based gate;validate(± a content check) would give planning a content-based gate.Open design questions (need a maintainer decision)
openspec validatesufficient, or is a separate quality/completeness bar needed for freeform artifacts (proposal.md,design.md) that the validator only lightly constrains?isPlanningReadyalongsideisPlanningComplete, or redefine planning-complete to already imply validity? (Backward-compatibility:isCompleteis a documented alias many scripts/agents read — seedocs/agent-contract.md.)status) or enforced (e.g.instructions apply/ handoff refuses until ready)? Enforcement risks deadlocking agents on schemas whose artifacts validate loosely.spec-drivenartifact names — it has to be computed from the active schema's declared artifacts so custom schemas keep working.skip_specs-style skipped artifacts as satisfied, consistent with howisPlanningCompletealready handles them.Scope / non-goals
tasks.md) — that already works.validatestricter here; only to (optionally) consume it as a readiness input.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.