Skip to content

Release dev to main: module install state consistency#537

Merged
djm81 merged 431 commits intomainfrom
dev
Apr 28, 2026
Merged

Release dev to main: module install state consistency#537
djm81 merged 431 commits intomainfrom
dev

Conversation

@djm81
Copy link
Copy Markdown
Collaborator

@djm81 djm81 commented Apr 28, 2026

Description

Promote the merged module install state consistency work from dev to main.

This release includes the fixes from #535 for inconsistent module install/init state handling, repo-aware module discovery, improved command-availability diagnostics, and expanded real-world installer/init coverage.

Fixes #533

New Features #534

Contract References: None.

Type of Change

Please check all that apply:

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🔒 Contract enforcement (adding/updating @icontract decorators)
  • 🧪 Test enhancement (scenario tests, property-based tests)
  • 🔧 Refactoring (code improvement without functionality change)

Contract-First Testing Evidence

Required for all changes affecting CLI commands or public APIs:

Contract Validation

  • Runtime contracts added/updated (@icontract decorators on public APIs)
  • Type checking enforced (@beartype decorators applied)
  • CrossHair exploration completed: hatch run contract-test-exploration
  • Contract violations reviewed and addressed

Test Execution

  • Contract validation: hatch run contract-test-contracts
  • Contract exploration: hatch run contract-test-exploration
  • Scenario tests: hatch run contract-test-scenarios
  • Full test suite: hatch run contract-test-full

Test Quality

  • CLI commands tested with typer test client
  • Edge cases covered with Hypothesis property tests
  • Error handling tested with invalid inputs
  • Rich console output verified manually or with snapshots

How Has This Been Tested?

Contract-First Approach: Validation was carried on the merged dev PR #535 with focused unit/integration coverage, CLI reality testing, linting, code review runs, and OpenSpec validation.

Manual Testing

  • Tested CLI commands manually
  • Verified rich console output
  • Tested with different input scenarios
  • Checked error messages for clarity

Automated Testing

  • Contract validation passes
  • Property-based tests cover edge cases
  • Scenario tests cover user workflows
  • All existing tests still pass

Test Environment

  • Python version: 3.11, 3.12
  • OS: Ubuntu

Checklist

  • My code follows the style guidelines (PEP 8, ruff format, isort)
  • I have performed a self-review of my code
  • I have added/updated contracts (@icontract, @beartype)
  • I have added/updated docstrings (Google style)
  • I have made corresponding changes to documentation
  • My changes generate no new warnings (basedpyright, ruff, pylint)
  • All tests pass locally
  • I have added tests that prove my fix/feature works
  • Any dependent changes have been merged

Quality Gates Status

  • Type checking ✅ (hatch run type-check)
  • Linting ✅ (hatch run lint)
  • Contract validation ✅ (hatch run contract-test-contracts)
  • Contract exploration ✅ (hatch run contract-test-exploration)
  • Scenario tests ✅ (hatch run contract-test-scenarios)

Screenshots/Recordings (if applicable)

Not applicable.

