diff --git a/docs/agent-rules/20-repository-context.md b/docs/agent-rules/20-repository-context.md index 63b5805a..7a246b3f 100644 --- a/docs/agent-rules/20-repository-context.md +++ b/docs/agent-rules/20-repository-context.md @@ -78,4 +78,4 @@ In this checkout: - Prefer **`specfact module init --scope project --repo .`** (and project-scoped installs) so bundled modules live under the repo, not only under user scope. - **`SPECFACT_MODULES_REPO`** is set to the modules repo root for every **`hatch run`** (`pyproject.toml` env-vars) and via **`apply_specfact_workspace_env`** from `specfact_cli_modules.dev_bootstrap` (also used by `ensure_core_dependency`, pytest `conftest`, and `scripts/pre_commit_code_review.py`). **`SPECFACT_REPO_ROOT`** defaults to the resolved sibling/core specfact-cli checkout when discoverable. -- If you still see a precedence warning for a module id, remove the stale user copy: **`specfact module uninstall --scope user`**, then confirm with **`specfact module list --show-origin`**. +- A user-scoped copy shadowed here remains installed and available outside this repository. Normal precedence requires no uninstall or cleanup action; use **`specfact module list --show-origin`** only when you need to inspect the effective source. diff --git a/openspec/CHANGE_ORDER.md b/openspec/CHANGE_ORDER.md index 631aef59..1495dece 100644 --- a/openspec/CHANGE_ORDER.md +++ b/openspec/CHANGE_ORDER.md @@ -7,13 +7,27 @@ must be read together with the core repo change order in `nold-ai/specfact-cli`. | Bucket | Count | Location | |---|---:|---| -| **Active** | 19 | [`openspec/changes/`](changes/) | -| **Parked** | 16 | [`openspec/parking-lot/`](parking-lot/) | -| **Archived** | 49 | [`openspec/changes/archive/`](changes/archive/) | +| **Active-tree entries** | 19 | [`openspec/changes/`](changes/) | +| **Parking-lot entries** | 16 | [`openspec/parking-lot/`](parking-lot/) | +| **Archived** | 50 | [`openspec/changes/archive/`](changes/archive/) | +| **Abandoned history** | 1 | [`openspec/history/abandoned/`](history/abandoned/) | -`openspec list` reflects the active set only. Completed changes are archived -with date-prefixed folders. Parked changes are preserved for later customer pull -but are not implementation-ready. +`openspec list` reflects all 19 direct active-tree entries. The closed R08 +proposal is retained under non-canonical abandoned history, outside +`openspec/changes/` and its completed-change archive; no unimplemented delta +entered canonical specifications. Completed changes still use native OpenSpec +archival. Parking-lot changes are preserved for later customer pull but are not +implementation-ready. + +## Abandoned Planning History Without Specification Promotion + +| Change | GitHub issue | Historical status | +|---|---|---| +| [`requirements-08-bounded-red-green-proof`](history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/) | [#414](https://github.com/nold-ai/specfact-cli-modules/issues/414) | Closed Not Planned on 2026-08-27; never implemented; retained outside the completed-change archive; canonical specs unchanged | + +This non-canonical history is not an OpenSpec archive and is not implementation +authority. Completed work must use `openspec archive` so implemented deltas are +validated and promoted normally. ## Product Thesis @@ -45,6 +59,7 @@ issues and are now archived: | `code-review-11-simplification-feedback-loop` | archived 2026-06-06 | | `code-review-12-guided-simplification-enforcement` | archived 2026-06-06 | | `code-review-13-cleanup-forecast-agent-handoff` | archived 2026-06-06 | +| `module-scope-02-preserve-user-installs` | archived 2026-08-30 after #454 merged to `dev` | These archived specs are now the shipped basis for the flagship demo: run review, produce JSON evidence, identify AI-bloat findings, hand remediation packets to an @@ -110,8 +125,8 @@ and adapters reference it without duplicating Python checks. |---:|---|---|---|---| | 1 | `preflight-02-assurance-runtime` | [#431](https://github.com/nold-ai/specfact-cli-modules/issues/431) | Unpublished runtime, Python validators, CLI/rendering/persistence, and canonical bundled `specfact-preflight` workflow | core contract [#682](https://github.com/nold-ai/specfact-cli/issues/682) | | 2 | `preflight-03-dogfood-hardening-and-release` | [#432](https://github.com/nold-ai/specfact-cli-modules/issues/432) | Evidence-backed hardening, bounded compatibility proof, signing, and stable publication | modules #431; core C14 dogfood/readiness [#683](https://github.com/nold-ai/specfact-cli/issues/683) | -| 3 | `preflight-04-harness-adapters` | [#433](https://github.com/nold-ai/specfact-cli-modules/issues/433) | Later thin Codex plugin, ECC companion, and hatch3r pack; no duplicate validators | stable modules release #432; core generated instructions [#253](https://github.com/nold-ai/specfact-cli/issues/253) | -| 4 | `preflight-05-implementation-conformance` | [#434](https://github.com/nold-ai/specfact-cli-modules/issues/434) | Later postimplementation extraction/comparison/rendering; explicitly outside preflight MVP | modules #432 and adapters #433; paired core conformance contract [#684](https://github.com/nold-ai/specfact-cli/issues/684) | +| 3 | `preflight-05-implementation-conformance` | [#434](https://github.com/nold-ai/specfact-cli-modules/issues/434) | Worktree/index checkpoints, final range conformance, C14/Requirements/review evidence reuse, seal-aware pre-commit, bounded agent handoff, and signed publication | modules #432; paired core implementation-assurance contract [#684](https://github.com/nold-ai/specfact-cli/issues/684) | +| 4 | `preflight-04-harness-adapters` | [#433](https://github.com/nold-ai/specfact-cli-modules/issues/433) | Later thin Codex plugin, ECC companion, and hatch3r pack; no duplicate validators | exact signed #434 module identity plus preflight and implementation-check workflow identities/digests; core generated instructions [#253](https://github.com/nold-ai/specfact-cli/issues/253) | ### Track B - Upstream Context Adapters @@ -123,7 +138,6 @@ and adapters reference it without duplicating Python checks. | 4 | `requirements-05-dogfood-evidence-gate` | [#352](https://github.com/nold-ai/specfact-cli-modules/issues/352) | CI evidence adapter that reports green/red requirement-source validity and traceability evidence; not test-execution proof | requirements-04 shipped; existing Requirements runtime | | 5 | `requirements-06-evidence-enforcement` | [#361](https://github.com/nold-ai/specfact-cli-modules/issues/361) | Reusable Requirements evidence command plus staged pre-commit enforcement and CI parity | [#352](https://github.com/nold-ai/specfact-cli-modules/issues/352); paired core [#657](https://github.com/nold-ai/specfact-cli/issues/657) | | 6 | `requirements-07-scenario-runtime-proof` | [#368](https://github.com/nold-ai/specfact-cli-modules/issues/368) | Plan exact selectors and reconcile current-run JUnit independently from historical chronology | requirements-06; paired corrected core R07 | -| 7 | `requirements-08-bounded-red-green-proof` | [#414](https://github.com/nold-ai/specfact-cli-modules/issues/414) | Validate a core-emitted structural B < R < H <= D replay capsule as an independent chronology claim; pass requires distinct H/D (`H < D`) | corrected R07; paired core [#675](https://github.com/nold-ai/specfact-cli/issues/675) | | 8 | `architecture-01-solution-layer` | [#164](https://github.com/nold-ai/specfact-cli-modules/issues/164) | Architecture-boundary validation input | core architecture-boundary contracts | | 9 | `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 | @@ -172,7 +186,9 @@ ceremony rather than validation evidence: 3. Core C14 adoption [#680](https://github.com/nold-ai/specfact-cli/issues/680). 4. Core C14 dogfood/readiness [#683](https://github.com/nold-ai/specfact-cli/issues/683). 5. Evidence-backed modules hardening and stable publication [#432](https://github.com/nold-ai/specfact-cli-modules/issues/432). -6. Shared skill installation #251 -> generated instructions #253 -> adapters #433; later conformance #684/#434; modules C15 #417 -> core C15 #679. +6. Core implementation-assurance contracts [#684](https://github.com/nold-ai/specfact-cli/issues/684). +7. Modules checkpoint/conformance runtime, dogfood, signing, and publication [#434](https://github.com/nold-ai/specfact-cli-modules/issues/434). +8. Shared skill installation #251 -> generated instructions #253 -> adapters #433. Modules C15 #417 -> core C15 #679 may proceed independently after stable #432. Modules C15 #417 keeps its existing policy and exception blockers (#158, core #248, and modules #167) plus the stable preflight release. Existing native @@ -206,7 +222,7 @@ dedicated issue-linked worktree and session. - `requirements-05-dogfood-evidence-gate` - `requirements-06-evidence-enforcement` (after requirements-05 archival/release evidence) - `requirements-07-scenario-runtime-proof` (current-run reconciliation correction after requirements-06) -- `requirements-08-bounded-red-green-proof` (paired with core bounded replay after corrected R07) +- abandoned-history `requirements-08-bounded-red-green-proof` is superseded and non-canonical; no replay implementation or specification promotion occurred - `architecture-01-solution-layer` - `sync-01-unified-kernel` - `requirements-03-backlog-sync` (parked 2026-07-13) @@ -216,8 +232,8 @@ dedicated issue-linked worktree and session. - `docs-16-core-accountability-sync` - `architecture-02-module-well-architected` - `docs-14-module-release-history` -- `preflight-04-harness-adapters` after core #253 and stable publication -- `preflight-05-implementation-conformance` after stable publication and core #684 +- `preflight-05-implementation-conformance` after stable #432 and core #684 +- `preflight-04-harness-adapters` after signed #434, core #251, and core #253 ## Parent Issues And Epic Framing @@ -236,4 +252,6 @@ implementation starts. After a change ships and merges, run `openspec archive ` from the repo root. Do not manually move completed changes into `openspec/changes/archive/`. Parking-lot moves are allowed for paused proposals that are explicitly not active -scope. +scope. Abandoned, never-implemented proposals may be retained only under +`openspec/history/abandoned/`, whose records are non-canonical and never imply +specification promotion or implementation authority. diff --git a/openspec/INTEGRATION.md b/openspec/INTEGRATION.md index bcc14198..4caca8f0 100644 --- a/openspec/INTEGRATION.md +++ b/openspec/INTEGRATION.md @@ -7,8 +7,9 @@ changes without creating runtime behavior. ## Preflight Ownership - Core `preflight-01-design-contract-core` owns design-contract, - validation-result, digest, approval-seal, and side-effect-free verifier - interfaces. + role-classified scope, component/risk/verification intent, Requirements-plan + references, validation-result, digest, approval-seal, and side-effect-free + verifier interfaces. - Modules `preflight-02-assurance-runtime` owns executable Python validators, CLI orchestration, rendering, explicit persistence, and canonical bundled `specfact-preflight` workflow content. @@ -19,10 +20,20 @@ changes without creating runtime behavior. canonical `.agents/skills` export. Core `ai-integration-03-instruction-files` owns generated gate references. Neither owns the workflow body or validators. - Modules `preflight-04-harness-adapters` owns thin Codex, ECC, and hatch3r - packaging. Adapters map native invocation and assets only. -- Core `preflight-05-implementation-conformance` owns later comparison - interfaces; paired modules owns extraction and runtime comparison. This phase - is explicitly excluded from the preflight MVP. + packaging after the signed #434 handoff. That handoff is one exact signed + module identity plus separately named preflight and implementation-check + workflow identities/digests. Adapters map native invocation and assets only. +- Core `preflight-05-implementation-conformance` owns worktree/index/range + snapshot, obligation-map, finding/result, authority, and pure comparison + interfaces. Paired modules owns checkpoint/conform commands, C14-backed Git + extraction, Requirements pytest/JUnit and code-review evidence, caching, + pre-commit policy, remediation packets, bounded agent workflow, + checkpoint/conformance-result rendering, optional atomic snapshot/result + persistence under its distinct result schema, signing, and publication of the + module identity plus separately bound preflight and implementation-check + workflow identities/digests. These surfaces are separate from + `preflight-02-assurance-runtime`, which exclusively owns preflight + readiness/validation/seal rendering and persistence. ## Shared Rules @@ -32,21 +43,22 @@ changes without creating runtime behavior. OpenSpec, Spec Kit, ECC, hatch3r, and Codex instructions contain a compact gate/reference only. - Python validators are the canonical determinate checks. Prompts and adapters - must not recompute readiness, approval, or conformance. + must not recompute readiness, approval, checkpoint, or conformance status. - A seal proves exact reviewed-input identity and recorded approval, not design, LLM, implementation, security, or semantic correctness. - Any pre-implementation bound-input change invalidates readiness and requires a complete rerun and explicit user approval. During later conformance, the approved seal is verified against its sealed contract and base source - snapshot while the implementation head/range is captured as a separate, - explicit identity; implementation commits do not silently rewrite the seal. + snapshot while worktree/index/range implementation evidence is captured as a + separate identity; implementation commits do not silently rewrite the seal. +- Worktree/index checkpoint results have local authority only. They cannot be + promoted to protected PR-range evidence; final conformance requires a new + explicit immutable base/head evaluation. - Native GitHub parents, project status, blockers, and blocked-by relationships are required before implementation; body-only references are insufficient. ## Delivery Sequence -`core #682 -> modules #431 -> core C14 #680 -> core #683 -> modules #432`. -After the signed release, `#251 -> #253 -> modules #433`; stable modules #432, -modules #433, and core #684 all block modules #434. Issue #434 remains a later -branch; modules C15 `#417` -> core C15 #679 remains the signal-calibration -branch. Existing policy/exception blockers remain in force. +`core #682 -> modules #431 -> core C14 #680/#683 -> modules #432 -> core #684 -> modules #434 -> core #251 -> core #253 -> modules #433`. +Modules C15 `#417` -> core C15 #679 remains an independent signal-calibration +branch after stable #432. Existing policy/exception blockers remain in force. diff --git a/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/.openspec.yaml b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/.openspec.yaml new file mode 100644 index 00000000..50adc910 --- /dev/null +++ b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-08-29 diff --git a/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/TDD_EVIDENCE.md b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/TDD_EVIDENCE.md new file mode 100644 index 00000000..4e735943 --- /dev/null +++ b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/TDD_EVIDENCE.md @@ -0,0 +1,29 @@ +# TDD Evidence + +## Failing Before + +- `hatch run pytest tests/unit/test_dev_bootstrap.py tests/unit/test_local_bundle_source_alignment.py -q` + - Result: FAIL before production edits (`2 failed, 11 passed`). + - The new bootstrap and repository-guidance assertions could not find the required preservation language; both existing surfaces still prescribed a user-scope uninstall. + +## Passing After + +- `hatch run pytest tests/unit/test_dev_bootstrap.py tests/unit/test_local_bundle_source_alignment.py -q` + - Result: PASS (`13 passed`). + - The bootstrap and repository rule surfaces now preserve user-scoped installations, and the local import-isolation test remains green under its accurate in-memory eviction name. + +## Quality Gates + +- `hatch run format`: PASS (1,229 files unchanged). +- `hatch run type-check`: PASS (0 errors, 0 warnings). +- `hatch run lint`: PASS (Pylint 10.00/10). +- `hatch run yaml-lint`: PASS (seven manifests plus registry). +- `hatch run check-bundle-imports`: PASS. +- `hatch run verify-modules-signature --payload-from-filesystem --enforce-version-bump --allow-missing-public-key`: PASS for all seven modules. No signed payload or manifest changed, so no module version bump is required. The strict local-key form was also attempted and stopped only because this worktree does not contain the public key. +- `hatch run contract-test`: PASS (`28 passed, 1753 deselected`). +- Staged Requirements evidence gate at maturity `planned`: PASS with schema-v2 mappings for all changed scenarios and exact pytest selectors. +- `hatch run smart-test`: reached the full suite with one failure in `test_capsule_runtime_loads_the_packaged_signed_lock_before_materialization`; the same failure reproduces from an isolated clean `origin/dev` worktree at `870fea3d`, so it is baseline C14/environment debt rather than a regression from this change. +- `hatch run test`: `1780 passed, 1 failed`; the only failure is the same clean-`origin/dev` capsule-runtime baseline failure. +- `hatch run specfact code review run --enforcement changed --bug-hunt --json --out .specfact/code-review.json`: PASS after replacing one changed-file `print(..., file=sys.stderr)` warning; the worktree review reported schema 1.4, score 120, zero findings, exit code 0. +- The staged commit-hook review exposed three whole-file Pylint warnings in pre-existing test helpers; they were refactored and the focused tests/lint reran green. Its remaining advisory is environment-only: the external CrossHair process cannot import `pytest` while inspecting the staged test module. +- `git diff --check`: PASS. diff --git a/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/design.md b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/design.md new file mode 100644 index 00000000..06fef7f9 --- /dev/null +++ b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/design.md @@ -0,0 +1,21 @@ +## Overview + +Keep module precedence unchanged while removing guidance that turns normal shadowing into destructive cleanup. The modules repository only needs to describe the correct contract and protect that wording with focused tests; core owns runtime discovery and doctor output. + +## Decisions + +- Treat project-over-user shadowing as workspace-local precedence, not evidence of a stale or invalid user installation. +- State that the user copy remains installed and available in repositories without the project-scoped copy. +- Keep explicit user-initiated uninstall behavior unchanged. This change removes routine recommendations; it does not disable the command. +- Test the exact contributor-facing surfaces that caused the defect instead of adding a new runtime abstraction. +- Rename the local test bootstrap test to describe in-memory import eviction accurately. The helper changes `sys.path` and `sys.modules`; it does not delete installed files. + +## Risks + +- A user may still need to remove a genuinely unwanted duplicate. Mitigation: origin diagnostics remain available through `specfact module list --show-origin`, and explicit uninstall remains documented elsewhere. +- A wording-only regression could reintroduce destructive agent behavior. Mitigation: focused tests reject user-scope uninstall recommendations on these bootstrap surfaces. +- Core output could remain inconsistent with repository guidance. Mitigation: paired bug `nold-ai/specfact-cli#699` carries matching OpenSpec and tests. + +## Rollback + +Revert the guidance and test changes. No module data, installation state, manifest, registry row, or signature is migrated by this change. diff --git a/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/proposal.md b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/proposal.md new file mode 100644 index 00000000..70ed201f --- /dev/null +++ b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/proposal.md @@ -0,0 +1,37 @@ +## Why + +The modules repository tells development agents to uninstall user-scoped modules when a project-local copy shadows them. Review and bootstrap workflows repeatedly follow that instruction and remove `specfact-codebase` and `specfact-code-review` from the user scope, even though project-over-user precedence is expected and the user installation is still needed in other repositories. + +## What Changes + +- Replace destructive shadow-cleanup guidance in the development bootstrap and repository rules with an explicit preservation contract. +- Explain that project scope takes precedence only inside the current repository and does not delete or invalidate the user-scoped installation. +- Add regression coverage that fails if routine bootstrap guidance recommends `specfact module uninstall ... --scope user` again. +- Clarify the local test bootstrap name so in-memory import eviction cannot be mistaken for filesystem module removal. + +## Capabilities + +### Modified Capabilities + +- `agent-governance-loading`: Repository bootstrap guidance preserves valid user-scoped module installations when project-local sources shadow them. + +## Impact + +- Affected code and guidance: `src/specfact_cli_modules/dev_bootstrap.py`, `docs/agent-rules/20-repository-context.md`, and focused unit tests. +- Paired core behavior: `nold-ai/specfact-cli#699` removes the same destructive recommendation from discovery and doctor diagnostics. +- Registry and signed module payload impact: none. No `registry/index.json`, `packages/*/module-package.yaml`, or signed module asset changes are planned. +- Published docs impact: none; the affected rule is contributor/agent guidance rather than a modules.specfact.io page. + +--- + +## Source Tracking + + +- **Parent Epic**: [#162](https://github.com/nold-ai/specfact-cli-modules/issues/162) +- **Bug Issue**: [#452](https://github.com/nold-ai/specfact-cli-modules/issues/452) +- **Paired Core Bug**: [nold-ai/specfact-cli#699](https://github.com/nold-ai/specfact-cli/issues/699) +- **Issue Relationships**: `#452` is a sub-issue of Epic `#162`; the paired core bug is a sub-issue of Feature `nold-ai/specfact-cli#353`. +- **Blocked By**: none +- **Repository**: nold-ai/specfact-cli-modules +- **Last Synced Status**: issue type, labels, assignee, parent, project assignment, In Progress status, and blocker metadata verified on 2026-08-29 +- **Sanitized**: false diff --git a/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/requirements-evidence.yaml b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/requirements-evidence.yaml new file mode 100644 index 00000000..8f880e41 --- /dev/null +++ b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/requirements-evidence.yaml @@ -0,0 +1,42 @@ +schema_version: "2" +requirements: + openspec:module-scope-02-preserve-user-installs:agent-governance-loading:repository-bootstrap-guidance-preserves-user-scoped-modules: + rationale: "Repository and bootstrap guidance must preserve valid user-scoped installations during normal project shadowing." + stakeholder_refs: + - "nold-ai/specfact-cli-modules#452" + - "nold-ai/specfact-cli#699" + touchpoints: + - id: workspace-bootstrap-guidance + kind: source_file + locator: "src/specfact_cli_modules/dev_bootstrap.py" + - id: repository-scope-guidance + kind: documentation + locator: "docs/agent-rules/20-repository-context.md" + - id: local-source-alignment + kind: test_file + locator: "tests/unit/test_local_bundle_source_alignment.py" + verification_cases: + - case_id: MSI-MOD-001 + scenario_id: repository-bootstrap-guidance-preserves-user-scoped-modules + method: test + intent: "Prevent bootstrap guidance from recommending user-scope uninstall." + observable: "Bootstrap states that the user copy remains installed and available elsewhere." + selector: + runner: pytest + node_id: tests/unit/test_dev_bootstrap.py::test_workspace_env_guidance_preserves_user_scoped_modules + - case_id: MSI-MOD-002 + scenario_id: repository-bootstrap-guidance-preserves-user-scoped-modules + method: test + intent: "Prevent repository rules from recommending user-scope uninstall." + observable: "Repository guidance states that the user copy remains installed and available elsewhere." + selector: + runner: pytest + node_id: tests/unit/test_dev_bootstrap.py::test_repository_scope_guidance_preserves_user_scoped_modules + - case_id: MSI-MOD-003 + scenario_id: repository-bootstrap-guidance-preserves-user-scoped-modules + method: test + intent: "Keep in-memory import eviction distinct from filesystem module removal." + observable: "Local source alignment passes without deleting or uninstalling user-scoped files." + selector: + runner: pytest + node_id: tests/unit/test_local_bundle_source_alignment.py::test_enforce_local_bundle_sources_evicts_loaded_user_bundle_imports diff --git a/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/specs/agent-governance-loading/spec.md b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/specs/agent-governance-loading/spec.md new file mode 100644 index 00000000..1006d6fd --- /dev/null +++ b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/specs/agent-governance-loading/spec.md @@ -0,0 +1,20 @@ +## ADDED Requirements + +### Requirement: Repository bootstrap guidance preserves user-scoped modules + +Contributor and agent bootstrap guidance SHALL treat project-over-user module shadowing as workspace-local precedence and SHALL NOT prescribe deletion of the shadowed user-scoped installation as routine cleanup. + +#### Scenario: Project module shadows a user installation + +- **GIVEN** the same module id is installed in project scope and user scope +- **WHEN** an agent loads repository bootstrap or module-scope guidance +- **THEN** the guidance states that project scope takes precedence inside the current repository +- **AND** the guidance states that the user-scoped copy remains installed and usable outside the repository +- **AND** the guidance does not recommend a user-scope uninstall merely because the copy is shadowed + +#### Scenario: Local test bootstrap evicts an imported user module + +- **GIVEN** a test process imported a bundled module from the user-scoped source path +- **WHEN** the local bundle source bootstrap realigns the test process to repository sources +- **THEN** it removes the loaded module from in-memory import state or enforces an equivalent before-import guarantee that prevents reuse of the cached user-scoped module +- **AND** it does not delete or uninstall the user-scoped module files diff --git a/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/tasks.md b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/tasks.md new file mode 100644 index 00000000..3286fc4f --- /dev/null +++ b/openspec/changes/archive/2026-08-30-module-scope-02-preserve-user-installs/tasks.md @@ -0,0 +1,26 @@ +## 1. Governance and Scope + +- [x] 1.1 Create bug issue #452 with Bug type, labels, assignee, parent Epic #162, project assignment, In Progress status, and explicit no-blocker metadata. +- [x] 1.2 Cross-link paired core bug nold-ai/specfact-cli#699 and confirm no active change owns this corrective scope. +- [x] 1.3 Add and strictly validate the paired OpenSpec change before behavior edits. +- [x] 1.4 Keep the internal wiki source mirror aligned with both active public changes. + +## 2. Tests Before Implementation + +- [x] 2.1 Add a failing regression test for non-destructive development-bootstrap guidance. +- [x] 2.2 Add a failing regression test for non-destructive repository rule guidance. +- [x] 2.3 Rename the local import-isolation test so it does not imply filesystem uninstall behavior. +- [x] 2.4 Record the failing-before command and result in `TDD_EVIDENCE.md` before production edits. + +## 3. Implementation + +- [x] 3.1 Update the development bootstrap docstring to preserve shadowed user installations. +- [x] 3.2 Update repository context guidance to explain workspace-local precedence and no-action behavior. +- [x] 3.3 Keep registry, manifests, signed module payloads, and explicit uninstall behavior unchanged. + +## 4. Evidence and Delivery + +- [x] 4.1 Run focused passing tests and record passing-after evidence. +- [x] 4.2 Run format, type-check, lint, yaml-lint, bundle-import, contract, smart-test, full test, and applicable signature gates; document reproducible `origin/dev` baseline failures. +- [x] 4.3 Run SpecFact changed-scope bug-hunt review, resolve every finding, and record fresh JSON evidence. +- [x] 4.4 Commit with a signed Conventional Commit, push the bugfix branch, and open PR #454 to `dev` cross-linked to both issues and paired core PR #700. diff --git a/openspec/changes/preflight-02-assurance-runtime/CHANGE_VALIDATION.md b/openspec/changes/preflight-02-assurance-runtime/CHANGE_VALIDATION.md index 22f0385f..c816ad5d 100644 --- a/openspec/changes/preflight-02-assurance-runtime/CHANGE_VALIDATION.md +++ b/openspec/changes/preflight-02-assurance-runtime/CHANGE_VALIDATION.md @@ -12,8 +12,8 @@ ## Scope and Ownership Review -- Modules owns CLI orchestration, Python validators, rendering, persistence, and canonical bundled workflow content. -- Core `preflight-01-design-contract-core` owns the durable contract/result/seal/verifier interfaces. +- Modules owns CLI orchestration, Python validators for scope/component/risk/Requirements-plan readiness, rendering, persistence, and canonical bundled workflow content. +- Core `preflight-01-design-contract-core` owns the durable contract/result/seal/verifier interfaces and closed scope/risk/stage vocabulary. - Core #251 owns generic skill installation/export; core #253 owns generated instruction references; `preflight-04-harness-adapters` owns external packages. - Stable signing and publication remain downstream in modules `preflight-03-dogfood-hardening-and-release`. @@ -31,6 +31,9 @@ - Markdown lint limited to changed planning Markdown: PASS on 2026-08-25. - Staged schema-v2 Requirements planning evidence: PASS on 2026-08-25 with inspection-only cases and no test selectors or execution claims. - Review follow-up on 2026-08-27: strict OpenSpec validation and staged schema-v2 Requirements planning evidence PASS after the write-safety clarification; the diff remains planning-only. +- Review follow-up on 2026-08-30: `openspec validate preflight-02-assurance-runtime --strict` PASS after distinguishing ignored local working copies from the required tracked or independently attested shared canonical approval source and adding fresh-checkout `UNKNOWN` behavior; the diff remains planning-only. +- Second review follow-up on 2026-08-30: canonical state now requires an explicitly authorized approval write, the complete artifact/source-binding set, and either protected-history anchoring outside candidate control or an independent append-only/monotonic authority; read-only runs cannot write state. +- Third review follow-up on 2026-08-30: no-impact approval now requires an exact sealed-baseline observation plus a policy-authorized deterministic, role-supported, semantics-preserving permitted-transition predicate with closed change class and observable invariants; rationale and path/role alone cannot authorize an empty downstream semantic selection. ## Decision diff --git a/openspec/changes/preflight-02-assurance-runtime/design.md b/openspec/changes/preflight-02-assurance-runtime/design.md index 678f08e7..b60ac8db 100644 --- a/openspec/changes/preflight-02-assurance-runtime/design.md +++ b/openspec/changes/preflight-02-assurance-runtime/design.md @@ -22,7 +22,7 @@ The integration research reviewed on 2026-08-25 supports a canonical-skill plus - Publish or sign the module in this change. - Generate harness-specific files or edit project AGENTS.md. -- Implement postimplementation conformance. +- Implement worktree/index checkpoints or final range conformance. - Let prompts decide structural readiness independently of Python validators. ## Decisions @@ -33,7 +33,7 @@ The runtime state machine is `DISCOVER -> SNAPSHOT -> VALIDATE -> REVIEW`. A use ### 2. Read-only default and explicit persistence -`specfact preflight run ` is read-only by default. `--write` may persist normalized artifacts only after the user confirms exact target paths. The planned project-local layout is `.specfact/preflight//` with a contract, validation result, and approval seal. Final filenames and schemas are derived from the core contract tests before implementation. Any authorized refinement of a user-owned artifact routes through its owning workflow and the paired core safe-write contract, checks the expected source identity before commit, and preserves unrelated content rather than replacing the file wholesale. +`specfact preflight run ` is read-only by default and writes no local, project, or shared state. Only an explicitly authorized approval write may persist artifacts after the user confirms exact targets. The planned ignored project-local layout `.specfact/preflight//` may hold working copies of the contract, validation result, approval seal, and lineage-tip response, but it is never the canonical cross-checkout approval authority by itself. Repository policy that enables seal-aware enforcement SHALL identify a rollback-resistant canonical approval source that is either tracked with governed repository state and anchored to policy-authorized protected base/history outside candidate control, or independently attested by an authenticated append-only/monotonic authority. Either source must be immutable and shareable with a fresh clone or protected consumer and must let the verifier reject restoration of an older internally valid seal/tip. Canonical approval state consists of the contract, normalized validation result, seal, canonical lineage-tip record, and their source bindings. It binds the latest seal digest/monotonic sequence, complete predecessor-chain digest, registry/source identity, update authority, and repository/change/lineage identity; an authorized successor approval updates the complete set atomically. If the protected history/monotonic anchor or required shared state is unavailable, missing, stale, rolled back, forked, or ambiguous, selection is `UNKNOWN` and cannot fall back to a self-contained branch tip, local cache, or older valid ancestor. Final filenames, source adapters, and schemas are derived from the core contract tests before implementation. Any authorized refinement of a user-owned artifact routes through its owning workflow and the paired core safe-write contract, checks the expected source identity before commit, and preserves unrelated content rather than replacing the file wholesale. ### 3. Python validator registry @@ -44,7 +44,15 @@ Validators are Python implementations registered under stable IDs and versions. - request-to-scope and task-to-requirement traceability; - dependency graph completeness, native GitHub metadata, cycles, and readiness; - interface ownership and cross-repository counterpart consistency; -- acceptance criteria, test selectors, failing-first plan, rollback, and non-goals; +- role-classified implementation paths and explicit exclusions; +- component ownership with bounded pytest targets; +- approved influence mappings for every non-excluded sealed path and seal-bound test, dependency, policy, toolchain, or relevant configuration input, or an explicit no-impact disposition that binds the exact sealed input/path identity, role, baseline observation identity/digest, a non-empty rationale, and a policy-authorized deterministic permitted-transition predicate identity/version/configuration digest plus closed change-class and observable invariants; +- no-impact transition predicates must be supported and semantics-preserving for the input role, must not admit arbitrary content/behavior/configuration/dependency/execution changes, and must be evaluable later against exact provenance-bound base/current observations; otherwise influence mappings are mandatory; +- every closed core risk dimension (`boundary`, `malformed_or_missing_input`, `state_transition`, `idempotency`, `cache`, `error`, `status`, `timeout`, `unknown_precedence`, `path`, `repository_lifecycle`, `platform`, and `compatibility`) marked `covered` or `not_applicable`, with rationale where not applicable; +- covered risk rows mapped at `planned` maturity to existing Requirements requirement/scenario/case identities, method, intent, observable, and touchpoints without fabricating selectors; +- test-authored refinement that reconciles the Requirements-owned exact pytest selector to the same planned case, requires explicit successor-seal approval before production implementation, and preserves the original implementation-lineage baseline; +- earliest execution stage from `slice`, `commit`, `prepush`, or `ci`; +- acceptance criteria, failing-first plan, rollback, and non-goals; - active-issue/worktree collision and planning-only boundary checks. Validators return structured findings only. Rendering, policy aggregation, and persistence consume those results. @@ -67,10 +75,12 @@ General AGENTS.md/OpenSpec/Spec Kit instructions should contain only the gate: s - **Accidental artifact edits during review:** Default to read-only and require explicit target confirmation, source-owner routing, conflict detection, and preservation of unrelated user content. - **False-ready result from missing validators:** Required validator absence yields `UNKNOWN`, never success. - **Cross-repository race:** Capture repository refs and GitHub identities; stale identities invalidate approval. +- **False semantic coverage:** Missing component ownership, unresolved risk disposition, or stale Requirements plan identity is blocking or `UNKNOWN`, never inferred ready. +- **Duplicate selector ownership:** Reuse the existing Requirements maturity lifecycle: seal complete planned cases without selectors, then validate Requirements-owned exact selectors at test-authored maturity rather than creating a preflight-specific selector grammar. ## Migration and Rollback -The first implementation remains unpublished and dogfood-only. Repositories without the module continue their existing OpenSpec process. Before stable publication, rollback is removal of the opt-in module and its project-local `.specfact/preflight/` artifacts. +The first implementation remains unpublished and dogfood-only. Repositories without the module continue their existing OpenSpec process. Before stable publication, rollback is removal of the opt-in module and its project-local `.specfact/preflight/` working artifacts; canonical shared approval records follow their source-owned retention/revocation policy and are not silently deleted by local rollback. ## Open Questions Deferred to Implementation diff --git a/openspec/changes/preflight-02-assurance-runtime/proposal.md b/openspec/changes/preflight-02-assurance-runtime/proposal.md index 34c13607..64ca4480 100644 --- a/openspec/changes/preflight-02-assurance-runtime/proposal.md +++ b/openspec/changes/preflight-02-assurance-runtime/proposal.md @@ -6,12 +6,12 @@ Core contracts alone cannot stop an agent from implementing a stale or internall ## What Changes -- **NEW**: A future official `specfact-preflight` module with Python validators for artifact completeness, source freshness, scope traceability, dependency readiness, interface ownership, acceptance-testability, and conflicting active work. -- **NEW**: A future `specfact preflight run ` CLI that renders human and JSON results, supports read-only review by default, and persists an approved contract and seal only after explicit user approval. +- **NEW**: A future official `specfact-preflight` module with Python validators for artifact completeness, source freshness, role-classified scope, component ownership, approved influence mappings or justified no-impact dispositions for every non-excluded sealed input, risk-dimension disposition, Requirements-plan references, dependency readiness, interface ownership, acceptance-testability, and conflicting active work. A no-impact disposition must bind the sealed baseline observation and a policy-authorized deterministic permitted-transition predicate; path/role plus rationale alone cannot authorize empty downstream semantic selection. +- **NEW**: A future `specfact preflight run ` CLI that renders human and JSON results and is read-only by default. An explicitly authorized approval write may atomically persist local working copies of the normalized validation result, approved contract, seal, and lineage-tip response. It atomically persists canonical approval state—the normalized validation result, approved contract, seal, canonical lineage-tip record, and their source bindings—only in a policy-authorized rollback-resistant shared source. - **NEW**: A modules-owned bundled skill contract exposed as the harness-neutral `specfact-preflight` workflow and installable slash-command equivalent, such as `/specfact-preflight ` where the harness supports slash commands. - **NEW**: A deterministic loop: discover -> snapshot -> validate -> review -> user-approved refine/re-run -> approve -> seal -> verify-before-implementation. - **CLARIFY**: The skill orchestrates the CLI and presents evidence. It does not duplicate validator logic, silently edit ambiguous change artifacts, approve on behalf of a user, or implement production code. -- **EXCLUDE**: Stable publication, external ECC/hatch3r/Codex adapters, and postimplementation conformance are separate downstream changes. +- **EXCLUDE**: Stable publication, external ECC/hatch3r/Codex adapters, and seal-bound implementation checkpoint/conformance execution are separate downstream changes. ## Capabilities @@ -39,7 +39,7 @@ Core contracts alone cannot stop an agent from implementing a stale or internall ## Explicit Non-Goals -- No stable module publication, compatibility promotion, signing, external harness packaging, or postimplementation comparison. +- No stable module publication, compatibility promotion, signing, external harness packaging, checkpoint execution, or final implementation comparison. - No AGENTS.md/OpenSpec/Spec Kit instruction generation; core `ai-integration-03-instruction-files` owns generated instruction surfaces. - No generic skill discovery or export; core `ai-integration-01-agent-skill` owns that distribution mechanism. - No proof that an LLM, design, or future implementation is correct. diff --git a/openspec/changes/preflight-02-assurance-runtime/requirements-evidence.yaml b/openspec/changes/preflight-02-assurance-runtime/requirements-evidence.yaml index bdd55e96..e202f7a0 100644 --- a/openspec/changes/preflight-02-assurance-runtime/requirements-evidence.yaml +++ b/openspec/changes/preflight-02-assurance-runtime/requirements-evidence.yaml @@ -71,7 +71,31 @@ requirements: - case_id: PF02-005 scenario_id: persisted-approval-artifacts method: inspection - intent: "Inspect the persisted approval artifacts planning contract before implementation." + intent: >- + Inspect separate normalized validation-result persistence, atomic + shared approval artifacts, canonical lineage-tip advance, + missing/stale/rollback/fork/ambiguity handling, and rejection of + older-ancestor fallback before implementation. + observable: >- + Strict OpenSpec validation retains the requirement and its scenarios + without claiming implementation or test execution. + - case_id: PF02-009 + scenario_id: persisted-approval-artifacts + method: inspection + intent: >- + Inspect tracked or independently attested shared approval authority + and fresh-checkout UNKNOWN behavior when required canonical state is + unavailable. + observable: >- + Strict OpenSpec validation retains the requirement and its scenarios + without claiming implementation or test execution. + - case_id: PF02-010 + scenario_id: persisted-approval-artifacts + method: inspection + intent: >- + Inspect explicit approval-write authorization, complete canonical + artifact/source-binding persistence, and rollback-resistant protected + history or independent monotonic anchoring. observable: >- Strict OpenSpec validation retains the requirement and its scenarios without claiming implementation or test execution. @@ -101,7 +125,13 @@ requirements: - case_id: PF02-007 scenario_id: required-mvp-validation-domains method: inspection - intent: "Inspect the required mvp validation domains planning contract before implementation." + intent: >- + Inspect the required MVP validation domains, including approved + influence mappings or no-impact dispositions bound to an exact sealed + baseline and policy-authorized deterministic permitted-transition + predicate/change-class/observable invariants for every non-excluded + sealed path and seal-bound test, dependency, policy, toolchain, or + relevant configuration input, before implementation. observable: >- Strict OpenSpec validation retains the requirement and its scenarios without claiming implementation or test execution. diff --git a/openspec/changes/preflight-02-assurance-runtime/specs/preflight-assurance-runtime/spec.md b/openspec/changes/preflight-02-assurance-runtime/specs/preflight-assurance-runtime/spec.md index 852ae16a..987664c8 100644 --- a/openspec/changes/preflight-02-assurance-runtime/specs/preflight-assurance-runtime/spec.md +++ b/openspec/changes/preflight-02-assurance-runtime/specs/preflight-assurance-runtime/spec.md @@ -35,7 +35,7 @@ The preflight command SHALL inspect and render without modifying change artifact - **WHEN** the user authorizes those edits - **THEN** the orchestration applies only the approved edits through the owning workflow - **AND** the owning workflow reuses the paired core safe-write contract, rejects concurrent source drift, and preserves unrelated user-owned content -- **AND** captures a new source snapshot and reruns every required validator before approval. +- **AND** captures a new source snapshot, binds the predecessor seal where implementation work already exists, preserves the immutable implementation-lineage origin baseline, and reruns every required validator before approval. ### Requirement: Versioned Python validator registry @@ -57,7 +57,7 @@ The module SHALL run validators identified by stable ID and version and SHALL di ### Requirement: Required MVP validation domains -The initial runtime SHALL validate artifact completeness, source freshness, scope traceability, dependency readiness, interface ownership, acceptance-testability, and conflicting active work. +The initial runtime SHALL validate artifact completeness, source freshness, role-classified scope, component ownership, per-input influence or no-impact disposition, risk-dimension disposition, Requirements-plan identity, dependency readiness, interface ownership, acceptance-testability, and conflicting active work. A no-impact disposition SHALL bind the exact sealed input/path identity and role, its baseline observation identity/digest, a non-empty rationale, and a policy-authorized deterministic permitted-transition predicate identity/version/configuration digest with a closed change class and observable invariants. The predicate SHALL be supported and semantics-preserving for that role, SHALL NOT admit arbitrary content, behavior, configuration, dependency, or execution changes, and SHALL be evaluable by a later checkpoint against exact provenance-bound base/current observations. If those properties cannot be established, the input SHALL require explicit influence mappings instead. Risk validation SHALL require every affected behavior or interface to contain the closed core dimensions `boundary`, `malformed_or_missing_input`, `state_transition`, `idempotency`, `cache`, `error`, `status`, `timeout`, `unknown_precedence`, `path`, `repository_lifecycle`, `platform`, and `compatibility`. #### Scenario: Scope has no acceptance or test trace @@ -66,6 +66,48 @@ The initial runtime SHALL validate artifact completeness, source freshness, scop - **THEN** they emit a blocking finding against the owning artifact path - **AND** the result identifies the refinement target. +#### Scenario: Source scope cannot select semantic evidence + +- **GIVEN** a governed source path has no component owner or bounded pytest targets +- **WHEN** scope and testability validators run +- **THEN** they emit a blocking finding against the source scope entry +- **AND** later implementation checkpoints are not described as selectable. + +#### Scenario: Sealed input lacks an influence disposition + +- **GIVEN** a non-excluded source, test, docs, generated, or evidence path or a seal-bound test, dependency, policy, toolchain, or relevant configuration input has neither approved influence mappings to every obligation it can affect nor a complete policy-authorized no-impact transition disposition +- **WHEN** scope and testability validators run +- **THEN** readiness is blocked or unknown according to source availability +- **AND** no approval seal is issued with an input that a downstream checkpoint would have to map by inference. + +#### Scenario: No-impact disposition cannot constrain the future delta + +- **GIVEN** a proposed no-impact disposition omits or ambiguously binds its exact sealed baseline observation, predicate identity/version/configuration, closed permitted change class, observable invariants, or role support, or its predicate admits arbitrary semantic or execution-relevant changes +- **WHEN** scope and testability validators run +- **THEN** readiness is blocked or unknown according to source availability +- **AND** path/role identity plus rationale alone cannot authorize a downstream empty semantic-selector set. + +#### Scenario: Risk dimension lacks an explicit disposition + +- **GIVEN** an affected behavior omits a closed risk dimension, marks it covered without a complete existing Requirements case at planned maturity or stronger, or marks it not applicable without a rationale +- **WHEN** semantic-risk validation runs +- **THEN** readiness is blocked or unknown according to source availability +- **AND** the missing case is not inferred from filenames or prose. + +#### Scenario: Planned covered risk declares its execution stage + +- **GIVEN** a covered risk references an existing complete Requirements verification case at `planned` maturity with stable case identity, method, intent, observable, and touchpoints but no authored test +- **WHEN** verification intent is validated +- **THEN** the contract retains the planned mapping/plan and case identities plus `slice`, `commit`, `prepush`, or `ci` as its earliest required stage without fabricating a selector +- **AND** the result records test-authored selector reconciliation as required before production implementation. + +#### Scenario: Failing-first test creates the exact selector + +- **GIVEN** an approved planned case has no selector and failing-first test authoring produces a Requirements-owned test-authored plan +- **WHEN** preflight validates the refinement +- **THEN** it requires the same requirement/scenario/case identity, method, intent, observable, touchpoints, and declared stage plus a valid exact pytest selector under the existing Requirements contract +- **AND** production implementation waits for explicit approval of a successor seal that binds the predecessor and preserves the implementation-lineage origin baseline. + #### Scenario: GitHub dependency metadata disagrees with proposal - **GIVEN** proposal dependencies and native GitHub blocked-by relationships differ @@ -86,7 +128,7 @@ The CLI SHALL derive human and JSON output from the same normalized validation r ### Requirement: Persisted approval artifacts -When explicitly requested, the runtime SHALL persist the normalized contract, validation result, and seal atomically under a project-local, change-specific path. +Only during an explicitly authorized approval write MAY the runtime atomically persist working copies of the normalized contract, validation result, seal, and lineage-tip response under an ignored project-local, change-specific path; that path SHALL NOT be the canonical cross-checkout approval authority by itself. Seal-aware repository policy SHALL identify a rollback-resistant canonical approval source that is either tracked with governed repository state and anchored to policy-authorized protected base/history outside candidate control, or independently attested by an authenticated append-only/monotonic authority. Either source SHALL be immutable and shareable with a fresh clone or protected consumer and SHALL permit rejection of an older internally valid seal/tip restoration. During that explicitly authorized approval write, the runtime SHALL atomically persist the normalized contract, validation result, seal, canonical lineage-tip record, and their source bindings to the canonical source. The tip SHALL bind the repository, change, and lineage identities, latest seal digest and monotonic sequence, complete predecessor-chain digest, registry/source identity, protected-history or independent-monotonic anchor, and update authority. A successor approval SHALL advance the complete canonical set exactly once; an ancestor seal SHALL NOT remain representable as the current tip. A read-only preflight run SHALL write no local, project, or shared state. #### Scenario: Persistence is interrupted @@ -95,6 +137,29 @@ When explicitly requested, the runtime SHALL persist the normalized contract, va - **THEN** no partial set is treated as a valid approved contract - **AND** the runtime reports a non-ready persistence result. +#### Scenario: Canonical lineage tip cannot be established + +- **GIVEN** persisted approval artifacts contain a missing, stale, rolled-back, forked, or ambiguously current lineage-tip record +- **WHEN** the approval source is read for checkpoint or conformance handoff +- **THEN** current-seal selection is `UNKNOWN` and non-passing +- **AND** an older valid ancestor seal is not substituted for the canonical latest seal. + +#### Scenario: Fresh checkout cannot access required approval authority + +- **GIVEN** repository policy or authoritative base provenance requires seal-aware approval state +- **AND** a fresh clone or protected consumer can access only an ignored local cache or cannot authenticate the policy-authorized shared approval source +- **WHEN** the runtime selects a seal or lineage tip +- **THEN** selection is `UNKNOWN` and non-passing rather than `NOT_APPLICABLE` +- **AND** local absence cannot reclassify the governed repository as never sealed. + +#### Scenario: Tracked approval state lacks an independent rollback anchor + +- **GIVEN** a branch contains an internally valid older seal and matching tip +- **AND** the tracked approval source cannot be verified against policy-authorized protected base/history outside candidate control or an independent append-only/monotonic authority +- **WHEN** the runtime selects canonical approval state +- **THEN** selection is `UNKNOWN` and non-passing +- **AND** the self-contained branch state cannot establish itself as the latest canonical tip. + ### Requirement: Canonical skill and slash-command contract The future module SHALL bundle one canonical `specfact-preflight` workflow that invokes the deterministic CLI and can be exported to harness-native invocation forms. diff --git a/openspec/changes/preflight-02-assurance-runtime/tasks.md b/openspec/changes/preflight-02-assurance-runtime/tasks.md index 309524fa..d8ce9e76 100644 --- a/openspec/changes/preflight-02-assurance-runtime/tasks.md +++ b/openspec/changes/preflight-02-assurance-runtime/tasks.md @@ -10,15 +10,15 @@ All tasks below are future implementation work. This planning change completes n ## 2. Specification and failing-first evidence -- [ ] 2.1 Finalize CLI, validator registry, persistence, renderer, and canonical workflow deltas without adding publication or external adapters. -- [ ] 2.2 Add tests mapped to every runtime and workflow scenario, including read-only defaults, unknown fail-closed behavior, approval invalidation, and renderer parity. +- [ ] 2.1 Finalize CLI, validator registry, scope-role, component, per-input influence/no-impact including sealed-baseline and deterministic permitted-transition bindings, risk-disposition, Requirements-plan reference, verification-stage, persistence, renderer, and canonical workflow deltas without adding checkpoint execution, publication, or external adapters. +- [ ] 2.2 Add tests mapped to every runtime and workflow scenario, including invalid path roles, missing component targets, missing/ambiguous influence dispositions, no-impact dispositions missing exact baseline or predicate identity/version/configuration/closed change class/observable invariants, unsupported or arbitrary semantic transition predicates, uncovered/not-applicable risk rows, planned cases without selectors, planned-to-test-authored selector reconciliation, successor-seal lineage preservation, separate normalized validation-result persistence, explicit approval-write authorization and read-only no-write behavior, complete canonical artifact/source-binding atomicity, protected-history or independent-monotonic rollback anchoring, fresh-checkout transport, canonical-tip advance plus missing/stale/rollback/fork/ambiguity handling and older-ancestor fallback rejection, required shared-source/anchor unavailability as `UNKNOWN` rather than `NOT_APPLICABLE`, stale Requirements plans, unknown fail-closed behavior, approval invalidation, and renderer parity. - [ ] 2.3 Run targeted tests before production edits, capture failing-first results, and create `TDD_EVIDENCE.md` with the red evidence. ## 3. Minimal unpublished runtime implementation - [ ] 3.1 Implement the official module boundary and `specfact preflight run ` orchestration against the released core interfaces. -- [ ] 3.2 Implement the required versioned Python validators and deterministic readiness aggregation. -- [ ] 3.3 Implement human/JSON rendering and explicit, atomic persistence of approved artifacts. +- [ ] 3.2 Implement the required versioned Python validators and deterministic readiness aggregation, reusing Requirements maturity/selector/plan contracts by identity and preserving the implementation-lineage origin across successor seals. +- [ ] 3.3 Implement human/JSON rendering, optional ignored local working copies, and explicitly authorized atomic persistence of the complete canonical artifact/source-binding set through the policy-authorized protected-history-anchored or independent-monotonic shared approval source. - [ ] 3.4 Implement the canonical bundled workflow content and slash-command metadata without adding ECC, hatch3r, Codex-plugin, or other external adapter packages. ## 4. Passing evidence and quality gates @@ -31,6 +31,6 @@ All tasks below are future implementation work. This planning change completes n ## 5. Delivery and post-merge cleanup -- [ ] 5.1 Prove the implementation remains unpublished and excludes external adapters and postimplementation conformance. +- [ ] 5.1 Prove the implementation remains unpublished and excludes external adapters, checkpoint execution, and final conformance. - [ ] 5.2 Open the implementation PR to `dev` as the final pre-merge task, linking both repositories and all evidence. - [ ] 5.3 After merge, run `openspec archive preflight-02-assurance-runtime`, update ordering/source mirrors, and remove the dedicated worktree and merged branch. diff --git a/openspec/changes/preflight-03-dogfood-hardening-and-release/CHANGE_VALIDATION.md b/openspec/changes/preflight-03-dogfood-hardening-and-release/CHANGE_VALIDATION.md index e81fa33c..07975cbc 100644 --- a/openspec/changes/preflight-03-dogfood-hardening-and-release/CHANGE_VALIDATION.md +++ b/openspec/changes/preflight-03-dogfood-hardening-and-release/CHANGE_VALIDATION.md @@ -21,7 +21,7 @@ - Parent Feature: modules [#163](https://github.com/nold-ai/specfact-cli-modules/issues/163). - Native direct blockers verified: modules [#431](https://github.com/nold-ai/specfact-cli-modules/issues/431) and paired core [#683](https://github.com/nold-ai/specfact-cli/issues/683). - Required transitive sequence verified: core [#682](https://github.com/nold-ai/specfact-cli/issues/682) -> modules #431 -> core C14 [#680](https://github.com/nold-ai/specfact-cli/issues/680) -> core #683 -> this change. -- Native downstream edges verified: core #251, modules adapters #433, both preflight-05 stories, and modules C15 #417. +- Native downstream sequence verified: this #432 release blocks core #684 and modules C15 #417; modules #434 then consumes #432 plus core #684 and blocks core #251 -> #253 -> modules #433. - GitHub readback verified User Story type, parent #163, project `SpecFact CLI` / `Todo`, assignee `djm81`, and the required labels. - Modules C14 #416 is referenced as delivered-by-publication context but remains untouched while GitHub shows it `In Progress`. diff --git a/openspec/changes/preflight-03-dogfood-hardening-and-release/design.md b/openspec/changes/preflight-03-dogfood-hardening-and-release/design.md index 26109a64..b7ae13a6 100644 --- a/openspec/changes/preflight-03-dogfood-hardening-and-release/design.md +++ b/openspec/changes/preflight-03-dogfood-hardening-and-release/design.md @@ -48,7 +48,7 @@ Publication is blocked until the selected registry and installer expose a suppor - **Overfitting to C14:** Require generalized rules plus a bounded independent regression corpus. - **Compatibility overclaim:** Pin only tested identities and retain explicit matrix evidence. - **Signed asset drift:** Run filesystem-payload signature verification with version-bump enforcement before publication. -- **Downstream race:** Publish immutable handoff identities before unblocking #251, conformance, or C15. +- **Downstream race:** Publish immutable handoff identities before unblocking core #684 or C15. Modules #434 consumes this handoff plus core #684 before #251/#253/#433 can proceed. ## Migration and Rollback diff --git a/openspec/changes/preflight-03-dogfood-hardening-and-release/proposal.md b/openspec/changes/preflight-03-dogfood-hardening-and-release/proposal.md index 9f067031..1c8caa15 100644 --- a/openspec/changes/preflight-03-dogfood-hardening-and-release/proposal.md +++ b/openspec/changes/preflight-03-dogfood-hardening-and-release/proposal.md @@ -35,7 +35,7 @@ The unpublished preflight runtime must not become a stable module or a dependenc - Blocked by modules `preflight-02-assurance-runtime` [#431](https://github.com/nold-ai/specfact-cli-modules/issues/431) and paired core `preflight-03-dogfood-hardening-and-release` readiness evidence [#683](https://github.com/nold-ai/specfact-cli/issues/683). - Required selection order is core contract [#682](https://github.com/nold-ai/specfact-cli/issues/682) -> modules #431 -> core C14 [#680](https://github.com/nold-ai/specfact-cli/issues/680) -> core #683 -> this change; transitive prerequisites cannot be skipped merely because #431 and #683 are the direct native blockers. - Publication is also conditional on a released core installer/registry contract that can reject a withdrawn exact version; absence of that interface requires a separately accepted core change before release work proceeds. -- Blocks core `ai-integration-01-agent-skill` [#251](https://github.com/nold-ai/specfact-cli/issues/251), modules `preflight-04-harness-adapters` [#433](https://github.com/nold-ai/specfact-cli-modules/issues/433), both `preflight-05-implementation-conformance` stories, and modules C15 [#417](https://github.com/nold-ai/specfact-cli-modules/issues/417). +- Blocks core `preflight-05-implementation-conformance` [#684](https://github.com/nold-ai/specfact-cli/issues/684) and modules C15 [#417](https://github.com/nold-ai/specfact-cli-modules/issues/417). Modules #434 then consumes both this stable #432 handoff and core #684; core #251/#253 and modules #433 remain downstream of signed #434. ## Explicit Non-Goals diff --git a/openspec/changes/preflight-03-dogfood-hardening-and-release/tasks.md b/openspec/changes/preflight-03-dogfood-hardening-and-release/tasks.md index 43ab66b6..46bb2709 100644 --- a/openspec/changes/preflight-03-dogfood-hardening-and-release/tasks.md +++ b/openspec/changes/preflight-03-dogfood-hardening-and-release/tasks.md @@ -32,5 +32,5 @@ All tasks below are future implementation and release work. This planning change - [ ] 5.1 Open, review, and merge the behavior-ready implementation PR to `dev`, linking the paired core evidence and issue; feature-branch artifacts are not publishable release identities. - [ ] 5.2 Allow only the canonical post-merge publish workflow to generate, sign, and propose registry/archive/checksum/signature/history artifacts; review and merge that publication PR only after immutable artifact, registry, checksum, signature, core-compatibility, signed workflow version/digest, delegated CLI identity, history, rollback-operation, installer-rejection, and persisted-state rollback identities pass. Verify that every post-publication correction or withdrawal uses a new patch version and retains the prior artifact, digest, signature, registry record, and release-history entry unchanged. -- [ ] 5.3 Update downstream issues with the exact merged stable handoff, including the signed workflow version/digest and delegated CLI identity. Publication-PR merge and registry/install readback may unblock #251, #433, or C15; conformance remains blocked until the #432 stable handoff plus modules #433 and core #684 handoffs are each complete and read back. +- [ ] 5.3 Update downstream issues with the exact merged stable handoff, including the signed workflow version/digest and delegated CLI identity. Publication-PR merge and registry/install readback may unblock core #684 and C15. Modules #434 remains blocked until both this #432 handoff and core #684 are complete; #251, #253, and #433 remain downstream of signed #434 and never block it. - [ ] 5.4 After implementation merge and verified publication, run `openspec archive preflight-03-dogfood-hardening-and-release`, update ordering/source mirrors, and remove the dedicated worktree and merged branch. diff --git a/openspec/changes/preflight-04-harness-adapters/CHANGE_VALIDATION.md b/openspec/changes/preflight-04-harness-adapters/CHANGE_VALIDATION.md index bd84c5b0..6a969b7c 100644 --- a/openspec/changes/preflight-04-harness-adapters/CHANGE_VALIDATION.md +++ b/openspec/changes/preflight-04-harness-adapters/CHANGE_VALIDATION.md @@ -14,12 +14,20 @@ - This change owns thin Codex, ECC, and hatch3r installation/invocation adapters. - The signed modules runtime remains the only validator/readiness implementation. -- Core #251 owns generic installation/export and core #253 owns generated instruction references. +- Core #251 owns generic installation/export and must expose the explicit `verified-install-result-v1` contract defined by this planning change; core #253 owns generated instruction references. ## Dependency Review - Parent Feature: modules [#163](https://github.com/nold-ai/specfact-cli-modules/issues/163). -- Native blocker verified: core [#253](https://github.com/nold-ai/specfact-cli/issues/253), transitively after #251 and the stable modules preflight release. +- Required delivery order: signed modules checkpoint/conformance identity #434, + then core #251 and #253, then this adapter change #433. +- Adapter implementation remains blocked until the completed #251 contract binds + verifier, module, artifact, signed manifest, registry, signer/trust root, core, + installed inventory, and both role-specific workflow mappings to the exact + installed bytes and requested descriptor. +- Native dependency relationships must be refreshed and read back before + implementation so #433 consumes the exact #434 identity and does not become + a prerequisite of #434. - GitHub readback verified User Story type, parent #163, project `SpecFact CLI` / `Todo`, assignee `djm81`, and the required labels. - External upstream issues/PRs are future separately authorized work and do not exist yet. diff --git a/openspec/changes/preflight-04-harness-adapters/design.md b/openspec/changes/preflight-04-harness-adapters/design.md index 33062c33..975dcc10 100644 --- a/openspec/changes/preflight-04-harness-adapters/design.md +++ b/openspec/changes/preflight-04-harness-adapters/design.md @@ -1,6 +1,6 @@ ## Context -The stable module owns one canonical workflow. This change maps that workflow into three first-party/companion installation shapes without turning any harness package into a second validation engine. +The stable #434 module identity owns canonical preflight and implementation-check workflows. This change maps those workflows into three first-party/companion installation shapes without turning any harness package into a second validation engine. Current primary-source observations reviewed on 2026-08-25: @@ -29,7 +29,9 @@ These are integration inputs, not permanent assumptions. Each adapter must decla ### 1. Shared adapter descriptor -Every adapter consumes a descriptor containing the exact SpecFact module version, artifact digest, authorized signature/trust-root identity, registry identity, compatible core identity, canonical workflow identity/digest, supported harness and version range, native invocation form, asset mapping, instruction markers, install scope, and uninstall inventory. It consumes the official installer's verified result when that interface owns verification. Invalid, untrusted, unsupported, or mismatched identities fail closed before installation, upgrade, invocation, or packaging. +Every adapter consumes a descriptor containing three separately named release inputs: the exact signed SpecFact #434 module version/artifact digest/signature/trust-root/registry identity, the preflight workflow identity/digest, and the implementation-check workflow identity/digest. The descriptor also binds compatible core identity, supported harness and version range, native invocation form, asset mapping, instruction markers, install scope, and uninstall inventory. + +Core #251 must first define and ship `verified-install-result-v1`. A successful result binds the verifier identity/version, requested and installed module version, artifact and signed-manifest digests, registry, signer/trust root, compatible core, exact installed asset inventory/digests, and both role-specific signed-manifest workflow mappings to the installed bytes and requested descriptor. Every adapter consumes that result and proves the preflight identity-to-digest and implementation-check identity-to-digest mappings. Missing, unsuccessful, stale, incomplete, untrusted, omitted, mismatched, or cross-paired evidence fails closed before installation, upgrade, invocation, or packaging. Descriptor text and adapter-generated assertions are not verification fallbacks. ### 2. Codex plugin is an installation shell diff --git a/openspec/changes/preflight-04-harness-adapters/proposal.md b/openspec/changes/preflight-04-harness-adapters/proposal.md index 134e30fd..7ac7a2ea 100644 --- a/openspec/changes/preflight-04-harness-adapters/proposal.md +++ b/openspec/changes/preflight-04-harness-adapters/proposal.md @@ -25,19 +25,19 @@ The stable preflight workflow should be installable in compatible agent harnesse ## Impact - Planning artifacts only in this phase. No plugin, skill file, command shim, pack, manifest, hook, workflow, dependency, publication artifact, or external repository contribution is created. -- Future implementation consumes the stable signed module workflow, core #251 installation/export behavior, and core #253 generated instruction contract. +- Future implementation consumes the exact signed #434 module identity plus the separately named preflight workflow identity/digest and implementation-check workflow identity/digest, core #251 installation/export behavior, and core #253 generated instruction contract. - Each external repository contribution requires its own accepted upstream issue/PR and must preserve that project's current contribution and packaging rules. An accepted contribution does not authorize packaging until it is merged and the selected hatch3r release contains and documents the supported surface. The implementation must not write hatch3r's internal inventory or claim a third-party pack API that the selected release does not document. ## Dependencies - Parent Feature: modules [#163](https://github.com/nold-ai/specfact-cli-modules/issues/163). -- Blocked by core `ai-integration-03-instruction-files` [#253](https://github.com/nold-ai/specfact-cli/issues/253), which is blocked by #251 and the stable preflight module handoff. -- Consumes the signed module identity from paired modules `preflight-03-dogfood-hardening-and-release` transitively; no feature-branch asset may be packaged. +- Blocked by core `ai-integration-03-instruction-files` [#253](https://github.com/nold-ai/specfact-cli/issues/253), which is blocked by #251 and the signed modules #434 handoff. +- Consumes the signed #434 module identity and both separately named workflow identities/digests from modules `preflight-05-implementation-conformance`; no feature-branch asset may be packaged. - hatch3r support is additionally blocked until the selected release contains and documents a supported third-party distribution/extension mechanism. A separately accepted upstream change is insufficient until it is merged, released, and documented in that selected release. ## Explicit Non-Goals -- No new validators, readiness policy, contract schema, approval behavior, or conformance logic. +- No new validators, readiness policy, contract schema, approval behavior, checkpoint logic, or conformance logic. - No hooks that bypass explicit user approval or automatically edit source artifacts. - No promise of harness support beyond versions and platforms proved by adapter tests. - No external repository write or publication during this planning-only setup. diff --git a/openspec/changes/preflight-04-harness-adapters/requirements-evidence.yaml b/openspec/changes/preflight-04-harness-adapters/requirements-evidence.yaml index 84587e4a..54b18b14 100644 --- a/openspec/changes/preflight-04-harness-adapters/requirements-evidence.yaml +++ b/openspec/changes/preflight-04-harness-adapters/requirements-evidence.yaml @@ -1,5 +1,22 @@ schema_version: "2" requirements: + openspec:preflight-04-harness-adapters:preflight-harness-adapters:core-installer-verification-result-is-explicit: + rationale: "The proposal must block adapter implementation until core #251 exposes a result bound to the exact verified installation." + stakeholder_refs: + - "nold-ai/specfact-cli-modules#433" + - "nold-ai/specfact-cli#251" + touchpoints: + - id: openspec-source-spec + kind: config_file + locator: "openspec/changes/preflight-04-harness-adapters/specs/preflight-harness-adapters/spec.md" + verification_cases: + - case_id: PF04-008 + scenario_id: core-installer-verification-result-is-explicit + method: inspection + intent: "Inspect the explicit verified-install-result-v1 prerequisite and fail-closed behavior before implementation." + observable: >- + Strict OpenSpec validation retains the complete result binding and + prohibits descriptor-only or adapter-generated verification fallback. openspec:preflight-04-harness-adapters:preflight-harness-adapters:codex-plugin-adapter: rationale: "The proposal must make this requirement reviewable before implementation begins." stakeholder_refs: ["nold-ai/specfact-cli-modules#433"] @@ -86,7 +103,7 @@ requirements: - case_id: PF04-006 scenario_id: shared-adapter-identity-contract method: inspection - intent: "Inspect the shared adapter identity contract planning contract before implementation." + intent: "Inspect the signed #434 module plus separate preflight and implementation-check workflow identity/digest contract before implementation." observable: >- Strict OpenSpec validation retains the requirement and its scenarios without claiming implementation or test execution. diff --git a/openspec/changes/preflight-04-harness-adapters/specs/preflight-harness-adapters/spec.md b/openspec/changes/preflight-04-harness-adapters/specs/preflight-harness-adapters/spec.md index 5a972dbd..89565294 100644 --- a/openspec/changes/preflight-04-harness-adapters/specs/preflight-harness-adapters/spec.md +++ b/openspec/changes/preflight-04-harness-adapters/specs/preflight-harness-adapters/spec.md @@ -1,8 +1,19 @@ ## ADDED Requirements +### Requirement: Core installer verification result is explicit + +Before adapter implementation begins, core #251 SHALL define and ship a machine-readable `verified-install-result-v1` for the exact installed or exported assets. A successful result SHALL bind the verification outcome, verifier identity and version, requested and installed module version, artifact and signed-manifest digests, registry identity, authorized signer and trust-root identity, compatible core identity, installed asset inventory and digests, and the signed-manifest mappings for both the preflight and implementation-check workflow identities and digests. The result SHALL be bound to the installed bytes and the requested adapter descriptor. A missing, unsuccessful, stale, incomplete, or mismatched result SHALL fail closed. Adapters SHALL NOT replace it with descriptor text or an adapter-generated verification assertion. + +#### Scenario: Core installer result contract is unavailable + +- **GIVEN** core #251 does not expose `verified-install-result-v1` with every required identity and digest binding +- **WHEN** adapter implementation, installation, upgrade, invocation, or packaging is requested +- **THEN** the adapter work remains blocked +- **AND** adapter-owned verification is not used as an implicit fallback. + ### Requirement: Shared adapter identity contract -Every harness adapter SHALL declare and verify the exact SpecFact module version, artifact digest, authorized signature/trust-root identity, registry identity, compatible core identity, canonical workflow identity/digest, supported harness versions, native invocation mapping, installed asset inventory, and upgrade/uninstall rules. When the released installer owns cryptographic verification, adapters SHALL consume its verified result and SHALL bind the installed workflow digest to the signed artifact before installation, upgrade, invocation, or packaging. +Every harness adapter SHALL declare and verify the exact signed #434 module version, artifact digest, authorized signature/trust-root identity, registry identity, compatible core identity, separately named preflight workflow identity/digest and implementation-check workflow identity/digest, supported harness versions, native invocation mapping, installed asset inventory, and upgrade/uninstall rules. Adapters SHALL consume the successful core #251 `verified-install-result-v1` and SHALL verify the role-specific manifest mappings `preflight workflow identity -> preflight workflow digest` and `implementation-check workflow identity -> implementation-check workflow digest` before installation, upgrade, invocation, or packaging. Presence of both identities and both digests without the correct pairings SHALL NOT satisfy verification. #### Scenario: Immutable release identity does not match @@ -13,7 +24,7 @@ Every harness adapter SHALL declare and verify the exact SpecFact module version #### Scenario: Signature or installed workflow is invalid or untrusted -- **GIVEN** signature verification fails against the authorized trust root, the verified installer result is absent, or the installed workflow digest differs from the signed artifact and canonical workflow identity +- **GIVEN** signature verification fails against the authorized trust root, `verified-install-result-v1` is absent, unsuccessful, stale, incomplete, or mismatched, either role-specific workflow identity/digest pair is omitted or mismatched, the identities/digests are cross-paired, or either installed workflow digest differs from its corresponding signed manifest mapping - **WHEN** installation, upgrade, invocation, or packaging is requested - **THEN** the adapter fails closed before the operation - **AND** it does not treat descriptor text alone as verification. @@ -102,5 +113,5 @@ Codex, ECC, and hatch3r adapters SHALL preserve the canonical workflow phases, C - **GIVEN** fixtures for all supported adapter/version pairs - **WHEN** the parity matrix evaluates generated assets and invocations -- **THEN** every adapter maps to the same canonical workflow identity and semantics +- **THEN** every adapter maps to the same signed #434 module identity plus the same preflight and implementation-check workflow identities/digests and semantics - **AND** platform-specific syntax differences are explicitly recorded rather than treated as workflow differences. diff --git a/openspec/changes/preflight-04-harness-adapters/tasks.md b/openspec/changes/preflight-04-harness-adapters/tasks.md index 0e0965b5..f0efb96d 100644 --- a/openspec/changes/preflight-04-harness-adapters/tasks.md +++ b/openspec/changes/preflight-04-harness-adapters/tasks.md @@ -6,18 +6,18 @@ All tasks below are future implementation and external integration work. This pl - [ ] 1.1 In a dedicated issue-linked session, create `feature/preflight-04-harness-adapters` from current `origin/dev` in a new modules worktree before any implementation edit. - [ ] 1.2 Refresh hierarchy metadata and verify this issue is `Todo`, correctly parented/labeled/assigned, blocked by core #253, and not concurrently `In Progress`. -- [ ] 1.3 Verify the exact signed preflight module identity, completed #251/#253 contracts, and current Codex/ECC/hatch3r contribution and packaging rules. For hatch3r, require the selected release to contain and document a supported distribution/extension surface; an upstream contribution qualifies only after it is merged, included in that release, and documented there. Stop hatch3r work otherwise. +- [ ] 1.3 Verify the exact signed #434 module and preflight/implementation-check workflow identities, a completed core #251 `verified-install-result-v1` contract bound to installed bytes and the requested descriptor, the completed #253 contract, and current Codex/ECC/hatch3r contribution and packaging rules. The #251 result must bind every verifier, module, artifact, manifest, registry, signer/trust-root, core, installed-inventory, and role-specific workflow identity/digest field required by the specification. Stop all adapter work if that result contract is absent or incomplete. For hatch3r, require the selected release to contain and document a supported distribution/extension surface; an upstream contribution qualifies only after it is merged, included in that release, and documented there. Stop hatch3r work otherwise. ## 2. Adapter specs and failing-first tests - [ ] 2.1 Finalize the shared descriptor and a tested harness/version matrix; remove assumptions contradicted by current upstream primary sources. -- [ ] 2.2 Add failing contract tests for install, invocation mapping, semantic parity, exact-version rejection, registry/core identity mismatch, invalid/untrusted signature rejection, absent verified-installer result, signed workflow-digest binding, unsupported hatch3r distribution rejection, drift, upgrade, and safe uninstall before adapter production edits; exercise every fail-closed identity case across installation, upgrade, invocation, and packaging. +- [ ] 2.2 Add failing contract tests for install, invocation mapping, semantic parity, exact-version rejection, registry/core identity mismatch, invalid/untrusted signature rejection, missing/unsuccessful/stale/incomplete/mismatched `verified-install-result-v1`, forbidden adapter-generated verification fallback, role-specific signed workflow identity-to-digest binding including omission/mismatch/cross-pairing, unsupported hatch3r distribution rejection, drift, upgrade, and safe uninstall before adapter production edits; exercise every fail-closed identity case across installation, upgrade, invocation, and packaging. - [ ] 2.3 Capture failing-first results in a newly created `TDD_EVIDENCE.md`. ## 3. Minimal adapter implementation -- [ ] 3.1 Implement the Codex plugin shell using the canonical workflow identity and installed CLI. -- [ ] 3.2 Implement the ECC skills-first companion and only the command shims required by the supported matrix. +- [ ] 3.1 Implement the Codex plugin shell using the successful core #251 `verified-install-result-v1`, exact signed #434 module identity, preflight workflow identity/digest, implementation-check workflow identity/digest, and installed CLI. +- [ ] 3.2 Implement the ECC skills-first companion using the same verified result and only the command shims required by the supported matrix. - [ ] 3.3 Implement hatch3r packaging only through the released and documented supported surface verified in 1.3; an accepted or merged upstream prerequisite alone is insufficient until the selected release contains and documents it. Never write internal inventory data or depend on private package layout. - [ ] 3.4 Keep all validators, approval decisions, and readiness aggregation in the released SpecFact runtime. diff --git a/openspec/changes/preflight-05-implementation-conformance/CHANGE_VALIDATION.md b/openspec/changes/preflight-05-implementation-conformance/CHANGE_VALIDATION.md index 43b8239d..34399746 100644 --- a/openspec/changes/preflight-05-implementation-conformance/CHANGE_VALIDATION.md +++ b/openspec/changes/preflight-05-implementation-conformance/CHANGE_VALIDATION.md @@ -12,15 +12,16 @@ ## Scope and Ownership Review -- Modules owns postimplementation evidence extraction, executable comparison, rendering, persistence, and workflow handoff. -- Paired core owns implementation snapshot, obligation mapping, drift/result, and verifier interfaces. -- The work is outside the preflight MVP and does not silently alter external harness packages or C15 semantics; a changed signed identity requires tested adapter compatibility evidence or a separately accepted adapter release. +- Modules owns worktree/index checkpoint and immutable-range conformance execution, Git/pytest/review evidence import, caching, remediation packets, bounded agent workflow, pre-commit integration, rendering, persistence, signing, and publication. +- Paired core owns snapshot kinds, obligation mapping, finding/result, authority, and pure verifier interfaces. +- The work follows stable preflight publication and precedes #251/#253/#433. It packages no external harness adapter and does not alter C15 semantics. ## Dependency Review - Parent Feature: modules [#163](https://github.com/nold-ai/specfact-cli-modules/issues/163). -- Native blockers verified: stable modules [#432](https://github.com/nold-ai/specfact-cli-modules/issues/432), modules adapters [#433](https://github.com/nold-ai/specfact-cli-modules/issues/433), and paired core [#684](https://github.com/nold-ai/specfact-cli/issues/684). -- Delivery ordering records the complete core #682 -> modules #431 -> core #680/#683 -> modules #432 -> core #251/#253 -> modules #433 sequence before this later workflow handoff; native relationships and exact released identities must be read back again before implementation. +- Native blockers to verify: stable modules [#432](https://github.com/nold-ai/specfact-cli-modules/issues/432) and paired core [#684](https://github.com/nold-ai/specfact-cli/issues/684). +- Native downstream to add: core [#251](https://github.com/nold-ai/specfact-cli/issues/251), followed by #253 and modules #433. +- Delivery ordering records core #682 -> modules #431 -> core #680/#683 -> modules #432 -> core #684 -> modules #434 -> core #251/#253 -> modules #433; exact released identities must be read back again before implementation. - GitHub readback verified User Story type, parent #163, project `SpecFact CLI` / `Todo`, assignee `djm81`, and the required labels. ## Validation Record @@ -30,7 +31,16 @@ - Markdown lint limited to changed planning Markdown: PASS on 2026-08-25. - Staged schema-v2 Requirements planning evidence: PASS on 2026-08-25 with inspection-only cases and no test selectors or execution claims. - Review follow-up on 2026-08-27: strict OpenSpec validation and schema-v2 Requirements planning evidence PASS after base/head seal semantics, explicit implementation identity, the complete delivery chain, C14-status preservation, and signed-release adapter compatibility were aligned; the diff remains planning-only. +- Review follow-up on 2026-08-30: shadow evidence is bound to the exact promotion candidate and invalidated by relevant changes; implementation-branch release proof uses a projected registry row while official registry mutation remains post-merge publication work. +- Second review follow-up on 2026-08-30: release preparation and release-matrix fixes force rollout-evidence recollection for the final unchanged candidate; interface additions, deletions, and rename endpoints use provenance-bound absent-side tombstones rather than missing evidence. +- Third review follow-up on 2026-08-30: publication preserves or derives the exclusive core-compatibility upper bound from the complete bundled-module dependency intersection, keeps the complete range identical across manifest and registry, and tests rejection at and above that bound as well as lower-bound behavior. +- Fourth review follow-up on 2026-08-30: checkpoint applicability is derived from the selected snapshot so worktree-only unstaged/untracked changes cannot be skipped; staged-only selection remains pre-commit/index-specific. Scope-expansion recovery removes already-implemented production expansion before successor approval and failing-first evidence, then permits reimplementation only afterward without automatic code/history/seal mutation. +- Fifth review follow-up on 2026-08-30: absence of Git approval artifacts cannot prove a repository was never sealed when policy permits an independent canonical authority; `NOT_APPLICABLE` requires authoritative confirmation of no applicable current/history state, while unavailable or ambiguous canonical history returns `UNKNOWN`. +- Sixth review follow-up on 2026-08-30: no-impact can yield an empty semantic selector set only when its sealed, deterministic, role-supported permitted-transition predicate verifies the exact provenance-bound baseline/current delta; path/role/rationale or unchanged public interface alone is insufficient, and missing or mismatched transition evidence fails closed. +- Seventh review follow-up on 2026-08-30: the implementation PR uses the documented unsigned dev-target workflow to refresh the exact payload checksum and remove a stale signature before full filesystem/version verification; post-merge publication verifies that unchanged candidate and exclusively adds the cryptographic signature and generated registry/history artifacts, failing back to implementation review on drift. +- Eighth review follow-up on 2026-08-30: checksum preparation now supplies an explicit changed-manifest selector and full PR-base identity, records the resolved manifests, and fails on empty/incomplete/ambiguous selection rather than invoking `sign-modules.py` without a target. +- Ninth review follow-up on 2026-08-30: post-merge signing and generated publication artifacts create a distinct promotion candidate, so the publication PR must recollect negative and known-good rollout evidence and reevaluate every promotion gate on its exact unchanged signed head before merge; checksum-only or earlier signed-head evidence cannot authorize publication. ## Decision -The proposal is ready for review and a planning-only PR. Postimplementation conformance runtime work remains explicitly unstarted. +The proposal is ready for review and a planning-only PR. Checkpoint, pre-commit, bounded workflow, publication, and final conformance runtime work remain explicitly unstarted. diff --git a/openspec/changes/preflight-05-implementation-conformance/design.md b/openspec/changes/preflight-05-implementation-conformance/design.md index 60b5f182..8443b052 100644 --- a/openspec/changes/preflight-05-implementation-conformance/design.md +++ b/openspec/changes/preflight-05-implementation-conformance/design.md @@ -1,61 +1,73 @@ ## Context -This paired modules change executes the core conformance contract after implementation. It deliberately has a different command, result, policy phase, and evidence boundary from `specfact preflight run` so pre-implementation approval cannot be mistaken for delivery proof. +This paired modules change executes the released core implementation-assurance contracts throughout development and at final delivery. It keeps `specfact preflight run`, local checkpoints, and immutable-range conformance as distinct result lifecycles so approval identity, local feedback, and PR authority cannot be confused. ## Goals / Non-Goals **Goals:** -- Capture exact implementation and test evidence without mutating the sealed contract. -- Evaluate approved obligations and unexpected drift through the released core verifier. -- Give humans and agents one actionable, provenance-rich result before PR/archive decisions. -- Require explicit reapproval when implementation intentionally changes the contract. +- Catch seal/scope/test mismatches and known semantic boundary defects before a PR. +- Reuse Requirements exact selectors, C14 scope/capsule identities, and code-review JSON rather than duplicate analyzers. +- Return one compact remediation contract to the current coding agent with bounded reruns. +- Preserve explicit unknowns and distinct local versus range authority. **Non-Goals:** -- Implement general code review, coverage, architecture analysis, or security scanning already owned elsewhere. -- Generate missing tests or change production code. -- Treat unavailable evidence as success. +- Invoke an LLM or network from the deterministic CLI. +- Generate tests, edit implementation, or mutate/reseal the approved contract. +- Replace platform CI, protected PR review, security analysis, or architecture judgment. ## Decisions -### 1. Separate command and result lifecycle +### 1. Separate checkpoint and conformance commands -`specfact preflight conform ` requires a preflight seal that verifies against its sealed contract and base source snapshot plus an explicit implementation identity in the released core snapshot format. The implementation base/head or exact range is supplied separately; a missing, implicit, or ambiguous identity is rejected. Implementation commits do not by themselves invalidate the base-bound seal, and the command produces a conformance result rather than a new preflight readiness result or altered seal. +`specfact preflight checkpoint ` accepts `slice` with `worktree` or `index`, `commit` with `index` only, and `deep` with `worktree` or `index`. Any other scope/profile pair is rejected before extraction rather than silently overriding the requested scope. Applicability follows the selected snapshot: worktree selection includes staged, unstaged tracked, and untracked changes; index selection includes staged changes only. Staged-only applicability belongs to the index-based pre-commit wrapper, not explicit worktree checkpoints. The command returns the released core `DevelopmentCheckpointResult` with local authority. `specfact preflight conform ` discovers the policy-authorized canonical lineage tip, verifies that the selected seal digest/monotonic sequence and complete predecessor chain match that tip, and rejects ancestor, rolled-back, forked, missing, or ambiguous tip state. It requires its base commit/tree to equal the first seal's immutable implementation-lineage origin rather than a successor's later source snapshot, uses C14 to attest origin-to-head ancestry, and requires the head commit/tree to equal a separately policy-authorized current delivery target. Local runs resolve the current delivery ref/HEAD; protected PR/CI runs consume an authenticated target supplied by their orchestrator without adding network access to the CLI. It extracts the complete cumulative lineage-origin-to-current-delivery-head manifest and range-bound evidence, derives the exhaustive affected final-delivery obligation closure, and invokes the core comparator. It preserves `FAIL` and `UNKNOWN` rather than synthesizing success from immutable references, an ancestor seal, a current-seal or caller-selected shorter range, an older descendant head, or prior local evidence. An applicable `ci`-stage obligation can pass only with authenticated evidence from a seal/policy-authorized protected-CI producer bound to that exact range; otherwise conform remains `UNKNOWN`/deferred. Neither command changes the seal. -### 2. Evidence adapters reuse existing outputs +### 2. Three bounded checkpoint profiles -The runtime imports exact repository diff manifests, interface/traceability records, and current-run test evidence from existing SpecFact contracts where available. It records producer/version/digest and does not reimplement those analyzers. Missing required evidence yields unknown or blocking conformance according to policy. +- `slice` verifies the seal, compares the complete changed-path/input manifest and snapshot-bound public-interface delta with sealed roles and influence mappings, runs affected exact Requirements cases, and imports changed-scope code-review evidence. +- `commit` requires the index snapshot, includes applicable `slice` checks, adds every affected component's bounded pytest targets, and is the pre-commit profile. +- `deep` includes all lower-profile checks applicable to its worktree or index snapshot, bounded bug-hunt analysis, and all locally executable `prepush` obligations. `ci` obligations are reported as deferred with identity and reason, never silently passed. -### 3. Closed mapping validators +V1 invokes pytest through the active Python environment using repository-contained selectors. Other runners remain later adapters. -Python validators map sealed scope, exclusions, interfaces, acceptance criteria, test intent, and tasks to normalized implementation evidence. They emit only the core drift classes and retain source/evidence paths for remediation. +### 3. C14 provides scope and execution identity -### 4. Human decides drift resolution +Worktree and index extraction reuses C14 scope, sandbox, and toolchain primitives and implements the released core matrix exactly. Every snapshot base is the seal-bound implementation-lineage origin repository/base commit/base tree. A worktree snapshot additionally binds a worktree-manifest digest and includes staged, unstaged, and untracked state. An index snapshot additionally binds the exact index tree ID; untracked paths are absent unless staged as additions. A range snapshot binds full head commit/tree, separately authorized current delivery-target commit/tree, and origin-to-head ancestry; untracked paths are not representable. Every manifest retains additions, deletions, both rename endpoints, before/after modes, symlink target identity, and byte-preserving path identity. Rename classification is bound to producer, toolchain, and policy identity. For each affected governed path that policy classifies as capable of defining a public interface, regardless of whether its role is `source`, `test`, `docs`, `generated`, or `evidence`, a policy-authorized extractor normalizes base/current public-interface observations into the released core snapshot records and binds extractor identity/version/configuration digest, toolchain/policy, path, role, and exact snapshot provenance. A nonexistent side of an addition, deletion, or rename endpoint is represented by a provenance-bound `absent` record/tombstone, not omitted evidence; it binds the same path, role, snapshot, extractor/configuration, policy/toolchain, and transition identities while carrying no fabricated interface members. Deterministic comparison of `absent` with `present` derives interface addition/removal, including each rename endpoint. Only an expected provenance-valid tombstone satisfies a nonexistent side; an omitted record or an `absent` record for a path that exists remains `UNKNOWN`. Changed interfaces are derived by deterministic record comparison; missing, incomplete, unsupported, stale, ambiguous, or wrong-snapshot extraction returns `UNKNOWN`, and a caller-supplied empty set is never authoritative. Index claims execute against the captured index capsule; a differing worktree cannot satisfy staged evidence. -For unexpected or modified implementation, the workflow offers two explicit paths: correct the implementation to the sealed contract, or return to preflight to review/refine/reapprove the contract. It cannot mark intentional drift accepted by itself. +### 4. Seal-bound semantic selection -### 5. Delivery integration remains opt-in +Every changed non-excluded sealed role, derived public interface, or input—not only source paths—maps through approved ownership and influence relationships to existing Requirements verification cases, bounded component pytest targets, and review/evidence obligations. This includes `source`, `test`, `docs`, `generated`, and `evidence` paths plus seal-bound approval, test, dependency, policy, toolchain, and relevant configuration inputs. Approval-state discovery compares the authoritative base with the selected worktree/index snapshot; deletion, relocation, or replacement of the last seal or canonical lineage-tip artifact is therefore a governed transition that returns `UNKNOWN`, never evidence that the repository was never sealed. A checkpoint may select only the affected subset of requirement, scenario, verification-case, and exact pytest-selector identities already bound by the seal. A no-impact disposition from the current valid canonical seal is a determinate empty semantic-selector result only when it binds the exact input/path identity and role, the applicable sealed-baseline observation identity/digest, a non-empty rationale, and a policy-authorized deterministic permitted-transition predicate identity/version/configuration digest with a closed change class and observable invariants. The runtime evaluates that predicate against exact provenance-bound baseline/current content, mode, interface, and relevant input observations from the selected snapshot. The predicate must be supported and semantics-preserving for the role and cannot admit arbitrary content, behavior, configuration, dependency, or execution changes. The result retains the disposition, predicate, baseline/current observation, transition-evidence, and validation identities/digests. No-impact does not bypass seal, scope, approval-state, interface, or changed-scope code-review checks. Missing, stale, unsupported, ambiguous, or mismatched baseline/predicate/transition evidence returns `UNKNOWN`; an observed transition outside the permitted class selects the normal mapped obligations or returns `UNKNOWN` when no mapping exists, never an empty set. Otherwise, if an applicable changed path/interface/input or the obligations it influences cannot be derived deterministically, selection returns `UNKNOWN`; it never accepts an empty affected set by default. Final conformance has no discretionary subset: it deterministically closes over every changed governed path and interface plus every applicable component, acceptance criterion, risk row, Requirements case, component target, verification stage (including `ci`), exclusion, and no-impact disposition with its exact transition evidence bound to the affected range. The closure and its digest are result-bound. An incomplete, empty-for-an-affected-range, duplicate, or ambiguous closure produces `UNKNOWN`; determinate unsatisfied obligations produce `FAIL`. Any addition, removal, replacement, or change of a seal-bound identity returns to preflight validation and reapproval. An already-implemented out-of-scope production expansion must first be absent from the selected implementation snapshot; the successor contract/test intent is then approved, failing-first evidence is captured with that production behavior absent, and only then is the expansion reimplemented. The checkpoint/workflow reports and stops rather than automatically removing code, rewriting history, approving, or resealing. Missing ownership, stale plan identity, invalid/uncollected selectors, ambiguous scope, or unavailable required evidence produces `UNKNOWN`. Work outside sealed roles produces `FAIL` and routes intentional expansion through that ordered preflight/TDD recovery. -The first release provides command and workflow evidence without making every PR gate depend on it. A later policy change may require conformance for selected projects only after dogfood demonstrates usable signal. +### 5. Evidence aggregation and cache identity -### 6. Signed identity changes require adapter compatibility evidence +The runtime supplies the upstream design contract, validation result, seal, policy, and current source identities to core verification before selecting implementation obligations. It imports current-run JUnit and `specfact code review run` JSON and delegates mutually exclusive finding classification, precedence, and status aggregation to released core interfaces. Cache reuse requires exact seal, snapshot, obligation-set, pytest-target, runner, policy, toolchain, relevant configuration, and execution-environment digests. The execution-environment digest attests the Python executable/version/ABI, environment-manager provenance, resolved installed-distribution or sealed lock/artifact identities, and policy-allowlisted relevant environment-variable names with hashed values; secret values are never persisted. Any identity change invalidates the cache. If this state cannot be attested, cache reuse is disabled and required checks rerun; unavailable required execution returns `UNKNOWN`. -Adding the conformance command or workflow handoff changes the signed module/workflow identity that #433 adapters pin. This change may publish a tested compatible-upgrade descriptor, but it does not silently rewrite external adapter packages. If the existing adapters cannot accept the new exact identity, conformance adoption remains blocked on a separately accepted adapter release. +### 6. Seal-aware pre-commit rollout + +The pre-commit wrapper first validates canonical tip, complete predecessor chain, approval authority, and required Git identities, then classifies every staged path against repository preflight-governance policy and sealed `source`, `test`, `docs`, `generated`, `evidence`, and `excluded` roles plus seal-bound approval, test, dependency, policy, toolchain, and relevant configuration inputs. Missing, stale, multiple, rolled-back, forked, unavailable, or ambiguous canonical/Git state returns `UNKNOWN` before path coverage; uncovered-path `FAIL` applies only after a single valid canonical seal and snapshot identity exist. It auto-selects only when exactly one policy-authorized canonical lineage tip covers every staged non-excluded governed path/input; historical predecessor seals in that verified chain do not count as competing tips. `NOT_APPLICABLE` is limited to an empty staged set; a policy-authorized canonical-source determination that the repository has no current or historical applicable approval, with no base/index approval-state transition; or paths deterministically outside the configured preflight-governed universe whose lack of relationship to every current or prior seal is confirmed against canonical history. Absence of approval artifacts from the authoritative base and index is insufficient because policy may use an independently attested canonical source; unavailable or ambiguous canonical history returns `UNKNOWN`. A base seal/tip deleted, relocated, or replaced in the index is governed missing approval state and returns `UNKNOWN`/exit one; index-only discovery cannot reinterpret it as a never-sealed repository. When seals exist, a governed path/input with no seal coverage is `unexpected`/`FAIL`; missing or ambiguous influence mapping under a covering seal is `UNKNOWN`. If any staged path associates with a seal but another non-excluded seal-relevant path is uncovered, the uncovered path is `unexpected`, the result is `FAIL`, and intentional expansion returns to preflight refinement with a successor seal that preserves the original implementation-lineage origin. Dogfood begins in shadow mode with negative defect fixtures and representative known-green controls for every enabled scope/profile pair. Every corpus and live observation is bound to the exact candidate implementation commit/tree and runtime/module identity plus release-surface, policy, relevant configuration, corpus, runner, and toolchain digests. A change to any promotion-relevant identity invalidates the affected evidence and requires recollection before promotion; release preparation and later quality fixes cannot inherit an older candidate's sample. Blocking requires exact expected corpus results, zero false PASS, zero corpus false block, no destructive/ambiguous behavior, at least 20 applicable known-good live observations per enabled pair and 100 aggregate, and pairwise plus aggregate false-block rates no greater than 1%; policy may only make those thresholds stricter. + +### 7. Compact bounded agent handoff + +Each finding packet contains a stable fingerprint, action class (`fix_implementation`, `fix_or_add_test`, `rerun`, `return_to_preflight`, or `human_decision`), contract/risk reference, implementation evidence, expected observable, recommended action, and validation selectors. The harness-neutral workflow may hand packets to the current coding agent for at most three fix/rerun cycles. It stops on a repeated consecutive fingerprint, scope expansion, `UNKNOWN`, contract/design judgment, or requested sealed-artifact change. + +### 8. Post-merge publication precedes adapters + +The implementation PR prepares the version and manifest bindings, projects the registry row that the post-merge publisher would generate, and proves compatibility without mutating the official registry or producing a publishable feature-branch identity. Because those edits change the signed payload, the implementation PR uses the documented dev-target preparation command `scripts/sign-modules.py --allow-unsigned --payload-from-filesystem --changed-only --base-ref `: the explicit change selector resolves every affected manifest, refreshes its checksum against the exact proposed merge-tree payload, and removes rather than retains an invalid stale signature. The selected manifest set and full base identity are recorded in evidence; an empty or ambiguous selection fails. The resulting checksum-only candidate must pass `verify-modules-signature --payload-from-filesystem --enforce-version-bump`; it is not cryptographically signed, published, registry-addressable, or eligible for downstream handoff. The PR identifies the first released core containing the final #684 interfaces and validates matching complete `core_compatibility` ranges between the proposed bundle manifest and projected registry row. The lower bound is raised to that #684 release. The exclusive upper bound is preserved from, or deterministically derived from, the intersection of the complete bundled-module dependency graph; it cannot be omitted or widened beyond any required dependency's supported range. The release matrix rejects the immediately older supported core, passes the exact lower bound and supported newer cores strictly below the upper bound, and rejects the upper-bound core plus a representative newer core. After that implementation is merged to `dev`, only the canonical post-merge workflow may verify the exact merged version/payload/checksum, cryptographically sign it, generate the actual registry/signature/history artifacts, compatibility-test, and propose the immutable #434 module. The publication workflow must fail rather than silently change the merged payload, version, checksum, workflow bindings, or compatibility range; any required payload change returns through implementation evidence and review. The publication PR verifies equality between the signed manifest and generated registry entry, re-derives the dependency-backed range, and repeats both boundary checks. The signed manifest separately binds the existing preflight workflow identity/digest and the new implementation-check workflow identity/digest; the latter owns checkpoint, conform, and bounded remediation semantics. Signing and generated registry/signature/history artifacts create a new promotion candidate, so the canonical publication workflow must then recollect the negative corpus and known-good live observations and reevaluate every pairwise, aggregate, identity, compatibility, quality, and rollback promotion gate against the exact signed publication head. Any fix or identity drift invalidates that evidence and repeats signed-candidate recollection; the publication PR cannot merge on checksum-only or earlier signed-head evidence. After that unchanged signed PR merges and official registry/install readback passes, #434 hands the exact module and workflow identities to core #251 only. Completed #251 then enables #253; only completed #251 and #253 enable modules #433. #434 does not package adapters or authorize parallel #433 consumption. ## Risks / Trade-offs -- **Duplicate analyzer ownership:** Import existing normalized evidence rather than running parallel analyzers. -- **Mapping noise:** Require exact contract paths and evidence identities; preserve unknowns. -- **Approval confusion:** Keep separate command/result vocabulary and never reseal from conform. -- **Premature blocking rollout:** Start opt-in and require a later policy decision for enforcement. -- **Adapter identity drift:** Test the new signed identity against every claimed #433 descriptor and block adoption on a follow-up adapter release when compatibility is not proven. +- **Incomplete risk matrix:** Preflight validators block missing dispositions and checkpoint preserves unknown evidence. +- **Slow component selection:** Use slice/commit/deep profiles and digest-bound cache; never fall back silently to a full repository suite. +- **Local/CI divergence:** Keep `ci` obligations deferred and retain protected PR/CI authority. +- **Looping token cost:** Cap workflow cycles at three and stop repeated fingerprints. +- **Duplicate ownership:** Import Requirements, C14, and code-review contracts instead of creating parallel schemas. ## Migration and Rollback -The command is additive and optional. Removing the conformance module surface leaves the original preflight contract/seal unchanged. Persisted conformance results can be deleted without invalidating pre-implementation approval identity; delivery policy must then treat conformance as unavailable, not passed. +Dogfood is shadow-only until both negative and known-green controls plus the minimum live sample satisfy the promotion policy. Stable rollout blocks pre-commit only for repositories with an applicable valid seal. Rollback removes the hook/workflow checkpoint entry and published update; existing seals, Requirements evidence, code review, and final PR gates remain valid. Ephemeral checkpoint artifacts may be deleted without changing approval identity. ## Open Questions Deferred to Implementation -- Which existing test/traceability evidence schemas are mandatory for the first supported profile. -- Retention policy for multiple conformance runs against one seal. +- Exact released core class/module names and canonical serialization library established by #682/#684 tests. +- Retention limit for explicitly persisted checkpoint history; ephemeral output remains the default. diff --git a/openspec/changes/preflight-05-implementation-conformance/proposal.md b/openspec/changes/preflight-05-implementation-conformance/proposal.md index 5e11cc80..f56c5f85 100644 --- a/openspec/changes/preflight-05-implementation-conformance/proposal.md +++ b/openspec/changes/preflight-05-implementation-conformance/proposal.md @@ -1,23 +1,26 @@ -# Change: Implementation-to-Sealed-Contract Conformance Runtime +# Change: Seal-Bound Development Checkpoint and Conformance Runtime ## Why -After code is written, teams need a separate deterministic comparison between the implementation evidence and the previously approved preflight contract. That comparison must reuse the sealed contract without pretending the pre-implementation gate proved delivery, and it must remain outside the initial preflight MVP. +Preflight approval records what was reviewed, but defects and mismatches can still accumulate while code is being written. SpecFact needs a cheap local checkpoint that maps the current implementation back to the sealed scope, risk, and test intent, returns compact remediation evidence to the coding agent before a PR, and preserves a distinct immutable-range conformance authority for delivery. ## What Changes -- **NEW**: A later `specfact preflight conform ` runtime that loads a base-bound valid preflight seal, captures implementation evidence through the released paired-core snapshot interface, imports exact test/evidence identities, and evaluates the core conformance contract without defining a second snapshot or obligation-mapping contract. -- **NEW**: Python extractors and validators for changed-path, interface, acceptance-criterion, test-intent, task, and exclusion mappings. -- **NEW**: Human and JSON conformance rendering plus optional atomic persistence alongside the original preflight artifacts. -- **NEW**: A workflow handoff for agents to run conformance after implementation evidence is available and before delivery/archive decisions. -- **NEW**: A tested adapter-compatibility handoff for any new signed module/workflow identity, or a blocking follow-up adapter release when the exact #433 descriptor no longer matches. -- **CLARIFY**: Material implementation drift requires explicit contract reapproval or implementation correction; the runtime does not rewrite the sealed contract automatically. +- **NEW**: `specfact preflight checkpoint --scope worktree|index --profile slice|commit|deep` using the released core snapshot and checkpoint-result contracts. +- **NEW**: Complete Git path extraction by reusing C14 worktree/index/range scope and capsule primitives, plus policy-authorized snapshot-bound public-interface extraction using the released core records and provenance-bound absent-side tombstones for additions, deletions, and rename endpoints; missing or ambiguous interface discovery fails closed instead of accepting a caller-supplied empty set. +- **NEW**: Seal-bound selection of Requirements cases through the existing planned-to-test-authored maturity lifecycle, exact pytest selectors when test-authored, bounded affected-component pytest targets, and no-impact empty selection only after the seal-bound deterministic permitted-transition predicate verifies the exact base/current snapshot delta; no second selector schema or implicit empty-set fallback. +- **NEW**: Import of current-run JUnit and `specfact code review run` evidence with cache identity bound to the seal, snapshot, selected obligations/targets, runner, policy, and configuration. +- **NEW**: `specfact preflight conform ` selects only the policy-authorized canonical latest seal and performs explicit cumulative implementation-lineage-origin-to-authoritative-current-delivery-head comparison across successor seals, with a separate final conformance result. +- **NEW**: Human/JSON parity, compact remediation packets, a harness-neutral implementation-check workflow with at most three fix/rerun cycles, and optional atomic persistence. +- **NEW**: Seal-aware staged pre-commit integration that validates canonical approval/Git identity before coverage, evaluates sealed approval state, tests, configuration, and evidence as well as source; distinguishes a never-sealed repository from staged removal of its last seal/tip by combining authoritative base/index state with the policy-authorized canonical approval history, including an independently attested source; is non-applicable only after that source confirms no current/historical applicable approval or relationship; fails closed when canonical history or other applicable evidence is unavailable or ambiguous; and requires both defect and known-green shadow controls plus pairwise and aggregate bounded live false-block rates bound and, after release preparation or fixes, recollected for the exact unchanged promotion candidate before blocking rollout. +- **NEW**: The implementation PR prepares the versioned manifest and refreshes a checksum-only, non-publishable candidate with the documented unsigned dev-target workflow so full filesystem checksum/version verification is reachable without a stale signature. After implementation merges, the canonical post-merge publication workflow verifies that exact merged version/payload/checksum, cryptographically signs it, generates the registry/history artifacts, compatibility-tests, and proposes one #434 release identity that separately binds the existing preflight workflow identity/digest and the new implementation-check workflow identity/digest. Because signing and generated publication artifacts change promotion-relevant identities, the publication PR must recollect rollout evidence and reevaluate every promotion gate against its exact signed head before merge. Matching bundle-manifest and registry `core_compatibility` ranges raise the lower bound to the first released core containing #684 while preserving or deriving the exclusive upper bound required by the complete bundled-module dependency graph. The identity becomes published only after the unchanged signed publication PR merges, lower/upper boundary tests pass, and official registry/install readback passes; only then enforce #434 -> #251 -> #253 -> #433. +- **CLARIFY**: The deterministic CLI never invokes an LLM, edits implementation, mutates/reseals a contract, or promotes local evidence to protected PR authority. ## Capabilities ### New Capabilities -- `preflight-implementation-conformance-runtime`: Executable postimplementation evidence extraction, comparison, rendering, persistence, and workflow handoff. +- `preflight-implementation-conformance-runtime`: Worktree/index checkpoints, immutable range conformance, evidence selection/execution/import, rendering, persistence, pre-commit integration, and bounded agent handoff. ### Modified Capabilities @@ -25,21 +28,22 @@ After code is written, teams need a separate deterministic comparison between th ## Impact -- Planning artifacts only in this phase. No production or test code, module package, manifest, signature, version, workflow asset, generated snapshot/result, adapter, or dependency is created. -- Explicitly excluded from the preflight MVP; work begins only after stable preflight publication and the paired core conformance contract. -- No external harness-specific packaging is included; compatible harnesses consume the canonical workflow only after a tested compatible-upgrade descriptor or separately accepted adapter release covers the new signed identity. +- Planning artifacts only in this phase. No production code, tests, package, manifest, signature, version, workflow asset, hook, generated snapshot/result, adapter, or dependency is created. +- Implementation begins only after the stable #432 preflight handoff and released core #684 contracts. +- External Codex/ECC/hatch3r packaging remains in #433, which consumes the signed module identity and both separately named workflow identities/digests published here. ## Dependencies - Parent Feature: modules [#163](https://github.com/nold-ai/specfact-cli-modules/issues/163). -- Blocked by the complete preflight delivery chain: core contract [#682](https://github.com/nold-ai/specfact-cli/issues/682) -> modules runtime [#431](https://github.com/nold-ai/specfact-cli-modules/issues/431) -> core C14 adoption/readiness [#680](https://github.com/nold-ai/specfact-cli/issues/680) and [#683](https://github.com/nold-ai/specfact-cli/issues/683) -> stable modules release [#432](https://github.com/nold-ai/specfact-cli-modules/issues/432) -> core installation/instructions [#251](https://github.com/nold-ai/specfact-cli/issues/251) and [#253](https://github.com/nold-ai/specfact-cli/issues/253) -> modules harness adapters [#433](https://github.com/nold-ai/specfact-cli-modules/issues/433), plus paired core conformance contract [#684](https://github.com/nold-ai/specfact-cli/issues/684). Modules C14 #416 remains open and `In Progress` unless separately authorized; this change neither closes nor supersedes it. -- Runs independently of the C15 chain; neither change may silently redefine the other's evidence semantics. +- Blocked by the stable modules release [#432](https://github.com/nold-ai/specfact-cli-modules/issues/432) and paired core implementation-assurance contracts [#684](https://github.com/nold-ai/specfact-cli/issues/684). +- Blocks core skill installation [#251](https://github.com/nold-ai/specfact-cli/issues/251), then #253 and modules adapters #433. +- Runs independently of C15; neither change may silently redefine the other's policy or evidence semantics. ## Explicit Non-Goals - No pre-implementation readiness, approval, or sealing behavior. -- No automatic contract mutation, implementation edits, or test generation. -- No universal semantic correctness, security, or completeness claim. +- No direct LLM/network invocation, automatic contract mutation, implementation edits, or test generation in the deterministic CLI. +- No universal semantic correctness, platform correctness, security, or completeness claim. - No Codex/ECC/hatch3r adapter packaging. ## Source Tracking diff --git a/openspec/changes/preflight-05-implementation-conformance/requirements-evidence.yaml b/openspec/changes/preflight-05-implementation-conformance/requirements-evidence.yaml index c6839fe4..37807555 100644 --- a/openspec/changes/preflight-05-implementation-conformance/requirements-evidence.yaml +++ b/openspec/changes/preflight-05-implementation-conformance/requirements-evidence.yaml @@ -1,125 +1,125 @@ schema_version: "2" +x-planning-rationale: &planning-rationale "The proposal must make this requirement reviewable before implementation begins." +x-planning-touchpoints: &planning-touchpoints + - id: openspec-source-spec + kind: config_file + locator: "openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md" +x-planning-observable: &planning-observable >- + Strict OpenSpec validation retains the requirement and its scenarios + without claiming implementation, test execution, checkpoint, conformance, or publication evidence. requirements: - openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:adapter-compatibility-across-conformance-release: - rationale: "The proposal must make this requirement reviewable before implementation begins." + openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:separate-development-checkpoint-command: + rationale: *planning-rationale stakeholder_refs: ["nold-ai/specfact-cli-modules#434"] - touchpoints: - - id: openspec-source-spec - kind: config_file - locator: "openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md" - verification_cases: - - case_id: PF05M-008 - scenario_id: adapter-compatibility-across-conformance-release - method: inspection - intent: "Inspect the conformance release adapter compatibility contract before implementation." - observable: >- - Strict OpenSpec validation retains the exact signed-identity - compatibility proof or separately accepted adapter-release blocker - without claiming implementation or test execution. - openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:atomic-optional-persistence: - rationale: "The proposal must make this requirement reviewable before implementation begins." - stakeholder_refs: ["nold-ai/specfact-cli-modules#434"] - touchpoints: - - id: openspec-source-spec - kind: config_file - locator: "openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md" + touchpoints: *planning-touchpoints verification_cases: - case_id: PF05M-001 - scenario_id: atomic-optional-persistence + scenario_id: separate-development-checkpoint-command method: inspection - intent: "Inspect the atomic optional persistence planning contract before implementation." - observable: >- - Strict OpenSpec validation retains the requirement and its scenarios - without claiming implementation or test execution. - openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:core-conformance-evaluation: - rationale: "The proposal must make this requirement reviewable before implementation begins." + intent: "Inspect canonical-tip/chain/Git UNKNOWN precedence before uncovered-scope FAIL; checkpoint scopes/statuses; selected-snapshot applicability including unstaged/untracked-only worktree changes versus staged-only index/pre-commit behavior; independent canonical approval with no Git artifact; canonical-source confirmation of no current/historical approval versus unavailable/ambiguous history as UNKNOWN; seal behavior; never-sealed versus staged last-seal/tip removal; partial and wholly uncovered governed-path failure versus missing-influence UNKNOWN; and the complete source/test/docs/generated/evidence/excluded plus seal-bound approval/test/dependency/policy/toolchain/relevant-configuration applicability matrix before implementation." + observable: *planning-observable + openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:bounded-checkpoint-profiles: + rationale: *planning-rationale stakeholder_refs: ["nold-ai/specfact-cli-modules#434"] - touchpoints: - - id: openspec-source-spec - kind: config_file - locator: "openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md" + touchpoints: *planning-touchpoints verification_cases: - case_id: PF05M-002 - scenario_id: core-conformance-evaluation + scenario_id: bounded-checkpoint-profiles method: inspection - intent: "Inspect the core conformance evaluation planning contract before implementation." - observable: >- - Strict OpenSpec validation retains the requirement and its scenarios - without claiming implementation or test execution. - openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:explicit-drift-resolution-paths: - rationale: "The proposal must make this requirement reviewable before implementation begins." + intent: "Inspect the scope/profile matrix, cumulative slice/commit/deep execution, bounded bug-hunt/prepush checks, and deferred CI semantics before implementation." + observable: *planning-observable + openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:complete-implementation-scope-evidence: + rationale: *planning-rationale stakeholder_refs: ["nold-ai/specfact-cli-modules#434"] - touchpoints: - - id: openspec-source-spec - kind: config_file - locator: "openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md" + touchpoints: *planning-touchpoints verification_cases: - case_id: PF05M-003 - scenario_id: explicit-drift-resolution-paths + scenario_id: complete-implementation-scope-evidence method: inspection - intent: "Inspect the explicit drift resolution paths planning contract before implementation." - observable: >- - Strict OpenSpec validation retains the requirement and its scenarios - without claiming implementation or test execution. - openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:human-and-json-parity: - rationale: "The proposal must make this requirement reviewable before implementation begins." + intent: "Inspect complete C14-backed Git transition identity plus role-independent policy-authorized, snapshot-bound public-interface extraction, provenance-bound absent tombstones for additions/deletions/rename endpoints, and fail-closed changed-interface discovery before implementation." + observable: *planning-observable + openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:seal-bound-semantic-evidence-selection: + rationale: *planning-rationale stakeholder_refs: ["nold-ai/specfact-cli-modules#434"] - touchpoints: - - id: openspec-source-spec - kind: config_file - locator: "openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md" + touchpoints: *planning-touchpoints verification_cases: - case_id: PF05M-004 - scenario_id: human-and-json-parity + scenario_id: seal-bound-semantic-evidence-selection method: inspection - intent: "Inspect the human and json parity planning contract before implementation." - observable: >- - Strict OpenSpec validation retains the requirement and its scenarios - without claiming implementation or test execution. - openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:opt-in-delivery-policy: - rationale: "The proposal must make this requirement reviewable before implementation begins." + intent: "Inspect component, public-interface, risk, Requirements-plan, selector, sealed-baseline and deterministic permitted-transition predicate bindings for no-impact, exact snapshot-transition verification before empty selection, missing/unsupported/mismatched predicate or semantic-delta handling, implicit-empty-set rejection, scope-drift mappings, and removal of already-implemented out-of-scope production expansion before successor approval/failing-first evidence and later reimplementation before implementation." + observable: *planning-observable + openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:current-run-pytest-and-code-review-evidence: + rationale: *planning-rationale stakeholder_refs: ["nold-ai/specfact-cli-modules#434"] - touchpoints: - - id: openspec-source-spec - kind: config_file - locator: "openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md" + touchpoints: *planning-touchpoints verification_cases: - case_id: PF05M-005 - scenario_id: opt-in-delivery-policy + scenario_id: current-run-pytest-and-code-review-evidence method: inspection - intent: "Inspect the opt in delivery policy planning contract before implementation." - observable: >- - Strict OpenSpec validation retains the requirement and its scenarios - without claiming implementation or test execution. - openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:provenance-rich-implementation-evidence: - rationale: "The proposal must make this requirement reviewable before implementation begins." + intent: "Inspect current-run evidence import, reconciliation, and cache invalidation before implementation." + observable: *planning-observable + openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:local-and-range-authority-separation: + rationale: *planning-rationale stakeholder_refs: ["nold-ai/specfact-cli-modules#434"] - touchpoints: - - id: openspec-source-spec - kind: config_file - locator: "openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md" + touchpoints: *planning-touchpoints verification_cases: - case_id: PF05M-006 - scenario_id: provenance-rich-implementation-evidence + scenario_id: local-and-range-authority-separation method: inspection - intent: "Inspect the provenance rich implementation evidence planning contract before implementation." - observable: >- - Strict OpenSpec validation retains the requirement and its scenarios - without claiming implementation or test execution. - openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:separate-conformance-command: - rationale: "The proposal must make this requirement reviewable before implementation begins." + intent: "Inspect rejection of local-to-PR authority promotion before implementation." + observable: *planning-observable + openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:immutable-range-conformance-evaluation: + rationale: *planning-rationale + stakeholder_refs: ["nold-ai/specfact-cli-modules#434", "nold-ai/specfact-cli#684"] + touchpoints: *planning-touchpoints + verification_cases: + - case_id: PF05M-011 + scenario_id: immutable-range-conformance-evaluation + method: inspection + intent: "Inspect canonical latest-seal tip/sequence/chain selection, exact origin-to-authoritative-current-delivery-head and base/head public-interface extraction, exhaustive sealed-obligation comparison including no-impact predicate and exact range-transition evidence, and fail-closed final conformance rendering before implementation." + observable: *planning-observable + - case_id: PF05M-012 + scenario_id: immutable-range-conformance-evaluation + method: inspection + intent: "Inspect rejection of omitted, duplicate, ambiguous, or empty final obligation closures for affected ranges." + observable: *planning-observable + openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:compact-bounded-remediation-workflow: + rationale: *planning-rationale stakeholder_refs: ["nold-ai/specfact-cli-modules#434"] - touchpoints: - - id: openspec-source-spec - kind: config_file - locator: "openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md" + touchpoints: *planning-touchpoints verification_cases: - case_id: PF05M-007 - scenario_id: separate-conformance-command + scenario_id: compact-bounded-remediation-workflow + method: inspection + intent: "Inspect deterministic packets, three-cycle cap, and stop states before implementation." + observable: *planning-observable + openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:human-and-json-parity-with-optional-persistence: + rationale: *planning-rationale + stakeholder_refs: ["nold-ai/specfact-cli-modules#434"] + touchpoints: *planning-touchpoints + verification_cases: + - case_id: PF05M-008 + scenario_id: human-and-json-parity-with-optional-persistence + method: inspection + intent: "Inspect renderer parity, atomic persistence, and sealed-artifact immutability before implementation." + observable: *planning-observable + openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:shadow-dogfood-before-seal-aware-blocking: + rationale: *planning-rationale + stakeholder_refs: ["nold-ai/specfact-cli-modules#434"] + touchpoints: *planning-touchpoints + verification_cases: + - case_id: PF05M-009 + scenario_id: shadow-dogfood-before-seal-aware-blocking + method: inspection + intent: "Inspect negative C14 regression fixtures, representative known-green controls, exact expected-result parity, candidate runtime/release-surface/policy/configuration/corpus identity binding and invalidation/recollection, per-scope/profile and aggregate minimum live samples, pairwise and aggregate bounded false-block rates, metrics, and the blocking promotion gate before implementation." + observable: *planning-observable + openspec:preflight-05-implementation-conformance:preflight-implementation-conformance-runtime:signed-publication-before-adapter-consumption: + rationale: *planning-rationale + stakeholder_refs: ["nold-ai/specfact-cli-modules#434"] + touchpoints: *planning-touchpoints + verification_cases: + - case_id: PF05M-010 + scenario_id: signed-publication-before-adapter-consumption method: inspection - intent: "Inspect the separate conformance command, explicit implementation identity, and sealed-base/head separation contract before implementation." - observable: >- - Strict OpenSpec validation retains rejection of missing or ambiguous - implementation identity and the distinction between the sealed base - snapshot and postapproval implementation head without claiming - implementation or test execution. + intent: "Inspect documented unsigned dev-target checksum refresh with an explicit affected-manifest path set or changed-only/full-base selector; selected-manifest/base evidence and empty/incomplete/ambiguous selection failure; stale-signature removal for the exact pre-merge payload; reachable full filesystem checksum/version verification; non-publishable checksum-only candidate status; projected-registry validation without official registry mutation; post-merge exact-payload/checksum verification and cryptographic signing with fail-closed return on drift; mandatory negative-corpus and known-good live evidence recollection plus full promotion reevaluation on the exact unchanged signed publication head before merge; rejection of checksum-only or earlier signed-head evidence; matching complete signed-manifest/generated-registry core_compatibility ranges; the lower bound at the first released #684 core; an exclusive upper bound preserved or derived from the complete bundled-module dependency intersection; rejection below the lower bound and at/above the upper bound; acceptance at the lower bound and for supported newer cores below the upper bound; role-specific signed #434 workflow identity/digest bindings; and the mandatory ordered handoff #434 to #251 to #253 to #433 before implementation." + observable: *planning-observable diff --git a/openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md b/openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md index b178739f..7f09561c 100644 --- a/openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md +++ b/openspec/changes/preflight-05-implementation-conformance/specs/preflight-implementation-conformance-runtime/spec.md @@ -1,103 +1,394 @@ ## ADDED Requirements -### Requirement: Separate conformance command +### Requirement: Separate development checkpoint command -The module SHALL expose a postimplementation conformance command that requires a preflight seal valid against its sealed contract and base source snapshot plus a separate explicit implementation identity in the released core format, and SHALL produce a distinct conformance result. +The module SHALL expose `specfact preflight checkpoint ` with `worktree` or `index` scope and `slice`, `commit`, or `deep` profile, and SHALL return the released core local checkpoint result without modifying the approved seal. Allowed pairs are `slice/worktree`, `slice/index`, `commit/index`, `deep/worktree`, and `deep/index`; every other pair SHALL be rejected as invalid usage before snapshot extraction, without silently overriding either argument. Automatic selection SHALL validate the canonical tip, complete predecessor chain, approval authority, and required Git identities before evaluating path coverage. Applicability and coverage SHALL be computed from the selected snapshot: `worktree` includes staged, unstaged tracked, and untracked changes, while `index` includes staged changes only. The pre-commit wrapper SHALL use `index`; it SHALL NOT make staged-only selection govern an explicit `worktree` checkpoint. Absence of Git approval artifacts SHALL NOT establish absence of approval history: before returning `NOT_APPLICABLE` for a never-sealed repository or paths unrelated to every seal, the runtime SHALL require the policy-authorized canonical approval source to confirm that no current or historical applicable approval exists. Missing, stale, multiple, rolled-back, forked, unavailable, or ambiguous canonical/Git state SHALL return `UNKNOWN`; uncovered governed-path `FAIL` applies only after one valid canonical seal and snapshot identity are established. -#### Scenario: No valid preflight seal exists +#### Scenario: No selected-scope seal-relevant change or associated seal -- **GIVEN** a change has no seal that verifies against its sealed contract and base source snapshot -- **WHEN** `specfact preflight conform ` is invoked -- **THEN** comparison does not proceed as successful conformance -- **AND** the user is directed to the pre-implementation review workflow. +- **GIVEN** the policy-authorized canonical approval source authoritatively confirms that no current or historical applicable approval exists, neither the authoritative base nor the selected worktree/index snapshot contains working approval state, and no selected-scope approval-artifact path is changed; or it confirms that every path changed in the selected scope is deterministically outside the repository's configured preflight-governed path/input universe and unrelated to every current or prior seal +- **WHEN** automatic checkpoint selection runs +- **THEN** the result is `NOT_APPLICABLE` and exits zero +- **AND** an unsealed repository does not acquire a universal blocking policy. -#### Scenario: Missing or ambiguous implementation identity +#### Scenario: Canonical approval is independent of Git artifacts -- **GIVEN** the caller omits the implementation base/head or supplies an implicit or ambiguous revision/range -- **WHEN** `specfact preflight conform ` is invoked -- **THEN** comparison does not start -- **AND** the command requests an explicit implementation identity accepted by the released core snapshot interface. +- **GIVEN** neither the authoritative base nor the selected snapshot contains approval artifacts but the policy-authorized independent canonical source contains a current applicable seal or historical applicable approval +- **WHEN** automatic checkpoint selection runs +- **THEN** the runtime evaluates that canonical approval and the selected-scope changes instead of returning `NOT_APPLICABLE` +- **AND** a current seal proceeds to coverage while historical state prevents the repository from being treated as never sealed. -#### Scenario: Implementation head advances from sealed base +#### Scenario: Canonical approval history cannot be established -- **GIVEN** a seal verifies against the approved contract and base source snapshot and implementation commits create a distinct head -- **WHEN** conformance runs with that base/head identity -- **THEN** the seal remains the reference for approved obligations while the head is captured separately as implementation evidence -- **AND** the implementation commits alone do not require resealing the unchanged design contract. +- **GIVEN** Git approval artifacts are absent and the policy-authorized canonical source is unavailable, unauthenticated, stale, rolled back, forked, or ambiguous +- **WHEN** automatic checkpoint selection evaluates applicability +- **THEN** the result is `UNKNOWN` and exits non-zero +- **AND** missing canonical history is never converted to `NOT_APPLICABLE`. -### Requirement: Provenance-rich implementation evidence +#### Scenario: Worktree checkpoint has only unstaged or untracked changes -The runtime SHALL capture or import changed paths, public interfaces, traceability, acceptance/test evidence, and extractor identities with exact revisions or digests. +- **GIVEN** a valid applicable seal exists and governed changes appear only as unstaged tracked or untracked worktree paths +- **WHEN** `slice/worktree` or `deep/worktree` selection runs with an empty staged index +- **THEN** applicability, coverage, and obligations are evaluated from the complete worktree snapshot and the result is not `NOT_APPLICABLE` merely because the index is empty +- **AND** the staged-only rule remains limited to the separate index-based pre-commit wrapper. -#### Scenario: Historical test result is supplied for new implementation +#### Scenario: Staged change removes the last approval state -- **GIVEN** test evidence does not bind to the selected implementation revision -- **WHEN** the runtime normalizes evidence -- **THEN** the evidence is stale or unverifiable -- **AND** it cannot satisfy a sealed acceptance or test-intent obligation. +- **GIVEN** the authoritative base contains a seal or canonical lineage-tip artifact and the staged index deletes, relocates, or replaces that approval state so current-index discovery finds no valid seal +- **WHEN** automatic checkpoint selection runs +- **THEN** the base-to-index approval-state transition is classified as governed and the result is `UNKNOWN` with exit one +- **AND** the repository is not treated as never sealed, whether or not other governed paths are staged. -### Requirement: Core conformance evaluation +#### Scenario: Governed selected-scope paths have no covering seal -The runtime SHALL delegate obligation comparison and drift semantics to the released core conformance interface and SHALL not invent additional success states in rendering. +- **GIVEN** the repository contains one or more preflight seals and at least one path/input changed in the selected worktree/index scope is classified by repository policy as preflight-governed but is covered by no seal role +- **WHEN** automatic checkpoint selection runs +- **THEN** every wholly uncovered governed path/input is `unexpected`, the result is `FAIL`, and the hook exits non-zero +- **AND** absent or ambiguous governed/unrelated classification returns `UNKNOWN`, never `NOT_APPLICABLE`. -#### Scenario: Core verifier returns unexpected drift +#### Scenario: A matching seal covers only part of the selected seal-relevant scope -- **GIVEN** implementation includes a governed public change outside sealed scope -- **WHEN** conformance is evaluated and rendered -- **THEN** human and JSON output preserve the core unexpected finding and evidence identity -- **AND** rendering cannot convert it to conforming. +- **GIVEN** at least one source, test, docs, generated, evidence, or seal-bound configuration path changed in the selected worktree/index scope associates with a valid seal +- **AND** another selected-scope non-excluded seal-relevant path is outside that seal +- **WHEN** automatic checkpoint selection runs +- **THEN** every uncovered path is reported as `unexpected` +- **AND** the result is `FAIL` and exits non-zero +- **AND** intentional expansion returns to preflight refinement and reapproval. -### Requirement: Explicit drift resolution paths +#### Scenario: Applicable checkpoint evidence is ambiguous -The workflow SHALL require the user to choose between correcting implementation and returning to preflight for contract refinement/reapproval when material drift is intentional. +- **GIVEN** one or more paths changed in the selected worktree/index scope are covered by a seal but the canonical tip/chain, Git identity, component owner, influence mapping, selector, runner, or required evidence is stale, multiple, missing, or ambiguous +- **WHEN** checkpoint status is aggregated +- **THEN** the result is `UNKNOWN` and exits non-zero +- **AND** no renderer or workflow converts it to pass. -#### Scenario: User accepts a new implementation behavior +#### Scenario: Ambiguous canonical state overlaps uncovered scope -- **GIVEN** conformance reports material unexpected or modified behavior -- **WHEN** the user decides the behavior is desired -- **THEN** the current conformance result remains non-passing -- **AND** the workflow returns to the preflight review loop for a new contract and seal. +- **GIVEN** a staged governed path appears uncovered while the canonical tip, predecessor chain, approval authority, or required Git identity is missing, stale, multiple, rolled back, forked, or ambiguous +- **WHEN** automatic checkpoint selection runs +- **THEN** canonical and Git validation runs first and returns `UNKNOWN` with exit one +- **AND** uncovered-path `FAIL` is not asserted until a single valid canonical seal and snapshot identity make coverage determinate. -### Requirement: Human and JSON parity +### Requirement: Bounded checkpoint profiles -Conformance human and JSON renderers SHALL derive from the same normalized result and preserve seal, implementation, extractor, evidence, finding, and assurance-limit identities. +The module SHALL define cumulative `slice`, `commit`, and `deep` profiles whose selected obligations are derived from the sealed execution stages. `commit` SHALL include all applicable `slice` checks plus affected-component bounded targets. `deep` SHALL include all applicable lower-profile checks for its snapshot, bounded bug-hunt analysis, and every locally executable `prepush` obligation. -#### Scenario: Renderers process an unknown result +#### Scenario: Scope and profile are incompatible -- **GIVEN** required evidence is unavailable -- **WHEN** both renderers emit output -- **THEN** each reports the same unknown status and missing evidence -- **AND** neither describes the implementation as conforming. +- **GIVEN** a caller requests `--scope worktree --profile commit` or any scope/profile pair outside the allowed matrix +- **WHEN** checkpoint argument validation runs +- **THEN** the command rejects the request before Git extraction or evidence execution +- **AND** it neither evaluates worktree state as staged evidence nor silently switches to the index. -### Requirement: Atomic optional persistence +#### Scenario: Slice profile runs immediate semantic evidence -When explicitly requested, the runtime SHALL persist the implementation snapshot and conformance result atomically without modifying the original contract or seal. +- **GIVEN** changed seal-relevant paths or inputs in any non-excluded role map to sealed `slice` obligations +- **WHEN** the slice profile runs +- **THEN** it verifies the seal and scope, runs the affected exact Requirements pytest cases, and imports changed-scope code-review evidence +- **AND** it does not run unrelated component or full-repository tests. -#### Scenario: Persistence fails after comparison +#### Scenario: Commit profile evaluates the staged index -- **GIVEN** the result is computed but the complete persistence set cannot be verified -- **WHEN** the command exits -- **THEN** no partial record is treated as durable conformance evidence +- **GIVEN** exactly one policy-authorized canonical lineage-tip seal covers all staged non-excluded seal-relevant paths and `--scope index --profile commit` is selected +- **WHEN** the commit profile runs +- **THEN** it adds every affected component's bounded pytest targets and current-run JUnit evidence +- **AND** execution is bound to the captured index capsule rather than a differing worktree. + +#### Scenario: Deep profile encounters CI-only obligation + +- **GIVEN** a sealed obligation has earliest stage `ci` +- **WHEN** the deep local profile runs +- **THEN** the obligation is reported as deferred with identity and reason +- **AND** it is not described as locally passed or missing. + +#### Scenario: Deep profile executes local pre-push assurance + +- **GIVEN** the selected snapshot has applicable slice and affected-component checks, bounded bug-hunt analysis, and locally executable `prepush` obligations +- **WHEN** the deep profile runs +- **THEN** it executes the applicable lower-profile checks, bounded bug-hunt, and every locally executable `prepush` obligation +- **AND** missing or non-passing required evidence is aggregated through the released core result semantics rather than skipped or deferred. + +### Requirement: Complete implementation scope evidence + +The runtime SHALL reuse C14 worktree/index/range primitives and implement the released core snapshot matrix without guessing or lossy path parsing. Every snapshot base SHALL equal the seal-bound implementation-lineage origin repository/base commit/base tree. Worktree snapshots SHALL additionally bind a worktree-manifest digest and include staged, unstaged, and untracked state. Index snapshots SHALL additionally bind the exact index tree ID and exclude untracked paths unless staged as additions. Range snapshots SHALL bind full head commit/tree, policy-authorized current delivery-target commit/tree, plus origin-to-head ancestry and SHALL NOT represent untracked paths. Every manifest SHALL preserve additions, deletions, both rename endpoints, before/after modes, symlink target identity, and byte-preserving path identity; rename interpretation SHALL be bound to producer, policy, and toolchain identity. For every affected governed path that repository policy classifies as capable of defining a public interface, regardless of whether its role is `source`, `test`, `docs`, `generated`, or `evidence`, the runtime SHALL extract or import normalized base/current public-interface records using the released core snapshot schema. A side that does not exist by construction for an addition, deletion, or rename endpoint SHALL be represented by a normalized `absent` record/tombstone, not omitted. The tombstone SHALL bind the same path, role, exact snapshot, extractor identity/version/configuration, policy/toolchain, and Git-transition provenance required of a present observation and SHALL contain no fabricated interface members. Comparison of `absent` with `present` SHALL deterministically derive interface additions/removals, including both rename endpoints; an omitted record, unverifiable absence, or `absent` record for an existing path remains `UNKNOWN`. Base/current records SHALL otherwise bind extractor identity/version/configuration digest, policy/toolchain identity, path, role, and exact base/current snapshot provenance; changed-interface identities SHALL be derived by deterministic comparison rather than accepted as a caller-supplied set. + +#### Scenario: Repository contains difficult path transitions + +- **GIVEN** a change adds, deletes, renames, changes mode, symlinks, or uses quoted, Unicode, or trailing-character paths +- **WHEN** the implementation snapshot is extracted +- **THEN** every path and both rename endpoints are preserved with exact transition identity +- **AND** unresolved Git evidence yields `UNKNOWN`. + +#### Scenario: Interface-capable path is added, deleted, or renamed + +- **GIVEN** one side of an interface-capable path or rename endpoint does not exist in the exact base/current snapshot +- **WHEN** public-interface observations are normalized +- **THEN** the nonexistent side is a provenance-bound `absent` tombstone and the existing side is a provenance-bound `present` record +- **AND** their deterministic comparison derives the interface addition/removal instead of treating expected absence as missing evidence. + +#### Scenario: Public-interface delta cannot be established + +- **GIVEN** an affected governed path in any role can define a public interface but its base/current interface records are missing, unsupported, incomplete, stale, ambiguously normalized, or bound to a different snapshot or extractor configuration +- **WHEN** implementation scope evidence is assembled +- **THEN** changed-interface discovery is `unverifiable` and the checkpoint or conformance result is `UNKNOWN` +- **AND** an empty caller-supplied changed-interface set cannot close or omit interface obligations. + +#### Scenario: Generated path defines a public interface + +- **GIVEN** an affected governed path is classified as `generated` and repository policy classifies it as capable of defining a public interface +- **WHEN** checkpoint or conform extracts the snapshot-bound interface delta +- **THEN** the same complete base/current observations and extractor provenance required for any interface-capable role are enforced +- **AND** missing or unverifiable observations return `UNKNOWN` rather than an empty changed-interface set. + +### Requirement: Seal-bound semantic evidence selection + +The runtime SHALL classify every changed non-excluded seal-relevant path, public-interface record, and input in the selected worktree/index scope across `source`, `test`, `docs`, `generated`, and `evidence` roles plus seal-bound approval, test, dependency, policy, toolchain, and relevant configuration inputs. Approval-state discovery SHALL compare the authoritative base with the selected worktree/index snapshot so deletion, relocation, or replacement of the last seal or canonical lineage-tip artifact cannot be reclassified as a never-sealed repository. The runtime SHALL map each applicable path, changed-interface identity, and input through the sealed ownership and influence relationships to the corresponding risk rows, Requirements plan identities, exact pytest cases, bounded component targets, review/evidence obligations, and execution stages. A checkpoint MAY select only the affected subset of requirement, scenario, verification-case, and exact pytest-selector identities already bound by the seal; any addition, removal, replacement, or change of a bound identity SHALL require preflight validation, approval, and a new seal. Before intentional expansion can receive successor approval or failing-first evidence, any already-implemented out-of-scope production delta SHALL be removed from the selected implementation snapshot. The successor contract and tests SHALL then be authored and approved, failing-first evidence SHALL be captured against that expanded contract with the production behavior absent, and only then MAY the production expansion be reimplemented. The runtime and bundled workflow SHALL report and stop; they SHALL NOT automatically remove code, rewrite history, approve, or reseal. A non-excluded changed path or input MAY produce a determinate empty semantic-selector set only when the current valid canonical seal binds a complete no-impact disposition: exact input/path identity and role; applicable sealed-baseline observation identity/digest; non-empty rationale; and policy-authorized deterministic permitted-transition predicate identity/version/configuration digest, closed change class, and observable invariants. The runtime SHALL evaluate that predicate against exact provenance-bound baseline/current content, mode, interface, and relevant input observations from the selected snapshot. The predicate SHALL be supported and semantics-preserving for the role and SHALL NOT admit arbitrary content, behavior, configuration, dependency, or execution changes. The result SHALL retain the disposition, predicate, baseline/current observation, transition-evidence, and validation identities/digests. No-impact SHALL NOT suppress seal, scope, interface-discovery, approval-state, or changed-scope code-review checks. Missing, stale, unsupported, ambiguous, or mismatched baseline/predicate/transition evidence SHALL return `UNKNOWN`; a transition outside the permitted class SHALL select normal mapped obligations or return `UNKNOWN` when no mapping exists, never an empty set. + +#### Scenario: Production path lacks semantic ownership + +- **GIVEN** a changed production path has no sealed component or required semantic evidence mapping +- **WHEN** checkpoint selection runs +- **THEN** the result is `UNKNOWN` +- **AND** overall pytest success cannot satisfy the missing obligation. + +#### Scenario: Test or execution input changes without source changes + +- **GIVEN** only a sealed test, pytest configuration, dependency, policy, toolchain, generated/evidence path, or other relevant execution input changes +- **WHEN** checkpoint selection runs +- **THEN** the runtime selects every corresponding sealed case, target, review, and evidence obligation through the approved influence mapping +- **AND** an absent or ambiguous mapping returns `UNKNOWN` rather than an empty affected set or `NOT_APPLICABLE`. + +#### Scenario: Changed input has an approved no-impact disposition + +- **GIVEN** the canonical valid seal binds a complete no-impact disposition to the exact changed input/path identity and role, applicable sealed-baseline observation, non-empty rationale, and policy-authorized deterministic permitted-transition predicate/change class/observable invariants +- **WHEN** semantic evidence selection runs +- **THEN** the runtime evaluates that predicate against the exact provenance-bound baseline/current snapshot observations and derives a determinate empty semantic-selector set only when the transition matches +- **AND** it records the disposition, predicate, baseline/current observations, transition evidence, rationale, and validation identities/digests while still performing seal, scope, approval-state, interface-discovery, and changed-scope code-review checks. + +#### Scenario: No-impact disposition cannot be verified + +- **GIVEN** a changed input has no influence mapping and its claimed no-impact disposition, sealed-baseline observation, predicate identity/version/configuration, closed change class, observable invariants, role support, or exact transition evidence is missing, stale, unsupported, ambiguous, or mismatched +- **WHEN** semantic evidence selection runs +- **THEN** the result is `UNKNOWN` +- **AND** an empty affected set cannot be inferred from the absence of a mapping. + +#### Scenario: Observed delta exceeds the no-impact transition + +- **GIVEN** a changed source or execution-relevant input has a sealed no-impact disposition but its exact baseline/current snapshot transition does not satisfy the permitted change class or observable invariants +- **WHEN** semantic evidence selection runs +- **THEN** the runtime selects the input's normal approved influence mappings, or returns `UNKNOWN` when none exist +- **AND** unchanged public-interface observations cannot by themselves justify an empty semantic-selector set. + +#### Scenario: Implementation exceeds sealed scope + +- **GIVEN** a changed path or behavior lies outside sealed roles and exclusions +- **WHEN** checkpoint comparison runs +- **THEN** it returns an `unexpected` failure and a `return_to_preflight` remediation class +- **AND** the already-implemented out-of-scope production delta is removed from the selected implementation snapshot before successor-contract approval and failing-first evidence +- **AND** intentional expansion is reimplemented only after the successor preflight review/seal and failing-first evidence, while preserving the original implementation-lineage origin baseline. + +### Requirement: Current-run pytest and code-review evidence + +The runtime SHALL first supply the upstream design contract, validation result, seal, policy, and current source identities to released core verification, then reuse existing Requirements pytest/JUnit and SpecFact code-review JSON contracts with exact producer and snapshot identities. It SHALL use released core finding precedence and deterministic `FAIL`/`UNKNOWN`/`PASS` aggregation rather than redefining them. + +#### Scenario: Selector is missing, duplicate, uncollected, failed, or stale + +- **GIVEN** required pytest evidence cannot be reconciled exactly to the selected snapshot and plan +- **WHEN** checkpoint evidence is normalized +- **THEN** the result is `FAIL` for a determinate violation or `UNKNOWN` for unresolved provenance +- **AND** no alternate selector grammar or historical overall exit code is accepted. + +#### Scenario: Cache identity changes + +- **GIVEN** the seal, snapshot, obligation set, pytest targets, runner, policy, toolchain, attested execution-environment/dependency state, allowlisted relevant environment, or relevant configuration changes +- **WHEN** cached evidence is considered +- **THEN** the prior cache entry is rejected +- **AND** required checks execute again. + +#### Scenario: Execution environment cannot be attested + +- **GIVEN** the active Python environment or a policy-allowlisted relevant environment variable cannot be deterministically identified without exposing secret values +- **WHEN** cached evidence is considered +- **THEN** cache reuse is disabled for that checkpoint +- **AND** the runtime reruns required checks, or returns `UNKNOWN` if the required execution itself cannot be performed. + +### Requirement: Local and range authority separation + +The runtime SHALL preserve core checkpoint authority for worktree/index results and SHALL require repository identity, the seal-bound implementation-lineage origin commit/tree, full immutable head commit/tree, a policy-authorized current delivery-target commit/tree identity, and origin-to-head ancestry for `specfact preflight conform `. Tree attestations and the complete path manifest SHALL bind to that exact repository and cumulative lineage-origin-to-current-delivery-head range across all successor seals. + +#### Scenario: Local pass is presented as PR proof + +- **GIVEN** a worktree or index checkpoint passed +- **WHEN** a consumer requests final or protected PR authority +- **THEN** the runtime rejects promotion +- **AND** requires a new immutable-range conformance or protected consumer run. + +### Requirement: Immutable-range conformance evaluation + +`specfact preflight conform ` SHALL discover the policy-authorized canonical lineage tip from the canonical approval source; verify the supplied design contract, validation result, selected seal, policy, current source identities, implementation-lineage identity, immutable origin repository/base commit/base tree, and complete predecessor-seal chain; require the selected seal digest/monotonic sequence and chain digest to equal the canonical tip; require the range base to equal the lineage origin rather than a later successor-seal source snapshot; use C14 to prove that the full head descends from the origin and to extract the complete immutable lineage-origin-to-head manifest and range-bound evidence; extract or import snapshot-bound base/head public-interface records through the policy-authorized extractor and derive their complete changed-interface set; require the range head commit/tree to equal a policy-authorized current delivery-target identity resolved from the current local delivery ref/HEAD or supplied by an authenticated protected-PR/CI orchestrator; derive the deterministic exhaustive final-delivery obligation set; and invoke the released core implementation-assurance verifier. The exhaustive set SHALL include every changed governed path/interface and every applicable sealed component, acceptance criterion, risk row, Requirements verification case, component target, verification stage including `ci`, exclusion, and no-impact disposition plus its predicate and exact transition evidence in their transitive obligation closure. The set and its digest SHALL be bound to the result. A no-impact disposition MAY close an input with no influenced selectors only after its sealed deterministic permitted-transition predicate verifies the exact provenance-bound baseline/current range observations; its disposition, predicate, baseline/current observation, transition-evidence, rationale, and validation identities/digests SHALL remain in the exhaustive closure. Missing, unsupported, incomplete, stale, ambiguous, wrong-snapshot, or wrong-extractor interface or no-impact transition evidence SHALL keep conformance `UNKNOWN`; a caller cannot provide an empty interface set or self-asserted no-impact transition to shrink the closure. For an obligation whose earliest stage is `ci`, the runtime SHALL accept satisfaction only from a seal/policy-authorized protected-CI producer whose authenticated provenance is bound to the exact immutable range. Missing, local, self-asserted, unauthenticated, or wrong-range CI evidence SHALL remain `UNKNOWN`/deferred and SHALL prevent `PASS`. Human and JSON output SHALL preserve the core result status, findings, authority, evidence identities, and assurance limits without converting a non-passing outcome. + +#### Scenario: Caller supplies an ancestor seal + +- **GIVEN** an older seal and its predecessor chain are internally valid but the canonical approval source identifies a later approved successor as the current lineage tip +- **WHEN** checkpoint selection or final conformance runs +- **THEN** the selected-seal/tip mismatch is `stale` and returns `UNKNOWN` +- **AND** obligations introduced by the successor cannot be omitted by selecting the ancestor. + +#### Scenario: Canonical seal tip is unavailable or ambiguous + +- **GIVEN** the canonical approval source or its lineage-tip/chain/authority identity is missing, stale, rolled back, forked, or ambiguous +- **WHEN** checkpoint selection or final conformance runs +- **THEN** the result is `UNKNOWN` and exits non-zero +- **AND** the runtime does not guess the latest seal from timestamps or caller ordering. + +#### Scenario: Final range is evaluated against the seal + +- **GIVEN** a canonical latest valid seal and explicit repository, implementation-lineage origin commit/tree, full head commit/tree equal to the policy-authorized current delivery target, and origin-to-head ancestry identities +- **WHEN** final conformance runs +- **THEN** the runtime verifies upstream identities, extracts the exact immutable-range manifest and evidence, maps sealed final-delivery obligations, and invokes the core comparator +- **AND** the result remains independent from prior local checkpoint authority and protected PR review. + +#### Scenario: Final obligation selection is incomplete + +- **GIVEN** an immutable range affects one or more sealed paths, interfaces, behaviors, components, acceptance criteria, risk rows, Requirements cases, targets, stages, or exclusions +- **WHEN** final conformance omits, duplicates, or cannot deterministically resolve any member of the exhaustive transitive obligation closure, or selects an empty set for that affected range +- **THEN** the result is `UNKNOWN` with the incomplete selection identities +- **AND** comparison cannot pass until the complete result-bound obligation set is available. + +#### Scenario: Caller attempts a truncated final range + +- **GIVEN** implementation changes exist after the first seal's implementation-lineage origin baseline, including changes retained across successor seals +- **WHEN** a caller supplies a later range base, a different base tree, or a head without valid ancestry from the lineage origin +- **THEN** conform returns the released core `stale` or `unverifiable` finding and `UNKNOWN` +- **AND** it does not extract or compare a current-seal or caller-selected shorter range. + +#### Scenario: Caller supplies an older descendant head + +- **GIVEN** the requested range head descends from the lineage origin but differs from the policy-authorized current delivery-target commit or tree identity +- **WHEN** conform validates the immutable range +- **THEN** the head mismatch is `stale`, conform returns `UNKNOWN`, and the command exits non-zero +- **AND** later delivery commits cannot remain outside the evaluated manifest and obligation closure. + +#### Scenario: CI-only final obligation has no protected evidence + +- **GIVEN** the exhaustive final range closure contains an applicable obligation whose earliest stage is `ci` +- **WHEN** conform runs without authenticated evidence from an authorized protected-CI producer bound to that exact range +- **THEN** the obligation remains deferred with an `unverifiable` finding and `UNKNOWN` +- **AND** local or caller-constructed evidence cannot make final conformance pass. + +#### Scenario: Final range comparison cannot be completed or does not conform + +- **GIVEN** a stale or mismatched seal, unresolved range identity, unavailable required range-bound evidence, or a blocking core comparison finding +- **WHEN** final conformance is aggregated and rendered +- **THEN** the exact core `UNKNOWN` or `FAIL` outcome and findings are preserved +- **AND** the runtime cannot synthesize `PASS` from immutable references, prior local evidence, or overall test exit status alone. + +### Requirement: Compact bounded remediation workflow + +The module SHALL emit deterministic compact remediation packets and bundle a harness-neutral workflow that permits at most three agent fix/rerun cycles. + +#### Scenario: Finding can return to implementation + +- **GIVEN** a determinate finding is classified `fix_implementation`, `fix_or_add_test`, or `rerun` +- **WHEN** the workflow hands it to the current coding agent +- **THEN** the packet includes fingerprint, contract/risk reference, implementation evidence, expected observable, recommended action, and validation selectors +- **AND** the deterministic CLI itself performs no LLM or network call. + +#### Scenario: Workflow must stop + +- **GIVEN** a fingerprint repeats consecutively, three cycles are exhausted, scope expands, status is `UNKNOWN`, design judgment is required, or a sealed artifact would change +- **WHEN** the workflow evaluates the next action +- **THEN** it stops and reports the human or preflight handoff +- **AND** it does not edit or reseal the contract automatically. + +### Requirement: Human and JSON parity with optional persistence + +Human and JSON renderers SHALL derive from one normalized result, and explicit persistence SHALL atomically retain the complete snapshot/result without modifying the original contract or seal. + +#### Scenario: Persistence or rendering is incomplete + +- **GIVEN** output cannot preserve all status, authority, finding, packet, evidence, policy, and assurance-limit identities +- **WHEN** rendering or persistence runs +- **THEN** no partial artifact is treated as valid checkpoint or conformance evidence - **AND** the original preflight artifacts remain unchanged. -### Requirement: Opt-in delivery policy +### Requirement: Shadow dogfood before seal-aware blocking + +The first rollout SHALL measure checkpoint behavior in shadow mode and SHALL exercise both accepted defect fixtures and representative known-green controls. Every corpus result and live observation SHALL bind the exact candidate implementation commit/tree and runtime/module identity, release-surface, policy, relevant configuration, corpus, runner, and toolchain digests. Any promotion-relevant identity change, including release preparation, SHALL invalidate the affected evidence and require recollection; evidence from an older candidate SHALL NOT authorize blocking for changed behavior. Blocking SHALL remain disabled until every corpus case produces its predeclared status, authority, finding set, and exit behavior; the exact current candidate's corpus has zero false PASS, zero false block, and no destructive/ambiguous behavior; and its live shadow observations meet a rollout-policy threshold declared before collection. The default threshold SHALL require at least 20 applicable known-good observations for each enabled scope/profile pair and at least 100 in aggregate, with both each pair's false-block rate and the aggregate rate no greater than 1%. Repository policy MAY require a larger per-pair or aggregate sample or lower rate but SHALL NOT weaken those defaults. + +#### Scenario: C14 regression fixture is exercised + +- **GIVEN** an accepted fixture represents an illegal exit, cache identity drift, malformed input, deletion-only change, difficult path, suppression relocation, or FAIL/UNKNOWN precedence defect +- **WHEN** slice or commit checkpoint dogfood runs +- **THEN** the defect is non-passing before simulated PR delivery +- **AND** duration, local detection, cycles, packet size, repeated class, and later-review outcome are recorded. + +#### Scenario: Known-green control is exercised + +- **GIVEN** a valid sealed fixture has complete scope, interface, ownership, selectors, evidence, and cache identity for an enabled scope/profile pair +- **WHEN** checkpoint dogfood runs +- **THEN** it produces the predeclared passing status, local authority, empty blocking-finding set, and exit zero +- **AND** a blanket `FAIL` or `UNKNOWN` implementation is recorded as a false block and cannot enable blocking. + +#### Scenario: Pairwise shadow sample is too small or false-blocking exceeds policy + +- **GIVEN** an enabled scope/profile pair has fewer than 20 applicable known-good observations, the aggregate has fewer than 100, a pairwise or aggregate observed false-block rate exceeds 1%, or any corpus expectation is mismatched +- **WHEN** rollout promotion is evaluated +- **THEN** seal-aware blocking remains disabled and shadow measurement continues +- **AND** one high-volume passing pair cannot hide an under-sampled or false-blocking pair. + +#### Scenario: Candidate changes after shadow evidence is collected + +- **GIVEN** corpus or live observations were collected for one candidate identity +- **AND** implementation, runtime/module, release-surface, policy, relevant configuration, corpus, runner, or toolchain identity changes before promotion +- **WHEN** rollout promotion is evaluated +- **THEN** the affected evidence is invalid for the changed candidate and cannot contribute to its thresholds +- **AND** shadow observations are recollected and all promotion gates are reevaluated against the exact current identity. + +### Requirement: Signed publication before adapter consumption + +The implementation PR SHALL prepare the versioned manifest and SHALL use the documented unsigned dev-target preparation workflow with either every affected manifest path or `--changed-only --base-ref ` to refresh each selected checksum against the exact proposed merge-tree payload while removing any stale signature. The selected manifest set and full base identity SHALL be recorded in evidence; an empty, incomplete, or ambiguous selection SHALL fail. That checksum-only candidate SHALL pass full filesystem checksum and version-bump verification but SHALL NOT be considered cryptographically signed, published, registry-addressable, or eligible for downstream handoff. After the implementation PR is merged to `dev`, the canonical post-merge publication workflow SHALL verify the exact merged version/payload/checksum, cryptographically sign it, generate registry/signature/history artifacts, compatibility-test, and propose one immutable #434 module release identity whose signed manifest separately binds the existing preflight workflow identity/digest and the new implementation-check workflow identity/digest. The publication workflow SHALL fail rather than silently modify the merged payload, version, checksum, workflow bindings, or compatibility range; a required payload change SHALL return through implementation evidence and review. Because signing or generated publication artifacts change promotion-relevant identities, the canonical workflow SHALL recollect negative-corpus and known-good live rollout evidence and reevaluate every promotion gate against the exact signed publication head before merge; checksum-only or earlier signed-head evidence SHALL NOT authorize publication. Any subsequent fix or identity drift SHALL invalidate the affected evidence and repeat signed-candidate recollection and promotion evaluation. The proposal SHALL set the complete `core_compatibility` range identically in the bundle manifest and registry entry. Its lower bound SHALL identify the first released core containing the final #684 interfaces. Its exclusive upper bound SHALL be preserved from, or deterministically derived from, the intersection of the complete bundled-module dependency graph and SHALL NOT be omitted or widened past any required dependency's supported range. A core below the lower bound, at the upper bound, or above the upper bound SHALL be rejected; the exact lower bound and supported newer cores strictly below the upper bound SHALL pass the compatibility matrix. Neither a feature-branch artifact nor a merely proposed post-merge artifact is published or eligible for downstream handoff. Only after the unchanged signed publication PR is reviewed and merged and official registry/install readback passes SHALL the #434 identity be considered published and handed to core #251. Core #253 SHALL follow completed #251, and modules #433 SHALL consume the identities only after both #251 and #253 complete. + +#### Scenario: Implementation branch prepares publication inputs + +- **GIVEN** the #434 implementation PR has not merged to `dev` +- **WHEN** its release-surface matrix validates the proposed manifest, payload, checksum, version bump, and compatibility metadata +- **THEN** it refreshes checksum-only integrity metadata through the documented unsigned dev-target workflow, removes any stale signature, passes full filesystem checksum/version verification, and compares the proposed manifest with a projected registry row without mutating the official registry +- **AND** cryptographic signing, actual registry generation, and signed-manifest/registry equality verification remain exclusive to the canonical post-merge publication PR. + +#### Scenario: Post-merge signing sees a different payload + +- **GIVEN** the merged module payload, version, checksum, workflow bindings, or compatibility range differs from the checksum-only candidate that passed implementation evidence and review +- **WHEN** the canonical publication workflow prepares the cryptographic signature and registry artifacts +- **THEN** publication fails and returns the changed payload through implementation evidence and review +- **AND** the publisher does not silently repair or publish an identity that was not the reviewed merge candidate. + +#### Scenario: Signed publication candidate lacks matching rollout evidence -The first conformance runtime SHALL remain opt-in and SHALL require a separate accepted policy change before becoming a universal blocking PR or archive gate. +- **GIVEN** the canonical post-merge workflow has signed the module and generated registry, signature, or history artifacts +- **AND** rollout evidence was collected only for the checksum-only implementation candidate or an earlier signed publication head +- **WHEN** publication promotion is evaluated +- **THEN** the publication PR remains unmergeable because the evidence does not bind the exact signed head +- **AND** negative-corpus and known-good live observations are recollected and every promotion gate is reevaluated before merge. -#### Scenario: Repository has no conformance policy +#### Scenario: Installation uses a core older than implementation assurance -- **GIVEN** the command is installed but no project policy requires it -- **WHEN** ordinary delivery proceeds -- **THEN** absence of a conformance run is reported as unavailable where queried -- **AND** the module does not silently create a new blocking merge rule. +- **GIVEN** the #434 module is resolved with a core identity below the manifest/registry `core_compatibility` lower bound containing #684 +- **WHEN** compatibility or installation validation runs +- **THEN** the combination is rejected before checkpoint or conform execution +- **AND** manifest and registry metadata cannot advertise an unusable older core. -### Requirement: Adapter compatibility across conformance release +#### Scenario: Installation reaches a dependency-backed upper bound -When the conformance command or workflow changes the signed module/workflow identity, the release SHALL provide tested compatibility evidence for each claimed #433 adapter through a compatible-upgrade descriptor or SHALL keep adapter-mediated adoption blocked on a separately accepted adapter release. +- **GIVEN** one or more required bundled modules impose an exclusive upper core-compatibility bound +- **WHEN** the #434 manifest and projected or generated registry entry are prepared or compatibility-tested +- **THEN** both surfaces carry the same upper bound derived from the complete dependency intersection +- **AND** the matrix accepts supported cores below it and rejects the bound itself plus a representative core above it. -#### Scenario: Existing adapter pins the prior release identity +#### Scenario: Adapter requests the new workflow -- **GIVEN** an installed adapter descriptor pins the exact module/workflow identity published by #433 -- **WHEN** the conformance release presents a different signed identity -- **THEN** compatibility must be proven through a tested descriptor before that adapter can consume the release -- **AND** an unproven or mismatched descriptor blocks adapter invocation and downstream adoption. +- **GIVEN** the #434 implementation and canonical publication PRs are merged, matching complete manifest/registry `core_compatibility` ranges and their lower/upper-bound matrix pass, official registry/install readback passes, and core #251 then #253 are complete +- **AND** #433 prepares a harness adapter +- **WHEN** it resolves the canonical module and workflow identities +- **THEN** it consumes the exact signed #434 module identity, preflight workflow identity/digest, and implementation-check workflow identity/digest +- **AND** #434 contains no harness-specific adapter package. diff --git a/openspec/changes/preflight-05-implementation-conformance/tasks.md b/openspec/changes/preflight-05-implementation-conformance/tasks.md index 3e4b2d0a..b71a7c1e 100644 --- a/openspec/changes/preflight-05-implementation-conformance/tasks.md +++ b/openspec/changes/preflight-05-implementation-conformance/tasks.md @@ -5,31 +5,37 @@ All tasks below are future implementation work. This planning change completes n ## 1. Dedicated session, worktree, and readiness - [ ] 1.1 In a dedicated issue-linked session, create `feature/preflight-05-implementation-conformance` from current `origin/dev` in a new modules worktree before any implementation edit. -- [ ] 1.2 Refresh hierarchy metadata and verify issue type, parent, labels, project `Todo`, assignee, blockers, and concurrency status. -- [ ] 1.3 Verify the complete core #682 -> modules #431 -> core #680/#683 -> modules #432 -> core #251/#253 -> modules adapters #433 sequence plus paired core #684, preserve modules C14 #416 as open and `In Progress` unless separately authorized, and read back the exact stable preflight module, adapter descriptor, and released core conformance interface identities. +- [ ] 1.2 Refresh hierarchy metadata and verify #434 is `Todo`, correctly parented/labeled/assigned, blocked only by stable modules #432 and core #684, blocks core #251, and is not concurrently `In Progress`. +- [ ] 1.3 Read back the exact released preflight, Requirements, C14 scope/capsule, code-review JSON, and core #684 identities; preserve C14 #416 state unless separately authorized. ## 2. Specification and failing-first evidence -- [ ] 2.1 Finalize command, evidence adapter, validator, rendering, persistence, workflow, and adapter-compatibility handoff deltas without adding preflight MVP or external adapter packaging scope. -- [ ] 2.2 Add tests mapped to every invalid-seal, explicit implementation-identity, base/head separation, stale-evidence, drift, reapproval, renderer-parity, persistence, opt-in-policy, and changed-release-identity adapter-compatibility scenario. -- [ ] 2.3 Run targeted tests before production edits and record failing-first results in a newly created `TDD_EVIDENCE.md`. +- [ ] 2.1 Finalize checkpoint/conform CLI, profile, evidence adapter, cache, pre-commit, remediation packet, bounded workflow, persistence, signing, and publication deltas without external adapter packaging. +- [ ] 2.2 Add mapped tests for upstream verifier inputs, canonical latest-seal tip/monotonic-sequence/chain selection, seal rollback/fork ambiguity and canonical/Git UNKNOWN precedence over uncovered-scope FAIL, selected-snapshot applicability including unstaged/untracked-only worktree changes versus staged-only index/pre-commit behavior, independent canonical approval with no Git artifact, canonical-source confirmation of genuinely absent current/historical approval versus unavailable/ambiguous history as UNKNOWN, staged deletion/relocation/replacement of the last seal or tip versus a genuinely never-sealed repository, reseal boundaries and immutable lineage-origin preservation, out-of-scope production-expansion removal before successor approval/failing-first evidence and reimplementation only afterward, the normative worktree/index/range and scope/profile matrices, origin-base equality, origin-to-head ancestry, exact authoritative current-delivery-head equality and stale older-head rejection, complete Git transitions, policy-authorized base/current public-interface extraction for every interface-capable governed role with extractor/configuration/snapshot provenance, provenance-bound absent tombstones for additions/deletions/both rename endpoints, invalid absence and missing/ambiguous/empty-set rejection, exhaustive immutable-range obligation selection including sealed no-impact baseline/predicate/exact-transition evidence, protected-CI producer authorization and exact-range provenance, conformance evaluation and fail-closed rendering, source/test/docs/generated/evidence and approval/test/dependency/policy/toolchain/config-input selection, no-impact empty selection only for a matching supported semantics-preserving transition versus missing/stale/unsupported/mismatched predicates or semantic deltas as UNKNOWN/normal mapped selection, wholly uncovered governed paths as FAIL versus empty/ambiguous influence mapping as UNKNOWN, scope/interface/component/risk mapping, planned-to-test-authored Requirements selectors/JUnit, all core finding classes and precedence, code-review import, execution-environment/dependency/environment-variable cache invalidation and no-attestation bypass, statuses/authority, cumulative profile behavior including deep bug-hunt/prepush execution, renderer parity, persistence, and post-merge publication. +- [ ] 2.3 Add workflow tests for deterministic packets, three-cycle maximum, repeated fingerprints, scope expansion, unknown/design stops, and non-mutation of sealed artifacts. +- [ ] 2.4 Run targeted tests before production edits and record failing-first results in a new `TDD_EVIDENCE.md`. ## 3. Minimal runtime implementation -- [ ] 3.1 Implement `specfact preflight conform ` against the released core interface. -- [ ] 3.2 Implement evidence import/extraction adapters and closed mapping validators without duplicating existing analyzers. -- [ ] 3.3 Implement human/JSON rendering, explicit drift resolution handoff, and optional atomic persistence. -- [ ] 3.4 Keep delivery enforcement opt-in and exclude external harness packages; emit a tested compatible-upgrade descriptor only when #433's adapters can consume the new exact module/workflow identity, otherwise block adoption on a separately accepted adapter release. +- [ ] 3.1 Implement `specfact preflight checkpoint --scope worktree|index --profile slice|commit|deep` against released core #684 interfaces. +- [ ] 3.2 Reuse C14 scope/capsule/toolchain extraction, Requirements plans/selectors/JUnit, and code-review JSON; add no duplicate selector or analyzer schema. +- [ ] 3.3 Implement obligation selection, pytest execution, status aggregation, digest-bound caching, human/JSON rendering, compact remediation packets, and optional atomic persistence. +- [ ] 3.4 Implement the seal-aware index pre-commit wrapper and harness-neutral implementation-check workflow; keep the deterministic CLI free of LLM/network calls and implementation or sealed-artifact mutation while permitting only explicitly requested atomic snapshot/result persistence. +- [ ] 3.5 Implement `specfact preflight conform ` as explicit immutable-range extraction, sealed-obligation mapping, core comparison, and non-passing result preservation with separate authority. -## 4. Passing evidence and quality gates +## 4. Dogfood and passing evidence -- [ ] 4.1 Re-run mapped tests and capture passing evidence after implementation. -- [ ] 4.2 Run format, type, lint, YAML, bundle-import, signature/version, contract, smart-test, test, and SpecFact code-review gates; resolve all findings. -- [ ] 4.3 Run official install/load and compatibility smoke against the selected released core/module identities and prove that every claimed existing adapter accepts the exact new identity; treat a descriptor mismatch as a release blocker, not a best-effort upgrade. -- [ ] 4.4 Run `openspec status --change preflight-05-implementation-conformance --json` and `openspec validate preflight-05-implementation-conformance --strict`. +- [ ] 4.1 Run shadow dogfood against C14-derived negative fixtures for illegal analyzer exits, cache identity/mode drift, malformed input, deletion-only changes, quoted/trailing/Unicode paths, suppression relocation, and FAIL/UNKNOWN precedence, plus representative known-green fixtures for every enabled scope/profile pair; require exact predeclared status, authority, finding-set, and exit behavior for every fixture and bind every result to the exact candidate implementation commit/tree, runtime/module, release-surface, policy, relevant configuration, corpus, runner, and toolchain digests. +- [ ] 4.2 Record duration, locally detected defects, cycles-to-green, packet size, repeated finding classes, false PASS, false block, and later PR findings per enabled scope/profile pair and in aggregate; enable seal-aware blocking only after the exact current candidate has zero false PASS, zero known-green corpus false block, no destructive/ambiguous behavior, at least 20 applicable known-good live observations per enabled pair and 100 aggregate, and pairwise plus aggregate false-block rates no greater than 1%. Repository policy may require larger samples or lower rates but not weaker thresholds. +- [ ] 4.3 Run format, type, lint, YAML, bundle-import, contract, smart-test, full test, independent analysis where applicable, and SpecFact code-review gates; resolve all findings. Any fix or other promotion-relevant identity change invalidates affected shadow evidence and returns to 4.1/4.2 for recollection before blocking promotion. +- [ ] 4.4 Run strict OpenSpec and Requirements planning/evidence gates and record only observed results. -## 5. Delivery and post-merge cleanup +## 5. Release and downstream handoff -- [ ] 5.1 Document assurance limits, opt-in policy, and rollback using observed evidence only. -- [ ] 5.2 Open the implementation PR to `dev` as the final pre-merge task, linking the paired core issue, evidence, and the tested compatible-upgrade descriptor or separately accepted adapter-release blocker. -- [ ] 5.3 After merge, run `openspec archive preflight-05-implementation-conformance`, update ordering/source mirrors, and remove the dedicated worktree and merged branch. +- [ ] 5.1 Prepare the proposed semver bump and bundle-manifest bindings for the existing preflight and new implementation-check workflow identities/digests. Run `scripts/sign-modules.py --allow-unsigned --payload-from-filesystem --changed-only --base-ref ` so the explicit selector resolves every affected manifest and the exact proposed merge-tree payload has refreshed checksums with no stale signatures; record the full base identity and selected manifest set, and fail on empty/incomplete/ambiguous selection. This checksum-only candidate is not cryptographically signed or publishable. Project, but do not write to the official registry, the row that the canonical post-merge publisher would generate. Set matching proposed-manifest/projected-row `core_compatibility` ranges: raise the lower bound to the first released core containing the final #684 interfaces, and preserve or derive an exclusive upper bound from the intersection of every required bundled module's dependency constraint. Prepare immediately-below-lower rejection, exact-lower and supported-newer-below-upper acceptance, upper-bound and above-upper rejection, and publication inputs. Feature-branch artifacts are not publishable identities. +- [ ] 5.2 After 5.1, recollect 4.1/4.2 shadow corpus and live evidence for the resulting exact release-ready checksum-only candidate, then rerun the complete release-surface matrix against that same proposed merge tree, including `verify-modules-signature --payload-from-filesystem --enforce-version-bump`, proposed-manifest/projected-registry-row complete `core_compatibility` parity, dependency-graph upper-bound derivation, below-lower rejection, exact-lower and supported-newer-below-upper acceptance, upper-bound and above-upper rejection, bundle-import, contract, full test, independent analysis where applicable, and SpecFact code review. Resolve every finding without mutating the official registry; any fix or identity change repeats unsigned checksum preparation, 4.1/4.2, and 5.2 until both rollout evidence and the matrix bind the same unchanged candidate. +- [ ] 5.3 Open, review, and merge the behavior-ready implementation PR to `dev` only after 5.2 passes and the candidate identity remains unchanged since the most recent 4.1/4.2 recollection and release-surface matrix, linking core #684, dogfood, assurance limits, metrics, and rollback evidence. +- [ ] 5.4 Allow only the canonical post-merge publication workflow to verify the exact merged version/payload/checksum, cryptographically sign it, generate the actual registry/signature/history artifacts, compatibility-test, and propose the immutable #434 release with matching complete manifest/registry `core_compatibility` ranges. Fail and return through implementation evidence/review rather than silently changing the merged payload, version, checksum, workflow bindings, or compatibility range; do not merge the publication PR yet. +- [ ] 5.5 On that exact signed publication head, recollect 4.1/4.2 negative-corpus and known-good live evidence and reevaluate every pairwise, aggregate, identity, compatibility, quality, and rollback promotion gate. Rerun the signed-manifest/generated-registry equality, dependency-intersection, and lower/upper-bound matrix. Any fix or promotion-relevant identity change invalidates the affected evidence and repeats 5.5. Review and merge the publication PR only when the evidence and all gates bind the same unchanged signed head; checksum-only or earlier signed-head evidence cannot authorize the merge. +- [ ] 5.6 After merged publication and official registry/install readback, hand the exact signed module identity and both named workflow identity/digest pairs to core #251 only; record that #253 follows completed #251 and #433 follows completed #251/#253, with no direct or parallel adapter handoff from #434. +- [ ] 5.7 After implementation merge and verified publication, run `openspec archive preflight-05-implementation-conformance` from the repository root, update ordering/source mirrors, and remove the dedicated worktree and merged branch. diff --git a/openspec/changes/requirements-07-scenario-runtime-proof/README.md b/openspec/changes/requirements-07-scenario-runtime-proof/README.md index 97ec9260..f8c2d19a 100644 --- a/openspec/changes/requirements-07-scenario-runtime-proof/README.md +++ b/openspec/changes/requirements-07-scenario-runtime-proof/README.md @@ -2,5 +2,4 @@ This corrected change owns deterministic scenario plans and reconciliation of exact selector results observed in the current run. -Historical red-to-green chronology is a separate claim owned by `requirements-08-bounded-red-green-proof`. R07 does not require a retained red artifact or legacy ledger before it can report current execution. - +Historical red-to-green chronology is a separate claim with no active owning change. The abandoned `requirements-08-bounded-red-green-proof` proposal is retained only as non-canonical history. R07 does not require a retained red artifact or legacy ledger before it can report current execution. diff --git a/openspec/changes/requirements-07-scenario-runtime-proof/TDD_EVIDENCE.md b/openspec/changes/requirements-07-scenario-runtime-proof/TDD_EVIDENCE.md index 0b503c8a..fb7e7ff3 100644 --- a/openspec/changes/requirements-07-scenario-runtime-proof/TDD_EVIDENCE.md +++ b/openspec/changes/requirements-07-scenario-runtime-proof/TDD_EVIDENCE.md @@ -134,7 +134,7 @@ ## 2026-08-13 scope-correction record -This planning commit preserves the historical entries above but supersedes their coupling of current execution to prior-red or legacy-ledger evidence. Those results describe the previous contract; they do not prove the corrected R07 behavior or the new R08 capsule contract. +This planning commit preserves the historical entries above but supersedes their coupling of current execution to prior-red or legacy-ledger evidence. Those results describe the previous contract; they do not prove the corrected R07 behavior. The later R08 capsule proposal was abandoned and has no active replacement. - Corrected behavior status: not started. - Package, registry, schema, runtime, and test changes in this commit: none. diff --git a/openspec/changes/requirements-07-scenario-runtime-proof/design.md b/openspec/changes/requirements-07-scenario-runtime-proof/design.md index b90da677..a0f91cac 100644 --- a/openspec/changes/requirements-07-scenario-runtime-proof/design.md +++ b/openspec/changes/requirements-07-scenario-runtime-proof/design.md @@ -31,17 +31,17 @@ The mapping sidecar remains `schema_version: "2"`; this change does not alter ma `current_execution` records status, mapping/plan/source identities, exact selectors, result digest, collection counts, outcome counts, runner identity, and environment provenance supplied by core. -`red_green_chronology` is a mandatory placeholder claim object in the corrected R07 report. R07 has no chronology-request or capsule input and always emits `status: not_evaluated` with `reason: capsule_not_supplied`; it cannot emit chronology pass, fail, or unknown. R08 later MODIFIES this claim with the explicit request input, capsule validation, and non-not-evaluated statuses. The placeholder cannot erase or inflate current execution. +`red_green_chronology` is a mandatory placeholder claim object in the corrected R07 report. R07 has no chronology-request or capsule input and always emits `status: not_evaluated` with `reason: capsule_not_supplied`; it cannot emit chronology pass, fail, or unknown. No active change currently extends this claim. Any future chronology input, validation, or non-not-evaluated status requires a separately approved contract. The placeholder cannot erase or inflate current execution. ### Current reconciliation needs only current evidence Final current-run reconciliation validates the original deterministic plan and trusted JUnit. Every exact selector must match one canonical result. Passing, failing, skipped, errored, missing, or ambiguous outcomes remain distinct. -A current execution pass must not be called `verified-red-green`, `passing-after-red`, or `change-proven` without an independently validated R08 capsule. +A current execution pass must not be called `verified-red-green`, `passing-after-red`, or `change-proven` without independently validated chronology evidence from a separately approved contract. ### Legacy history remains labelled compatibility -Existing `legacy-tdd-ledger` payloads may remain readable for old artifacts. The command cannot generate them for new changes, and they cannot silently satisfy the new R08 chronology claim. +Existing `legacy-tdd-ledger` payloads may remain readable for old artifacts. The command cannot generate them for new changes, and they cannot silently satisfy a new chronology claim. ### Review context is provenance-only @@ -67,4 +67,3 @@ Do not add Git orchestration, pytest execution, or static import/plugin/configur 4. Remove generation of new legacy-ledger evidence after core migrates. 5. Roll back by disabling the new writer while preserving every already-written `current_execution` and `red_green_chronology` object byte-for-byte. The old reader must treat unknown corrected fields as opaque provenance and must never reinterpret them as legacy chronology. 6. After the implementation and signed handoff merge, finalize the shipped change from the repository root with `openspec archive requirements-07-scenario-runtime-proof`; never move the change directory manually. - diff --git a/openspec/changes/requirements-07-scenario-runtime-proof/proposal.md b/openspec/changes/requirements-07-scenario-runtime-proof/proposal.md index 6d12a840..6f8b967f 100644 --- a/openspec/changes/requirements-07-scenario-runtime-proof/proposal.md +++ b/openspec/changes/requirements-07-scenario-runtime-proof/proposal.md @@ -14,7 +14,7 @@ This conflation pushed core toward static inference of every pytest-determining - Stop deriving `passing-after-red` from current-run pass or generic maturity. - Remove new use of the R07 legacy-ledger migration path; keep finalized-report v2 reading only for explicitly labelled compatibility and reject malformed v3 instead of treating it as legacy. - Accept finalized current-run Requirements evidence as Code Review provenance without requiring a historical proof basis. -- Move trusted historical chronology to `requirements-08-bounded-red-green-proof`. +- Keep trusted historical chronology outside R07; no active change owns that capability after the R08 proposal was abandoned. ## Capabilities @@ -42,6 +42,5 @@ This conflation pushed core toward static inference of every pytest-determining - **GitHub Issue**: [#368](https://github.com/nold-ai/specfact-cli-modules/issues/368) - **Paired Core Issue**: [nold-ai/specfact-cli#662](https://github.com/nold-ai/specfact-cli/issues/662) -- **Follow-up**: `requirements-08-bounded-red-green-proof` +- **Follow-up**: none; the abandoned R08 replay proposal is historical only, and any replacement requires a separately approved change - **Planning correction date**: 2026-08-13 - diff --git a/openspec/changes/requirements-07-scenario-runtime-proof/requirements-evidence.yaml b/openspec/changes/requirements-07-scenario-runtime-proof/requirements-evidence.yaml index f1045166..7000f402 100644 --- a/openspec/changes/requirements-07-scenario-runtime-proof/requirements-evidence.yaml +++ b/openspec/changes/requirements-07-scenario-runtime-proof/requirements-evidence.yaml @@ -62,7 +62,7 @@ requirements: intent: Reject every incomplete, non-pass, or non-canonical current selector result. observable: Missing, duplicate, ambiguous, skipped, failed, errored, missing/mismatched specfact.selector, display/class-only, non-canonical, or mismatched mapping/plan/source/selector identities cannot produce current_execution pass. openspec:requirements-07-scenario-runtime-proof:requirements-scenario-runtime-proof:historical-chronology-is-a-separate-claim: - rationale: Historical TDD chronology is optional evidence owned by R08, not a prerequisite for current execution. + rationale: Historical TDD chronology has no active owning change and is not a prerequisite for current execution. stakeholder_refs: - https://github.com/nold-ai/specfact-cli-modules/issues/368 - https://github.com/nold-ai/specfact-cli/issues/662 @@ -74,7 +74,7 @@ requirements: - case_id: lifecycle-chronology-independent scenario_id: historical-chronology-is-a-separate-claim method: test - intent: Emit finalized report schema v3 with a valid current-run observation and mandatory chronology placeholder when no R08 replay capsule is supplied. + intent: Emit finalized report schema v3 with a valid current-run observation and mandatory chronology placeholder; no active replay-capsule contract exists. observable: current_execution is final while red_green_chronology is the canonical R07 not_evaluated/capsule_not_supplied placeholder; R07 exposes no chronology request/capsule input or other chronology status. openspec:requirements-07-scenario-runtime-proof:requirements-proof-review-context:finalized-requirements-evidence-review-context: rationale: Code Review must consume finalized Requirements evidence as provenance without fusing delivery verdicts. diff --git a/openspec/changes/requirements-07-scenario-runtime-proof/specs/requirements-scenario-runtime-proof/spec.md b/openspec/changes/requirements-07-scenario-runtime-proof/specs/requirements-scenario-runtime-proof/spec.md index 7618cd9a..d995d3b1 100644 --- a/openspec/changes/requirements-07-scenario-runtime-proof/specs/requirements-scenario-runtime-proof/spec.md +++ b/openspec/changes/requirements-07-scenario-runtime-proof/specs/requirements-scenario-runtime-proof/spec.md @@ -108,7 +108,7 @@ The Requirements module SHALL reconcile a previously emitted deterministic plan ### Requirement: Historical Chronology Is a Separate Claim -New historical red-to-green claims SHALL be accepted only through the later R08 bounded replay contract. R07 SHALL NOT infer chronology from current maturity, current JUnit, static Python/pytest analysis, or a newly generated legacy ledger. +New historical red-to-green claims SHALL be accepted only through a future separately approved chronology contract; no active change currently owns that capability. R07 SHALL NOT infer chronology from current maturity, current JUnit, static Python/pytest analysis, or a newly generated legacy ledger. #### Scenario: R07 finalizes without chronology input @@ -123,4 +123,4 @@ New historical red-to-green claims SHALL be accepted only through the later R08 - **GIVEN** a finalized report v2 contains an explicitly labelled legacy-ledger basis - **WHEN** compatibility reading occurs - **THEN** the historical label remains migration-only with `source_schema_version: 2` -- **AND** it is not converted into a v3 claim, new R08 attestation, or chronology pass. +- **AND** it is not converted into a v3 claim, new chronology attestation, or chronology pass. diff --git a/openspec/changes/requirements-07-scenario-runtime-proof/tasks.md b/openspec/changes/requirements-07-scenario-runtime-proof/tasks.md index 606740f8..eebc6c20 100644 --- a/openspec/changes/requirements-07-scenario-runtime-proof/tasks.md +++ b/openspec/changes/requirements-07-scenario-runtime-proof/tasks.md @@ -3,13 +3,13 @@ ## 0. Planning-only correction - [x] 0.1 Define independent `current_execution` and `red_green_chronology` claims. -- [x] 0.2 Move new historical proof to R08 and prohibit dependency-closure inference. +- [x] 0.2 Separate historical proof from R07 and prohibit dependency-closure inference; no active replacement owns chronology proof. - [x] 0.3 Create OpenSpec-only planning changes with no package or registry edits. ## Implementation acceptance gate - [ ] A.1 Before any failing test, source edit, or `specfact_cli` adapter work, verify that the corrected paired core artifacts from merged core PR #674 and this modules contract have both been reviewed and accepted on their target `dev` branches. -- [ ] A.2 Verify issue #368/#414 hierarchy, labels, project assignment, blockers, and concurrency state. Stop when either paired interface or public-work prerequisite is incomplete; re-reading references or confirming the file allowlist is not acceptance. +- [ ] A.2 Verify issue #368 hierarchy, labels, project assignment, blockers, and concurrency state. Treat closed R08 issue #414 as historical only. Stop when either paired interface or public-work prerequisite is incomplete; re-reading references or confirming the file allowlist is not acceptance. ## 1. Failing tests first — each task at most two hours @@ -19,8 +19,8 @@ - [ ] 1.4 Add `test_review_context_accepts_final_current_execution_without_historical_basis`. Allowed files: focused Code Review context tests. - [ ] 1.5 Add `test_new_reconciliation_cannot_generate_legacy_tdd_ledger`. Allowed files: focused compatibility tests. - [ ] 1.6 Add or retain table-driven `test_planned_mapping_requires_every_schema_v2_field`, `test_selected_test_authored_scenario_requires_exact_selector`, and `test_current_execution_rejects_each_nonpass_or_noncanonical_result` covering missing, duplicate, ambiguous, skipped, failed, errored, missing/mismatched `specfact.selector` properties, display/class-name-only identity, non-canonical selector results, and mismatched mapping digest, plan identity/digest, source revision/tree, or selector set. -- [ ] 1.7 Add table-driven `test_review_context_rejects_each_invalid_requirements_evidence_class` covering unreadable, malformed, unsupported-schema, non-final top-level evidence, and schema-v3 evidence missing either mandatory claim object. Add `test_legacy_v2_passing_review_context_requires_red_junit_or_digest_bound_ledger`; invalid top-level/v3 input and invalid passing-v2 basis must reject before review execution. R07 review fixtures cover only the canonical not-evaluated chronology placeholder; R08 owns unknown/pass/fail chronology provenance. -- [ ] 1.8 Add `test_report_schema_v3_discriminates_corrected_from_legacy_v2` and `test_report_uses_canonical_no_chronology_claim_object` for the mandatory R07 `status: not_evaluated` plus `reason: capsule_not_supplied` placeholder. Assert finalized report v2 routes only to legacy compatibility, finalized report v3 missing either claim is rejected, mapping sidecars remain v2, and R07 has no chronology-request/capsule input and cannot emit chronology pass, fail, or unknown; those tests begin in R08. +- [ ] 1.7 Add table-driven `test_review_context_rejects_each_invalid_requirements_evidence_class` covering unreadable, malformed, unsupported-schema, non-final top-level evidence, and schema-v3 evidence missing either mandatory claim object. Add `test_legacy_v2_passing_review_context_requires_red_junit_or_digest_bound_ledger`; invalid top-level/v3 input and invalid passing-v2 basis must reject before review execution. R07 review fixtures cover only the canonical not-evaluated chronology placeholder; no active change owns unknown/pass/fail chronology provenance. +- [ ] 1.8 Add `test_report_schema_v3_discriminates_corrected_from_legacy_v2` and `test_report_uses_canonical_no_chronology_claim_object` for the mandatory R07 `status: not_evaluated` plus `reason: capsule_not_supplied` placeholder. Assert finalized report v2 routes only to legacy compatibility, finalized report v3 missing either claim is rejected, mapping sidecars remain v2, and R07 has no chronology-request/capsule input and cannot emit chronology pass, fail, or unknown; those states require a future separately approved contract. - [ ] 1.9 Add or retain `test_mapping_acceptance_requires_complete_provenance` covering mapping digest, decision, stable reviewer identity, reviewer role, timestamp, and immutable reference so the scope correction cannot weaken shipped acceptance checks. - [ ] 1.10 Add `test_rollback_reader_preserves_independent_claims_as_opaque_provenance` and prove old readers never reinterpret corrected chronology as a legacy basis. - [ ] 1.11 Collect the exact canonical pytest node ID for every test-authored R07 scenario from the named test files, write those selectors into `requirements-evidence.yaml`, and rerun strict mapping validation. Do not edit production source in this task. @@ -31,7 +31,7 @@ - [ ] 2.1 Add finalized report schema v3 with mandatory current-execution and chronology claim objects; preserve mapping sidecar schema v2 and add an explicit finalized-report v2 compatibility reader. Do not detect legacy by field absence. - [ ] 2.2 Reconcile current JUnit independently and retain exact outcome classes. -- [ ] 2.3 Update Code Review context validation to require and retain the top-level Requirements gate decision plus both schema-v3 claim objects, including the R07 not-evaluated chronology placeholder; use the versioned compatibility path for truly legacy payloads. R08 later adds non-not-evaluated chronology states. +- [ ] 2.3 Update Code Review context validation to require and retain the top-level Requirements gate decision plus both schema-v3 claim objects, including the R07 not-evaluated chronology placeholder; use the versioned compatibility path for truly legacy payloads. Non-not-evaluated chronology states remain outside active scope. - [ ] 2.4 Keep old report reading explicit; stop generating legacy-ledger evidence for new changes. - [ ] 2.5 Update public command/docs fixtures without adding execution or Git behavior. diff --git a/openspec/changes/requirements-08-bounded-red-green-proof/CHANGE_VALIDATION.md b/openspec/changes/requirements-08-bounded-red-green-proof/CHANGE_VALIDATION.md deleted file mode 100644 index b180cae3..00000000 --- a/openspec/changes/requirements-08-bounded-red-green-proof/CHANGE_VALIDATION.md +++ /dev/null @@ -1,22 +0,0 @@ -# Change Validation - -## Status - -`PLANNED — NO IMPLEMENTATION OR RELEASE EVIDENCE` - -The B/R/H/D capsule contract, three transition policies, ownership, non-goals, failing tests, signed release dependency, and rollback are planned. No package behavior or signed release implements them yet. - -## Planning evidence - -- Paired core issue/PR: nold-ai/specfact-cli#675 / nold-ai/specfact-cli#674. -- Modules tracking issue: #414 with required labels and assignee. -- Strict command required before implementation: `openspec validate requirements-08-bounded-red-green-proof --strict`. -- Failing-before and passing-after implementation artifacts: unavailable; no behavior changed. -- Package, registry, archive, checksum, signature, and verifier-epoch evidence: unavailable until implementation and release. - -## Readiness blockers - -- Issue #414 requested User Story type, project assignment, parent relationship, blocker metadata, and concurrency state must be verified before implementation; the current connector cannot update project fields. -- Core and modules must accept the same B/R/H/D capsule schema. -- No failing tests or implementation evidence exist. -- No signed module release or promoted verifier epoch exists. diff --git a/openspec/changes/requirements-08-bounded-red-green-proof/README.md b/openspec/changes/requirements-08-bounded-red-green-proof/README.md deleted file mode 100644 index 5af5d5ae..00000000 --- a/openspec/changes/requirements-08-bounded-red-green-proof/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Requirements 08: Bounded Red-Green Proof - -This module-side change defines the typed B/R/H/D replay capsule and chronology reconciliation contract consumed by paired core issue nold-ai/specfact-cli#675 and PR #674. Core resolves Git and executes tests; modules validate the versioned capsule and report only the bounded claim. - -Planning only: no package behavior, registry artifact, version, or signature changes on this branch. diff --git a/openspec/history/README.md b/openspec/history/README.md new file mode 100644 index 00000000..228c80b5 --- /dev/null +++ b/openspec/history/README.md @@ -0,0 +1,16 @@ +# OpenSpec Historical Records + +This directory preserves planning records that are not active OpenSpec changes +and are not completed-change archives. + +## Abandoned + +`abandoned/` contains never-implemented proposals closed without specification +promotion. These records are non-canonical, are excluded from `openspec list`, +and are not implementation authority. Reopening one requires a new issue and a +new active change validated against current repository reality. + +Completed changes do not belong here. After implementation merges, finalize +them with `openspec archive ` so OpenSpec validates and promotes the +implemented specification delta before moving the change under +`openspec/changes/archive/`. diff --git a/openspec/changes/requirements-08-bounded-red-green-proof/.openspec.yaml b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/.openspec.yaml similarity index 100% rename from openspec/changes/requirements-08-bounded-red-green-proof/.openspec.yaml rename to openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/.openspec.yaml diff --git a/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/CHANGE_VALIDATION.md b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/CHANGE_VALIDATION.md new file mode 100644 index 00000000..0779f606 --- /dev/null +++ b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/CHANGE_VALIDATION.md @@ -0,0 +1,35 @@ +# Change Validation + +## Status + +`ABANDONED HISTORY / SUPERSEDED / NOT IMPLEMENTED — NO SPEC PROMOTION` + +Issues #414 and nold-ai/specfact-cli#675 are closed as `not planned`. The +seal-bound development assurance work in #431/#434 and core #682/#684 replaces +the expensive historical replay proposal. No package behavior or signed release +implements this change. Retention under non-canonical abandoned history was +explicitly authorized on 2026-08-30 and did not run `openspec archive`, so the +unimplemented deltas were not merged into the canonical specification. + +## Planning evidence + +- Paired core issue/PR: nold-ai/specfact-cli#675 / nold-ai/specfact-cli#674. +- Modules tracking issue: #414 with required labels and assignee. +- Strict command required before implementation: `openspec validate requirements-08-bounded-red-green-proof --strict`. +- Failing-before and passing-after implementation artifacts: unavailable; no behavior changed. +- Package, registry, checksum, signature, and verifier-epoch evidence: unavailable because implementation and release never occurred. + +## Supersession record + +- Modules issue #414: closed `not planned` on 2026-08-27. +- Core issue #675: closed `not planned` on 2026-08-27. +- Replacement planning: modules #431/#434 and core #682/#684. +- The complete folder is preserved at + `openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/`. +- `openspec archive` was deliberately not invoked because it would have promoted + never-implemented delta specifications into canonical requirements. +- The relocation preserved the historical artifacts only. It changed no file + under `openspec/specs/`, package, registry, version, signature, or runtime path. +- Reopening requires a new issue and a new active OpenSpec change revalidated + against current architecture; this abandoned historical proposal is not + implementation authority. diff --git a/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/README.md b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/README.md new file mode 100644 index 00000000..035d6f6e --- /dev/null +++ b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/README.md @@ -0,0 +1,13 @@ +# Requirements 08: Bounded Red-Green Proof + +> **Abandoned planning history without specification promotion — superseded and never +> implemented.** Modules issue #414 and paired core issue #675 were closed as +> `not planned` on 2026-08-27. On 2026-08-30, an explicit repository-owner +> decision retained this complete folder under non-canonical abandoned history +> without running `openspec archive`; therefore none of its delta specifications +> were merged into canonical requirements. The lower-cost seal-bound checkpoint +> design in modules #431/#434 and core #682/#684 supersedes this replay approach. + +This module-side change historically proposed a typed B/R/H/D replay capsule and chronology reconciliation contract for paired core issue nold-ai/specfact-cli#675. It was never implemented, shipped, or merged. The active replacement is the seal-bound planning and checkpoint/conformance path in modules #431/#434 and core #682/#684; the retained replay artifacts are historical traceability only. + +Historical planning only: no package behavior, registry artifact, version, or signature implemented this change. diff --git a/openspec/changes/requirements-08-bounded-red-green-proof/TDD_EVIDENCE.md b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/TDD_EVIDENCE.md similarity index 100% rename from openspec/changes/requirements-08-bounded-red-green-proof/TDD_EVIDENCE.md rename to openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/TDD_EVIDENCE.md diff --git a/openspec/changes/requirements-08-bounded-red-green-proof/design.md b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/design.md similarity index 100% rename from openspec/changes/requirements-08-bounded-red-green-proof/design.md rename to openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/design.md diff --git a/openspec/changes/requirements-08-bounded-red-green-proof/proposal.md b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/proposal.md similarity index 98% rename from openspec/changes/requirements-08-bounded-red-green-proof/proposal.md rename to openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/proposal.md index e40d09a1..59bba565 100644 --- a/openspec/changes/requirements-08-bounded-red-green-proof/proposal.md +++ b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/proposal.md @@ -47,7 +47,7 @@ The Requirements module should validate a typed capsule produced by trusted core - **GitHub Issue**: #414 - **Issue URL**: https://github.com/nold-ai/specfact-cli-modules/issues/414 - **Repository**: nold-ai/specfact-cli-modules -- **Last Synced Status**: open +- **Last Synced Status**: closed-not-planned / archived without spec promotion / superseded - **Parent Feature**: #161 - **Paired Core Issue**: nold-ai/specfact-cli#675 - **Paired Core PR**: nold-ai/specfact-cli#674 diff --git a/openspec/changes/requirements-08-bounded-red-green-proof/requirements-evidence.yaml b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/requirements-evidence.yaml similarity index 100% rename from openspec/changes/requirements-08-bounded-red-green-proof/requirements-evidence.yaml rename to openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/requirements-evidence.yaml diff --git a/openspec/changes/requirements-08-bounded-red-green-proof/specs/requirements-bounded-red-green-proof/spec.md b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/specs/requirements-bounded-red-green-proof/spec.md similarity index 100% rename from openspec/changes/requirements-08-bounded-red-green-proof/specs/requirements-bounded-red-green-proof/spec.md rename to openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/specs/requirements-bounded-red-green-proof/spec.md diff --git a/openspec/changes/requirements-08-bounded-red-green-proof/specs/requirements-proof-review-context/spec.md b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/specs/requirements-proof-review-context/spec.md similarity index 100% rename from openspec/changes/requirements-08-bounded-red-green-proof/specs/requirements-proof-review-context/spec.md rename to openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/specs/requirements-proof-review-context/spec.md diff --git a/openspec/changes/requirements-08-bounded-red-green-proof/tasks.md b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/tasks.md similarity index 95% rename from openspec/changes/requirements-08-bounded-red-green-proof/tasks.md rename to openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/tasks.md index 44c700f8..f273d57f 100644 --- a/openspec/changes/requirements-08-bounded-red-green-proof/tasks.md +++ b/openspec/history/abandoned/2026-08-30-requirements-08-bounded-red-green-proof/tasks.md @@ -1,6 +1,15 @@ # Tasks: Historical Replay Capsule -All later tasks are bounded to at most two hours and must follow tests-before-code. +> **Archived historical plan only — do not execute.** Issue #414 and paired +> core issue #675 are closed as Not Planned. This change is superseded by +> #431/#434 plus core #682/#684. The folder was relocated without running +> `openspec archive`, so its unimplemented deltas were not promoted into +> canonical requirements. + +Every unchecked item below is retained historical planning text and is +non-executable. Reopening requires a new issue, a new active change, fresh +dependency/readiness evidence, strict revalidation, and an accepted replacement +task list. ## 0. Planning @@ -51,7 +60,7 @@ All later tasks are bounded to at most two hours and must follow tests-before-co - [ ] 3.5 Observe the canonical `.github/workflows/publish-modules.yml` run triggered by the `dev` push. It SHALL use the repository signing secret, generate the signed manifest plus `registry/index.json`, archive, checksum, and signature sidecar, and open its `auto/publish-dev-` PR. - [ ] 3.6 Review the exact auto-publish PR and require its generated `.tar.sig` sidecar, signed manifest/archive identity, `verify-modules-signature --require-signature --payload-from-filesystem --enforce-version-bump`, and full final quality matrix to pass before merging that PR to `dev`. - [ ] 3.7 Record the immutable merged `dev` commit/tree, package/capsule-schema versions, manifest integrity, signer/signature, registry/archive/checksum, workflow run, auto-publish PR, core compatibility, and passing verification identities. Promote the new verifier epoch independently; only later changes may use that already-trusted epoch for B/R/H/D chronology. -- [ ] 3.8 After the implementation and signed auto-publish PRs merge and rollout prerequisites hold, from the repository root run exactly `openspec archive requirements-08-bounded-red-green-proof`; never move the change directory manually. +- [ ] 3.8 **SUPERSEDED — MUST NOT RUN:** the former R08 archive step is retained only as historical planning text; the change was never implemented. - [ ] 3.9 Remove the merged worktree/branch, run `git worktree prune`, and record the policy self-check. ## Prohibited shortcuts diff --git a/openspec/specs/agent-governance-loading/spec.md b/openspec/specs/agent-governance-loading/spec.md index 05767591..8e1671da 100644 --- a/openspec/specs/agent-governance-loading/spec.md +++ b/openspec/specs/agent-governance-loading/spec.md @@ -115,3 +115,22 @@ Repository instruction surfaces other than `AGENTS.md` SHALL reference the canon - **THEN** the surface SHALL reference the canonical rule system for governance semantics - **AND** it SHALL avoid copying long-form governance content that could drift from the canonical source +### Requirement: Repository bootstrap guidance preserves user-scoped modules + +Contributor and agent bootstrap guidance SHALL treat project-over-user module shadowing as workspace-local precedence and SHALL NOT prescribe deletion of the shadowed user-scoped installation as routine cleanup. + +#### Scenario: Project module shadows a user installation + +- **GIVEN** the same module id is installed in project scope and user scope +- **WHEN** an agent loads repository bootstrap or module-scope guidance +- **THEN** the guidance states that project scope takes precedence inside the current repository +- **AND** the guidance states that the user-scoped copy remains installed and usable outside the repository +- **AND** the guidance does not recommend a user-scope uninstall merely because the copy is shadowed + +#### Scenario: Local test bootstrap evicts an imported user module + +- **GIVEN** a test process imported a bundled module from the user-scoped source path +- **WHEN** the local bundle source bootstrap realigns the test process to repository sources +- **THEN** it removes the loaded module from in-memory import state or enforces an equivalent before-import guarantee that prevents reuse of the cached user-scoped module +- **AND** it does not delete or uninstall the user-scoped module files + diff --git a/src/specfact_cli_modules/dev_bootstrap.py b/src/specfact_cli_modules/dev_bootstrap.py index 075ae44d..b931ac0c 100644 --- a/src/specfact_cli_modules/dev_bootstrap.py +++ b/src/specfact_cli_modules/dev_bootstrap.py @@ -53,7 +53,8 @@ def apply_specfact_workspace_env(repo_root: Path) -> None: Pins ``SPECFACT_MODULES_REPO`` to the modules repo root and ``SPECFACT_REPO_ROOT`` to the resolved sibling/core specfact-cli checkout when known. Discovery then agrees with ``specfact module list --show-origin`` expectations; project ``.specfact/modules`` still wins over ``~/.specfact/modules`` - when both exist—remove stale user copies with ``specfact module uninstall --scope user``. + when both exist. The user copy remains installed and available outside this workspace, so normal + shadowing requires no uninstall or cleanup action. """ resolved = repo_root.resolve() os.environ["SPECFACT_MODULES_REPO"] = str(resolved) @@ -93,7 +94,7 @@ def ensure_core_dependency(repo_root: Path) -> int: if core_repo is None: if _installed_core_exists(): return 0 - print("Unable to resolve specfact-cli checkout. Set SPECFACT_CLI_REPO.", file=sys.stderr) + sys.stderr.write("Unable to resolve specfact-cli checkout. Set SPECFACT_CLI_REPO.\n") return 1 installed_root = _installed_core_root() diff --git a/tests/unit/test_dev_bootstrap.py b/tests/unit/test_dev_bootstrap.py index 62964870..4c5e9b36 100644 --- a/tests/unit/test_dev_bootstrap.py +++ b/tests/unit/test_dev_bootstrap.py @@ -65,6 +65,24 @@ def test_apply_specfact_workspace_env_sets_defaults(monkeypatch: pytest.MonkeyPa assert os.environ["SPECFACT_REPO_ROOT"] == str(core.resolve()) +def test_workspace_env_guidance_preserves_user_scoped_modules() -> None: + guidance = apply_specfact_workspace_env.__doc__ or "" + + assert "remains installed" in guidance + assert "available outside this workspace" in guidance + assert "module uninstall" not in guidance + + +def test_repository_scope_guidance_preserves_user_scoped_modules() -> None: + repository_root = Path(__file__).resolve().parents[2] + guidance = (repository_root / "docs" / "agent-rules" / "20-repository-context.md").read_text(encoding="utf-8") + scope_guidance = guidance.split("## SpecFact module scopes", maxsplit=1)[1] + + assert "remains installed" in scope_guidance + assert "available outside this repository" in scope_guidance + assert "module uninstall --scope user" not in scope_guidance + + def test_apply_specfact_workspace_env_without_core_repo(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None: repo_root = tmp_path / "modules-repo" repo_root.mkdir() @@ -119,9 +137,13 @@ def test_ensure_core_dependency_allows_matching_editable_core(monkeypatch: pytes core = _make_core_repo(tmp_path / "paired-core") monkeypatch.setenv("SPECFACT_CLI_REPO", str(core)) + + def _installed_core_root() -> Path: + return core.resolve() + monkeypatch.setattr( "specfact_cli_modules.dev_bootstrap._installed_core_root", - lambda: core.resolve(), + _installed_core_root, ) assert ensure_core_dependency(repo_root) == 0 @@ -136,14 +158,18 @@ def test_ensure_core_dependency_reinstalls_when_editable_core_mismatches( core_wanted = _make_core_repo(tmp_path / "core-wanted") monkeypatch.setenv("SPECFACT_CLI_REPO", str(core_wanted)) + + def _installed_core_root() -> Path: + return core_wrong.resolve() + monkeypatch.setattr( "specfact_cli_modules.dev_bootstrap._installed_core_root", - lambda: core_wrong.resolve(), + _installed_core_root, ) recorded: list[list[str]] = [] - def _fake_run(cmd: list[str], **kwargs: object) -> SimpleNamespace: + def _fake_run(cmd: list[str], **_kwargs: object) -> SimpleNamespace: recorded.append(list(cmd)) return SimpleNamespace(returncode=0) diff --git a/tests/unit/test_local_bundle_source_alignment.py b/tests/unit/test_local_bundle_source_alignment.py index 98bcda1b..db176932 100644 --- a/tests/unit/test_local_bundle_source_alignment.py +++ b/tests/unit/test_local_bundle_source_alignment.py @@ -8,7 +8,7 @@ # pylint: disable=protected-access -def test_enforce_local_bundle_sources_removes_shadowed_user_bundle_modules(monkeypatch) -> None: +def test_enforce_local_bundle_sources_evicts_loaded_user_bundle_imports(monkeypatch) -> None: user_bundle_src = str((Path.home() / ".specfact" / "modules" / "specfact-backlog" / "src").resolve()) local_bundle_src = str((test_bootstrap.MODULES_REPO_ROOT / "packages" / "specfact-backlog" / "src").resolve()) fake_module_path = f"{user_bundle_src}/specfact_backlog/backlog/commands.py"