Skip to content

spec-driven fast-path workflow silently produces stale specs with no recovery path #1212

@srininara

Description

@srininara

Using opsx:propose (or opsx:ff) with the spec-driven schema produces a change that
is fully implemented, tested, and archived — but leaves openspec/specs/ permanently
out of date. No warning is raised at any point in the workflow. By the time the problem
is discoverable, the only recovery option is writing the spec by hand.

How to reproduce

  1. Start a new change using opsx:propose or opsx:ff in a spec-driven project.
  2. Let the skill complete — it creates proposal.md, design.md, and tasks.md.
  3. Implement via opsx:apply.
  4. Archive via opsx:archive.
  5. Check openspec/specs/ — it has not been updated.

Throughout all four steps, every skill reports success.

What's happening

Both opsx:propose and opsx:ff loop through artifacts and stop when all applyRequires
artifacts are done. For the spec-driven schema, applyRequires does not include delta
specs. So neither skill ever creates a specs/ subfolder in the change directory, no
matter how significant the change.

When opsx:archive runs, it checks for delta specs in the change folder (Step 4), finds
none, outputs "No delta specs", and archives cleanly. This is technically correct
behaviour given its inputs — but those inputs are wrong to begin with.

The step-by-step path (opsx:new + opsx:continue) does not have this problem because
it walks every artifact in the schema sequence rather than stopping at applyRequires.
The two paths are not equivalent for spec-driven projects, but nothing in the tooling
communicates this.

Why nothing catches it

This is the part that compounds the problem. Even if the root cause above is accepted as
a schema design gap rather than a bug, there are two places in the workflow where the
tooling could intervene and neither does:

opsx:apply is the right place to catch this. Before any implementation work begins,
the skill could check whether the change is spec-driven and whether a specs/ subfolder
exists. If not, it should stop and direct the user to write the delta spec first — at
which point the fix is easy, context is fresh, and no code has been written yet.

opsx:archive is the last line of defence. Rather than silently noting "No delta
specs" and proceeding, it should fail hard for a spec-driven change in this state and
require explicit acknowledgement of the consequences.

Currently neither check exists, which means the gap is only discoverable through a manual
audit of openspec/specs/ after the fact.

Impact

Any team using opsx:proposeopsx:applyopsx:archive as their standard workflow
will silently accumulate spec debt with each archived change. Once a change is archived
without delta specs, there is no supported recovery path — opsx:sync requires an active
change with an existing delta spec, neither of which exists. The user is left writing the
spec retroactively from a finished implementation.

Suggested fix

Primary: Add delta spec creation to applyRequires in the spec-driven schema. A
fast path that skips writing specs is not a valid fast path for a spec-driven workflow.

Safeguard: opsx:apply should block at startup if the change is spec-driven and
no delta specs exist, with a clear message directing the user to opsx:continue first.
opsx:archive should fail hard rather than silently proceed in the same condition.

The primary fix removes the gap. The safeguard catches it if it ever reappears.

Versions

  • openspec-propose: generatedBy: "1.3.0" (same behaviour confirmed in 1.2.0)
  • openspec-ff-change: generatedBy: "1.3.0"
  • openspec-apply-change: generatedBy: "1.3.0"
  • openspec-archive-change: generatedBy: "1.3.0"
  • Schema: spec-driven

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions