Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/remove-legacy-noun-command-groups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@fission-ai/openspec": major
---

### Breaking Changes

- Removed the deprecated `openspec change ...` and `openspec spec ...` command groups. Use the canonical verb-first commands instead: `openspec show <item> --type change|spec`, `openspec list --changes|--specs`, and `openspec validate <item> --type change|spec`.
2 changes: 1 addition & 1 deletion docs/agent-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,4 @@ Recorded by the capstone audit; published-key renames are product decisions defe
5. `list --json` reuses the `status` key as a string enum per change.
6. Only `validate` output carries a `version` field.
7. `schemas`/`templates` ignore root selection (cwd-based, no `--store`).
8. Deprecated noun forms (`change`/`spec` subcommands) emit unenveloped payloads without `root`/`status`.
8. Deprecated noun-form `change`/`spec` command groups are removed; the root-aware verb-first `list`, `show`, and `validate` shapes above are the supported CLI contracts.
7 changes: 4 additions & 3 deletions docs/stores-beta/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,10 @@ tells you which case you're in.
`openspec/config.yaml` declares `store: <id>` is treated as externalized
planning, not as a store checkout to register. Remove the `store:` line first
if you intentionally want to convert that repo into a local store root.
- **Some commands stay where they are.** `view`, `templates`, `schemas`,
and the deprecated noun forms (`openspec change show`, ...) act on the
current directory only — no `--store`.
- **Some commands stay where they are.** `view`, `templates`, and `schemas`
act on the current directory only — no `--store`. The deprecated noun-form
Comment on lines +430 to +431

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Document view --store support.

view supports --store <id>. These lines state the inverse. List only templates and schemas as current-directory-only commands.

Proposed fix
- **Some commands stay where they are.** `view`, `templates`, and `schemas`
+ **Some commands stay where they are.** `templates` and `schemas`
  act on the current directory only — no `--store`.

Based on learnings: openspec view supports --store <id> and must remain store-capable.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **Some commands stay where they are.** `view`, `templates`, and `schemas`
act on the current directory only — no `--store`. The deprecated noun-form
- **Some commands stay where they are.** `templates` and `schemas`
act on the current directory only — no `--store`. The deprecated noun-form
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/stores-beta/user-guide.md` around lines 430 - 431, Update the
command-scope statement in the user guide to keep view listed as supporting
--store <id>; identify only templates and schemas as current-directory-only
commands, while preserving the surrounding deprecated noun-form documentation.

Source: Learnings

command groups (`openspec change ...` and `openspec spec ...`) are removed;
use the root-aware verb-first commands instead.
- **Per-machine state is per-machine.** The store registry and worksets
are local settings. Nothing about your machine's layout is
ever committed to shared planning.
Expand Down
101 changes: 20 additions & 81 deletions openspec/specs/cli-change/spec.md
Original file line number Diff line number Diff line change
@@ -1,92 +1,31 @@
# cli-change Specification

## Purpose
Define `openspec change` command behavior for showing, listing, and validating change proposals and deltas.
Document the removal of the deprecated noun-form `openspec change ...` command group and the canonical verb-first replacements.

## Requirements
### Requirement: Change Command
### Requirement: Deprecated change command group is removed
The CLI SHALL NOT register a top-level `change` command group.

The system SHALL provide a `change` command with subcommands for displaying, listing, and validating change proposals.
#### Scenario: Removed change command is unavailable
- **WHEN** executing `openspec change ...`
- **THEN** the command SHALL fail without running a change command action or emitting the former deprecation warning
- **AND** users SHALL use `openspec show`, `openspec list`, or `openspec validate` instead

#### Scenario: Show change as JSON
### Requirement: Canonical change operations remain available
The CLI SHALL provide change operations through the canonical verb-first commands.

- **WHEN** executing `openspec change show update-error --json`
- **THEN** parse the markdown change file
- **AND** extract change structure and deltas
- **AND** output valid JSON to stdout
#### Scenario: Show a change
- **WHEN** executing `openspec show <change-id> --type change`
- **THEN** display the change using the existing top-level show behavior

#### Scenario: List all changes
#### Scenario: List changes
- **WHEN** executing `openspec list` or `openspec list --changes`
- **THEN** display active changes using the existing list behavior

- **WHEN** executing `openspec change list`
- **THEN** scan the openspec/changes directory
- **AND** return list of all pending changes
- **AND** support JSON output with `--json` flag

#### Scenario: Show only requirement changes

- **WHEN** executing `openspec change show update-error --requirements-only`
- **THEN** display only the requirement changes (ADDED/MODIFIED/REMOVED/RENAMED)
- **AND** exclude why and what changes sections

#### Scenario: Validate change structure

- **WHEN** executing `openspec change validate update-error`
- **THEN** parse the change file
- **AND** validate against Zod schema
- **AND** ensure deltas are well-formed

### Requirement: Legacy Compatibility

The system SHALL maintain backward compatibility with the existing `list` command while showing deprecation notices.

#### Scenario: Legacy list command

- **WHEN** executing `openspec list`
- **THEN** display current list of changes (existing behavior)
- **AND** show deprecation notice: "Note: 'openspec list' is deprecated. Use 'openspec change list' instead."

#### Scenario: Legacy list with --all flag

- **WHEN** executing `openspec list --all`
- **THEN** display all changes (existing behavior)
- **AND** show same deprecation notice

### Requirement: Interactive show selection

The change show command SHALL support interactive selection when no change name is provided.

#### Scenario: Interactive change selection for show

- **WHEN** executing `openspec change show` without arguments
- **THEN** display an interactive list of available changes
- **AND** allow the user to select a change to show
- **AND** display the selected change content
- **AND** maintain all existing show options (--json, --deltas-only)

#### Scenario: Non-interactive fallback keeps current behavior

- **GIVEN** stdin is not a TTY or `--no-interactive` is provided or environment variable `OPEN_SPEC_INTERACTIVE=0`
- **WHEN** executing `openspec change show` without a change name
- **THEN** do not prompt interactively
- **AND** print the existing hint including available change IDs
- **AND** set `process.exitCode = 1`

### Requirement: Interactive validation selection

The change validate command SHALL support interactive selection when no change name is provided.

#### Scenario: Interactive change selection for validation

- **WHEN** executing `openspec change validate` without arguments
- **THEN** display an interactive list of available changes
- **AND** allow the user to select a change to validate
- **AND** validate the selected change

#### Scenario: Non-interactive fallback keeps current behavior

- **GIVEN** stdin is not a TTY or `--no-interactive` is provided or environment variable `OPEN_SPEC_INTERACTIVE=0`
- **WHEN** executing `openspec change validate` without a change name
- **THEN** do not prompt interactively
- **AND** print the existing hint including available change IDs
- **AND** set `process.exitCode = 1`
#### Scenario: Validate a change
- **WHEN** executing `openspec validate <change-id> --type change`
- **THEN** validate the change using the existing top-level validate behavior

### Requirement: Change data is preserved
Removing the command group SHALL NOT delete or migrate change directories, proposals, delta specs, tasks, or archived changes.
4 changes: 2 additions & 2 deletions openspec/specs/cli-show/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The CLI SHALL provide a top-level `show` command for displaying changes and spec
- **GIVEN** stdin is not a TTY or `--no-interactive` is provided or environment variable `OPEN_SPEC_INTERACTIVE=0`
- **WHEN** executing `openspec show` without arguments
- **THEN** do not prompt
- **AND** print a helpful hint with examples for `openspec show <item>` or `openspec change/spec show`
- **AND** print a helpful hint with examples for `openspec show <item>` and `--type change|spec`
- **AND** exit with code 1

#### Scenario: Direct item display
Expand All @@ -34,7 +34,7 @@ The CLI SHALL provide a top-level `show` command for displaying changes and spec

- **WHEN** executing `openspec show <item-name>`
- **THEN** if `<item-name>` uniquely matches a change or a spec, show that item
- **AND** if it matches both, print an ambiguity error and suggest `--type change|spec` or using `openspec change show`/`openspec spec show`
- **AND** if it matches both, print an ambiguity error and suggest `--type change|spec`
- **AND** if it matches neither, print not-found with nearest-match suggestions

#### Scenario: Explicit type override
Expand Down
102 changes: 29 additions & 73 deletions openspec/specs/cli-spec/spec.md
Original file line number Diff line number Diff line change
@@ -1,88 +1,44 @@
# cli-spec Specification

## Purpose
Define `openspec spec` command behavior for listing, showing, and validating source-of-truth specifications.
Document the canonical verb-first commands for showing, listing, and validating source-of-truth specifications.

## Requirements
### Requirement: Interactive spec show
### Requirement: Canonical spec show
The CLI SHALL show specifications through the top-level `show` command.

The spec show command SHALL support interactive selection when no spec-id is provided.
#### Scenario: Interactive spec show
- **WHEN** executing `openspec show` without an item in an interactive terminal
- **THEN** allow selection of a spec and display its content

#### Scenario: Interactive spec selection for show
#### Scenario: Direct spec show
- **WHEN** executing `openspec show <spec-id> --type spec`
- **THEN** parse and display the specification
- **AND** preserve `--json`, `--requirements`, `--no-scenarios`, and `-r/--requirement`

- **WHEN** executing `openspec spec show` without arguments
- **THEN** display an interactive list of available specs
- **AND** allow the user to select a spec to show
- **AND** display the selected spec content
- **AND** maintain all existing show options (--json, --requirements, --no-scenarios, -r)

#### Scenario: Non-interactive fallback keeps current behavior

- **GIVEN** stdin is not a TTY or `--no-interactive` is provided or environment variable `OPEN_SPEC_INTERACTIVE=0`
- **WHEN** executing `openspec spec show` without a spec-id
- **THEN** do not prompt interactively
- **AND** print the existing error message for missing spec-id
- **AND** set non-zero exit code

### Requirement: Spec Command

The system SHALL provide a `spec` command with subcommands for displaying, listing, and validating specifications.

#### Scenario: Show spec as JSON

- **WHEN** executing `openspec spec show init --json`
- **THEN** parse the markdown spec file
- **AND** extract headings and content hierarchically
- **AND** output valid JSON to stdout
### Requirement: Canonical spec list
The CLI SHALL list specifications through `openspec list --specs`.

#### Scenario: List all specs
- **WHEN** executing `openspec list --specs`
- **THEN** scan `openspec/specs/`
- **AND** report available capabilities and requirement counts using the existing list behavior

- **WHEN** executing `openspec spec list`
- **THEN** scan the openspec/specs directory
- **AND** return list of all available capabilities
- **AND** support JSON output with `--json` flag

#### Scenario: Filter spec content

- **WHEN** executing `openspec spec show init --requirements`
- **THEN** display only requirement names and SHALL statements
- **AND** exclude scenario content

#### Scenario: Validate spec structure

- **WHEN** executing `openspec spec validate init`
- **THEN** parse the spec file
- **AND** validate against Zod schema
- **AND** report any structural issues

### Requirement: JSON Schema Definition

The system SHALL define Zod schemas that accurately represent the spec structure for runtime validation.

#### Scenario: Schema validation

- **WHEN** parsing a spec into JSON
- **THEN** validate the structure using Zod schemas
- **AND** ensure all required fields are present
- **AND** provide clear error messages for validation failures

### Requirement: Interactive spec validation

The spec validate command SHALL support interactive selection when no spec-id is provided.

#### Scenario: Interactive spec selection for validation
### Requirement: Canonical spec validation
The CLI SHALL validate specifications through the top-level `validate` command.

- **WHEN** executing `openspec spec validate` without arguments
- **THEN** display an interactive list of available specs
- **AND** allow the user to select a spec to validate
- **AND** validate the selected spec
- **AND** maintain all existing validation options (--strict, --json)
#### Scenario: Validate a spec
- **WHEN** executing `openspec validate <spec-id> --type spec`
- **THEN** validate the specification using the existing top-level validate behavior
- **AND** preserve `--strict` and `--json`

#### Scenario: Non-interactive fallback keeps current behavior
### Requirement: Removed spec command group
The CLI SHALL NOT register a top-level `spec` command group.

- **GIVEN** stdin is not a TTY or `--no-interactive` is provided or environment variable `OPEN_SPEC_INTERACTIVE=0`
- **WHEN** executing `openspec spec validate` without a spec-id
- **THEN** do not prompt interactively
- **AND** print the existing error message for missing spec-id
- **AND** set non-zero exit code
#### Scenario: Removed spec command is unavailable
- **WHEN** executing `openspec spec ...`
- **THEN** the command SHALL fail without running a spec command action or emitting the former deprecation warning
- **AND** users SHALL use the canonical verb-first commands above

### Requirement: Spec data is preserved
Removing the command group SHALL NOT delete or migrate files under `openspec/specs/`.
6 changes: 3 additions & 3 deletions openspec/specs/cli-validate/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Validation output SHALL include specific guidance to fix each error, including e
- Explain that change specs must include `## ADDED Requirements`, `## MODIFIED Requirements`, `## REMOVED Requirements`, or `## RENAMED Requirements`
- Remind authors that files must live under `openspec/changes/{id}/specs/<capability-path>/spec.md`
- Include an explicit note: "Spec delta files cannot start with titles before the operation headers"
- Suggest running `openspec change show {id} --json --deltas-only` for debugging
- Suggest running `openspec show {id} --type change --json --deltas-only` for debugging

#### Scenario: Missing required sections
- **WHEN** a required section is missing
Expand Down Expand Up @@ -88,7 +88,7 @@ The CLI SHALL append a Next steps footer when the item is invalid and not using

#### Scenario: Change invalid summary
- **WHEN** a change validation fails
- **THEN** print "Next steps" with 2-3 targeted bullets and suggest `openspec change show <id> --json --deltas-only`
- **THEN** print "Next steps" with 2-3 targeted bullets and suggest `openspec show <id> --type change --json --deltas-only`

### Requirement: Change validation SHALL report scenarios a MODIFIED block would drop

Expand Down Expand Up @@ -235,7 +235,7 @@ The validate command SHALL handle ambiguous names and explicit type overrides to
- **GIVEN** `<item-name>` exists both as a change and as a spec
- **WHEN** executing `openspec validate <item-name>`
- **THEN** print an ambiguity error explaining both matches
- **AND** suggest passing `--type change` or `--type spec`, or using `openspec change validate` / `openspec spec validate`
- **AND** suggest passing `--type change` or `--type spec`
- **AND** exit with code 1 without performing validation

#### Scenario: Unknown item name
Expand Down
8 changes: 4 additions & 4 deletions openspec/specs/openspec-conventions/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,10 @@ OpenSpec CLI design SHALL use verbs as top-level commands with nouns provided as
- **THEN** the verb communicates the action clearly
- **AND** nouns refine scope via flags or arguments (e.g., `--changes`, `--specs`)

#### Scenario: Backward compatibility for noun commands
- **WHEN** users run noun-prefixed commands such as `openspec spec ...` or `openspec change ...`
- **THEN** the CLI SHALL continue to support them for at least one release
- **AND** display a deprecation warning that points to verb-first alternatives
#### Scenario: Removed noun command groups
- **WHEN** users need to show, list, or validate changes and specs
- **THEN** they SHALL use the canonical verb-first commands `openspec show`, `openspec list`, and `openspec validate`
- **AND** the removed noun-form command groups `openspec spec ...` and `openspec change ...` SHALL NOT be presented as supported entry points

#### Scenario: Disambiguation guidance
- **WHEN** item names are ambiguous between changes and specs
Expand Down
Loading