Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
The bundle SHALL invoke `radon cc -j` for only the provided files and convert function
complexity above 12 into `ReviewFinding` records.

### Requirement: Radon is available in the standard repo environment
The bundle SHALL declare the Radon executable in the default development environment
used by local and CI quality gates.

#### Scenario: Complexity 13 produces a warning
- **GIVEN** Radon reports a function with complexity 13
- **WHEN** `run_radon(files=[...])` is called
Expand All @@ -34,3 +30,12 @@ used by local and CI quality gates.
- **GIVEN** Radon is unavailable or returns invalid JSON
- **WHEN** `run_radon(files=[...])` is called
- **THEN** exactly one `ReviewFinding` with `category="tool_error"` is returned

### Requirement: Radon is available in the standard repo environment
The bundle SHALL declare the Radon executable in the default development environment
used by local and CI quality gates.

#### Scenario: Repo quality environment can execute Radon
- **GIVEN** the standard repository development environment is created
- **WHEN** Radon-backed review tooling or tests run in that environment
- **THEN** the `radon` executable is available on `PATH`
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@
- [x] 5.1 Re-run the targeted docs validation checks and record passing evidence in `openspec/changes/docs-01-modules-docs-canonical-site/TDD_EVIDENCE.md`
- [x] 5.2 Run `openspec validate docs-01-modules-docs-canonical-site --strict`
- [x] 5.3 Run the relevant repo quality gates for touched docs/test files
- [ ] 5.4 Open PR to `dev` from `feature/docs-01-modules-docs-canonical-site`
- [x] 5.4 Open PR to `dev` from `feature/docs-01-modules-docs-canonical-site`
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ and emits a governed `ReviewReport` with correct exit codes.
- **AND** progress feedback does not replace the primary stdout contract such as
the final JSON output path

## ADDED Requirements

### Requirement: Developer runtime validation helper for local modules

The modules repository SHALL provide a repo-local helper that prepares a live
Expand Down
62 changes: 33 additions & 29 deletions openspec/specs/backlog-add/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,37 @@ TBD - created by archiving change backlog-02-migrate-core-commands. Update Purpo
## Requirements
### Requirement: Restore backlog add command functionality

`specfact backlog add` SHALL build valid provider payloads for mapped required provider fields.

#### Scenario: map-fields persists required mapped field type metadata
- **WHEN** `specfact backlog map-fields` discovers required ADO fields for a selected work item type
- **THEN** it persists required field type metadata for those field references in provider settings
- **AND** metadata is keyed by work item type so later create commands can resolve field types.

#### Scenario: map-fields clears stale selected-type field metadata
- **WHEN** `specfact backlog map-fields` is rerun for a selected ADO work item type
- **AND** the latest metadata no longer includes persisted field types for that selected type
- **THEN** the stored required field type metadata for that selected work item type is removed
- **AND** metadata for other work item types remains unchanged.

#### Scenario: add coerces mapped required boolean provider fields
- **WHEN** `specfact backlog add` resolves a mapped required field whose persisted metadata type is `boolean`
- **AND** the user passes a provider override such as `--provider-field Custom.Toggle=true`
- **THEN** the outgoing ADO provider payload contains the boolean value `true` (not a string).

#### Scenario: add rejects invalid typed values before provider calls
- **WHEN** `specfact backlog add --non-interactive` resolves a mapped required field whose persisted metadata type is `boolean`
- **AND** the user passes an invalid boolean text value
- **THEN** the CLI exits with a validation error that names the mapped field
- **AND** no provider create call is made.

#### Scenario: add rejects invalid picklist values before provider calls
- **WHEN** `specfact backlog add --non-interactive` resolves a mapped required field whose persisted metadata contains allowed picklist values
- **AND** the user passes a provider override value outside that allowed set
- **THEN** the CLI exits with a validation error that names the mapped field and allowed values
- **AND** no provider create call is made.
The system SHALL provide `specfact backlog add` command that creates backlog items with the same functionality as the deleted backlog-core implementation. For Azure DevOps, the command SHALL use `work_item_type_mappings` from the field mapping configuration to resolve canonical types to provider-specific work item types.

#### Scenario: Add command creates GitHub issue
- **WHEN** the user runs `specfact backlog add --adapter github --project-id <owner/repo> --type story --title "Test" --body "Body"`
- **THEN** a GitHub issue is created with the specified title, body, and type
- **AND** the command outputs the created issue ID, key, and URL

#### Scenario: Add command creates ADO work item with custom type mapping
- **WHEN** the user runs `specfact backlog add --adapter ado --project-id <org/project> --type story --title "Test"`
- **AND** `.specfact/templates/backlog/field_mappings/ado_custom.yaml` contains `work_item_type_mappings.story: "Product Backlog Item"`
- **THEN** an ADO work item of type "Product Backlog Item" is created
- **AND** the command outputs the created work item ID, key, and URL

#### Scenario: Add command creates ADO work item with fallback type mapping
- **WHEN** the user runs `specfact backlog add --adapter ado --project-id <org/project> --type story --title "Test"`
- **AND** no custom `work_item_type_mappings` is configured
- **THEN** an ADO work item of type "User Story" is created (backward compatible fallback)
- **AND** the command outputs the created work item ID, key, and URL

#### Scenario: Interactive mode prompts for missing fields
- **WHEN** the user runs `specfact backlog add` without required fields
- **THEN** interactive prompts request title, body, type, and parent
- **AND** validation ensures parent exists before create

#### Scenario: DoR validation before create
- **WHEN** the user runs `specfact backlog add --check-dor`
- **THEN** the item is validated against `.specfact/dor.yaml` rules
- **AND** creation proceeds only if DoR criteria are met

#### Scenario: Ceremony alias works
- **WHEN** the user runs `specfact backlog ceremony add`
- **THEN** the command forwards to `specfact backlog add`
- **AND** all add options are available

47 changes: 47 additions & 0 deletions openspec/specs/contract-runner/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# contract-runner Specification

## Purpose
TBD - created by archiving change code-review-04-contract-test-runners. Update Purpose after archive.
## Requirements
### Requirement: icontract Decorator AST Scan and CrossHair Fast Pass

The system SHALL AST-scan changed Python files for public functions missing
`@require` / `@ensure` decorators, and run CrossHair with a 2-second per-path timeout
for counterexample discovery.

#### Scenario: Public function without icontract decorators produces a contracts finding

- **GIVEN** a Python file with a public function lacking icontract decorators
- **WHEN** `run_contract_check(files=[...])` is called
- **THEN** a `ReviewFinding` is returned with `category="contracts"` and
`severity="warning"`

#### Scenario: Decorated public function produces no contracts finding

- **GIVEN** a Python file with a public function decorated with both `@require` and
`@ensure`
- **WHEN** `run_contract_check(files=[...])` is called
- **THEN** no contract-related finding is returned for that function

#### Scenario: Private functions are excluded from the scan

- **GIVEN** a Python file with a function named `_private_helper` and no icontract
decorators
- **WHEN** `run_contract_check(files=[...])` is called
- **THEN** no finding is produced for `_private_helper`

#### Scenario: CrossHair counterexample maps to a contracts warning

- **GIVEN** CrossHair finds a counterexample for a reviewed function
- **WHEN** `run_contract_check(files=[...])` is called
- **THEN** a `ReviewFinding` is returned with `category="contracts"`,
`severity="warning"`, and `tool="crosshair"`

#### Scenario: CrossHair timeout or unavailability degrades gracefully

- **GIVEN** CrossHair times out or is not installed
- **WHEN** `run_contract_check(files=[...])` is called
- **THEN** the AST scan still runs
- **AND** no exception propagates to the caller
- **AND** CrossHair unavailability does not produce a blocking finding

35 changes: 35 additions & 0 deletions openspec/specs/modules-docs-publishing/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# modules-docs-publishing Specification

## Purpose
TBD - created by archiving change docs-01-modules-docs-canonical-site. Update Purpose after archive.
## Requirements
### Requirement: Modules docs site is the canonical home for official bundle documentation

The modules documentation site SHALL present itself as the canonical published home for official bundle and module-specific deep documentation.

#### Scenario: Reader opens modules landing page

- **WHEN** a reader opens the modules docs landing page
- **THEN** the page states that official bundle and module-specific deep guidance is owned by `specfact-cli-modules`
- **AND** the page does not describe the GitHub Pages project-path URL as the long-term canonical public identity.

### Requirement: Modules docs expose shared cross-site navigation

The modules documentation site SHALL expose shared top-level navigation labels that align with the canonical docs information architecture.

#### Scenario: Reader uses top navigation

- **WHEN** a reader opens the modules docs site
- **THEN** the top navigation includes `Docs Home`, `Core CLI`, and `Modules`
- **AND** the links guide the reader to the canonical docs entry point and core docs section without ambiguity.

### Requirement: Modules docs remain independently publishable

The modules documentation site SHALL support independent publishing and deployment without requiring a combined docs build with `specfact-cli`.

#### Scenario: Module-only docs change is published

- **WHEN** a change affects only `specfact-cli-modules/docs`
- **THEN** the modules docs build and publication workflow can ship the change without rebuilding the core docs site
- **AND** the site metadata and navigation remain valid for the public docs topology.

45 changes: 45 additions & 0 deletions openspec/specs/radon-runner/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# radon-runner Specification

## Purpose
TBD - created by archiving change code-review-02-ruff-radon-runners. Update Purpose after archive.
## Requirements
### Requirement: Radon complexity maps to review findings
The bundle SHALL invoke `radon cc -j` for only the provided files and convert function
complexity above 12 into `ReviewFinding` records.

#### Scenario: Complexity 13 produces a warning
- **GIVEN** Radon reports a function with complexity 13
- **WHEN** `run_radon(files=[...])` is called
- **THEN** a `ReviewFinding` is returned with `severity="warning"` and
`category="clean_code"`

#### Scenario: Complexity 16 produces an error
- **GIVEN** Radon reports a function with complexity 16
- **WHEN** `run_radon(files=[...])` is called
- **THEN** a `ReviewFinding` is returned with `severity="error"` and
`category="clean_code"`

#### Scenario: Complexity 12 or below produces no finding
- **GIVEN** all reported blocks have complexity 12 or below
- **WHEN** `run_radon(files=[...])` is called
- **THEN** no findings are returned

#### Scenario: Findings are filtered to the provided file list
- **GIVEN** a file list containing one Python file
- **WHEN** mocked Radon output includes a second file
- **THEN** findings for the second file are excluded

#### Scenario: Parse errors or missing Radon produce tool_error
- **GIVEN** Radon is unavailable or returns invalid JSON
- **WHEN** `run_radon(files=[...])` is called
- **THEN** exactly one `ReviewFinding` with `category="tool_error"` is returned

### Requirement: Radon is available in the standard repo environment
The bundle SHALL declare the Radon executable in the default development environment
used by local and CI quality gates.

#### Scenario: Repo quality environment can execute Radon
- **GIVEN** the standard repository development environment is created
- **WHEN** Radon-backed review tooling or tests run in that environment
- **THEN** the `radon` executable is available on `PATH`

25 changes: 25 additions & 0 deletions openspec/specs/review-cli-contracts/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# review-cli-contracts Specification

## Purpose
TBD - created by archiving change code-review-08-review-run-integration. Update Purpose after archive.
## Requirements
### Requirement: cli-val scenarios exist for review command groups
The modules repository SHALL define cli-val-compatible scenario YAML files for
the `specfact code review run`, `ledger`, and `rules` command groups, including
scope-mode and path-filter coverage for the review run command.

#### Scenario: review-run scenarios cover success, scope selection, and error paths
- **GIVEN** `tests/cli-contracts/specfact-code-review-run.scenarios.yaml`
- **WHEN** it is validated
- **THEN** it includes success coverage, changed-only and full-review scope examples, subtree-filtered examples, and an error or anti-pattern scenario

#### Scenario: ledger scenarios cover update, status, and reset guardrails
- **GIVEN** `tests/cli-contracts/specfact-code-review-ledger.scenarios.yaml`
- **WHEN** it is validated
- **THEN** it includes `update`, `status`, and reset guardrail coverage

#### Scenario: rules scenarios cover init, show, and update
- **GIVEN** `tests/cli-contracts/specfact-code-review-rules.scenarios.yaml`
- **WHEN** it is validated
- **THEN** it includes the supported rules subcommands

69 changes: 69 additions & 0 deletions openspec/specs/review-run-command/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# review-run-command Specification

## Purpose
TBD - created by archiving change code-review-08-review-run-integration. Update Purpose after archive.
## Requirements
### Requirement: End-to-End `specfact code review run` in modules repo

The `specfact-code-review` bundle SHALL provide a fully wired
`specfact code review run` command that orchestrates the existing tool runners
and emits a governed `ReviewReport` with correct exit codes.

