Summary
The generated /opsx:verify command and the openspec-verify-change skill do not look at which delta operation a requirement comes from. Every ### Requirement: heading in the change's delta specs is treated as behaviour that must exist in the codebase, including the ones under ## REMOVED Requirements. As a result, a removal that was implemented correctly is reported as CRITICAL, and the report recommends re-implementing the removed behaviour.
Version
@fission-ai/openspec 1.13.1, Claude Code delivery (skills + commands), spec-driven schema.
Where
In .claude/commands/opsx/verify.md and the mirrored .claude/skills/openspec-verify-change/SKILL.md:
- Step 5, Spec Coverage: "Extract all requirements (marked with "### Requirement:")" → "Search codebase for keywords related to the requirement" → if not found: CRITICAL "Requirement not found: ", recommendation "Implement requirement X".
- Step 6, Requirement Implementation Mapping / Scenario Coverage: the same loop over every requirement and scenario in the delta specs, with no operation filter.
The verify text never mentions ADDED / MODIFIED / REMOVED / RENAMED.
Repro
- Create a change whose delta spec contains only a REMOVED requirement:
## REMOVED Requirements
### Requirement: Legacy CSV export
**Reason**: superseded by the JSON export
**Migration**: use the JSON export
- Implement it by deleting the CSV export code, and tick the task.
- Run
/opsx:verify <change>.
Expected: the requirement is verified as absent. It passes when no implementation remains, and it is flagged when the behaviour is still present.
Actual: CRITICAL: Requirement not found: Legacy CSV export, with the recommendation "Implement requirement …". An agent that follows the report restores the behaviour the change just removed.
Suggested fix
Classify each requirement by the section it appears under before running the checks:
- ADDED / MODIFIED: the current checks. For MODIFIED, check against the modified text.
- REMOVED: invert the check. It passes when no implementation evidence remains. It is a CRITICAL only if the behaviour is still there. Scenario-coverage checks are skipped, because a removed requirement usually carries Reason/Migration and no scenarios.
- RENAMED: check the new name. The old name being absent is expected.
/opsx:archive and /opsx:sync already handle each operation separately, so verify is the only step in the loop that doesn't.
Summary
The generated
/opsx:verifycommand and theopenspec-verify-changeskill do not look at which delta operation a requirement comes from. Every### Requirement:heading in the change's delta specs is treated as behaviour that must exist in the codebase, including the ones under## REMOVED Requirements. As a result, a removal that was implemented correctly is reported as CRITICAL, and the report recommends re-implementing the removed behaviour.Version
@fission-ai/openspec1.13.1, Claude Code delivery (skills + commands),spec-drivenschema.Where
In
.claude/commands/opsx/verify.mdand the mirrored.claude/skills/openspec-verify-change/SKILL.md:The verify text never mentions ADDED / MODIFIED / REMOVED / RENAMED.
Repro
/opsx:verify <change>.Expected: the requirement is verified as absent. It passes when no implementation remains, and it is flagged when the behaviour is still present.
Actual:
CRITICAL: Requirement not found: Legacy CSV export, with the recommendation "Implement requirement …". An agent that follows the report restores the behaviour the change just removed.Suggested fix
Classify each requirement by the section it appears under before running the checks:
/opsx:archiveand/opsx:syncalready handle each operation separately, so verify is the only step in the loop that doesn't.