djm81 and others added 30 commits February 24, 2026 23:37
…ics (#311)

* fix(backlog): harden refine writeback, prompts, and daily any filters

* fix(github): default story type fallback to feature

* Fix format

* Fix codex review findings

* bump and sign changed modules

* chore(hooks): enforce module signature verification in pre-commit

* chore(hooks): add markdownlint to pre-commit checks

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
* fix(backlog): harden refine writeback, prompts, and daily any filters

* fix(github): default story type fallback to feature

* Fix format

* Fix codex review findings

* bump and sign changed modules

* chore(hooks): enforce module signature verification in pre-commit

* chore(hooks): add markdownlint to pre-commit checks

* fix: finalize backlog-core-06 ado comment api versioning and ci hatch pins

* fix: address review findings for formatter safety and ado metric patch guards

* docs(openspec): update CHANGE_ORDER status tracking

* fix(ado): apply iteration filter for direct issue_id lookup

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
…olution, aliases, custom registries, publishing (#318)

* feat: advanced marketplace features (marketplace-02) - dependency resolution, aliases, custom registries, namespace enforcement, publishing

- dependency_resolver: resolve_dependencies(), --skip-deps, --force on install
- alias_manager: alias create/list/remove (no top-level alias commands)
- custom_registries: add-registry, list-registries, remove-registry; fetch_all_indexes; search Registry column
- module_installer: namespace/name enforcement, collision detection
- scripts/publish-module.py + .github/workflows/publish-modules.yml (optional signing)
- docs: publishing-modules, custom-registries, dependency-resolution; updated installing-modules, module-marketplace, commands
- version 0.38.0, CHANGELOG

Made-with: Cursor

* docs(openspec): defer 6.2.4 and 6.2.5 (index update/PR, workflow test) to later

Made-with: Cursor

* Add follow-up change proposals for marketplace

* Fix codex review findings

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
0.38.1

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
* feat(backlog): summarize Markdown normalization and TTY/CI rendering

* chore(openspec): drop implementation snapshot from change

* Update title

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
* feat(cli): category groups and flat shims using real module Typer

- Add category groups (code, backlog, project, spec, govern) with flatten same-name member
- Sort commands under backlog/project groups A–Z
- Fix flat shims to expose real module Typer so 'specfact sync bridge' and 'specfact plan update-idea' work
- Add first-run init, module grouping, OpenSpec change for 0.40.x remove-flat-shims
- Bump version to 0.39.0, CHANGELOG and OpenSpec updates

Made-with: Cursor

* Fix signature

* fix: resolve module grouping regressions and stabilize CI
  tests

* fix: keep uncategorized modules flat during grouped registration

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
djm81 and others added 8 commits April 17, 2026 00:41
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Add five-pillar governance openspec wave

* docs(openspec): address PR review findings for five-pillar wave

Align OpenSpec proposals, tasks, specs, and CHANGE_ORDER with CodeRabbit
feedback: worktree gates, envelope compatibility, GDPR/telemetry contracts,
and markdown structure. No runtime code changes.

Made-with: Cursor

* docs(openspec): hierarchy table, archive gates, and spec alignment

- CHANGE_ORDER: Epic/Feature columns (#511, #512-#517) and delivery archive note
- Tasks: archive-before-cleanup for architecture-02, enterprise-01/03, knowledge-01; security-02 archive step
- enterprise-03/knowledge-02: origin/dev worktree + hatch + pre-flight
- review-resiliency: mandatory schema_version on review-report-model
- security-01: explicit 4.4 quality gate checklist
- security-02: wrap design lines; policy-engine scenario aligns with enterprise-01 metadata
- telemetry design: unified resolution chain, Usernames wording

Made-with: Cursor

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
* fix: stabilize module install and init state

* test: align module lifecycle and backlog config helpers

* fix: address PR review findings

* fix: address remaining review feedback

* Fix format

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough
  • User-visible behavior and CLI surface

    • Missing-command help and install flows now classify modules into: absent, available, disabled, skipped, shadowed, and ambiguous. Help text provides state-specific recovery guidance (e.g., exact enable command for DISABLED, skip reason for SKIPPED, which origin is shadowing for SHADOWED) instead of a generic “not installed.”
    • specfact module install and specfact init/profile:
      • Install is repo-aware for project scope (normalizes --repo to the workspace/.git root) and reconciles lifecycle state when an artifact already exists — disabled modules are repaired/re-enabled (or reported as “installed but disabled” with an actionable recovery command) rather than treated as a satisfied no-op.
      • specfact init --repo/--profile performs discovery relative to the provided --repo, merges discovered module rows with existing modules.json (preserving unrelated rows and prior disabled settings), and treats profile-selected bundles as explicit enable requests (enabled ids are threaded into discovery/merge).
    • Discovery behavior:
      • Project-before-user precedence is preserved and shadowing is explicit in diagnostics; bare short IDs that match multiple namespaces produce AMBIGUOUS results with guidance to use fully-qualified ids.
    • CLI probes and optional tools:
      • pycg probe now uses -h (help) for availability checks to improve detection.
    • Other UX/ops:
      • Local semgrep/runtime tools are run with repo-local XDG/config/cache/log overrides to avoid polluting user homes.
      • Pre-commit quality checks run lint only on staged Python files via a new lint-changed flow.
  • Contract / API impact

    • Public surface changes:
      • New public functions added in the registry package:
        • discover_all_modules_for_project(base_path: Path | None) and discover_all_modules_for_project_with_shadowed(...)
        • classify_module_availability(*, module_id: str | None = None, command_name: str | None = None, base_path: Path | None = None) -> ModuleAvailability
      • New datatypes:
        • ModuleAvailabilityStatus enum {ABSENT, AVAILABLE, DISABLED, SKIPPED, SHADOWED, AMBIGUOUS}
        • ModuleAvailability dataclass with fields (status, module_id, source, package_dir, reason, recovery_command, shadowed_by)
      • discover_all_package_metadata and get_discovered_modules_for_state signatures updated to accept base_path and a preserve_existing flag.
    • Module package/manifest changes:
      • module package versions bumped (e.g., init 0.1.30 → 0.1.31, module_registry 0.1.20 → 0.1.23) and integrity checks updated (checksums/signatures updated).
      • Canonical identity normalization: install and lifecycle logic now resolve bare/legacy/marketplace/manifest identifiers to a single canonical manifest id before updating modules.json to avoid duplicate lifecycle rows.
    • Backwards compatibility:
      • Existing public CLI entry signatures unchanged; new registry/ discovery/availability helpers are additive but consumed by CLI internals.
      • Type-checked returns for classify_module_availability and constrained parameter requirements reduce ambiguous implicit behavior.
    • Notes for integrators:
      • Module lifecycle write behavior (merging vs replace) may alter modules.json contents when init/profile are used with --repo; callers that previously relied on discovery replacing state should expect preserved unrelated rows unless preserve_existing is false.
  • Testing and quality gates

    • Tests added/updated:
      • Unit tests for module availability classification, discovery (project-scoped and shadow handling), install re-enable behavior, init first-run/profile flows, and many CLI/UX permutations (new tests under tests/unit/specfact_cli/registry and tests/unit/specfact_cli/modules).
      • Integration/test helpers updated: version-only change detection includes src/specfact_cli/init.py; CI-version checks support --changed-vs fallback to HEAD~1 for amended/force-push histories.
      • Runtime/tooling tests: semgrep runtime isolation and optional tool probe (pycg) tests.
    • Quality gates and local developer UX:
      • Added lint-changed Hatch env for staged-only linting and a run_changed_lint.py script to scope linters/type-checkers to changed files.
      • Preflight and CI: openspec validate strict mode and contract-first/manual CLI reality tests reported executed (TDD_EVIDENCE captures failing-before -> passing-after runs).
      • Linting passes; some type/contract gates flagged as unchecked in the checklist — reviewers should confirm full contract/type validation in CI if required.
    • Coverage/impact:
      • Tests expand coverage in registry, init, module_registry install flows, and CI helper scripts; expected reviewer effort: medium for high-change registry/discovery areas, low for docs/version bumps.
  • OpenSpec change IDs, docs and CHANGELOG, module signing and version bumps

    • OpenSpec: This work is tracked under openspec/changes/marketplace-07-module-install-state-consistency (added .openspec.yaml, design.md, proposal.md, specs/*.md, tasks.md and TDD_EVIDENCE.md).
    • Documentation and changelog:
      • docs updated: docs/core-cli/init.md and docs/module-system/installing-modules.md reflect repo-aware init, profile enable semantics, and richer missing-command diagnostics.
      • CHANGELOG.md updated to 0.46.9 with entries describing module state consistency fixes, discovery/init improvements, and developer gate changes.
    • Versioning and signing:
      • Package versions bumped from 0.46.4 → 0.46.9 in pyproject.toml, setup.py, and package version exports.
      • Several module-package.yaml integrity/checksum/signature blobs updated; verify signing consumers handle updated integrity values.
      • scripts/verify-modules-signature.py: improved base-ref diff fallback (tries HEAD~1) to accommodate amended/force-pushed histories.
  • Summary of impact for maintainers

    • Behaviorally significant: install/init flows now reconcile on-disk artifacts with lifecycle state and provide richer, actionable CLI guidance when commands are missing. Project-scoped discovery respects --repo explicitly and preserves unrelated lifecycle rows.
    • API surface: new discovery/availability helpers are publicly callable and should be reviewed for consumer usage; update integrations that depended on previous discovery/merge semantics.
    • Tests and CI: reviewers should validate contract/type gates and ensure new tests run in CI; verify signature/version-check fallbacks in CI workflows for amended commits.

Walkthrough

Bumps package to 0.46.9 and applies repo-local runtime isolation, refactors module discovery/availability with a ModuleAvailability classifier and project-scoped discovery, tightens CI/version checks, introduces many OpenSpec governance artifacts, adjusts init/install reconciliation to preserve module state, and adds changed-only lint tooling and tests.

Changes

Cohort / File(s) Summary
Versioning & CI
pyproject.toml, setup.py, src/__init__.py, src/specfact_cli/__init__.py, .github/workflows/pr-orchestrator.yml, scripts/check_version_sources.py
Package bumped to 0.46.9; CI step computes a base SHA and uses --changed-vs for version comparisons; version-check script accepts a base ref and unions staged/changed files.
Repo-local runtime / tooling
scripts/pre_commit_code_review.py, src/specfact_cli/analyzers/code_analyzer.py, tests/unit/analyzers/test_code_analyzer.py, tests/unit/scripts/test_pre_commit_code_review.py
Create/use repo-local .specfact/ XDG/config/cache/log paths for nested tools (semgrep); semgrep invocations run with deterministic env; tests added to assert paths/env creation.
Changed-only lint runner
pyproject.toml, scripts/run_changed_lint.py, scripts/pre-commit-quality-checks.sh
Adds hatch env lint-changed, introduces run_changed_lint.py to lint only staged Python paths; pre-commit script now scopes lint to staged files and skips when none present.
Module availability & discovery
src/specfact_cli/registry/module_availability.py, src/specfact_cli/registry/module_discovery.py, src/specfact_cli/registry/module_packages.py
Adds availability classifier (ABSENT/AVAILABLE/DISABLED/SKIPPED/SHADOWED/AMBIGUOUS); refactors discovery to options-driven pipeline with project-scoped entrypoints; supports including shadowed duplicates and preserve-existing merge semantics for modules.json.
Install / registry behavior
src/specfact_cli/modules/module_registry/src/commands.py, src/specfact_cli/modules/module_registry/module-package.yaml
Install becomes repo-aware (normalizes --repo to git root), reconciles lifecycle state on already-present modules (auto-enable when appropriate), refreshes discovery cache, and threads repo context through install checks.
Init / profile handling
src/specfact_cli/modules/init/src/commands.py, src/specfact_cli/modules/init/module-package.yaml, docs/core-cli/init.md, tests under tests/unit/modules/*
specfact init treats profile/install selections as explicit enable requests, merges discovery into existing modules.json (preserving unrelated state), and passes enabled marketplace ids into discovery; IDE template resolution fallback tightened.
CLI diagnostics / UX
src/specfact_cli/cli.py, tests/unit/specfact_cli/test_module_not_found_error.py
Missing-bundle help queries the availability classifier and emits state-specific recovery guidance (enable command, skip reason, shadowing attribution) instead of generic "not installed" messaging.
Marketplace / docs / OpenSpec
openspec/CHANGE_ORDER.md, openspec/changes/...
Adds many OpenSpec change sets (architecture, enterprise, finops, telemetry, knowledge, marketplace, security, review-resiliency) with specs, proposals, tasks, and change-order sequencing.
Module init/install TDD & docs
openspec/changes/marketplace-07-*, docs/module-system/installing-modules.md, openspec/changes/marketplace-07-*/TDD_EVIDENCE.md
Design/proposal/spec/tasks for marketplace-07 describing availability classification, richer missing-command diagnostics, repo-aware init, enable-on-install semantics, and regression test plans.
Signature & version verification
scripts/verify-modules-signature.py, tests under tests/unit/specfact_cli/registry/test_signing_artifacts.py
_changed_manifests_from_git retries diffs against fallback HEAD~1 when provided base ref is missing; checksum parser retained for validation side-effects but unused tuple assignments removed.
Optional deps probing
src/specfact_cli/utils/optional_deps.py, tests/unit/utils/test_optional_deps.py
pycg probe uses -h instead of --version to detect availability; tests added to assert probe flag selection.
Smart-test & changed-detection
tools/smart_test_coverage.py, tests/unit/tools/test_smart_test_coverage.py
Treats src/specfact_cli/__init__.py as a version-only change (ignore for broad smart-test triggers) alongside other version files.
Pre-commit env normalization tests
scripts/pre_commit_code_review.py, tests/unit/scripts/test_pre_commit_code_review.py
Normalize nested tooling envs to repo-local XDG paths and semgrep logs; ensure overrides apply even when ENV vars present.
Tests: additions & updates
many under tests/unit/*, tests/integration/*
Extensive test coverage added/updated for discovery, availability classification, install re-enable flows, init/profile merging, semgrep env isolation, changed-vs version checks, and changed-only lint runner behavior. Notable: tests/unit/specfact_cli/registry/test_module_availability.py, tests/unit/modules/module_registry/test_commands.py, tests/integration/scripts/test_check_local_version_ahead_of_pypi_integration.py.
Reviewer guidance config
.coderabbit.yaml
Narrows review guidance to focus on contract/API safety, OpenSpec traceability, cross-repo module impact; restricts reviewer comments to material correctness/security/regression/data-loss/major maintainability risks; changes profile from assertivechill.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI as CLI (module install)
    participant Disc as ModuleDiscovery
    participant Avail as AvailabilityClassifier
    participant State as ModulesState (modules.json)
    participant Cache as DiscoveryCache

    User->>CLI: specfact module install <module-id> --repo <path>
    CLI->>Disc: discover_all_modules_for_project(base_path=repo_root)
    Disc-->>CLI: discovered modules
    CLI->>Avail: classify_module_availability(module_id=<module-id>)
    Avail->>Disc: discover_all_modules_for_project_with_shadowed()
    Avail->>State: read_modules_state()
    Avail-->>CLI: ModuleAvailability(status=..., reason=..., recovery_command=...)
    alt status == DISABLED
        CLI->>Disc: discover_all_modules_for_project(enable_ids=[<module-id>])
        CLI->>State: write_modules_state(enabled=True for <module-id>)
        CLI->>Cache: refresh(discovery, cli_version)
        CLI-->>User: "Module was disabled — enabled and refreshed."
    else status == AVAILABLE
        CLI-->>User: "Module already installed and available."
    else status == ABSENT
        CLI-->>User: "Module not found — run specfact module install ..."
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~40 minutes

Possibly related issues

  • #534 — Marketplace module install/state consistency: implements availability classifier, repo-aware discovery, and install/init reconciliation aligned with this PR’s objectives.
  • #527 — Enterprise policy-resolution: OpenSpec additions for enterprise policy overlays appear in this change set and may intersect policy-driven enable/override semantics.
  • #519 — Knowledge-distillation engine: this PR adds MemoryBackend spec and related knowledge artifacts that implement the feature described in that issue.

Possibly related PRs

  • #535 — Overlapping changes to module discovery/availability and install/init flows (module_availability, discovery, module_registry, CLI); strong code-level relation.
  • #509 — Overlaps on tool-probing, signature/verification scripts, and CI/version-check adjustments.
  • #463 — Related pre-commit/review runtime environment normalization and tests for repo-local runtime dirs.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

@djm81 djm81 self-assigned this Apr 28, 2026
@djm81 djm81 added bug Something isn't working enhancement New feature or request dependencies Dependency resolution and management labels Apr 28, 2026
@djm81 djm81 moved this from Todo to In Progress in SpecFact CLI Apr 28, 2026
Comment thread scripts/verify-modules-signature.py Fixed
Comment thread scripts/verify-modules-signature.py Fixed
djm81 and others added 2 commits April 28, 2026 23:16
Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>
@chatgpt-codex-connector
Copy link
Copy Markdown

💡 Codex Review

results["pycg"] = check_cli_tool_available("pycg")

P1 Badge Detect pycg availability without using --version

Using check_cli_tool_available("pycg") here invokes pycg --version, but PyCG’s CLI defines --version VERSION as a FASTEN metadata argument (it expects a value), so the probe exits non-zero even when PyCG is installed. That makes enhanced-analysis dependency checks report pycg as unavailable and causes call-graph extraction to be skipped at runtime. Please pass a valid probe flag for PyCG (for example -h) or add a tool-specific check path.


["git", "diff", "--cached", "--name-only", "--diff-filter=ACMRD"],

P2 Badge Compare changed files in CI, not only staged index

The packaged-artifact version gate now keys off git diff --cached, but in the PR orchestrator workflow the repository is checked out clean and python scripts/check_version_sources.py runs with an empty index, so this check never sees source/resource changes and silently skips the new version/changelog enforcement in CI. That allows commits to bypass the intended release gate whenever pre-commit is not run locally.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 36

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (32)
src/specfact_cli/analyzers/code_analyzer.py (1)

583-601: ⚠️ Potential issue | 🟠 Major

Handle filesystem/process OSError in Semgrep execution path.

_build_semgrep_env() can raise OSError/PermissionError (directory creation under .specfact). In this path those errors are currently uncaught, which can bubble up and skip analysis for a file unexpectedly.

Suggested fix
-        except (subprocess.TimeoutExpired, json.JSONDecodeError, FileNotFoundError, ValueError):
+        except (subprocess.TimeoutExpired, json.JSONDecodeError, FileNotFoundError, ValueError, OSError):
             # Semgrep not available or config missing - continue without it
             return []
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/specfact_cli/analyzers/code_analyzer.py` around lines 583 - 601, The
semgrep execution path can raise OSError/PermissionError from _build_semgrep_env
(e.g., creating .specfact), so update the exception handling around the
subprocess.run/JSON parsing block (the code that calls subprocess.run and then
json.loads) to also catch OSError and PermissionError; modify the existing
except tuple (which currently lists subprocess.TimeoutExpired,
json.JSONDecodeError, FileNotFoundError, ValueError) to include OSError and
PermissionError so these filesystem/process errors are swallowed the same way
and the method returns [] instead of bubbling up.
openspec/changes/knowledge-01-distillation-engine/tasks.md (1)

38-46: ⚠️ Potential issue | 🟠 Major

Add an explicit module-signing quality gate before archive/cleanup.

The final section includes archive and cleanup, but it omits module-signing verification, which is required in this workflow.

Proposed task addition
 ## 5. Delivery

 - [ ] 5.1 Mirror to `specfact-cli-internal/wiki/sources/knowledge-01-distillation-engine.md`; rebuild graph.
 - [ ] 5.2 Update `openspec/CHANGE_ORDER.md` — dependents: knowledge-02, enterprise-03.
 - [ ] 5.3 Open PR to `dev`.
+- [ ] 5.4 Run module-signing verification gate for affected bundled modules (if any) and attach evidence.
-- [ ] 5.4 After merge to `dev`, from **repository root** run `openspec archive knowledge-01-distillation-engine` (do **not**
+- [ ] 5.5 After merge to `dev`, from **repository root** run `openspec archive knowledge-01-distillation-engine` (do **not**
   manually move change folders under `openspec/changes/archive/`).
-- [ ] 5.5 After archive: `git worktree remove <worktree-path>`, `git branch -d feature/knowledge-01-distillation-engine`, `git worktree prune` (per `AGENTS.md`).
+- [ ] 5.6 After archive: `git worktree remove <worktree-path>`, `git branch -d feature/knowledge-01-distillation-engine`, `git worktree prune` (per `AGENTS.md`).
As per coding guidelines, `openspec/changes/**/*.md`: “For `/opsx:archive`... Include module signing and cleanup in final tasks.”
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/knowledge-01-distillation-engine/tasks.md` around lines 38 -
46, Insert an explicit pre-archive module-signing quality gate before the
existing archive/cleanup steps: add a new checklist item (e.g., "5.4 Verify
module signing") that instructs running the repository's module-signing
verification per the opsx:archive guidelines and AGENTS.md and requires a
successful verification result before running the existing openspec archive
knowledge-01-distillation-engine and subsequent cleanup steps (shift the current
5.4/5.5 to 5.5/5.6 accordingly).
openspec/changes/enterprise-04-budget-governance-and-chargeback/tasks.md (2)

34-40: ⚠️ Potential issue | 🟠 Major

Add explicit archive step in Delivery to complete OpenSpec lifecycle.

Delivery is missing openspec archive enterprise-04-budget-governance-and-chargeback from repo root. Without it, the change may remain unarchived and drift from source-of-truth specs.

As per coding guidelines, "For /opsx:archive (Archive change): Include module signing and cleanup in final tasks. Agents MUST run openspec archive <change-id> from repo root (no manual mv under openspec/changes/archive/)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/enterprise-04-budget-governance-and-chargeback/tasks.md`
around lines 34 - 40, Add an explicit archive task to the Delivery checklist:
append a new item instructing to run the exact command `openspec archive
enterprise-04-budget-governance-and-chargeback` from the repo root (do not move
files manually), and include module signing and cleanup steps as part of that
task so agents perform module signing and prune/cleanup archived state; update
the Delivery list (the 5.x tasks block) to include this as step 5.5 to ensure
the change is archived and cleaned up.

40-40: ⚠️ Potential issue | 🟡 Minor

Ensure a single trailing newline at end of file.

Line 40 appears to terminate the file without the required final newline.

As per coding guidelines, "Files must end with a single empty line (MD047: Files Must End With Single Newline)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/enterprise-04-budget-governance-and-chargeback/tasks.md` at
line 40, The file
openspec/changes/enterprise-04-budget-governance-and-chargeback/tasks.md is
missing a final newline; update the file so it ends with exactly one trailing
newline (one empty line at EOF) and remove any extra blank lines so it conforms
to MD047 (Files Must End With Single Newline).
openspec/changes/telemetry-01-opentelemetry-default-on/design.md (1)

87-87: ⚠️ Potential issue | 🟡 Minor

Add the required final newline.

Line 87 appears to end the file without a trailing newline.

As per coding guidelines, "Files must end with a single empty line (MD047: Files Must End With Single Newline)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/telemetry-01-opentelemetry-default-on/design.md` at line 87,
Add a single trailing newline at the end of the design.md file to satisfy MD047
(Files Must End With Single Newline); simply ensure the file's last line is
followed by one empty newline character so the file ends with exactly one final
newline.
openspec/changes/finops-02-budget-approval-gates/design.md (1)

48-48: ⚠️ Potential issue | 🟡 Minor

Add EOF newline for markdown lint compliance.

Line 48 appears to be the last line without a terminal newline.

As per coding guidelines, "Files must end with a single empty line (MD047: Files Must End With Single Newline)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/finops-02-budget-approval-gates/design.md` at line 48, The
Markdown file's final line is missing a terminal newline, triggering MD047; fix
it by adding a single EOF newline character (one empty line) at the end of the
design.md file so the file ends with exactly one trailing newline.
openspec/changes/review-resiliency-01-contracts/design.md (1)

90-90: ⚠️ Potential issue | 🟡 Minor

Ensure file ends with exactly one newline.

Line 90 appears to be EOF without the required trailing newline.

As per coding guidelines, "Files must end with a single empty line (MD047: Files Must End With Single Newline)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/review-resiliency-01-contracts/design.md` at line 90, The
file ends without the required trailing newline; open the Markdown document
(design.md) and ensure the file terminates with exactly one newline character
(i.e., a single empty line at EOF), removing any extra blank lines so it
complies with MD047 (Files Must End With Single Newline).
openspec/changes/architecture-02-well-architected-review/design.md (1)

48-48: ⚠️ Potential issue | 🟡 Minor

Fix trailing newline at file end.

Line 48 appears to end the document without the required final newline.

As per coding guidelines, "Files must end with a single empty line (MD047: Files Must End With Single Newline)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/architecture-02-well-architected-review/design.md` at line
48, The file design.md is missing the required final newline; open the design.md
document for the "architecture-02-well-architected-review" section and ensure
the file ends with exactly one empty line (a single trailing newline character),
removing any extra blank lines at EOF so the file conforms to MD047 (Files Must
End With Single Newline).
openspec/changes/finops-01-telemetry-and-outcomes/design.md (1)

48-48: ⚠️ Potential issue | 🟡 Minor

Add the final newline to pass MD047.

Line 48 appears to be the final line and should be followed by one newline.

As per coding guidelines, "Files must end with a single empty line (MD047: Files Must End With Single Newline)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/finops-01-telemetry-and-outcomes/design.md` at line 48, Add
a single trailing newline to the end of the design.md document to satisfy MD047
(Files Must End With Single Newline); ensure the file ends with exactly one
empty line (no extra blank lines) so the final newline is present and the linter
error for MD047 is resolved.
openspec/changes/finops-02-budget-approval-gates/proposal.md (1)

43-43: ⚠️ Potential issue | 🟡 Minor

Fix EOF newline for markdown lint compliance.

Line 43 appears to be the last line without the required terminal newline.

As per coding guidelines, "Files must end with a single empty line (MD047: Files Must End With Single Newline)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/finops-02-budget-approval-gates/proposal.md` at line 43, Add
a single trailing newline character at the end of the markdown document to
satisfy MD047 (Files Must End With Single Newline); open proposal.md and ensure
the file ends with exactly one empty line (no extra blank lines or missing
newline) so the final byte is a newline.
openspec/changes/finops-01-telemetry-and-outcomes/tasks.md (1)

41-41: ⚠️ Potential issue | 🟡 Minor

Add final newline to satisfy markdown lint.

Line 41 appears to end the file without the required single trailing newline, which will fail MD047 checks.

As per coding guidelines, "Files must end with a single empty line (MD047: Files Must End With Single Newline)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/finops-01-telemetry-and-outcomes/tasks.md` at line 41, The
file ends without a trailing newline which violates MD047; open the Markdown
file and add a single trailing newline at the end so the file ends with exactly
one empty line (ensure you do not add multiple blank lines), then save the file
(update the tasks.md end-of-file to include one final newline).
openspec/changes/enterprise-03-aggregation-and-drift-analytics/tasks.md (1)

43-44: ⚠️ Potential issue | 🟡 Minor

Missing trailing newline.

Per markdown guidelines (MD047), add a single empty line at end of file.

📝 Add trailing newline
 - [ ] 5.5 After archive, remove the worktree branch and prune stale worktree state.
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/enterprise-03-aggregation-and-drift-analytics/tasks.md`
around lines 43 - 44, The file ends without a trailing newline; add a single
empty line at EOF so the final task line "- [ ] 5.5 After archive, remove the
worktree branch and prune stale worktree state." is followed by one newline
character to satisfy MD047 (add one blank line at end of file).
openspec/changes/finops-02-budget-approval-gates/specs/finops-budget-gates/spec.md (1)

45-46: ⚠️ Potential issue | 🟡 Minor

Missing trailing newline.

Per markdown guidelines (MD047), files must end with a single empty line.

📝 Add trailing newline
 - **AND** JSON output remains available for downstream automation.
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/finops-02-budget-approval-gates/specs/finops-budget-gates/spec.md`
around lines 45 - 46, Add a single trailing newline at the end of the file so it
ends with one blank line; locate the end of the document (e.g., after the line
"- **AND** JSON output remains available for downstream automation.") in spec.md
and ensure there is exactly one empty newline character at EOF to satisfy MD047.
src/specfact_cli/modules/init/src/commands.py (1)

159-160: ⚠️ Potential issue | 🟡 Minor

Broad except Exception violates coding guidelines.

Line 159 catches all exceptions during template copy. This can mask unexpected failures (permissions, encoding, symlink issues). Narrow to specific types or at minimum log the exception class.

🛡️ Proposed narrower exception handling
-        except Exception as e:
+        except (OSError, shutil.Error) as e:
             console.print(f"[yellow]⚠[/yellow] Failed to copy {template_file.name}: {e}")

As per coding guidelines: "Include comprehensive exception handling with specific exception types in Python code."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/specfact_cli/modules/init/src/commands.py` around lines 159 - 160, The
except block that currently catches all exceptions when copying template_file
(catching Exception as e and calling console.print) is too broad; update the
error handling in the function that performs the copy so it catches specific
exceptions like FileNotFoundError, PermissionError, OSError (and shutil.Error if
using shutil.copytree/shutil.copy) and handle them or re-raise unexpected ones,
and include the exception class/name in the console.print message (e.g., include
type(e).__name__) so the log shows the exact exception type alongside the
message for template_file.name.
openspec/changes/marketplace-07-module-install-state-consistency/specs/user-module-root/spec.md (1)

29-30: ⚠️ Potential issue | 🟡 Minor

Missing trailing newline.

Per markdown guidelines (MD047), the file must end with a single empty line.

📝 Add trailing newline
 - **AND** install diagnostics SHALL NOT imply that a project-scope module is required
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/marketplace-07-module-install-state-consistency/specs/user-module-root/spec.md`
around lines 29 - 30, The file is missing a trailing newline after the final
line "- **AND** install diagnostics SHALL NOT imply that a project-scope module
is required"; open the spec file and ensure it ends with a single empty line
(one newline character) so the file terminates with exactly one blank line.
openspec/changes/marketplace-07-module-install-state-consistency/TDD_EVIDENCE.md (1)

73-73: ⚠️ Potential issue | 🟡 Minor

Add a trailing newline to satisfy markdown linting.

The file must end with a single newline character.

As per coding guidelines: Files must end with a single empty line (MD047: Files Must End With Single Newline)

📝 Proposed fix
 - Install repair now merges with existing module lifecycle state instead of replacing unrelated rows.
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/marketplace-07-module-install-state-consistency/TDD_EVIDENCE.md`
at line 73, The file TDD_EVIDENCE.md is missing a trailing newline which
triggers MD047; open TDD_EVIDENCE.md and ensure the file ends with exactly one
newline character (i.e., add a single empty line at EOF and remove any extra
blank lines) so the file ends with a single newline to satisfy markdown linting.
openspec/changes/security-02-eu-gdpr-baseline/specs/policy-engine/spec.md (1)

48-48: ⚠️ Potential issue | 🟡 Minor

Add a trailing newline to satisfy markdown linting.

The file must end with a single newline character.

As per coding guidelines: Files must end with a single empty line (MD047: Files Must End With Single Newline)

📝 Proposed fix
 - **THEN** the engine MAY emit advisory findings without blocking execution.
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/security-02-eu-gdpr-baseline/specs/policy-engine/spec.md` at
line 48, The file
openspec/changes/security-02-eu-gdpr-baseline/specs/policy-engine/spec.md is
missing a trailing newline which violates MD047; open spec.md and add exactly
one final newline character at the end of the file so it ends with a single
empty line (no extra blank lines or whitespace).
openspec/changes/marketplace-07-module-install-state-consistency/specs/init-module-state/spec.md (1)

36-36: ⚠️ Potential issue | 🟡 Minor

Add a trailing newline to satisfy markdown linting.

The file must end with a single newline character.

As per coding guidelines: Files must end with a single empty line (MD047: Files Must End With Single Newline)

📝 Proposed fix
 - **AND** init SHALL either enable the profile-selected module or report the exact disabled-state recovery command
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/marketplace-07-module-install-state-consistency/specs/init-module-state/spec.md`
at line 36, The file spec.md under the init-module-state spec is missing the
required trailing newline; open that markdown file and append a single newline
character at the end so the file ends with exactly one empty line (no extra
blank lines), then save the file to satisfy MD047.
openspec/changes/enterprise-03-aggregation-and-drift-analytics/design.md (1)

48-48: ⚠️ Potential issue | 🟡 Minor

Add a trailing newline to satisfy markdown linting.

The file must end with a single newline character after the final line of content.

As per coding guidelines: Files must end with a single empty line (MD047: Files Must End With Single Newline)

📝 Proposed fix
 - Whether stale distillation thresholds belong in profiles or enterprise policy.
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/enterprise-03-aggregation-and-drift-analytics/design.md` at
line 48, The file is missing a trailing newline which fails MD047; open the
markdown document and ensure the very end of the file contains exactly one
newline character (i.e., add a single empty line after the final content), then
save so the file ends with a single trailing newline.
openspec/changes/architecture-02-well-architected-review/specs/architecture-review/spec.md (1)

37-37: ⚠️ Potential issue | 🟡 Minor

Add a trailing newline to satisfy markdown linting.

The file must end with a single newline character.

As per coding guidelines: Files must end with a single empty line (MD047: Files Must End With Single Newline)

📝 Proposed fix
 - **AND** the result remains consumable by review and governance tooling.
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/architecture-02-well-architected-review/specs/architecture-review/spec.md`
at line 37, The file ends without a trailing newline which violates MD047; open
the Markdown file and ensure it ends with exactly one newline character by
adding a single empty line at the end of the document (i.e., ensure the final
character is '\n' and there is no extra blank line after it).
openspec/changes/security-02-eu-gdpr-baseline/specs/security-gdpr-baseline/spec.md (1)

83-83: ⚠️ Potential issue | 🟡 Minor

Add a trailing newline to satisfy markdown linting.

The file must end with a single newline character.

As per coding guidelines: Files must end with a single empty line (MD047: Files Must End With Single Newline)

📝 Proposed fix
 - **AND** `hard` mode MAY fail the run when the baseline mandates explicit residency proof.
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/security-02-eu-gdpr-baseline/specs/security-gdpr-baseline/spec.md`
at line 83, Add a single trailing newline to the end of the Markdown file to
satisfy MD047 (Files Must End With Single Newline); open the
security-gdpr-baseline spec.md file and ensure the final character is a single
'\n' (no extra blank lines) so the file ends with exactly one empty line.
openspec/changes/enterprise-02-rbac-and-audit-trail/proposal.md (1)

43-43: ⚠️ Potential issue | 🟡 Minor

Add a trailing newline to satisfy markdown linting.

The file must end with a single newline character.

As per coding guidelines: Files must end with a single empty line (MD047: Files Must End With Single Newline)

📝 Proposed fix
 - **Sanitized**: false
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/enterprise-02-rbac-and-audit-trail/proposal.md` at line 43,
The markdown file proposal.md is missing a trailing newline which violates
MD047; open enterprise-02-rbac-and-audit-trail/proposal.md and ensure the file
ends with exactly one newline character (no extra blank lines or missing
newline), save the file so the final character is a single '\n' to satisfy the
linter.
openspec/changes/architecture-02-well-architected-review/proposal.md (1)

45-45: ⚠️ Potential issue | 🟡 Minor

Add a trailing newline to satisfy markdown linting.

The file must end with a single newline character.

As per coding guidelines: Files must end with a single empty line (MD047: Files Must End With Single Newline)

📝 Proposed fix
 - **Sanitized**: false
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/architecture-02-well-architected-review/proposal.md` at line
45, The markdown document fails lint MD047 because it lacks a single trailing
newline; fix by editing the proposal.md content to ensure the file ends with
exactly one newline character (no extra blank lines or missing newline) so the
file terminates with a single empty line.
openspec/changes/finops-02-budget-approval-gates/tasks.md (1)

34-41: ⚠️ Potential issue | 🟠 Major

Delivery checklist is missing module-signing closeout.

Archive and cleanup are present, but module-signing verification is still required in final closeout tasks.

Suggested fix
 ## 5. Delivery
 
 - [ ] 5.1 Mirror the change into `specfact-cli-internal/wiki/sources/finops-02-budget-approval-gates.md` and rebuild the internal wiki graph.
 - [ ] 5.2 Update `openspec/CHANGE_ORDER.md` with downstream dependency notes.
 - [ ] 5.3 Open PR from `feature/finops-02-budget-approval-gates` to `dev`.
 - [ ] 5.4 After merge to `dev`, from repository root run `openspec archive finops-02-budget-approval-gates` when the change completes.
-- [ ] 5.5 After merge, run worktree cleanup: `git worktree remove <path>`, `git branch -d feature/finops-02-budget-approval-gates`, `git worktree prune`, and delete remote branch if your release flow requires (`git push origin --delete feature/finops-02-budget-approval-gates`).
+- [ ] 5.5 Run module-signing verification/cleanup gates required by release policy (if bundled modules are touched).
+- [ ] 5.6 After merge, run worktree cleanup: `git worktree remove <path>`, `git branch -d feature/finops-02-budget-approval-gates`, `git worktree prune`, and delete remote branch if your release flow requires (`git push origin --delete feature/finops-02-budget-approval-gates`).

Based on learnings, /opsx:archive final tasks must include module signing and cleanup.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/finops-02-budget-approval-gates/tasks.md` around lines 34 -
41, The delivery checklist in tasks.md omits module-signing verification in
final closeout; update the Delivery section (around items 5.4 and 5.5) to add an
explicit module-signing step (e.g., "5.4.x Verify module signing via
/opsx:archive or the module-signing tool and confirm signatures and provenance")
and a corresponding verification/cleanup step (remove worktree, delete branch)
so that module signing is confirmed before archive and branch cleanup; reference
the existing items 5.4, 5.5 and the /opsx:archive final tasks when inserting the
new step.
openspec/changes/knowledge-02-preflight-context-assembly/tasks.md (1)

46-52: ⚠️ Potential issue | 🟠 Major

Add mandatory archive and module-signing closeout tasks.

Delivery currently skips explicit openspec archive <change-id> and module-signing verification steps required for OpenSpec archive workflows.

Suggested fix
 ## 5. Delivery
 
 - [ ] 5.1 Mirror to wiki; rebuild graph.
 - [ ] 5.2 Update `openspec/CHANGE_ORDER.md`.
 - [ ] 5.3 Open PR to `dev`.
-- [ ] 5.4 After merge, from the **same repository worktree** used for this change, run cleanup: `git worktree remove <worktree-path>`, `git branch -d feature/knowledge-02-preflight-context-assembly`, `git worktree prune` (and `git remote prune origin` if stale remotes accumulate) per `AGENTS.md`.
+- [ ] 5.4 After merge to `dev`, from repository root run `openspec archive knowledge-02-preflight-context-assembly`.
+- [ ] 5.5 Run module-signing verification/cleanup gates required by release policy (if bundled modules are touched).
+- [ ] 5.6 After merge, from the **same repository worktree** used for this change, run cleanup: `git worktree remove <worktree-path>`, `git branch -d feature/knowledge-02-preflight-context-assembly`, `git worktree prune` (and `git remote prune origin` if stale remotes accumulate) per `AGENTS.md`.

Based on learnings, for openspec/changes/**/*.md archive closeout must include openspec archive <change-id> and include module signing plus cleanup in final tasks.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/knowledge-02-preflight-context-assembly/tasks.md` around
lines 46 - 52, Update the Delivery checklist under "5. Delivery" to add
mandatory archive and module-signing closeout steps: insert a step that runs
"openspec archive <change-id>" (or equivalent archive command) before or
alongside the mirror/rebuild step, and add a step to verify module signing
(e.g., "verify module signing / check signatures" and any cleanup of signing
artifacts) prior to worktree removal; keep the existing cleanup instructions
(git worktree remove, branch delete, worktree prune, git remote prune origin)
and reference AGENTS.md as needed for workflow specifics so the final checklist
includes explicit archive and module-signing verification tasks.
openspec/changes/enterprise-02-rbac-and-audit-trail/tasks.md (1)

32-39: ⚠️ Potential issue | 🟠 Major

Add module-signing gate to final delivery steps.

This checklist includes archive + cleanup, but still omits module-signing verification expected for OpenSpec archive closeout.

Suggested fix
 ## 5. Delivery
 
 - [ ] 5.1 Mirror the change into `specfact-cli-internal/wiki/sources/enterprise-02-rbac-and-audit-trail.md` and rebuild the internal wiki graph.
 - [ ] 5.2 Update `openspec/CHANGE_ORDER.md` with downstream dependency notes.
 - [ ] 5.3 Open PR from `feature/enterprise-02-rbac-and-audit-trail` to `dev`.
-- [ ] 5.4 After merge, remove the worktree branch and prune stale worktree state.
-- [ ] 5.5 After merge to `dev`, from repository root run `openspec archive enterprise-02-rbac-and-audit-trail` (required closeout; do not manually move change folders under `openspec/changes/archive/`).
+- [ ] 5.4 After merge to `dev`, from repository root run `openspec archive enterprise-02-rbac-and-audit-trail` (required closeout; do not manually move change folders under `openspec/changes/archive/`).
+- [ ] 5.5 Run module-signing verification/cleanup gates required by release policy (if bundled modules are touched).
+- [ ] 5.6 After merge, remove the worktree branch and prune stale worktree state.

Based on learnings, /opsx:archive closeout requires module signing and cleanup tasks in final section.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/enterprise-02-rbac-and-audit-trail/tasks.md` around lines 32
- 39, Add a module-signing verification gate to the final delivery checklist:
update the Delivery section (items 5.1–5.5) to require running the
module-signing verification and confirming valid signatures before running the
archive command; specifically, add a step (e.g., new 5.5 or 5.6) that mandates
executing the module-signing verification command/process for the change set and
confirming successful verification, and adjust the existing archive step
(`openspec archive enterprise-02-rbac-and-audit-trail`) to be executed only
after that verification completes and signatures are present.
openspec/changes/security-01-unified-findings-model/tasks.md (1)

44-53: ⚠️ Potential issue | 🟠 Major

Include module-signing quality gate in final delivery checklist.

Delivery covers cleanup and archive, but it does not include an explicit module-signing verification step. Add it before archive/closeout so release artifacts are policy-compliant.

Based on learnings, /opsx:archive final tasks must include module signing and cleanup, with openspec archive <change-id> run from repo root.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/security-01-unified-findings-model/tasks.md` around lines 44
- 53, Add an explicit module-signing quality gate between steps 5.4 and 5.5:
verify all released modules/artifacts are signed and signatures validate (run
your project’s module-signing verification command or script and check signature
metadata), remediate unsigned artifacts, record the verification result, then
proceed to run the final archive command (the openspec archive <change-id> step)
from repo root; update the checklist text to insert this verification step and
reference the verification script/command used.
src/specfact_cli/registry/module_availability.py (1)

192-192: ⚠️ Potential issue | 🟡 Minor

File must end with a single newline.

Line 192 lacks a trailing newline.

📝 Proposed fix
     return _available_or_skipped_availability(primary, enabled_map)
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/specfact_cli/registry/module_availability.py` at line 192, The file
src/specfact_cli/registry/module_availability.py is missing a final newline;
open module_availability.py and ensure the file ends with exactly one trailing
newline character (add a single '\n' at EOF), then save so the file ends with a
single newline.
openspec/changes/knowledge-01-distillation-engine/design.md (1)

126-126: ⚠️ Potential issue | 🟡 Minor

File must end with a single newline (MD047).

Line 126 lacks a trailing newline.

📝 Proposed fix
 - Evidence accumulation without distillation cycles. Mitigated by `specfact memory status` surface showing un-distilled counts.
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/knowledge-01-distillation-engine/design.md` at line 126, The
file openspec/changes/knowledge-01-distillation-engine/design.md violates MD047
by missing a final newline; fix it by editing design.md (the document referenced
in the review) and ensuring the file ends with exactly one trailing newline
character (add a single '\n' at EOF and remove any extra blank lines so there is
only one final newline).
openspec/changes/knowledge-01-distillation-engine/specs/knowledge-distillation/spec.md (1)

83-83: ⚠️ Potential issue | 🟡 Minor

File must end with a single newline (MD047).

Line 83 lacks a trailing newline.

📝 Proposed fix
 - **AND** no partial backend instance is used for user commands until registration succeeds.
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/knowledge-01-distillation-engine/specs/knowledge-distillation/spec.md`
at line 83, The Markdown file spec.md for the knowledge-distillation spec is
missing a trailing newline; open the spec.md document and add exactly one
newline character at the end of the file (remove any extra blank lines so the
file ends with a single trailing newline) to satisfy MD047.
openspec/changes/marketplace-07-module-install-state-consistency/tasks.md (1)

45-45: ⚠️ Potential issue | 🟡 Minor

File must end with a single newline (MD047).

Line 45 lacks a trailing newline.

📝 Proposed fix
 - [x] 6.4 Record passing-after verification output in `TDD_EVIDENCE.md`.
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/marketplace-07-module-install-state-consistency/tasks.md` at
line 45, Add a single trailing newline at the end of the markdown file to
satisfy MD047: open the tasks.md file and ensure the final byte is a newline
character so the file ends with exactly one newline (i.e., add a blank line at
EOF if missing).
openspec/changes/telemetry-01-opentelemetry-default-on/specs/telemetry-otel/spec.md (1)

69-69: ⚠️ Potential issue | 🟡 Minor

File must end with a single newline (MD047).

Line 69 lacks a trailing newline. Per markdown guidelines, files must end with a single empty line.

📝 Proposed fix
 - **AND** behavior matches the **"Transmitted payload is recorded locally"** scenario for new invocations.
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/telemetry-01-opentelemetry-default-on/specs/telemetry-otel/spec.md`
at line 69, The Markdown file spec.md in the telemetry-otel spec is missing a
trailing newline at end of file; open telemetry-otel/spec.md and add a single
newline character at EOF so the file ends with exactly one blank line (ensure no
extra blank lines are appended).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d1c8be7a-2898-48cd-8b2f-2a3c8460bdd8

📥 Commits

Reviewing files that changed from the base of the PR and between 2b38c50 and be171d3.

📒 Files selected for processing (112)
  • .coderabbit.yaml
  • CHANGELOG.md
  • docs/core-cli/init.md
  • docs/module-system/installing-modules.md
  • openspec/CHANGE_ORDER.md
  • openspec/changes/architecture-02-well-architected-review/.openspec.yaml
  • openspec/changes/architecture-02-well-architected-review/design.md
  • openspec/changes/architecture-02-well-architected-review/proposal.md
  • openspec/changes/architecture-02-well-architected-review/specs/architecture-review/spec.md
  • openspec/changes/architecture-02-well-architected-review/specs/solution-architecture/spec.md
  • openspec/changes/architecture-02-well-architected-review/tasks.md
  • openspec/changes/enterprise-01-policy-resolution-extension/.openspec.yaml
  • openspec/changes/enterprise-01-policy-resolution-extension/design.md
  • openspec/changes/enterprise-01-policy-resolution-extension/proposal.md
  • openspec/changes/enterprise-01-policy-resolution-extension/specs/enterprise-policy-resolution/spec.md
  • openspec/changes/enterprise-01-policy-resolution-extension/specs/profile-config-layering/spec.md
  • openspec/changes/enterprise-01-policy-resolution-extension/tasks.md
  • openspec/changes/enterprise-02-rbac-and-audit-trail/.openspec.yaml
  • openspec/changes/enterprise-02-rbac-and-audit-trail/design.md
  • openspec/changes/enterprise-02-rbac-and-audit-trail/proposal.md
  • openspec/changes/enterprise-02-rbac-and-audit-trail/specs/enterprise-audit-trail/spec.md
  • openspec/changes/enterprise-02-rbac-and-audit-trail/specs/enterprise-policy-resolution/spec.md
  • openspec/changes/enterprise-02-rbac-and-audit-trail/tasks.md
  • openspec/changes/enterprise-03-aggregation-and-drift-analytics/.openspec.yaml
  • openspec/changes/enterprise-03-aggregation-and-drift-analytics/design.md
  • openspec/changes/enterprise-03-aggregation-and-drift-analytics/proposal.md
  • openspec/changes/enterprise-03-aggregation-and-drift-analytics/specs/enterprise-audit-trail/spec.md
  • openspec/changes/enterprise-03-aggregation-and-drift-analytics/specs/enterprise-drift-analytics/spec.md
  • openspec/changes/enterprise-03-aggregation-and-drift-analytics/tasks.md
  • openspec/changes/enterprise-04-budget-governance-and-chargeback/.openspec.yaml
  • openspec/changes/enterprise-04-budget-governance-and-chargeback/design.md
  • openspec/changes/enterprise-04-budget-governance-and-chargeback/proposal.md
  • openspec/changes/enterprise-04-budget-governance-and-chargeback/specs/enterprise-chargeback/spec.md
  • openspec/changes/enterprise-04-budget-governance-and-chargeback/specs/finops-budget-gates/spec.md
  • openspec/changes/enterprise-04-budget-governance-and-chargeback/tasks.md
  • openspec/changes/finops-01-telemetry-and-outcomes/.openspec.yaml
  • openspec/changes/finops-01-telemetry-and-outcomes/design.md
  • openspec/changes/finops-01-telemetry-and-outcomes/proposal.md
  • openspec/changes/finops-01-telemetry-and-outcomes/specs/finops-telemetry-outcomes/spec.md
  • openspec/changes/finops-01-telemetry-and-outcomes/specs/telemetry-otel/spec.md
  • openspec/changes/finops-01-telemetry-and-outcomes/tasks.md
  • openspec/changes/finops-02-budget-approval-gates/.openspec.yaml
  • openspec/changes/finops-02-budget-approval-gates/design.md
  • openspec/changes/finops-02-budget-approval-gates/proposal.md
  • openspec/changes/finops-02-budget-approval-gates/specs/finops-budget-gates/spec.md
  • openspec/changes/finops-02-budget-approval-gates/specs/finops-telemetry-outcomes/spec.md
  • openspec/changes/finops-02-budget-approval-gates/tasks.md
  • openspec/changes/knowledge-01-distillation-engine/.openspec.yaml
  • openspec/changes/knowledge-01-distillation-engine/design.md
  • openspec/changes/knowledge-01-distillation-engine/proposal.md
  • openspec/changes/knowledge-01-distillation-engine/specs/knowledge-distillation/spec.md
  • openspec/changes/knowledge-01-distillation-engine/tasks.md
  • openspec/changes/knowledge-02-preflight-context-assembly/.openspec.yaml
  • openspec/changes/knowledge-02-preflight-context-assembly/design.md
  • openspec/changes/knowledge-02-preflight-context-assembly/proposal.md
  • openspec/changes/knowledge-02-preflight-context-assembly/specs/preflight-context-assembly/spec.md
  • openspec/changes/knowledge-02-preflight-context-assembly/tasks.md
  • openspec/changes/marketplace-07-module-install-state-consistency/.openspec.yaml
  • openspec/changes/marketplace-07-module-install-state-consistency/TDD_EVIDENCE.md
  • openspec/changes/marketplace-07-module-install-state-consistency/design.md
  • openspec/changes/marketplace-07-module-install-state-consistency/proposal.md
  • openspec/changes/marketplace-07-module-install-state-consistency/specs/init-module-state/spec.md
  • openspec/changes/marketplace-07-module-install-state-consistency/specs/module-installation/spec.md
  • openspec/changes/marketplace-07-module-install-state-consistency/specs/user-module-root/spec.md
  • openspec/changes/marketplace-07-module-install-state-consistency/tasks.md
  • openspec/changes/review-resiliency-01-contracts/.openspec.yaml
  • openspec/changes/review-resiliency-01-contracts/design.md
  • openspec/changes/review-resiliency-01-contracts/proposal.md
  • openspec/changes/review-resiliency-01-contracts/specs/review-resiliency/spec.md
  • openspec/changes/review-resiliency-01-contracts/tasks.md
  • openspec/changes/security-01-unified-findings-model/.openspec.yaml
  • openspec/changes/security-01-unified-findings-model/design.md
  • openspec/changes/security-01-unified-findings-model/proposal.md
  • openspec/changes/security-01-unified-findings-model/specs/security-findings/spec.md
  • openspec/changes/security-01-unified-findings-model/tasks.md
  • openspec/changes/security-02-eu-gdpr-baseline/.openspec.yaml
  • openspec/changes/security-02-eu-gdpr-baseline/design.md
  • openspec/changes/security-02-eu-gdpr-baseline/proposal.md
  • openspec/changes/security-02-eu-gdpr-baseline/specs/policy-engine/spec.md
  • openspec/changes/security-02-eu-gdpr-baseline/specs/security-gdpr-baseline/spec.md
  • openspec/changes/security-02-eu-gdpr-baseline/tasks.md
  • openspec/changes/telemetry-01-opentelemetry-default-on/.openspec.yaml
  • openspec/changes/telemetry-01-opentelemetry-default-on/design.md
  • openspec/changes/telemetry-01-opentelemetry-default-on/proposal.md
  • openspec/changes/telemetry-01-opentelemetry-default-on/specs/telemetry-otel/spec.md
  • openspec/changes/telemetry-01-opentelemetry-default-on/tasks.md
  • pyproject.toml
  • scripts/pre_commit_code_review.py
  • scripts/verify-modules-signature.py
  • setup.py
  • src/__init__.py
  • src/specfact_cli/__init__.py
  • src/specfact_cli/analyzers/code_analyzer.py
  • src/specfact_cli/cli.py
  • src/specfact_cli/modules/init/module-package.yaml
  • src/specfact_cli/modules/init/src/commands.py
  • src/specfact_cli/modules/module_registry/module-package.yaml
  • src/specfact_cli/modules/module_registry/src/commands.py
  • src/specfact_cli/registry/module_availability.py
  • src/specfact_cli/registry/module_discovery.py
  • src/specfact_cli/registry/module_packages.py
  • tests/integration/scripts/test_check_local_version_ahead_of_pypi_integration.py
  • tests/unit/analyzers/test_code_analyzer.py
  • tests/unit/commands/test_backlog_config.py
  • tests/unit/modules/init/test_first_run_selection.py
  • tests/unit/modules/module_registry/test_commands.py
  • tests/unit/scripts/test_pre_commit_code_review.py
  • tests/unit/specfact_cli/modules/test_multi_module_install_uninstall.py
  • tests/unit/specfact_cli/registry/test_init_module_lifecycle_ux.py
  • tests/unit/specfact_cli/registry/test_init_module_state.py
  • tests/unit/specfact_cli/registry/test_module_availability.py
  • tests/unit/specfact_cli/test_module_not_found_error.py

Comment thread .coderabbit.yaml Outdated
Comment thread CHANGELOG.md
Comment thread docs/core-cli/init.md
Comment thread openspec/CHANGE_ORDER.md
Comment thread src/specfact_cli/registry/module_discovery.py
Comment thread src/specfact_cli/registry/module_packages.py
Comment thread tests/unit/analyzers/test_code_analyzer.py
Comment thread tests/unit/modules/module_registry/test_commands.py
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
CHANGELOG.md (1)

40-40: ⚠️ Potential issue | 🟡 Minor

Wrap overlong changelog bullet on Line 40

This line exceeds the markdown 120-character limit and can fail lint.

✂️ Suggested wrap
-- **PR follow-up**: fix project-scope module re-enable to honor `--repo` and restore reachable shadowed-module diagnostics during availability checks.
+- **PR follow-up**: fix project-scope module re-enable to honor `--repo`
+  and restore reachable shadowed-module diagnostics during
+  availability checks.

As per coding guidelines: “Keep line length under 120 characters in markdown files”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CHANGELOG.md` at line 40, The changelog bullet "PR follow-up: fix
project-scope module re-enable to honor `--repo` and restore reachable
shadowed-module diagnostics during availability checks." is over 120 characters;
split this single markdown bullet into multiple wrapped lines (preserve the
leading "- " or "**PR follow-up**:" styling) so no line exceeds 120 chars,
breaking at logical boundaries (e.g., before "to honor `--repo`" and before "and
restore reachable...") and keep the sentence content identical across the
wrapped lines.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/check_version_sources.py`:
- Around line 68-80: The current _changed_files_vs_git_ref function swallows
subprocess errors and returns an empty list which lets candidate_files be empty
and skip checks; update _changed_files_vs_git_ref to log a warning to stderr (or
a logger) when git fails and, if the user explicitly passed --changed-vs
(detectable by a non-empty git_ref / the sentinel logic used by your CLI), fail
closed by re-raising the CalledProcessError or calling sys.exit(1) so the
version-bump enforcement does not silently pass; reference
_changed_files_vs_git_ref, candidate_files and the --changed-vs flag when making
the change.

In `@tests/unit/scripts/test_check_version_sources.py`:
- Around line 222-245: The test function
test_check_version_sources_changed_vs_passes_with_version_bundle_and_changelog
currently calls the script with "--changed-vs HEAD" after modifying files but
not committing them, which yields no candidate_files and lets the script exit 0;
to exercise enforcement commit the second set of changes and invoke the script
against the previous commit (e.g., use git add/commit for the VALUE=2, updated
canonical files and CHANGELOG.md, then run the script with "--changed-vs
HEAD~1") so the code path in the version checking logic that validates the
version bundle is actually executed.

---

Duplicate comments:
In `@CHANGELOG.md`:
- Line 40: The changelog bullet "PR follow-up: fix project-scope module
re-enable to honor `--repo` and restore reachable shadowed-module diagnostics
during availability checks." is over 120 characters; split this single markdown
bullet into multiple wrapped lines (preserve the leading "- " or "**PR
follow-up**:" styling) so no line exceeds 120 chars, breaking at logical
boundaries (e.g., before "to honor `--repo`" and before "and restore
reachable...") and keep the sentence content identical across the wrapped lines.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c66e1606-e0b5-4365-aa5e-bd9cbb80e637

📥 Commits

Reviewing files that changed from the base of the PR and between be171d3 and 73741e4.

📒 Files selected for processing (11)
  • .github/workflows/pr-orchestrator.yml
  • CHANGELOG.md
  • pyproject.toml
  • scripts/check_version_sources.py
  • setup.py
  • src/__init__.py
  • src/specfact_cli/__init__.py
  • src/specfact_cli/utils/optional_deps.py
  • tests/unit/scripts/test_check_version_sources.py
  • tests/unit/utils/test_optional_deps.py
  • tests/unit/workflows/test_trustworthy_green_checks.py

Comment thread scripts/check_version_sources.py
Comment thread tests/unit/scripts/test_check_version_sources.py
@djm81 djm81 merged commit a884061 into main Apr 28, 2026
47 of 48 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in SpecFact CLI Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working dependencies Dependency resolution and management enhancement New feature or request

Projects

Status: Done

1 participant