diff --git a/openspec/CHANGE_ORDER.md b/openspec/CHANGE_ORDER.md index d179da8..1b658bb 100644 --- a/openspec/CHANGE_ORDER.md +++ b/openspec/CHANGE_ORDER.md @@ -7,7 +7,7 @@ must be read together with the core repo change order in `nold-ai/specfact-cli`. | Bucket | Count | Location | |---|---:|---| -| **Active** | 13 | [`openspec/changes/`](changes/) | +| **Active** | 14 | [`openspec/changes/`](changes/) | | **Parked** | 16 | [`openspec/parking-lot/`](parking-lot/) | | **Archived** | 43 | [`openspec/changes/archive/`](changes/archive/) | @@ -68,8 +68,9 @@ AI IDE, rerun, and compare improved evidence. |---:|---|---|---|---| | 1 | `requirements-02-module-commands` | [#165](https://github.com/nold-ai/specfact-cli-modules/issues/165) | Import/normalize requirement context for evidence (shipped via PR #326, archived 2026-07-13) | core requirements input model | | 2 | `openspec-01-intent-trace` | [#168](https://github.com/nold-ai/specfact-cli-modules/issues/168) | Import-first OpenSpec and Spec Kit requirement evidence runtime with gate surfacing (rescoped 2026-07-13) | requirements-02 runtime; core nold-ai/specfact-cli#350 contracts | -| 3 | `architecture-01-solution-layer` | [#164](https://github.com/nold-ai/specfact-cli-modules/issues/164) | Architecture-boundary validation input | core architecture-boundary contracts | -| 4 | `sync-01-unified-kernel` | [#157](https://github.com/nold-ai/specfact-cli-modules/issues/157) | Preview/apply safety only where validation adapters need it | project/runtime safety specs | +| 3 | `requirements-04-upstream-source-readiness` | [#346](https://github.com/nold-ai/specfact-cli-modules/issues/346) | Reject incomplete or policy-invalid native OpenSpec and Spec Kit sources before requirement evidence persistence | paired core follow-up to #350 (not yet created) | +| 4 | `architecture-01-solution-layer` | [#164](https://github.com/nold-ai/specfact-cli-modules/issues/164) | Architecture-boundary validation input | core architecture-boundary contracts | +| 5 | `sync-01-unified-kernel` | [#157](https://github.com/nold-ai/specfact-cli-modules/issues/157) | Preview/apply safety only where validation adapters need it | project/runtime safety specs | | Parked | `requirements-03-backlog-sync` | [#166](https://github.com/nold-ai/specfact-cli-modules/issues/166) | Read-first backlog drift evidence; no write-back critical path. Deprioritized 2026-07-13 behind openspec-01 | requirements-02, sync-01 | | Gated | `architecture-02-module-well-architected` | [#230](https://github.com/nold-ai/specfact-cli-modules/issues/230) | Architecture-boundary review findings | architecture-01 shipped plus one usage cycle | @@ -88,6 +89,7 @@ AI IDE, rerun, and compare improved evidence. | `traceability-01-index-and-orphans` | Keep artifact drift, orphan, and linkage evidence. Drop ceremony/dashboard positioning. | | `requirements-02-module-commands` | Drop requirement authoring as a flagship workflow. Keep import, normalization, validation, and coverage inspection. | | `requirements-03-backlog-sync` | Keep read-first drift evidence. Write-back remains preview-only and outside the validation critical path. | +| `requirements-04-upstream-source-readiness` | Keep source readiness core-owned; reject incomplete native sources atomically and do not require the OpenSpec CLI outside explicit or strict/enterprise policy. | | `architecture-01-solution-layer` | Keep architecture-boundary input and validation hooks. Drop architecture generation. | | `openspec-01-intent-trace` | Done 2026-07-13: rescoped to import-first runtime for native OpenSpec/Spec Kit artifacts with deterministic gate surfacing. | | `architecture-02-module-well-architected` | Keep gated until architecture-01 ships and is used for one complete cycle. | @@ -130,6 +132,7 @@ ceremony rather than validation evidence: - `requirements-02-module-commands` - `openspec-01-intent-trace` (pulled forward 2026-07-13, import-first rescope) +- `requirements-04-upstream-source-readiness` (blocked on paired core source-readiness contract) - `architecture-01-solution-layer` - `sync-01-unified-kernel` - `requirements-03-backlog-sync` (parked 2026-07-13) diff --git a/openspec/changes/requirements-04-upstream-source-readiness/.openspec.yaml b/openspec/changes/requirements-04-upstream-source-readiness/.openspec.yaml new file mode 100644 index 0000000..f036afc --- /dev/null +++ b/openspec/changes/requirements-04-upstream-source-readiness/.openspec.yaml @@ -0,0 +1,5 @@ +schema: spec-driven +created: 2026-07-14 +goal: Protect import-first requirement evidence from draft templates and invalid + upstream artifacts while keeping completed native imports read-only and + portable. diff --git a/openspec/changes/requirements-04-upstream-source-readiness/README.md b/openspec/changes/requirements-04-upstream-source-readiness/README.md new file mode 100644 index 0000000..a5e8245 --- /dev/null +++ b/openspec/changes/requirements-04-upstream-source-readiness/README.md @@ -0,0 +1,3 @@ +# requirements-04-upstream-source-readiness + +Reject incomplete or upstream-invalid OpenSpec and Spec Kit sources before requirements evidence is persisted. diff --git a/openspec/changes/requirements-04-upstream-source-readiness/design.md b/openspec/changes/requirements-04-upstream-source-readiness/design.md new file mode 100644 index 0000000..d6da42e --- /dev/null +++ b/openspec/changes/requirements-04-upstream-source-readiness/design.md @@ -0,0 +1,110 @@ +## Context + +`openspec-01-intent-trace` established that the Requirements module is a thin +command surface over core-owned OpenSpec and Spec Kit normalizers. Local +end-to-end testing against the official Spec Kit 0.12.15 scaffold found that a +pristine `spec.md` normalizes placeholder Functional Requirements into six +misleading records. OpenSpec has a native strict validator, whereas current +Spec Kit has no equivalent feature-validation command (`specify check` only +checks the tool installation). + +The module must not grow a second parser, hashing implementation, or authoring +schema to solve this. Source readiness therefore belongs in the paired core +contract and must be exposed to the module as structured import diagnostics. + +## Goals / Non-Goals + +**Goals:** + +- Ensure only ready native upstream artifacts become persisted requirement + evidence. +- Make rejected sources deterministic, machine-readable, non-zero, and + read-only. +- Preserve basic portable imports while allowing strict/enterprise policy to + require the native OpenSpec validator. +- Keep completed OpenSpec and Spec Kit import mapping, source hashes, and + idempotency stable. + +**Non-Goals:** + +- Defining a SpecFact authoring schema for OpenSpec or Spec Kit. +- Writing back validation results or remediation into upstream directories. +- Making the OpenSpec CLI a mandatory dependency for every basic import. +- Treating `specify check` as feature-artifact validation. +- Implementing native readiness parsing or policy evaluation in this module. + +## Decisions + +### Core returns an atomic readiness result before persistence + +The paired core API SHALL return normalized records only when a source is ready; +otherwise it SHALL return zero records and structured diagnostics. The module +shall reuse its existing persistence path only for accepted records. + +This prevents partial bundles and keeps the trust decision beside the parser, +normalizer, hash, and gate helpers already owned by core. An alternative of +filtering placeholders in the module is rejected because it duplicates +source-specific parsing and can diverge from the core contract. + +### Known incomplete Spec Kit markers are fail-closed + +Core SHALL recognise the official native draft markers needed to identify an +unfinished source: unresolved placeholder tokens, `NEEDS CLARIFICATION`, no +substantive Functional Requirement, and absent meaningful acceptance scenarios +when user stories are present. It SHALL return +`incomplete-source-template` or `source-incomplete`, with source locations, +instead of emitting partial records. + +Detection SHALL use narrow, documented marker rules rather than a whole-template +hash so valid prose containing ordinary brackets is not rejected. A pinned +official scaffold fixture and a scheduled upstream compatibility check guard +against template drift. + +### OpenSpec validation is policy-gated, not an ambient dependency + +When the core policy explicitly requires upstream validation, core SHALL invoke +the native OpenSpec CLI with `validate --strict --json` for the selected change. +A failed command yields `source-invalid`; an unavailable validator yields +`upstream-validator-unavailable`. Either result rejects the source atomically. + +Basic portable import remains available when policy does not require the CLI; +the existing core parser/schema fail-closed behavior remains in effect. This +avoids different results merely because a developer happens to have `openspec` +on `PATH`. An alternative of always probing any discovered binary is rejected +because it makes imports environment-dependent and falsely conflates tool +presence with an explicit assurance policy. + +### Module maps core diagnostics without reinterpretation + +The Requirements module SHALL surface the core diagnostic code, severity, +locator, and message unchanged in JSON and text output. It SHALL return a +non-zero command result when core reports an error and SHALL not write the +requirements sidecar for a rejected source. + +## Risks / Trade-offs + +- [Official Spec Kit templates change] → Pin a current scaffold fixture, + schedule a compatibility check, and fail only on narrow known markers. +- [A valid project uses bracketed prose] → Do not use generic bracket matching; + test legitimate bracketed requirements. +- [OpenSpec CLI is absent in portable environments] → Require it only when + policy explicitly demands upstream validation and return a named diagnostic. +- [Core follow-up is delayed] → Keep this modules change blocked; do not add + duplicate readiness logic locally. + +## Migration Plan + +1. Land the paired core readiness contract and its compatibility tests. +2. Raise `specfact-requirements` `core_compatibility` to the released core + version and delegate the new result unchanged. +3. Add module command tests, docs, signatures, registry publication, and a patch + release. +4. Roll back by restoring the previous module version; no upstream source files + or bundle mutation is required for rollback. + +## Open Questions + +- Which exact core release/version will expose the readiness result and policy + configuration contract? +- Should strict/enterprise policy require OpenSpec native validation by default, + or should repository configuration opt in explicitly for those profiles? diff --git a/openspec/changes/requirements-04-upstream-source-readiness/proposal.md b/openspec/changes/requirements-04-upstream-source-readiness/proposal.md new file mode 100644 index 0000000..eec2b1a --- /dev/null +++ b/openspec/changes/requirements-04-upstream-source-readiness/proposal.md @@ -0,0 +1,64 @@ +## Why + +The import-first runtime shipped by `openspec-01-intent-trace` can turn an +unfinished native source into apparently valid requirement evidence. A pristine +Spec Kit 0.12.15 scaffold produced six placeholder records during local +end-to-end testing. Invalid OpenSpec changes need the same protection when the +repository policy requires native OpenSpec validation. + +Evidence must be trustworthy before it reaches coverage and CI gates. An +incomplete or upstream-invalid source must be reported clearly, not silently +normalised into misleading records. + +## What Changes + +- Add a core-owned upstream-source readiness contract for native OpenSpec and + Spec Kit imports; the Requirements module only delegates and renders its + results. +- Reject incomplete Spec Kit sources that retain known official template + markers, unresolved `NEEDS CLARIFICATION` markers, no substantive functional + requirements, or no meaningful acceptance scenario where user stories exist. +- Reject OpenSpec sources whose strict native validation fails when an explicit + or strict/enterprise upstream-validation policy requires the OpenSpec CLI. +- Return structured diagnostics and a non-zero result while persisting zero + requirement records for any rejected source. +- Preserve completed native imports, stable identifiers, hash provenance, + idempotency, read-only source behavior, and portable basic imports. + +## Capabilities + +### New Capabilities + +None. + +### Modified Capabilities + +- `requirements-module`: Native OpenSpec and Spec Kit import gains + source-readiness diagnostics and fail-closed persistence semantics. + +## Impact + +- Paired core dependency: a new `specfact-cli` follow-up to #350 must own + native readiness evaluation, the OpenSpec CLI adapter/policy, and diagnostic + contracts. This modules change is blocked until that contract ships. +- Affected modules code: `packages/specfact-requirements` import command and + thin runtime delegation. +- Affected tests: Requirements module command/runtime integration coverage and + source read-only/idempotency regression coverage. +- Affected user docs: Requirements import examples and diagnostic guidance. +- Release impact: patch release of `nold-ai/specfact-requirements` after the + paired core compatibility floor is available; no registry or signed manifest + change belongs in this proposal-only change. + +--- + +## Source Tracking + + +- **GitHub Issue**: #346 +- **Issue URL**: +- **Parent Feature**: #161 Context Adapters For Validation Evidence +- **Follow-up To**: #168 +- **Core Counterpart**: required follow-up to nold-ai/specfact-cli#350 (not yet created) +- **Last Synced Status**: open / Todo (aligned 2026-07-14) +- **Sanitized**: false diff --git a/openspec/changes/requirements-04-upstream-source-readiness/specs/requirements-module/spec.md b/openspec/changes/requirements-04-upstream-source-readiness/specs/requirements-module/spec.md new file mode 100644 index 0000000..80cf1f9 --- /dev/null +++ b/openspec/changes/requirements-04-upstream-source-readiness/specs/requirements-module/spec.md @@ -0,0 +1,60 @@ +## ADDED Requirements + +### Requirement: Upstream source readiness for native requirement imports + +The Requirements module SHALL persist native OpenSpec or Spec Kit requirement +evidence only when the paired core source-readiness contract accepts the source. +The module SHALL surface core readiness diagnostics unchanged, SHALL return a +non-zero result when any readiness diagnostic has error severity, and SHALL not +persist partial records for a rejected source. The module SHALL remain read-only +toward upstream artifact directories and SHALL not implement source parsing, +placeholder detection, hashing, or upstream-validator policy itself. + +#### Scenario: Reject an incomplete Spec Kit scaffold + +- **GIVEN** a native Spec Kit feature source containing a recognised official + draft placeholder or an unresolved `NEEDS CLARIFICATION` marker +- **WHEN** `specfact requirements import --from-speckit --bundle ` runs +- **THEN** the module reports the core `incomplete-source-template` or + `source-incomplete` diagnostic with its source location +- **AND** it reports zero imported records and exits non-zero +- **AND** it does not create or modify the bundle requirements sidecar +- **AND** the upstream feature directory remains byte-identical. + +#### Scenario: Import a completed native Spec Kit feature + +- **GIVEN** a native Spec Kit feature with substantive Functional Requirements + and meaningful GIVEN/WHEN/THEN acceptance scenarios +- **WHEN** `specfact requirements import --from-speckit --bundle ` runs +- **THEN** the module persists the core-normalized records with stable IDs and + source hash provenance +- **AND** it reports no readiness diagnostics +- **AND** re-importing the unchanged feature creates no duplicates. + +#### Scenario: Reject an invalid OpenSpec change under required upstream validation + +- **GIVEN** repository policy requires native OpenSpec validation and the + selected change fails core-invoked `openspec validate --strict --json` +- **WHEN** `specfact requirements import --from-openspec --bundle ` runs +- **THEN** the module reports the core `source-invalid` diagnostic +- **AND** it reports zero imported records and exits non-zero +- **AND** it does not create or modify the bundle requirements sidecar. + +#### Scenario: Report a required but unavailable OpenSpec validator + +- **GIVEN** repository policy requires native OpenSpec validation and the + OpenSpec CLI is unavailable +- **WHEN** an OpenSpec import runs +- **THEN** the module reports the core `upstream-validator-unavailable` + diagnostic +- **AND** it reports zero imported records and exits non-zero +- **AND** it does not attempt fallback parsing that claims upstream validation. + +#### Scenario: Preserve portable basic OpenSpec import + +- **GIVEN** repository policy does not require native OpenSpec CLI validation + and the source satisfies the core-supported native schema +- **WHEN** an OpenSpec import runs without the OpenSpec CLI installed +- **THEN** the module delegates the source to the core normalizer +- **AND** it preserves the existing completed-import behavior without claiming + that native CLI validation occurred. diff --git a/openspec/changes/requirements-04-upstream-source-readiness/tasks.md b/openspec/changes/requirements-04-upstream-source-readiness/tasks.md new file mode 100644 index 0000000..84c72ac --- /dev/null +++ b/openspec/changes/requirements-04-upstream-source-readiness/tasks.md @@ -0,0 +1,61 @@ +## 1. Governance and paired-contract readiness + +- [x] 1.1 Create modules issue #346 under parent feature #161 with `enhancement`, + `project`, `openspec`, and `change-proposal` labels and SpecFact CLI project + assignment. +- [x] 1.2 Record the completed #168 follow-up relationship and the observed + official Spec Kit 0.12.15 scaffold behavior in the proposal and design. +- [ ] 1.3 Create and link the paired `specfact-cli` core follow-up to #350; + record its release version as this change's blocker and blocked-by relation. +- [ ] 1.4 Recheck current GitHub issue state, parent, labels, project assignment, + blockers, and active-work concurrency before implementation starts. + +## 2. Core contract and source-readiness tests + +- [ ] 2.1 In the paired core change, specify the structured source-readiness + result and diagnostics: `incomplete-source-template`, `source-incomplete`, + `source-invalid`, and `upstream-validator-unavailable`. +- [ ] 2.2 Add a pinned fixture for the official Spec Kit scaffold and tests that + reject its unresolved placeholders and `NEEDS CLARIFICATION` markers with + zero normalized records. +- [ ] 2.3 Add core tests that accept a completed native Spec Kit feature with + stable IDs, source hash provenance, given/when/then rules, and idempotency. +- [ ] 2.4 Add core tests for strict OpenSpec validator failure, required + validator absence, and portable import when policy does not require the CLI. +- [ ] 2.5 Add byte-identical upstream-source tests and capture failing-first + evidence before any production change. + +## 3. Modules integration and regression tests + +- [ ] 3.1 Raise `specfact-requirements` core compatibility only after the paired + core release exposes the readiness contract. +- [ ] 3.2 Add failing module command tests proving rejected OpenSpec and Spec Kit + sources report core diagnostics unchanged, exit non-zero, and do not create a + requirements sidecar. +- [ ] 3.3 Add module command tests proving completed sources retain current + import counts, stable records, read-only behavior, and re-import idempotency. +- [ ] 3.4 Implement thin runtime delegation and command rendering without local + parsing, placeholder detection, hashing, or upstream-validator policy logic. +- [ ] 3.5 Run targeted tests and record failing-before and passing-after output + in `TDD_EVIDENCE.md`. + +## 4. Documentation and release preparation + +- [ ] 4.1 Update Requirements module documentation with source-readiness + diagnostics, portable versus required upstream validation, and remediation + guidance for unfinished sources. +- [ ] 4.2 Bump the Requirements module patch version, regenerate payload + checksum/signature, and update registry artifacts only after behavior tests + pass. +- [ ] 4.3 Run formatting, lint, type, YAML, signature, contract, smart-test, + and targeted test gates. +- [ ] 4.4 Run a fresh SpecFact code review JSON report after the last proposal, + test, implementation, or documentation edit; resolve every finding and record + the command and result in `TDD_EVIDENCE.md`. + +## 5. Delivery + +- [ ] 5.1 Validate the OpenSpec change strictly and synchronize issue #346 with + final core dependency, scope, and acceptance evidence. +- [ ] 5.2 Open the modules PR to `dev` with the paired-core release requirement, + test evidence, signature verification, and documentation updates.