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
- Start a new change using
opsx:propose or opsx:ff in a spec-driven project.
- Let the skill complete — it creates
proposal.md, design.md, and tasks.md.
- Implement via
opsx:apply.
- Archive via
opsx:archive.
- 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:propose → opsx:apply → opsx: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
Using
opsx:propose(oropsx:ff) with thespec-drivenschema produces a change thatis fully implemented, tested, and archived — but leaves
openspec/specs/permanentlyout 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
opsx:proposeoropsx:ffin aspec-drivenproject.proposal.md,design.md, andtasks.md.opsx:apply.opsx:archive.openspec/specs/— it has not been updated.Throughout all four steps, every skill reports success.
What's happening
Both
opsx:proposeandopsx:ffloop through artifacts and stop when allapplyRequiresartifacts are done. For the
spec-drivenschema,applyRequiresdoes not include deltaspecs. So neither skill ever creates a
specs/subfolder in the change directory, nomatter how significant the change.
When
opsx:archiveruns, it checks for delta specs in the change folder (Step 4), findsnone, 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 becauseit walks every artifact in the schema sequence rather than stopping at
applyRequires.The two paths are not equivalent for
spec-drivenprojects, but nothing in the toolingcommunicates 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:applyis the right place to catch this. Before any implementation work begins,the skill could check whether the change is
spec-drivenand whether aspecs/subfolderexists. 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:archiveis the last line of defence. Rather than silently noting "No deltaspecs" and proceeding, it should fail hard for a
spec-drivenchange in this state andrequire 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:propose→opsx:apply→opsx:archiveas their standard workflowwill silently accumulate spec debt with each archived change. Once a change is archived
without delta specs, there is no supported recovery path —
opsx:syncrequires an activechange 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
applyRequiresin thespec-drivenschema. Afast path that skips writing specs is not a valid fast path for a spec-driven workflow.
Safeguard:
opsx:applyshould block at startup if the change isspec-drivenandno delta specs exist, with a clear message directing the user to
opsx:continuefirst.opsx:archiveshould 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 in1.2.0)openspec-ff-change:generatedBy: "1.3.0"openspec-apply-change:generatedBy: "1.3.0"openspec-archive-change:generatedBy: "1.3.0"spec-driven