docs(openspec): make every spec pass validate --all --strict - #106
docs(openspec): make every spec pass validate --all --strict#106thecodedrift wants to merge 1 commit into
Conversation
Two specs failed. Fixing them surfaced a third problem that was not failing, which is the worse one. `cli-update-engine` is deleted. It was a tombstone: the capability was decommissioned, every requirement removed, and the file kept "for historical reference". specs/ describes what is true now, and the history is already in the 2026-03-30-remove-scaffold-dependency archive, including that change's own cli-update-engine delta. Nothing outside the archives referenced it. `cli-rules` gets scenarios and SHALL keywords on 15 requirements, and loses the five that specify `taskless rule verify` — a command this stack removed and replaced with the path-addressed `verify` and `test`, now owned by cli-rule-validation. A requirement stating the subcommand is gone replaces them. Two requirements also named pre-layout paths (`.taskless/rule-tests/<id>.yml`, and deleting "rule and test files" rather than the rule directory); both repathed while being touched. The third problem: a second `##` inside a requirements section ends it, so every requirement below stops being read. `cli-rules` hid 10 behind `## API Contract`, `infrastructure` hid 19, and `skills` hid 6. Those last two PASSED --strict throughout, because the single requirement each still exposed was well-formed. 35 requirements were unread while the validator reported success. The groupings are preserved as bold lead-in lines instead, and un-nesting infrastructure immediately exposed a real requirement with no SHALL, now fixed. `skills` also still told agents to fetch recipes via `npx @taskless/cli help <topic>`. 23 specs, 0 failures. Refs #105 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jwc9FFroR3mTZ4hLiSkkX3
There was a problem hiding this comment.
Pull request overview
This PR cleans up OpenSpec capability specs so pnpm openspec validate --all --strict passes across the entire openspec/specs/ tree, removing hidden/invalid requirements and updating spec text to match the current CLI surface.
Changes:
- Remove the decommissioned
cli-update-enginecapability spec that no longer contains requirements. - Fix
cli-rulesstrict-validation failures by adding scenarios/SHALL language, removing obsoletetaskless rule verifyrequirements, and repathing rule/test layout references. - Prevent requirements from being accidentally hidden by nested
##headings ininfrastructureandskills, and updateskillsto referencenpx @taskless/cli agent <topic>.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| openspec/specs/skills/spec.md | Reworks section structure to avoid heading-related parser issues; updates recipe-fetch command to agent. |
| openspec/specs/infrastructure/spec.md | Introduces an explicit ## Requirements section and converts former nested headings into bold lead-ins to keep requirements parseable. |
| openspec/specs/cli-update-engine/spec.md | Deletes the spec content for a removed capability that had zero remaining requirements. |
| openspec/specs/cli-rules/spec.md | Adds scenarios/SHALL wording, removes obsolete rule verify requirements, updates paths, and restructures a section to avoid hidden requirements. |
Suppressed comments (2)
openspec/specs/skills/spec.md:23
- The scenario title still refers to “CLI help”, but the scenario text and the requirement now reference the
agentcommand. Renaming the scenario keeps the spec consistent and easier to search.
#### Scenario: Skill body delegates to CLI help
openspec/specs/cli-rules/spec.md:246
- This PR adds a requirement that
taskless rule verifySHALL NOT exist, but a few lines below the schema requirement’s scenario still references “therule verifycommand”. That makes the spec internally inconsistent; the scenario should describe schema usage without naming a removed command.
### Requirement: The rule subcommand group no longer validates rules
`taskless rule verify` SHALL NOT exist. Rule validation is addressed by path through the top-level `verify` and `test` commands, specified by the `cli-rule-validation` capability.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| The single skill SHALL be defined at `skills/taskless/SKILL.md` with YAML frontmatter (`name`, `description`, `metadata`) followed by markdown instructions. The `name` field SHALL be exactly `taskless` (no per-task prefix). The `metadata` field SHALL include `author`, `version`, and `commandName: tskl` keys. The `version` SHALL be used for staleness detection when the skill is installed into target repositories. | ||
|
|
||
| The skill body SHALL begin by instructing the agent that it does NOT have step-by-step instructions for any Taskless action and that recipes must be fetched via `npx @taskless/cli help <topic>` before proceeding. The body SHALL NOT contain inline step-by-step recipes for any individual task — those live in `packages/cli/src/help/<topic>.txt` files served by the help subcommand. | ||
| The skill body SHALL begin by instructing the agent that it does NOT have step-by-step instructions for any Taskless action and that recipes must be fetched via `npx @taskless/cli agent <topic>` before proceeding. The body SHALL NOT contain inline step-by-step recipes for any individual task — those live in `packages/cli/src/help/<topic>.txt` files served by the help subcommand. |
| ### Requirement: Rules create writes test files to disk | ||
|
|
||
| `taskless rule create` SHALL write generated test files to `.taskless/rule-tests/<id>.yml` regardless of whether `--anonymous` was set. (Renamed; strengthened.) | ||
| `taskless rule create` SHALL write generated test files into the rule's own directory, at `.taskless/rules/sg/<id>/.tests/`, regardless of whether `--anonymous` was set. (Renamed; strengthened; repathed for the rule-directory layout.) | ||
|
|
|
@claude /review |
|
Claude finished @thecodedrift's task in 3m 58s —— View job Review completeVerified structurally sound: I checked heading levels in all three edited spec files ( Findings posted inline — the theme across all of them is that this PR repathed/updated some requirements but left sibling text in the same file inconsistent:
None of these break No correctness/security/performance issues found in the mechanical parts of the diff (the heading restructuring, the |
| ### Requirement: Rules create writes test files to disk | ||
|
|
||
| `taskless rule create` SHALL write generated test files to `.taskless/rule-tests/<id>.yml` regardless of whether `--anonymous` was set. (Renamed; strengthened.) | ||
| `taskless rule create` SHALL write generated test files into the rule's own directory, at `.taskless/rules/sg/<id>/.tests/`, regardless of whether `--anonymous` was set. (Renamed; strengthened; repathed for the rule-directory layout.) |
There was a problem hiding this comment.
Two path inconsistencies introduced/exposed by this repath:
- The sibling requirement above ("Rules create writes rule files to disk", unchanged, ~line 85) still writes the rule file to the flat path
.taskless/rules/<id>.yml, while this requirement now nests test files under.taskless/rules/sg/<id>/.tests/. Per the "Rules delete" requirement below (also repathed by this PR, line 182), the rule file itself is expected to live inside that same.taskless/rules/<engine>/<id>/directory — and the actual implementation (packages/cli/src/rules/files.ts) agrees, writing to.taskless/rules/sg/{kebab-id}/{kebab-id}.yml.createanddeletenow describe two different locations for the rule file. - The anonymous local-only flow further down (line 270,
4. Write any generated test files to \.taskless/rule-tests/.yml`) still uses the old pre-layout path and wasn't updated to match this new.taskless/rules/sg//.tests/` convention.
|
|
||
| ### Requirement: The rule subcommand group no longer validates rules | ||
|
|
||
| `taskless rule verify` SHALL NOT exist. Rule validation is addressed by path through the top-level `verify` and `test` commands, specified by the `cli-rule-validation` capability. |
There was a problem hiding this comment.
This new requirement states taskless rule verify SHALL NOT exist, but two unchanged passages elsewhere in this same file still assume it does:
- The "Generated schema is importable at build time" scenario a few lines below ("Schema imported in verify command") still reads:
**WHEN** the \rule verify` command needs the ast-grep schema`. - "Rule improve supports anonymous local-only flow" (further down) still says the flow supports the feedback loop "by exposing the
rule verifyprimitive that the agent invokes between edits."
Since this PR is specifically about making every requirement internally consistent and strict-clean, these two leftover references to the removed rule verify command are worth fixing in the same pass (the codegen-schema scenario should probably reference verify/test from cli-rule-validation instead, matching the wording used here).
| The single skill SHALL be defined at `skills/taskless/SKILL.md` with YAML frontmatter (`name`, `description`, `metadata`) followed by markdown instructions. The `name` field SHALL be exactly `taskless` (no per-task prefix). The `metadata` field SHALL include `author`, `version`, and `commandName: tskl` keys. The `version` SHALL be used for staleness detection when the skill is installed into target repositories. | ||
|
|
||
| The skill body SHALL begin by instructing the agent that it does NOT have step-by-step instructions for any Taskless action and that recipes must be fetched via `npx @taskless/cli help <topic>` before proceeding. The body SHALL NOT contain inline step-by-step recipes for any individual task — those live in `packages/cli/src/help/<topic>.txt` files served by the help subcommand. | ||
| The skill body SHALL begin by instructing the agent that it does NOT have step-by-step instructions for any Taskless action and that recipes must be fetched via `npx @taskless/cli agent <topic>` before proceeding. The body SHALL NOT contain inline step-by-step recipes for any individual task — those live in `packages/cli/src/help/<topic>.txt` files served by the help subcommand. |
There was a problem hiding this comment.
This now says recipes are fetched via npx @taskless/cli agent <topic> but in the same sentence still claims the recipe files under packages/cli/src/help/<topic>.txt are "served by the help subcommand." Per packages/cli/src/commands/agent.ts, agent is its own top-level command (not a help subcommand) that calls getRecipe from ../prompts/recipes. Worth updating "served by the help subcommand" to reference the agent command so the requirement doesn't contradict itself.
| @@ -23,10 +23,10 @@ The skill body SHALL begin by instructing the agent that it does NOT have step-b | |||
| #### Scenario: Skill body delegates to CLI help | |||
There was a problem hiding this comment.
Minor/nit (already flagged by the Copilot review as a suppressed comment): the scenario title "Skill body delegates to CLI help" and its body ("fetch the canonical recipe via npx @taskless/cli agent <topic>") are now out of sync — the title still says "CLI help" though the command referenced is agent. Low severity since it doesn't affect validate --strict, but worth a rename while this file is already being touched.
Stack (root → tip):
Cleanup on top of the stack so
pnpm openspec validate --all --strictis green and the gate in #105 can be turned on without landing red.Two failures, and a third problem that wasn't failing
cli-update-engine— deleted. A tombstone: capability decommissioned, every requirement removed, file kept "for historical reference".--strictneeds at least one requirement.specs/describes what's true now, and the history is already in the2026-03-30-remove-scaffold-dependencyarchive, including that change's owncli-update-enginedelta. Nothing outside the archives referenced it.cli-rules— 18 errors. Scenarios and SHALL keywords added to 15 requirements. The five specifyingtaskless rule verifyare removed: this stack deleted that command in favour of the path-addressedverifyandtest, now owned bycli-rule-validation. A requirement stating the subcommand is gone replaces them. Two requirements named pre-layout paths (.taskless/rule-tests/<id>.yml, and deleting "rule and test files" rather than the rule directory); both repathed while being touched.The one worth reading. A second
##inside a requirements section ends it, so every requirement below stops being parsed:--strictbeforecli-rulesinfrastructureskillsinfrastructureandskillspassed throughout, because the single requirement each still exposed was well-formed. 35 requirements were unread while the validator reported success. This is the same shape as thecli-helpdefect repaired earlier in the stack, where a lost code fence turned a documentation template into real headings.The topical groupings are kept as bold lead-in lines instead of headings. Un-nesting
infrastructureimmediately exposed a real requirement with no SHALL, now fixed.skillsalso still told agents to fetch recipes vianpx @taskless/cli help <topic>.Result
23 specs, 0 failures, with every requirement actually visible to the parser. 594 tests, lint and typecheck unchanged: this PR touches only
openspec/specs/.Note that
--strictalone would not have caught the hidden-requirement class. Detecting it needs a separate check that every### Requirement:sits under## Requirements— noted on #105 for whoever wires the gate.Refs #105
🤖 Generated with Claude Code
https://claude.ai/code/session_01Jwc9FFroR3mTZ4hLiSkkX3