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
9 changes: 6 additions & 3 deletions openspec/CHANGE_ORDER.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Correct the active change count

This snapshot is now one too high: after this commit, openspec list/the openspec/changes tree contains 13 active changes including requirements-04-upstream-source-readiness, not 14. Since this file states it is the modules-side source of truth for active OpenSpec work, the inflated count immediately misreports the backlog and can mislead planning or follow-up cleanup; this line should remain 13 unless another active change is added.

Useful? React with 👍 / 👎.

| **Parked** | 16 | [`openspec/parking-lot/`](parking-lot/) |
| **Archived** | 43 | [`openspec/changes/archive/`](changes/archive/) |

Expand Down Expand Up @@ -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 |

Expand All @@ -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. |
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# requirements-04-upstream-source-readiness

Reject incomplete or upstream-invalid OpenSpec and Spec Kit sources before requirements evidence is persisted.
110 changes: 110 additions & 0 deletions openspec/changes/requirements-04-upstream-source-readiness/design.md
Original file line number Diff line number Diff line change
@@ -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?
Original file line number Diff line number Diff line change
@@ -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

<!-- source_repo: nold-ai/specfact-cli-modules -->
- **GitHub Issue**: #346
- **Issue URL**: <https://github.com/nold-ai/specfact-cli-modules/issues/346>
- **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
Original file line number Diff line number Diff line change
@@ -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 <path> --bundle <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 <path> --bundle <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 <path> --bundle <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.
Original file line number Diff line number Diff line change
@@ -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.
Loading