What
No workflow runs openspec validate. Add one so a spec that fails --strict can't reach main.
What exists today
There are two OpenSpec workflows, and neither validates spec content:
pr-check-openspec.yml: the archive gate. Checks that a change directory got archived, on the tip PR of a stack only.
openspec-rot.yml: a daily sweep of main for unarchived change debris.
Both are about change lifecycle. Nothing checks that the specs in openspec/specs/ are well-formed.
Why it matters
Because nothing enforces it, spec rot accumulates silently and only gets found by hand. Three examples turned up recently, all pre-existing on main:
openspec/specs/cli-help/spec.md carried an orphaned duplicate of a requirement that had lost both its ### Requirement: header and its opening code fence. A documentation template parsed as real ## Goal / ## Preconditions headings, which ended the Requirements section and hid every requirement below it from the parser. We only found it because it made an unrelated openspec archive fail.
openspec/specs/cli-rules/spec.md fails --strict with roughly 18 errors: requirements with no #### Scenario: block, and requirements whose text contains neither SHALL nor MUST.
openspec/specs/cli-update-engine/spec.md fails because it has zero requirements. It's a tombstone for a decommissioned capability, retained "for historical reference".
Suggested shape
A job running pnpm openspec validate --all --strict on pull requests and on pushes to main.
It has to be repo-wide (--all). The failures above live in specs that a given PR doesn't touch, so a changed-files-only check would never have surfaced them.
Blocked until the specs are clean
Turning the gate on while cli-rules and cli-update-engine fail would make it red from day one, which is how a check gets ignored. A cleanup PR addressing both is in flight on top of the current stack. Land that first, then add the gate.
What
No workflow runs
openspec validate. Add one so a spec that fails--strictcan't reachmain.What exists today
There are two OpenSpec workflows, and neither validates spec content:
pr-check-openspec.yml: the archive gate. Checks that a change directory got archived, on the tip PR of a stack only.openspec-rot.yml: a daily sweep ofmainfor unarchived change debris.Both are about change lifecycle. Nothing checks that the specs in
openspec/specs/are well-formed.Why it matters
Because nothing enforces it, spec rot accumulates silently and only gets found by hand. Three examples turned up recently, all pre-existing on
main:openspec/specs/cli-help/spec.mdcarried an orphaned duplicate of a requirement that had lost both its### Requirement:header and its opening code fence. A documentation template parsed as real## Goal/## Preconditionsheadings, which ended the Requirements section and hid every requirement below it from the parser. We only found it because it made an unrelatedopenspec archivefail.openspec/specs/cli-rules/spec.mdfails--strictwith roughly 18 errors: requirements with no#### Scenario:block, and requirements whose text contains neither SHALL nor MUST.openspec/specs/cli-update-engine/spec.mdfails because it has zero requirements. It's a tombstone for a decommissioned capability, retained "for historical reference".Suggested shape
A job running
pnpm openspec validate --all --stricton pull requests and on pushes tomain.It has to be repo-wide (
--all). The failures above live in specs that a given PR doesn't touch, so a changed-files-only check would never have surfaced them.Blocked until the specs are clean
Turning the gate on while
cli-rulesandcli-update-enginefail would make it red from day one, which is how a check gets ignored. A cleanup PR addressing both is in flight on top of the current stack. Land that first, then add the gate.