#### Scenario: Representative modules-repo source can be reviewed without command failure
- **GIVEN** a real Python source file from this repository
- **WHEN** `specfact code review run --json <file>` is executed in the modules repo
- **THEN** the command writes a `ReviewReport` JSON file
- **AND** the command does not fail because of command wiring, path handling, or tool invocation bugs in the bundle

#### Scenario: JSON output uses file-based routing
- **GIVEN** `specfact code review run --json`
- **WHEN** the command executes successfully
- **THEN** it writes the governed `ReviewReport` JSON payload to a file path
- **AND** `--out` overrides the default JSON output path

#### Scenario: Interactive runs ask whether to include test files
- **GIVEN** `specfact code review run` executes in interactive mode
- **WHEN** test-file inclusion has not been specified explicitly
- **THEN** the CLI asks whether test files should be included in the review scope
- **AND** the answer controls whether changed files under `tests/` are reviewed

#### Scenario: Auto-detected review scope includes untracked Python files
- **GIVEN** Python files exist in the workspace that are not yet tracked by Git
- **WHEN** `specfact code review run` auto-detects review scope
- **THEN** those untracked Python files are included in review scope
- **AND** test-file inclusion rules still apply to untracked files under `tests/`

#### Scenario: Known low-signal findings are suppressible by default
- **GIVEN** a review run includes test files or other paths that can emit
known low-signal findings
- **WHEN** noise suppression is enabled
- **THEN** the report omits those known low-signal findings
- **AND** a command option allows users to include the suppressed findings for a
strict/full review

#### Scenario: Bundled skill instructs whether to include tests
- **GIVEN** the bundled `specfact-code-review` skill is installed
- **WHEN** it guides a review workflow
- **THEN** it instructs the reviewer to decide whether tests should be included
before running the review

#### Scenario: Long-running review runs surface progress
- **GIVEN** a review run executes multiple tool steps that can take noticeable
time
- **WHEN** the command is running
- **THEN** the CLI shows which review step is currently executing
- **AND** progress feedback does not replace the primary stdout contract such as
the final JSON output path

### Requirement: Developer runtime validation helper for local modules

The modules repository SHALL provide a repo-local helper that prepares a live
module source tree for workspace runtime validation through `.specfact/modules`
without mutating the source package manifest.

#### Scenario: Helper creates shadow module with unsigned manifest copy
- **GIVEN** a local module source under `packages/<module>`
- **WHEN** the helper prepares a workspace shadow root
- **THEN** the shadow module directory contains symlinks to the live module content
- **AND** the shadow manifest omits integrity metadata so runtime validation can opt into unsigned local loading

39 changes: 39 additions & 0 deletions openspec/specs/ruff-runner/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# ruff-runner Specification

## Purpose
TBD - created by archiving change code-review-02-ruff-radon-runners. Update Purpose after archive.
## Requirements
### Requirement: Ruff findings map to governed review categories
The bundle SHALL invoke `ruff check --output-format json` for only the provided files
and translate supported Ruff rules into `ReviewFinding` records.

#### Scenario: Security rules map to the security category
- **GIVEN** Ruff reports a rule beginning with `S`
- **WHEN** `run_ruff(files=[...])` is called
- **THEN** the returned finding has `category="security"` and `tool="ruff"`

#### Scenario: Complexity rules map to clean_code
- **GIVEN** Ruff reports rule `C901`
- **WHEN** `run_ruff(files=[...])` is called
- **THEN** the returned finding has `category="clean_code"`

#### Scenario: Style rules map to style
- **GIVEN** Ruff reports a rule beginning with `E`, `F`, `I`, or `W`
- **WHEN** `run_ruff(files=[...])` is called
- **THEN** the returned finding has `category="style"`

#### Scenario: Unsupported rule families are skipped
- **GIVEN** Ruff reports rules outside the supported `S*`, `C9*`, `E*`, `F*`, `I*`, and `W*` families
- **WHEN** `run_ruff(files=[...])` is called
- **THEN** those unsupported rules do not produce governed review findings

#### Scenario: Findings are filtered to the provided file list
- **GIVEN** a file list containing one Python file
- **WHEN** mocked Ruff output includes findings for another file
- **THEN** only findings for the provided file are returned

#### Scenario: Parse errors or missing Ruff produce tool_error
- **GIVEN** Ruff is unavailable or returns invalid JSON
- **WHEN** `run_ruff(files=[...])` is called
- **THEN** exactly one `ReviewFinding` with `category="tool_error"` is returned

Loading
Loading