Skip to content

fix runtime module discovery reliability#558

Merged
djm81 merged 4 commits into
devfrom
bugfix/runtime-01-discovery-reliability
May 7, 2026
Merged

fix runtime module discovery reliability#558
djm81 merged 4 commits into
devfrom
bugfix/runtime-01-discovery-reliability

Conversation

@djm81
Copy link
Copy Markdown
Collaborator

@djm81 djm81 commented May 7, 2026

Summary

Fix runtime discovery failures reported in #552, #553, and #554 via the dedicated User Story #557.

  • Load active installed module src/ roots before lazy command app loading so installed marketplace modules can import dependency modules.
  • Preserve lazy-loader failure reasons and surface installed-but-unloadable modules as availability diagnostics instead of false "not installed" messages.
  • Improve environment-manager detection for rootless monorepos and add explicit specfact init ide --env-manager <auto|uv|hatch|poetry|pip>.
  • Add a CI runtime discovery smoke script that installs project/codebase/code-review modules from a local marketplace, checks upgrade command availability, validates init ide auto/uv behavior, and verifies specfact code, code review run, and code import command loading across direct, pip-editable, and uvx launchers.
  • Bump package version to 0.46.19 and bundled init/module-registry manifests for touched bundled module code.

Root Cause

Installed module command loading could resolve command metadata while still missing dependency module src roots at lazy-load time. The fallback diagnostics then treated the provider as absent, so users saw Module 'nold-ai/specfact-codebase' is not installed even when specfact module list showed it installed and enabled. Rootless monorepo environment detection also stopped too early when markers existed only below package directories.

Validation

  • OpenSpec: openspec validate runtime-01-discovery-reliability --strict
  • Unit/e2e targeted suites for module loading, availability diagnostics, env-manager detection, and init command behavior
  • Real-world smoke against sibling specfact-cli-modules and specfact-demo-repo
  • hatch run runtime-discovery-smoke --launcher direct
  • hatch run runtime-discovery-smoke --launcher pip-editable
  • hatch run runtime-discovery-smoke --launcher uvx
  • hatch run pytest tests/integration/scripts/test_runtime_discovery_smoke.py -q
  • hatch run check-version-sources
  • hatch run verify-modules-signature-pr
  • Pre-commit completed for commit 86feb9c2

Cross-Repo Companion

Companion modules PR: nold-ai/specfact-cli-modules#262.

While validating this branch, local specfact code review run exposed a separate specfact-code-review module defect: its Semgrep runner created a temp HOME and set XDG_CONFIG_HOME/XDG_CACHE_HOME inside it without creating those directories. The companion modules PR fixes that, bumps nold-ai/specfact-code-review to 0.47.15, and updates checksum-only integrity for CI signing.

Notes

Local specfact at /home/dom/.local/bin/specfact was still version 0.46.18 and reproduced the original bug. The patched worktree command (hatch run python -m specfact_cli.cli ...) successfully ran code review run, and the tightened smoke now covers code review run --help.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 911ee9e9-56c3-47ac-a739-770f44c36326

📥 Commits

Reviewing files that changed from the base of the PR and between 47ebc42 and 0e7f8db.

📒 Files selected for processing (4)
  • scripts/runtime_discovery_smoke.py
  • src/specfact_cli/registry/module_packages.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/specfact_cli/registry/module_packages.py
  • scripts/runtime_discovery_smoke.py
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Compatibility (Python 3.11)
  • GitHub Check: Linting (ruff, pylint, safe-write guard)
  • GitHub Check: Tests (Python 3.12)
🧰 Additional context used
📓 Path-based instructions (5)
**/test_*.py

📄 CodeRabbit inference engine (.cursor/rules/python-github-rules.mdc)

**/test_*.py: Write tests first in test-driven development (TDD) using the Red-Green-Refactor cycle
Ensure each test is independent and repeatable with no shared state between tests
Organize Python imports in tests using unittest.mock for Mock and patch
Use setup_method() for test initialization and Arrange-Act-Assert pattern in test files
Use @pytest.mark.asyncio decorator for async test functions in Python
Organize test files in structure: tests/unit/, tests/integration/, tests/e2e/ by module

Files:

  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
**/*.py

📄 CodeRabbit inference engine (.cursor/rules/python-github-rules.mdc)

**/*.py: Maintain minimum 80% test coverage, with 100% coverage for critical paths in Python code
Use clear naming and self-documenting code, preferring clear names over comments
Ensure each function/class has a single clear purpose (Single Responsibility Principle)
Extract common patterns to avoid code duplication (DRY principle)
Apply SOLID object-oriented design principles in Python code
Use type hints everywhere in Python code and enable basedpyright strict mode
Use Pydantic models for data validation and serialization in Python
Use async/await for I/O operations in Python code
Use context managers for resource management in Python
Use dataclasses for simple data containers in Python
Enforce maximum line length of 120 characters in Python code
Use 4 spaces for indentation in Python code (no tabs)
Use 2 blank lines between classes and 1 blank line between methods in Python
Organize imports in order: Standard library → Third party → Local in Python files
Use snake_case for variables and functions in Python
Use PascalCase for class names in Python
Use UPPER_SNAKE_CASE for constants in Python
Use leading underscore (_) for private methods in Python classes
Use snake_case for Python file names
Enable basedpyright strict mode with strict type checking configuration in Python
Use Google-style docstrings for functions and classes in Python
Include comprehensive exception handling with specific exception types in Python code
Use logging with structured context (extra parameters) instead of print statements
Use retry logic with tenacity decorators (@retry) for operations that might fail
Use Pydantic BaseSettings for environment-based configuration in Python
Validate user input using Pydantic validators in Python models
Use @lru_cache and Redis-based caching for expensive calculations in Python
Run code formatting with Black (120 character line length) and isort in Python
Run type checking with basedpyright on all Python files
Run linting with ruff and pylint on all Pyth...

Files:

  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
tests/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/spec-fact-cli-rules.mdc)

Tests must be meaningful and test actual functionality, cover both success and failure cases, be independent and repeatable, and have clear, descriptive names. NO EXCEPTIONS - no placeholder or empty tests.

tests/**/*.py: Trim low-value unit tests when a contract covers the same assertion (type/shape/raises on negative checks)
Delete tests that only assert input validation, datatype/shape enforcement, or raises on negative conditions now guarded by contracts and runtime typing
Convert repeated edge-case permutations into one Hypothesis property with contracts acting as oracles

Secret redaction via LoggerSetup.redact_secrets must be covered by unit tests

Files:

  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py

⚙️ CodeRabbit configuration file

tests/**/*.py: Contract-first testing: meaningful scenarios, not redundant assertions already covered by
contracts. Flag flakiness, environment coupling, and missing coverage for changed behavior.

Files:

  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
@(src|tests)/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/spec-fact-cli-rules.mdc)

Linting must pass with no errors using: pylint src tests

Files:

  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
**/*.{py,pyi}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{py,pyi}: After any code changes, follow these steps in order: (1) Apply linting and formatting to ensure code quality: hatch run format, (2) Type checking: hatch run type-check (basedpyright), (3) Contract-first approach: Run hatch run contract-test for contract validation, (4) Run full test suite: hatch test --cover -v, (5) Verify all tests pass and contracts are satisfied, (6) Fix any issues and repeat steps until all tests pass
All public APIs must have @icontract decorators and @beartype type checking
Use Pydantic models for all data structures with data validation
Only write high-value comments if at all. Avoid talking to the user through comments

Files:

  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
🔀 Multi-repo context nold-ai/specfact-cli-modules

Linked repositories findings

nold-ai/specfact-cli-modules

  • Consumers of detect_env_manager / build_tool_command:
    • packages/specfact-spec/src/specfact_spec/generate/commands.py — imports both and calls detect_env_manager(...) and build_tool_command(...) in multiple spots (e.g. lines ~1142, ~1271, ~1364). [::nold-ai/specfact-cli-modules::packages/specfact-spec/src/specfact_spec/generate/commands.py:23,24,1142,1271,1364]
    • packages/specfact-codebase/src/specfact_codebase/validators/repro_checker.py — imports build_tool_command and detect_env_manager; constructs tool commands (hits at ~873, ~915, ~936, ~973, ~995, ~1005). [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/repro_checker.py:873,875,882,915,936,973,995,1005]
    • packages/specfact-codebase/src/specfact_codebase/repro/commands.py — imports detect_env_manager and build_tool_command and uses them when composing install/run commands (calls at ~285, ~483, ~511, ~514). [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/repro/commands.py:23,285,483,511,514]
    • packages/specfact-codebase/src/specfact_codebase/validators/sidecar/specmatic_runner.py — calls detect_env_manager(...) and build_tool_command(...) (lines ~15,74). [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/sidecar/specmatic_runner.py:15,74]
    • packages/specfact-codebase/src/specfact_codebase/validators/sidecar/crosshair_runner.py — calls detect_env_manager(...) and build_tool_command(...) (lines ~16,74). [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/sidecar/crosshair_runner.py:16,74]
    • packages/specfact-codebase/src/specfact_codebase/validators/sidecar/orchestrator.py — calls detect_env_manager(...) (line ~399). [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/sidecar/orchestrator.py:19,399]
    • packages/specfact-codebase/src/specfact_codebase/validators/sidecar/dependency_installer.py — calls detect_env_manager(...) (lines ~16,97). [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/sidecar/dependency_installer.py:16,97]

Relevance / impact summary:

  • These consumers build runtime tool invocation commands from EnvManager detection results. Changes in detect_env_manager semantics (new AUTO, PATH-fallback behavior, command_prefix shapes like ["uv","run"], availability/message fields) or in build_tool_command behavior may change how those modules construct/execute tool commands and how they interpret env_info. Reviewers should verify callers handle:
    • EnvManager.AUTO/UNKNOWN return variants,
    • PATH-only uv/pip selection rules,
    • possible changes to EnvManagerInfo.command_prefix and available/message fields.
🔇 Additional comments (10)
tests/unit/specfact_cli/registry/test_module_packages.py (6)

39-47: LGTM: Fixture now correctly isolates module state between tests.

The autouse fixture properly clears _ACTIVE_MODULE_SRC_DIRS and clear_module_load_failures() both before yield and after each test. This addresses the past review comment about cross-test leakage and ensures test independence per coding guidelines.


156-192: Good coverage for lazy-loader failure diagnostics lifecycle.

These tests validate the core PR fix: failure reasons are recorded and retrievable via get_module_load_failure_reason, and successful loads clear stale diagnostics. This directly supports the PR objective of surfacing installed-but-unloadable modules with meaningful reasons rather than misreporting them as "not installed".


195-209: Test validates installed vs source-checkout src root tracking.

This test directly verifies the PR's fix for loading active installed module src/ roots: source checkouts are excluded while installed modules under .specfact/modules/ are correctly tracked. Good coverage for the root cause fix.


232-243: Test validates stale sys.path cleanup during re-registration.

The test correctly verifies that stale module src paths are removed from sys.path during re-registration. The hardcoded /tmp/... path works because the test only checks string membership, not filesystem access. For cross-platform robustness, consider using tmp_path fixture, but this is a minor consideration—the test logic is sound.


260-327: Comprehensive test for installed dependency module src roots resolution.

This test validates that installed command loading resolves imports from enabled installed module dependencies—directly exercising the PR's fix for loading dependency module src/ roots before lazy command app loading. The use of monkeypatch.delitem(sys.modules, ...) at line 309 correctly follows the pytest-friendly approach flagged in past review.


330-371: Key test validating availability diagnostics for installed-but-unloadable modules.

This test exercises the full diagnostic flow: an installed module with a missing dependency fails lazy load, and classify_module_availability correctly returns SKIPPED status with the missing dependency in the reason. This directly validates the PR's fix for surfacing meaningful availability diagnostics instead of misreporting installed modules as absent.

tests/integration/scripts/test_runtime_discovery_smoke.py (4)

15-31: Good defensive resolution with graceful skip on missing modules repo.

The _resolve_modules_repo function correctly validates that required package manifests exist before returning a candidate path, preventing false positives when a partial checkout exists. The fallback chain (env var → two repo-relative paths) provides flexibility for different CI and local development layouts.


34-59: Solid integration test with appropriate timeout handling.

The test correctly skips when the modules repo is unavailable and uses check=False with explicit returncode validation. The dual timeout (pytest marker + subprocess arg) is slightly redundant but provides defense in depth—the subprocess timeout handles hung child processes while the pytest timeout guards against test framework issues.


62-88: Proper cleanup pattern for workspace preservation test.

The try/finally block ensures the captured workspace is cleaned up even if the test fails, and ignore_errors=True handles edge cases gracefully. This follows good test isolation practices.


91-122: Validates demo isolation and single registry build across launchers.

The test correctly verifies that each launcher gets a fresh demo directory while the registry is only built once—important for CI efficiency. The assertion at line 122 that REPO_ROOT/src is in smoke.sys.path validates the smoke script correctly adds the source directory for direct execution mode.


📝 Walkthrough

Walkthrough

Version 0.46.19 restructures environment-manager detection (rootless + PATH fallback), records and surfaces installed-module load failures, adds an --env-manager option to init ide (persisted in IDE export), introduces a multi-launcher runtime-discovery smoke harness with CI step, and adds OpenSpec docs plus expanded tests.

Changes

Runtime Discovery Reliability

Layer / File(s) Summary
Package Versioning
pyproject.toml, setup.py, src/__init__.py, src/specfact_cli/__init__.py, src/specfact_cli/modules/*/module-package.yaml, CHANGELOG.md
Version incremented to 0.46.19; module-package manifests updated (versions/checksums) and CHANGELOG entry added.
OpenSpec Documentation
openspec/CHANGE_ORDER.md, openspec/changes/runtime-01-discovery-reliability/...
Proposal, specifications for env-manager detection and installed-runtime discovery, TDD evidence, and task checklist added.
Environment Manager Detection Refactoring
src/specfact_cli/utils/env_manager.py
Added EnvManager.AUTO; detection split into lock/marker helpers, breadth-first monorepo candidate scanning (depth-limited), and PATH fallback (prefers uv, then pip); added explicit-tool selection helper.
Module Package Discovery & Failure Tracking
src/specfact_cli/registry/module_packages.py
Remembers eligible installed-module src/ roots and prepends them to sys.path for lazy loads; adds process-scoped _MODULE_LOAD_FAILURES with get_module_load_failure_reason() and clear_module_load_failures(); workspace traversal stops at system temp dir.
Module Availability Diagnostics
src/specfact_cli/registry/module_availability.py
_skip_reason now prioritizes recorded load-failure diagnostics to enable accurate “installed-but-unavailable” vs “not installed” classification.
CLI Error Handling
src/specfact_cli/cli.py
_RootCLIGroup.resolve_command catches ValueError for known bundle groups, prints missing-bundle guidance, and exits with code 1 instead of propagating.
Init IDE Environment Override
src/specfact_cli/modules/init/src/commands.py
Added --env-manager CLI option (auto default); explicit choices use env_info_from_tool_choice() and error when unavailable; selected env_manager persisted when exporting IDE prompt state.
IDE Export State API
src/specfact_cli/utils/ide_setup.py
write_ide_prompt_export_state() signature extended to accept optional env_manager and persist it to .specfact/ide-prompt-export.yaml.
Workspace Root Safety
src/specfact_cli/modules/module_registry/src/commands.py
Normalization stops when reaching system temp directory to prevent incorrect workspace root detection in CI/temp environments.
Smoke Testing Script
scripts/runtime_discovery_smoke.py
New fail-fast smoke harness that stages a local registry, runs per-launcher installs/init/code checks (direct, pip-editable, uvx), asserts modules are present and no env-manager warning, validates specfact code help, and manages isolated workspaces.
Integration Smoke Test
tests/integration/scripts/test_runtime_discovery_smoke.py
Integration test invoking the smoke script with --launcher direct and validating success markers; skips when modules repo cannot be resolved.
Unit & E2E Tests
tests/unit/utils/test_env_manager.py, tests/unit/specfact_cli/registry/*, tests/e2e/test_init_command.py
Added unit tests for PATH fallback and rootless monorepo detection (up to 2 levels), tests for loader failure recording/clearing and active-src tracking, e2e tests for explicit --env-manager uv and rootless-monorepo behavior, and autouse fixtures to clear module-load failures.
CI Workflow & Changelog
.github/workflows/pr-orchestrator.yml, pyproject.toml, CHANGELOG.md
Added runtime discovery smoke step to Python 3.12 Tests job; added Hatch runtime-discovery-smoke script alias; documented v0.46.19 fixes and smoke coverage.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related issues

Possibly related PRs

Suggested labels

enhancement

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 51.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive Title 'fix runtime module discovery reliability' clearly describes the main bug-fix objective but lacks Conventional Commits prefix (fix:). Prefix title with 'fix: ' to follow Conventional Commits style: 'fix: runtime module discovery reliability'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed Description includes root cause, validation summary, and cross-repo companion notes but lacks completed checklist marks and formal Contract-First Testing Evidence sections required by template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 bugfix/runtime-01-discovery-reliability

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: 8

Caution

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

⚠️ Outside diff range comments (1)
src/specfact_cli/registry/module_packages.py (1)

646-681: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Record every lazy-load failure in _MODULE_LOAD_FAILURES.

Right now only ImportError/ModuleNotFoundError/OSError from exec_module() are cached. A different import-time exception, or the later "no 'app' attribute" path, still degrades back to "not installed" because nothing is recorded. A later successful retry also never clears an older failure reason.

Suggested fix
 def _make_package_loader(package_dir: Path, package_name: str, command_name: str) -> Any:
     """Return a callable that loads the package's app (from src/app.py or src/<name>/__init__.py)."""

     def loader() -> Any:
         _prepend_active_module_src_roots()
         src_dir = package_dir / "src"
         if str(src_dir) not in sys.path:
             sys.path.insert(0, str(src_dir))
-        load_path, submodule_locations = _resolve_command_loader_path(package_dir, package_name, command_name)
-        module_token = _normalized_module_name(package_dir.name)
-        spec = importlib.util.spec_from_file_location(
-            f"_specfact_module_{module_token}",
-            load_path,
-            submodule_search_locations=submodule_locations,
-        )
-        if spec is None or spec.loader is None:
-            raise ValueError(f"Cannot load from {package_dir.name}")
-        mod = importlib.util.module_from_spec(spec)
-        sys.modules[spec.name] = mod
         try:
+            load_path, submodule_locations = _resolve_command_loader_path(package_dir, package_name, command_name)
+            module_token = _normalized_module_name(package_dir.name)
+            spec = importlib.util.spec_from_file_location(
+                f"_specfact_module_{module_token}",
+                load_path,
+                submodule_search_locations=submodule_locations,
+            )
+            if spec is None or spec.loader is None:
+                raise ValueError(f"Cannot load from {package_dir.name}")
+            mod = importlib.util.module_from_spec(spec)
+            sys.modules[spec.name] = mod
             spec.loader.exec_module(mod)
-        except (ImportError, ModuleNotFoundError, OSError) as exc:
+            command_attr = f"{_normalized_module_name(command_name)}_app"
+            app = getattr(mod, command_attr, None) or getattr(mod, "app", None)
+            if app is None:
+                raise ValueError(f"Package {package_dir.name} has no '{command_attr}' or 'app' attribute")
+        except Exception as exc:
             message = (
                 "Runtime compatibility error while loading "
                 f"module '{package_name}' command '{command_name}' from {package_dir}: {exc}. "
                 f"Reinstall the module and run SpecFact with the same Python interpreter ({sys.executable})."
             )
             _record_module_load_failure(package_name, command_name, message)
             raise ValueError(message) from exc
-        command_attr = f"{_normalized_module_name(command_name)}_app"
-        app = getattr(mod, command_attr, None)
-        if app is None:
-            app = getattr(mod, "app", None)
-        if app is None:
-            raise ValueError(f"Package {package_dir.name} has no '{command_attr}' or 'app' attribute")
+        _MODULE_LOAD_FAILURES.pop((package_name, command_name), None)
+        _MODULE_LOAD_FAILURES.pop((package_name, "*"), None)
         return app

     return loader

As per coding guidelines, "Missing-command diagnostics must distinguish absent vs installed-but-unavailable: if a known module command group can’t be imported during lazy loading due to runtime dependency/module import issues, report “installed but unavailable” and include the captured failing load reason when possible; do not collapse all failures into “module not installed.”"

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/specfact_cli/registry/module_packages.py` around lines 646 - 681, The
loader currently only records import-time failures in
_record_module_load_failure when exec_module raises
ImportError/ModuleNotFoundError/OSError, but other exceptions during exec_module
or the subsequent "no app attribute" path are not cached (and successful loads
never clear old failures); update _make_package_loader's inner loader to catch
Exception (or at least broad Exception around spec.loader.exec_module) and call
_record_module_load_failure(package_name, command_name, message) for any
exec_module failure, also record a failure when the final app lookup fails (the
branch that raises ValueError "has no '{command_attr}' or 'app' attribute"), and
ensure that on successful load you clear any existing entry in
_MODULE_LOAD_FAILURES for that package/command so stale failures don't persist;
reference loader(), spec.loader.exec_module, command_attr,
_record_module_load_failure, and _MODULE_LOAD_FAILURES to locate changes.
🧹 Nitpick comments (1)
tests/e2e/test_init_command.py (1)

538-585: ⚡ Quick win

Strengthen the UV-path assertions to prove manager selection, not only warning suppression.

These tests currently pass if the warning is hidden, even if the implementation silently falls back to a different manager. Add one assertion that verifies uv-specific metadata/command wiring (for example, an emitted uv run setup hint or equivalent exported artifact content).

As per coding guidelines, "tests//*.py: Contract-first testing: meaningful scenarios, not redundant assertions already covered by contracts. Flag ... missing coverage for changed behavior." and "openspec//*.md: Treat as specification source of truth ... and scenario coverage."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/e2e/test_init_command.py` around lines 538 - 585, Both tests only
assert the absence of the generic "No Compatible Environment Manager Detected"
warning; update each test (test_init_no_warning_with_explicit_uv_env_manager and
test_init_no_warning_with_rootless_monorepo_uv) to also assert that the CLI
actually selected/configured the "uv" manager by checking for a uv-specific
artifact in the command output or created files (for example assert "uv run" or
"uv:" or an exported env-manager=uv hint appears in result.stdout or in any
generated config file); locate the runner.invoke(app, ...) call and add one
assertion after the existing exit_code and warning checks that validates the
presence of a uv-specific message or file content to prove manager selection
rather than mere warning suppression.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CHANGELOG.md`:
- Around line 15-23: The CHANGELOG entry currently lists everything under
"Fixed" but misses documenting the new CLI surface; add a new "Added" or
"Changed" subsection above or alongside the existing "Fixed" notes that
explicitly documents the new specfact CLI option and behavior by naming the
command and flag (specfact init ide --env-manager <auto|uv|hatch|poetry|pip>),
briefly describing it as a user-facing change (explicit environment manager
selection), and ensuring it follows the project's changelog format and placement
conventions.

In `@scripts/runtime_discovery_smoke.py`:
- Around line 298-304: The code drops the TemporaryDirectory reference when
args.keep_workspace is true which lets the finalizer delete the dir; instead,
when args.keep_workspace is true create the workspace with tempfile.mkdtemp()
(or create a TemporaryDirectory but call .name and avoid dropping the object)
and manage explicit cleanup: keep workspace_obj as None and do not call cleanup
in finally for kept dirs, or set workspace_obj to a structure that records the
path and only call shutil.rmtree(path) in the finally when not keeping; update
the code paths that currently assign workspace_obj = None to use
tempfile.mkdtemp()/shutil.rmtree and ensure cleanup() is only invoked for real
TemporaryDirectory instances (referencing workspace_obj, args.keep_workspace,
tempfile.mkdtemp, TemporaryDirectory, shutil.rmtree, and workspace_obj.cleanup),
and add a test that verifies --keep-workspace preserves the directory.
- Around line 107-113: The code is indexing REPO_ROOT.parents[2] directly which
can raise IndexError on shallow checkouts; update the logic around the
candidates.extend call to first check that REPO_ROOT has at least 3 parent
segments (e.g., len(REPO_ROOT.parents) > 2) or catch IndexError before
referencing parents[2], and only append the REPO_ROOT.parents[2] path when that
check passes; adjust the block around candidates.extend / REPO_ROOT usage so
that probing for specfact-cli-modules skips unavailable parent paths instead of
crashing.
- Around line 176-181: The venv creation uses system_site_packages=True
(venv.EnvBuilder(with_pip=True, system_site_packages=True)) and the virtualenv
fallback invokes "--system-site-packages", which allows host packages to leak
into the test venv and mask missing deps; change both to create isolated
environments by removing system_site_packages=True from the venv.EnvBuilder call
and by removing the "--system-site-packages" flag from the _run([virtualenv,
...]) invocation (keep with_pip=True and the same venv_dir, REPO_ROOT, env and
timeout behavior), referencing venv.EnvBuilder, virtualenv variable, _run and
venv_dir to locate the edits.

In `@src/specfact_cli/cli.py`:
- Around line 181-185: The except handler for ValueError currently swallows the
original exception (using except ValueError: and raise SystemExit(1) from None);
change it to capture the original exception (except ValueError as e:) and
re-raise the SystemExit with that exception as its cause (raise SystemExit(1)
from e) when invoked is in KNOWN_BUNDLE_GROUP_OR_SHIM_NAMES, so that
_print_missing_bundle_command_help(invoked) still runs but the original
ValueError context is preserved for diagnostics.

In `@src/specfact_cli/registry/module_availability.py`:
- Around line 108-110: The docstring for classify_module_availability is stale
because _skip_reason now consults the process-scoped mutable registry returned
by get_module_load_failure_reason (backed by _MODULE_LOAD_FAILURES), so update
classify_module_availability's docstring to state that availability decisions
may depend on process-scoped module load failure state (via
get_module_load_failure_reason/_MODULE_LOAD_FAILURES) and are not purely
manifest/modules.json-driven; additionally, add or update test fixtures in
test_module_packages.py (or the test suite) to explicitly clear or reset the
_MODULE_LOAD_FAILURES registry between tests (e.g., via the public helper used
by get_module_load_failure_reason or a dedicated clear function) so tests that
expect AVAILABLE are not affected by prior SKIPPED state.

In `@src/specfact_cli/registry/module_packages.py`:
- Around line 607-615: Change _remember_active_module_src to only record src/
roots for actually installed packages and prepend them into
_ACTIVE_MODULE_SRC_DIRS: detect installation by checking package_dir for an
accompanying *.dist-info or *.egg-info directory or by verifying package_dir is
located under the interpreter's site-packages/purelib paths (use
sysconfig/site.getsitepackages or sysconfig.get_paths()), skip otherwise, then
compute resolved = src_dir.resolve() and insert it at the front (e.g.,
_ACTIVE_MODULE_SRC_DIRS.insert(0, resolved)) only if not already present.

---

Outside diff comments:
In `@src/specfact_cli/registry/module_packages.py`:
- Around line 646-681: The loader currently only records import-time failures in
_record_module_load_failure when exec_module raises
ImportError/ModuleNotFoundError/OSError, but other exceptions during exec_module
or the subsequent "no app attribute" path are not cached (and successful loads
never clear old failures); update _make_package_loader's inner loader to catch
Exception (or at least broad Exception around spec.loader.exec_module) and call
_record_module_load_failure(package_name, command_name, message) for any
exec_module failure, also record a failure when the final app lookup fails (the
branch that raises ValueError "has no '{command_attr}' or 'app' attribute"), and
ensure that on successful load you clear any existing entry in
_MODULE_LOAD_FAILURES for that package/command so stale failures don't persist;
reference loader(), spec.loader.exec_module, command_attr,
_record_module_load_failure, and _MODULE_LOAD_FAILURES to locate changes.

---

Nitpick comments:
In `@tests/e2e/test_init_command.py`:
- Around line 538-585: Both tests only assert the absence of the generic "No
Compatible Environment Manager Detected" warning; update each test
(test_init_no_warning_with_explicit_uv_env_manager and
test_init_no_warning_with_rootless_monorepo_uv) to also assert that the CLI
actually selected/configured the "uv" manager by checking for a uv-specific
artifact in the command output or created files (for example assert "uv run" or
"uv:" or an exported env-manager=uv hint appears in result.stdout or in any
generated config file); locate the runner.invoke(app, ...) call and add one
assertion after the existing exit_code and warning checks that validates the
presence of a uv-specific message or file content to prove manager selection
rather than mere warning suppression.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5dfc6cf7-db69-4e60-b4df-a7578edf8889

📥 Commits

Reviewing files that changed from the base of the PR and between a7a5336 and 86feb9c.

📒 Files selected for processing (28)
  • .github/workflows/pr-orchestrator.yml
  • CHANGELOG.md
  • openspec/CHANGE_ORDER.md
  • openspec/changes/runtime-01-discovery-reliability/.openspec.yaml
  • openspec/changes/runtime-01-discovery-reliability/TDD_EVIDENCE.md
  • openspec/changes/runtime-01-discovery-reliability/proposal.md
  • openspec/changes/runtime-01-discovery-reliability/specs/environment-manager-detection/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/installed-runtime-module-discovery/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/module-installation/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/module-owned-ide-prompts/spec.md
  • openspec/changes/runtime-01-discovery-reliability/tasks.md
  • pyproject.toml
  • scripts/runtime_discovery_smoke.py
  • setup.py
  • src/__init__.py
  • src/specfact_cli/__init__.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_packages.py
  • src/specfact_cli/utils/env_manager.py
  • tests/e2e/test_init_command.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
  • tests/unit/utils/test_env_manager.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Tests (Python 3.12)
🧰 Additional context used
📓 Path-based instructions (23)
**/*.py

📄 CodeRabbit inference engine (.cursor/rules/python-github-rules.mdc)

**/*.py: Maintain minimum 80% test coverage, with 100% coverage for critical paths in Python code
Use clear naming and self-documenting code, preferring clear names over comments
Ensure each function/class has a single clear purpose (Single Responsibility Principle)
Extract common patterns to avoid code duplication (DRY principle)
Apply SOLID object-oriented design principles in Python code
Use type hints everywhere in Python code and enable basedpyright strict mode
Use Pydantic models for data validation and serialization in Python
Use async/await for I/O operations in Python code
Use context managers for resource management in Python
Use dataclasses for simple data containers in Python
Enforce maximum line length of 120 characters in Python code
Use 4 spaces for indentation in Python code (no tabs)
Use 2 blank lines between classes and 1 blank line between methods in Python
Organize imports in order: Standard library → Third party → Local in Python files
Use snake_case for variables and functions in Python
Use PascalCase for class names in Python
Use UPPER_SNAKE_CASE for constants in Python
Use leading underscore (_) for private methods in Python classes
Use snake_case for Python file names
Enable basedpyright strict mode with strict type checking configuration in Python
Use Google-style docstrings for functions and classes in Python
Include comprehensive exception handling with specific exception types in Python code
Use logging with structured context (extra parameters) instead of print statements
Use retry logic with tenacity decorators (@retry) for operations that might fail
Use Pydantic BaseSettings for environment-based configuration in Python
Validate user input using Pydantic validators in Python models
Use @lru_cache and Redis-based caching for expensive calculations in Python
Run code formatting with Black (120 character line length) and isort in Python
Run type checking with basedpyright on all Python files
Run linting with ruff and pylint on all Pyth...

Files:

  • src/__init__.py
  • src/specfact_cli/cli.py
  • src/specfact_cli/registry/module_availability.py
  • src/specfact_cli/modules/module_registry/src/commands.py
  • src/specfact_cli/modules/init/src/commands.py
  • tests/unit/utils/test_env_manager.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • src/specfact_cli/__init__.py
  • setup.py
  • src/specfact_cli/registry/module_packages.py
  • tests/e2e/test_init_command.py
  • src/specfact_cli/utils/env_manager.py
  • scripts/runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
{src/__init__.py,pyproject.toml,setup.py}

📄 CodeRabbit inference engine (.cursor/rules/python-github-rules.mdc)

{src/__init__.py,pyproject.toml,setup.py}: Update src/init.py first as primary source of truth for package version, then pyproject.toml and setup.py
Maintain version synchronization across src/init.py, pyproject.toml, and setup.py

Files:

  • src/__init__.py
  • pyproject.toml
  • setup.py
src/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/spec-fact-cli-rules.mdc)

src/**/*.py: All code changes must be followed by running the full test suite using the smart test system.
All Python files in src/ and tools/ directories must have corresponding test files in tests/ directory. If you modify src/common/logger_setup.py, you MUST have tests/unit/common/test_logger_setup.py. NO EXCEPTIONS - even small changes require tests.
All new Python runtime code files must have corresponding test files created BEFORE committing the code. NO EXCEPTIONS - no code without tests.
Test Coverage Validation: Run hatch run smart-test-unit for modified files, hatch run smart-test-folder for modified directories, and hatch run smart-test-full before committing. ALL TESTS MUST PASS.
All components must support TEST_MODE=true environment variable with test-specific behavior defined as: if os.environ.get('TEST_MODE') == 'true': # test-specific behavior
Use src/common/logger_setup.py for all logging via: from common.logger_setup import get_logger; logger = get_logger(name)
Use src/common/redis_client.py with fallback for Redis operations via: from common.redis_client import get_redis_client; redis_client = get_redis_client()
Type checking must pass with no errors using: mypy .
Test coverage must meet or exceed 80% total coverage. New code must have corresponding tests. Modified code must maintain or improve coverage. Critical paths must have 100% coverage.
Use Pydantic v2 validation for all context and data schemas.

Add/update contracts on new or modified public APIs, stateful classes and adapters using icontract decorators and beartype runtime type checks

src/**/*.py: Meaningful Naming — identifiers reveal intent; avoid abbreviations. Identifiers in src/ must use snake_case (modules/functions), PascalCase (classes), UPPER_SNAKE_CASE (constants). Avoid single-letter names outside short loop variables.
KISS — keep functions and modules small and single-purpose. Maximum function length: 120 lines (Phase A error threshold). Maximum cyclomati...

Files:

  • src/__init__.py
  • src/specfact_cli/cli.py
  • src/specfact_cli/registry/module_availability.py
  • src/specfact_cli/modules/module_registry/src/commands.py
  • src/specfact_cli/modules/init/src/commands.py
  • src/specfact_cli/__init__.py
  • src/specfact_cli/registry/module_packages.py
  • src/specfact_cli/utils/env_manager.py
@(src|tests)/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/spec-fact-cli-rules.mdc)

Linting must pass with no errors using: pylint src tests

Files:

  • src/__init__.py
  • src/specfact_cli/cli.py
  • src/specfact_cli/registry/module_availability.py
  • src/specfact_cli/modules/module_registry/src/commands.py
  • src/specfact_cli/modules/init/src/commands.py
  • tests/unit/utils/test_env_manager.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • src/specfact_cli/__init__.py
  • src/specfact_cli/registry/module_packages.py
  • tests/e2e/test_init_command.py
  • src/specfact_cli/utils/env_manager.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
{pyproject.toml,setup.py,src/__init__.py}

📄 CodeRabbit inference engine (.cursor/rules/testing-and-build-guide.mdc)

Manually update version numbers in pyproject.toml, setup.py, and src/init.py when making a formal version change

Files:

  • src/__init__.py
  • pyproject.toml
  • setup.py
**/*.{py,pyi}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{py,pyi}: After any code changes, follow these steps in order: (1) Apply linting and formatting to ensure code quality: hatch run format, (2) Type checking: hatch run type-check (basedpyright), (3) Contract-first approach: Run hatch run contract-test for contract validation, (4) Run full test suite: hatch test --cover -v, (5) Verify all tests pass and contracts are satisfied, (6) Fix any issues and repeat steps until all tests pass
All public APIs must have @icontract decorators and @beartype type checking
Use Pydantic models for all data structures with data validation
Only write high-value comments if at all. Avoid talking to the user through comments

Files:

  • src/__init__.py
  • src/specfact_cli/cli.py
  • src/specfact_cli/registry/module_availability.py
  • src/specfact_cli/modules/module_registry/src/commands.py
  • src/specfact_cli/modules/init/src/commands.py
  • tests/unit/utils/test_env_manager.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • src/specfact_cli/__init__.py
  • setup.py
  • src/specfact_cli/registry/module_packages.py
  • tests/e2e/test_init_command.py
  • src/specfact_cli/utils/env_manager.py
  • scripts/runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
**/*cli*.{py,pyi}

📄 CodeRabbit inference engine (.cursorrules)

Commands should follow typer patterns with rich console output

Files:

  • src/specfact_cli/cli.py
src/specfact_cli/**/*.py

⚙️ CodeRabbit configuration file

src/specfact_cli/**/*.py: Focus on modular CLI architecture: lazy module loading, registry/bootstrap patterns, and
dependency direction. Flag breaking changes to public APIs, Pydantic models, and resource
bundling. Verify @icontract + @beartype on public surfaces; prefer centralized logging
(get_bridge_logger) over print().

Files:

  • src/specfact_cli/cli.py
  • src/specfact_cli/registry/module_availability.py
  • src/specfact_cli/modules/module_registry/src/commands.py
  • src/specfact_cli/modules/init/src/commands.py
  • src/specfact_cli/__init__.py
  • src/specfact_cli/registry/module_packages.py
  • src/specfact_cli/utils/env_manager.py
**/*.{md,mdc}

📄 CodeRabbit inference engine (.cursor/rules/markdown-rules.mdc)

**/*.{md,mdc}: Do not use more than one consecutive blank line anywhere in the document (MD012: No Multiple Consecutive Blank Lines)
Fenced code blocks should be surrounded by blank lines (MD031: Fenced Code Blocks)
Lists should be surrounded by blank lines (MD032: Lists)
Files must end with a single empty line (MD047: Files Must End With Single Newline)
Lines should not have trailing spaces (MD009: No Trailing Spaces)
Use asterisks (**) for strong emphasis, not underscores (__) (MD050: Strong Style)
Fenced code blocks must have a language specified (MD040: Fenced Code Language)
Headers should increment by one level at a time (MD001: Header Increment)
Headers should be surrounded by blank lines (MD022: Headers Should Be Surrounded By Blank Lines)
Only one top-level header (H1) is allowed per document (MD025: Single H1 Header)
Use consistent list markers, preferring dashes (-) for unordered lists (MD004: List Style)
Nested unordered list items should be indented consistently, typically by 2 spaces (MD007: Unordered List Indentation)
Use exactly one space after the list marker (e.g., -, *, +, 1.) (MD030: Spaces After List Markers)
Use incrementing numbers for ordered lists (MD029: Ordered List Item Prefix)
Enclose bare URLs in angle brackets or format them as links (MD034: Bare URLs)
Don't use spaces immediately inside code spans (MD038: Spaces Inside Code Spans)
Use consistent indentation (usually 2 or 4 spaces) throughout markdown files
Keep line length under 120 characters in markdown files
Use reference-style links for better readability in markdown files
Use a trailing slash for directory paths in markdown files
Ensure proper escaping of special characters in markdown files

Files:

  • openspec/CHANGE_ORDER.md
  • openspec/changes/runtime-01-discovery-reliability/specs/module-owned-ide-prompts/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/module-installation/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/environment-manager-detection/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/installed-runtime-module-discovery/spec.md
  • CHANGELOG.md
  • openspec/changes/runtime-01-discovery-reliability/proposal.md
  • openspec/changes/runtime-01-discovery-reliability/tasks.md
  • openspec/changes/runtime-01-discovery-reliability/TDD_EVIDENCE.md
**/*.md

📄 CodeRabbit inference engine (.cursorrules)

Avoid markdown linting errors (refer to markdown-rules)

Files:

  • openspec/CHANGE_ORDER.md
  • openspec/changes/runtime-01-discovery-reliability/specs/module-owned-ide-prompts/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/module-installation/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/environment-manager-detection/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/installed-runtime-module-discovery/spec.md
  • CHANGELOG.md
  • openspec/changes/runtime-01-discovery-reliability/proposal.md
  • openspec/changes/runtime-01-discovery-reliability/tasks.md
  • openspec/changes/runtime-01-discovery-reliability/TDD_EVIDENCE.md
openspec/**/*.md

⚙️ CodeRabbit configuration file

openspec/**/*.md: Treat as specification source of truth: proposal/tasks/spec deltas vs. code behavior,
CHANGE_ORDER consistency, and scenario coverage. Surface drift between OpenSpec and
implementation.

Files:

  • openspec/CHANGE_ORDER.md
  • openspec/changes/runtime-01-discovery-reliability/specs/module-owned-ide-prompts/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/module-installation/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/environment-manager-detection/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/installed-runtime-module-discovery/spec.md
  • openspec/changes/runtime-01-discovery-reliability/proposal.md
  • openspec/changes/runtime-01-discovery-reliability/tasks.md
  • openspec/changes/runtime-01-discovery-reliability/TDD_EVIDENCE.md
openspec/changes/**/*.md

📄 CodeRabbit inference engine (.cursorrules)

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/)

Files:

  • openspec/changes/runtime-01-discovery-reliability/specs/module-owned-ide-prompts/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/module-installation/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/environment-manager-detection/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/installed-runtime-module-discovery/spec.md
  • openspec/changes/runtime-01-discovery-reliability/proposal.md
  • openspec/changes/runtime-01-discovery-reliability/tasks.md
  • openspec/changes/runtime-01-discovery-reliability/TDD_EVIDENCE.md
openspec/**/{proposal.md,tasks.md,design.md,spec.md}

📄 CodeRabbit inference engine (.cursor/rules/automatic-openspec-workflow.mdc)

openspec/**/{proposal.md,tasks.md,design.md,spec.md}: Apply openspec/config.yaml project context and per-artifact rules (for proposal, specs, design, tasks) when creating or updating any OpenSpec change artifact in the specfact-cli codebase
After implementation, validate the change with openspec validate <change-id> --strict; fix validation errors in proposal, specs, design, or tasks and re-validate until passing before considering the change complete

Files:

  • openspec/changes/runtime-01-discovery-reliability/specs/module-owned-ide-prompts/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/module-installation/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/environment-manager-detection/spec.md
  • openspec/changes/runtime-01-discovery-reliability/specs/installed-runtime-module-discovery/spec.md
  • openspec/changes/runtime-01-discovery-reliability/proposal.md
  • openspec/changes/runtime-01-discovery-reliability/tasks.md
**/*.yaml

📄 CodeRabbit inference engine (.cursor/rules/spec-fact-cli-rules.mdc)

YAML files must pass linting using: hatch run yaml-lint with relaxed policy.

Files:

  • src/specfact_cli/modules/module_registry/module-package.yaml
  • src/specfact_cli/modules/init/module-package.yaml
**/*.{yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/testing-and-build-guide.mdc)

Validate YAML configuration files locally using hatch run yaml-lint before committing

**/*.{yml,yaml}: Format all YAML and workflow files using hatch run yaml-fix-all before committing
Use Prettier to fix whitespace, indentation, and final newline across YAML files
Use yamllint with the repo .yamllint configuration (line-length 140, trailing spaces and final newline enforced) to lint non-workflow YAML files

Files:

  • src/specfact_cli/modules/module_registry/module-package.yaml
  • src/specfact_cli/modules/init/module-package.yaml
pyproject.toml

📄 CodeRabbit inference engine (.cursorrules)

When updating the version in pyproject.toml, ensure it's newer than the latest PyPI version. The CI/CD pipeline will automatically publish to PyPI only if the new version is greater than the published version

Files:

  • pyproject.toml
CHANGELOG.md

📄 CodeRabbit inference engine (.cursor/rules/python-github-rules.mdc)

Include new version entries at the top of CHANGELOG.md when updating versions

Update CHANGELOG.md with all code changes as part of version control requirements.

Update CHANGELOG.md to document all significant changes under Added, Fixed, Changed, or Removed sections when making a version change

Files:

  • CHANGELOG.md
**/test_*.py

📄 CodeRabbit inference engine (.cursor/rules/python-github-rules.mdc)

**/test_*.py: Write tests first in test-driven development (TDD) using the Red-Green-Refactor cycle
Ensure each test is independent and repeatable with no shared state between tests
Organize Python imports in tests using unittest.mock for Mock and patch
Use setup_method() for test initialization and Arrange-Act-Assert pattern in test files
Use @pytest.mark.asyncio decorator for async test functions in Python
Organize test files in structure: tests/unit/, tests/integration/, tests/e2e/ by module

Files:

  • tests/unit/utils/test_env_manager.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/e2e/test_init_command.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
tests/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/spec-fact-cli-rules.mdc)

Tests must be meaningful and test actual functionality, cover both success and failure cases, be independent and repeatable, and have clear, descriptive names. NO EXCEPTIONS - no placeholder or empty tests.

tests/**/*.py: Trim low-value unit tests when a contract covers the same assertion (type/shape/raises on negative checks)
Delete tests that only assert input validation, datatype/shape enforcement, or raises on negative conditions now guarded by contracts and runtime typing
Convert repeated edge-case permutations into one Hypothesis property with contracts acting as oracles

Secret redaction via LoggerSetup.redact_secrets must be covered by unit tests

Files:

  • tests/unit/utils/test_env_manager.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/e2e/test_init_command.py
  • tests/unit/specfact_cli/registry/test_module_packages.py

⚙️ CodeRabbit configuration file

tests/**/*.py: Contract-first testing: meaningful scenarios, not redundant assertions already covered by
contracts. Flag flakiness, environment coupling, and missing coverage for changed behavior.

Files:

  • tests/unit/utils/test_env_manager.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/e2e/test_init_command.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
.github/workflows/*.{yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/testing-and-build-guide.mdc)

Validate GitHub workflow files using hatch run lint-workflows before committing

.github/workflows/*.{yml,yaml}: Use actionlint for semantic validation of GitHub Actions workflows
Format GitHub Actions workflows using hatch run workflows-fmt and lint them with hatch run workflows-lint after editing

Files:

  • .github/workflows/pr-orchestrator.yml
.github/workflows/!(tests).{yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/testing-and-build-guide.mdc)

Do not re-run the full test suite in other CI workflows; tests are enforced only in the dedicated Tests workflow (.github/workflows/tests.yml)

Files:

  • .github/workflows/pr-orchestrator.yml
.github/workflows/**

⚙️ CodeRabbit configuration file

.github/workflows/**: CI safety: secrets usage, workflow dependencies, alignment with hatch test / contract-test
gates, and action versions.

Files:

  • .github/workflows/pr-orchestrator.yml
scripts/**/*.py

⚙️ CodeRabbit configuration file

scripts/**/*.py: Deterministic tooling: subprocess safety, Hatch integration, and parity with documented
quality gates (format, type-check, module signing).

Files:

  • scripts/runtime_discovery_smoke.py
🪛 LanguageTool
openspec/changes/runtime-01-discovery-reliability/tasks.md

[grammar] ~11-~11: Use a hyphen to join words.
Context: ...rst tests - [x] 2.1 Add tests for clean installed module runtime loading with te...

(QB_NEW_EN_HYPHEN)


[grammar] ~11-~11: Use a hyphen to join words.
Context: ...stalled module runtime loading with temp installed specfact-project and `specfa...

(QB_NEW_EN_HYPHEN)

openspec/changes/runtime-01-discovery-reliability/TDD_EVIDENCE.md

[grammar] ~31-~31: Use a hyphen to join words.
Context: ...CI across Hatch/current-interpreter, pip editable, and uvx launch paths. - `hatch...

(QB_NEW_EN_HYPHEN)

🔀 Multi-repo context nold-ai/specfact-cli-modules

Findings (consumers of changed APIs)

  • packages/specfact-spec/src/specfact_spec/generate/commands.py — calls detect_env_manager(repo_path) and imports detect_env_manager. [::nold-ai/specfact-cli-modules::packages/specfact-spec/src/specfact_spec/generate/commands.py]

  • packages/specfact-codebase/src/specfact_codebase/validators/sidecar/specmatic_runner.py — imports build_tool_command, detect_env_manager from specfact_cli.utils.env_manager and calls detect_env_manager(repo_path). [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/sidecar/specmatic_runner.py]

  • packages/specfact-codebase/src/specfact_codebase/validators/repro_checker.py — references detect_env_manager. [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/repro_checker.py]

  • packages/specfact-codebase/src/specfact_codebase/validators/sidecar/orchestrator.py — imports and uses detect_env_manager(config.repo_path). [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/sidecar/orchestrator.py]

  • packages/specfact-codebase/src/specfact_codebase/validators/sidecar/dependency_installer.py — imports detect_env_manager and calls it. [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/sidecar/dependency_installer.py]

  • packages/specfact-codebase/src/specfact_codebase/validators/sidecar/crosshair_runner.py — imports build_tool_command, detect_env_manager and uses detect_env_manager(repo_path). [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/sidecar/crosshair_runner.py]

  • packages/specfact-codebase/src/specfact_codebase/repro/commands.py — imports/checks detect_env_manager and detect_source_directories; uses detect_env_manager(repo). [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/repro/commands.py]

Notes:

  • Multiple modules in this repo call detect_env_manager and related helpers — the env_manager API and semantics changed (EnvManager.AUTO added and detection behavior reworked). These consumers may be affected and should be reviewed to ensure behavior remains compatible (e.g., handling of returned EnvManager enum, tuple/structure shape, fields like available/command_prefix/message).
🔇 Additional comments (2)
src/specfact_cli/registry/module_availability.py (1)

108-108: No issue. The function signature at src/specfact_cli/registry/module_packages.py:637 confirms get_module_load_failure_reason(package_name: str, command_name: str | None = None) accepts the two-positional-argument call pattern—the second parameter defaults to None when omitted or explicitly passed. The code is correct.

			> Likely an incorrect or invalid review comment.
pyproject.toml (1)

7-7: Version bump is properly synchronized and publishable.

All three files are correctly updated to 0.46.19 (pyproject.toml, src/init.py, setup.py), and the version is ahead of the current PyPI release (0.46.18). The version bump meets coding guidelines for synchronization and PyPI advancement.

Comment thread CHANGELOG.md
Comment thread scripts/runtime_discovery_smoke.py
Comment thread scripts/runtime_discovery_smoke.py Outdated
Comment thread scripts/runtime_discovery_smoke.py
Comment thread src/specfact_cli/cli.py Outdated
Comment thread src/specfact_cli/modules/init/src/commands.py
Comment thread src/specfact_cli/registry/module_availability.py
Comment thread src/specfact_cli/registry/module_packages.py
@djm81 djm81 marked this pull request as draft May 7, 2026 21:47
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 86feb9c2dd

ℹ️ 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".

Comment thread src/specfact_cli/utils/env_manager.py Outdated
@djm81 djm81 marked this pull request as ready for review May 7, 2026 21:49
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 86feb9c2dd

ℹ️ 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".

Comment thread src/specfact_cli/modules/init/src/commands.py
@djm81
Copy link
Copy Markdown
Collaborator Author

djm81 commented May 7, 2026

Review follow-up pushed in cb567fd.

Validated PR review fixes:

  • upgraded installed nold-ai/specfact-code-review from 0.47.14 to 0.47.15 after the module patch merged to main; reran hatch run specfact code review run --scope changed, Semgrep runtime-dir crash is gone, result PASS_WITH_ADVISORY / exit 0.
  • hatch run pytest tests/unit/specfact_cli/registry/test_module_packages.py tests/unit/specfact_cli/registry/test_module_availability.py tests/unit/utils/test_env_manager.py tests/unit/utils/test_ide_setup.py tests/e2e/test_init_command.py tests/integration/scripts/test_runtime_discovery_smoke.py -q -> 137 passed.
  • hatch run lint -> clean.
  • hatch run type-check -> 0 errors, existing warnings only.
  • openspec validate runtime-01-discovery-reliability --strict -> valid.

Notes:

  • Confirmed the earlier Semgrep failure reproduced stale installed module behavior: user/runtime module was still specfact-code-review 0.47.14 and did not create Semgrep .config / .cache; 0.47.15 does.
  • Remaining code-review findings are advisory pre-existing clean-code/naming debt in touched surfaces, not blocking regressions.

@djm81
Copy link
Copy Markdown
Collaborator Author

djm81 commented May 7, 2026

CI follow-up pushed in 47ebc42.

Root cause of the failed Compatibility (Python 3.11) job was tests/unit/specfact_cli/registry/test_module_packages.py::test_installed_group_loader_adds_enabled_dependency_module_src_roots: the fixture described installed modules but created fake packages directly under tmp_path. The production code now intentionally records dependency src/ roots only for installed module package locations, so Python 3.11 CI correctly failed to import the fake dependency. Updated the fixture to create packages under .specfact/modules, matching the real installed module layout.

Local validation after the fix:

  • hatch run pytest tests/unit/specfact_cli/registry/test_module_packages.py::test_installed_group_loader_adds_enabled_dependency_module_src_roots -q -> passed
  • hatch run pytest tests/unit/specfact_cli/registry/test_module_packages.py tests/unit/specfact_cli/registry/test_module_availability.py -q -> 53 passed
  • hatch run lint -> clean

Note: local pre-commit code-review hook still reproduces stale sibling module behavior because scripts/pre_commit_code_review.py prepends the sibling specfact-cli-modules checkout, which can override the upgraded user-installed specfact-code-review 0.47.15. The pushed CI fixture fix itself is unrelated to that hook issue.

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: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/runtime_discovery_smoke.py`:
- Around line 299-302: The current loop reuses a single demo created by
_create_rootless_monorepo_demo when iterating launchers, causing state leakage
into subsequent runs; instead ensure each launcher gets a fresh demo checkout by
creating or cloning the demo inside the launcher loop (call
_create_rootless_monorepo_demo or fresh-copy the demo for each iteration) before
calling _smoke_launcher(launcher, workspace, demo, index_path, modules_repo);
keep _build_local_registry outside the loop if shared, and ensure any temp/demo
dirs are uniquely named or cleaned between runs (e.g., via tempfile or explicit
teardown) so each _smoke_launcher runs against a pristine rootless-monorepo.
- Around line 123-126: The smoke test is non-deterministic because it doesn't
bootstrap the checkout's src/ tree and it reuses a single demo repo across
launcher runs; modify the test to prepend the repository's src/ directory to
sys.path or set PYTHONPATH before importing/launching (so imports like
specfact_cli.registry.module_installer and launching "python -m
specfact_cli.cli" use the PR code) and change the test harness so
_smoke_launcher (and the loop that calls it) creates a fresh demo repository per
launcher invocation (do not reuse the single demo created at the previous demo
creation site), ensuring each call to _smoke_launcher runs against an isolated
demo state.

In `@src/specfact_cli/registry/module_packages.py`:
- Around line 680-682: The current _clear_module_load_failure function removes
both the specific (package_name, command_name) entry and the package-wide
(package_name, "*") entry every time a single command recovers; update it so it
only removes the specific (package_name, command_name) entry and only removes
(package_name, "*") if there are no remaining (package_name, other_command) keys
in _MODULE_LOAD_FAILURES. Modify _clear_module_load_failure to pop
(package_name, command_name) first, then check _MODULE_LOAD_FAILURES keys for
any other entries whose first element equals package_name and only pop
(package_name, "*") when none remain.
- Around line 1496-1497: When re-registering, also remove any previously
injected module root paths from sys.path so stale workspace/install roots can't
be resolved; before clearing _ACTIVE_MODULE_SRC_DIRS and _MODULE_LOAD_FAILURES,
iterate the entries in _ACTIVE_MODULE_SRC_DIRS and remove any matching entries
from sys.path (taking care to remove duplicates and ignore missing entries),
then clear the sets as currently done; this change should be applied where the
registry reset occurs (the function that calls or contains
_prepend_active_module_src_roots() and currently clears
_ACTIVE_MODULE_SRC_DIRS/_MODULE_LOAD_FAILURES).
- Around line 170-175: The function _has_installed_distribution_metadata
incorrectly compares package_dir.name to metadata directory names because it
only replaces "-" in metadata names and then expects a "-" before the version;
update the normalization logic to treat "-", "_", and "." uniformly (e.g.,
collapse any sequence of [-_.] to "_" for both package_dir.name and path.name)
and then check startswith(f"{normalized}_") or equivalent; modify the body of
_has_installed_distribution_metadata to compute normalized =
re.sub(r"[-_.]+","_", package_dir.name).lower() and meta_normalized =
re.sub(r"[-_.]+","_", path.name).lower() (or use a regex startswith check like
r"^{normalized}[-_.]") when scanning metadata_dirs so editable/dist-info names
match correctly.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cb02eda4-636f-4212-9a43-53370a76b367

📥 Commits

Reviewing files that changed from the base of the PR and between 86feb9c and cb567fd.

📒 Files selected for processing (15)
  • CHANGELOG.md
  • scripts/runtime_discovery_smoke.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/registry/module_availability.py
  • src/specfact_cli/registry/module_packages.py
  • src/specfact_cli/utils/env_manager.py
  • src/specfact_cli/utils/ide_setup.py
  • tests/e2e/test_init_command.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_availability.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
  • tests/unit/utils/test_env_manager.py
  • tests/unit/utils/test_ide_setup.py
✅ Files skipped from review due to trivial changes (2)
  • src/specfact_cli/cli.py
  • tests/e2e/test_init_command.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/specfact_cli/registry/module_availability.py
  • src/specfact_cli/modules/init/src/commands.py
  • CHANGELOG.md
  • tests/unit/utils/test_env_manager.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Contract-First CI
  • GitHub Check: Type Checking (basedpyright)
  • GitHub Check: Linting (ruff, pylint, safe-write guard)
  • GitHub Check: Tests (Python 3.12)
  • GitHub Check: Compatibility (Python 3.11)
  • GitHub Check: Socket Security: Pull Request Alerts
🧰 Additional context used
📓 Path-based instructions (10)
**/test_*.py

📄 CodeRabbit inference engine (.cursor/rules/python-github-rules.mdc)

**/test_*.py: Write tests first in test-driven development (TDD) using the Red-Green-Refactor cycle
Ensure each test is independent and repeatable with no shared state between tests
Organize Python imports in tests using unittest.mock for Mock and patch
Use setup_method() for test initialization and Arrange-Act-Assert pattern in test files
Use @pytest.mark.asyncio decorator for async test functions in Python
Organize test files in structure: tests/unit/, tests/integration/, tests/e2e/ by module

Files:

  • tests/unit/utils/test_ide_setup.py
  • tests/unit/specfact_cli/registry/test_module_availability.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
**/*.py

📄 CodeRabbit inference engine (.cursor/rules/python-github-rules.mdc)

**/*.py: Maintain minimum 80% test coverage, with 100% coverage for critical paths in Python code
Use clear naming and self-documenting code, preferring clear names over comments
Ensure each function/class has a single clear purpose (Single Responsibility Principle)
Extract common patterns to avoid code duplication (DRY principle)
Apply SOLID object-oriented design principles in Python code
Use type hints everywhere in Python code and enable basedpyright strict mode
Use Pydantic models for data validation and serialization in Python
Use async/await for I/O operations in Python code
Use context managers for resource management in Python
Use dataclasses for simple data containers in Python
Enforce maximum line length of 120 characters in Python code
Use 4 spaces for indentation in Python code (no tabs)
Use 2 blank lines between classes and 1 blank line between methods in Python
Organize imports in order: Standard library → Third party → Local in Python files
Use snake_case for variables and functions in Python
Use PascalCase for class names in Python
Use UPPER_SNAKE_CASE for constants in Python
Use leading underscore (_) for private methods in Python classes
Use snake_case for Python file names
Enable basedpyright strict mode with strict type checking configuration in Python
Use Google-style docstrings for functions and classes in Python
Include comprehensive exception handling with specific exception types in Python code
Use logging with structured context (extra parameters) instead of print statements
Use retry logic with tenacity decorators (@retry) for operations that might fail
Use Pydantic BaseSettings for environment-based configuration in Python
Validate user input using Pydantic validators in Python models
Use @lru_cache and Redis-based caching for expensive calculations in Python
Run code formatting with Black (120 character line length) and isort in Python
Run type checking with basedpyright on all Python files
Run linting with ruff and pylint on all Pyth...

Files:

  • tests/unit/utils/test_ide_setup.py
  • src/specfact_cli/utils/ide_setup.py
  • tests/unit/specfact_cli/registry/test_module_availability.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • scripts/runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
  • src/specfact_cli/registry/module_packages.py
  • src/specfact_cli/utils/env_manager.py
tests/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/spec-fact-cli-rules.mdc)

Tests must be meaningful and test actual functionality, cover both success and failure cases, be independent and repeatable, and have clear, descriptive names. NO EXCEPTIONS - no placeholder or empty tests.

tests/**/*.py: Trim low-value unit tests when a contract covers the same assertion (type/shape/raises on negative checks)
Delete tests that only assert input validation, datatype/shape enforcement, or raises on negative conditions now guarded by contracts and runtime typing
Convert repeated edge-case permutations into one Hypothesis property with contracts acting as oracles

Secret redaction via LoggerSetup.redact_secrets must be covered by unit tests

Files:

  • tests/unit/utils/test_ide_setup.py
  • tests/unit/specfact_cli/registry/test_module_availability.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py

⚙️ CodeRabbit configuration file

tests/**/*.py: Contract-first testing: meaningful scenarios, not redundant assertions already covered by
contracts. Flag flakiness, environment coupling, and missing coverage for changed behavior.

Files:

  • tests/unit/utils/test_ide_setup.py
  • tests/unit/specfact_cli/registry/test_module_availability.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
@(src|tests)/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/spec-fact-cli-rules.mdc)

Linting must pass with no errors using: pylint src tests

Files:

  • tests/unit/utils/test_ide_setup.py
  • src/specfact_cli/utils/ide_setup.py
  • tests/unit/specfact_cli/registry/test_module_availability.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
  • src/specfact_cli/registry/module_packages.py
  • src/specfact_cli/utils/env_manager.py
**/*.{py,pyi}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{py,pyi}: After any code changes, follow these steps in order: (1) Apply linting and formatting to ensure code quality: hatch run format, (2) Type checking: hatch run type-check (basedpyright), (3) Contract-first approach: Run hatch run contract-test for contract validation, (4) Run full test suite: hatch test --cover -v, (5) Verify all tests pass and contracts are satisfied, (6) Fix any issues and repeat steps until all tests pass
All public APIs must have @icontract decorators and @beartype type checking
Use Pydantic models for all data structures with data validation
Only write high-value comments if at all. Avoid talking to the user through comments

Files:

  • tests/unit/utils/test_ide_setup.py
  • src/specfact_cli/utils/ide_setup.py
  • tests/unit/specfact_cli/registry/test_module_availability.py
  • tests/integration/scripts/test_runtime_discovery_smoke.py
  • scripts/runtime_discovery_smoke.py
  • tests/unit/specfact_cli/registry/test_module_packages.py
  • src/specfact_cli/registry/module_packages.py
  • src/specfact_cli/utils/env_manager.py
**/*.yaml

📄 CodeRabbit inference engine (.cursor/rules/spec-fact-cli-rules.mdc)

YAML files must pass linting using: hatch run yaml-lint with relaxed policy.

Files:

  • src/specfact_cli/modules/init/module-package.yaml
**/*.{yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/testing-and-build-guide.mdc)

Validate YAML configuration files locally using hatch run yaml-lint before committing

**/*.{yml,yaml}: Format all YAML and workflow files using hatch run yaml-fix-all before committing
Use Prettier to fix whitespace, indentation, and final newline across YAML files
Use yamllint with the repo .yamllint configuration (line-length 140, trailing spaces and final newline enforced) to lint non-workflow YAML files

Files:

  • src/specfact_cli/modules/init/module-package.yaml
src/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/spec-fact-cli-rules.mdc)

src/**/*.py: All code changes must be followed by running the full test suite using the smart test system.
All Python files in src/ and tools/ directories must have corresponding test files in tests/ directory. If you modify src/common/logger_setup.py, you MUST have tests/unit/common/test_logger_setup.py. NO EXCEPTIONS - even small changes require tests.
All new Python runtime code files must have corresponding test files created BEFORE committing the code. NO EXCEPTIONS - no code without tests.
Test Coverage Validation: Run hatch run smart-test-unit for modified files, hatch run smart-test-folder for modified directories, and hatch run smart-test-full before committing. ALL TESTS MUST PASS.
All components must support TEST_MODE=true environment variable with test-specific behavior defined as: if os.environ.get('TEST_MODE') == 'true': # test-specific behavior
Use src/common/logger_setup.py for all logging via: from common.logger_setup import get_logger; logger = get_logger(name)
Use src/common/redis_client.py with fallback for Redis operations via: from common.redis_client import get_redis_client; redis_client = get_redis_client()
Type checking must pass with no errors using: mypy .
Test coverage must meet or exceed 80% total coverage. New code must have corresponding tests. Modified code must maintain or improve coverage. Critical paths must have 100% coverage.
Use Pydantic v2 validation for all context and data schemas.

Add/update contracts on new or modified public APIs, stateful classes and adapters using icontract decorators and beartype runtime type checks

src/**/*.py: Meaningful Naming — identifiers reveal intent; avoid abbreviations. Identifiers in src/ must use snake_case (modules/functions), PascalCase (classes), UPPER_SNAKE_CASE (constants). Avoid single-letter names outside short loop variables.
KISS — keep functions and modules small and single-purpose. Maximum function length: 120 lines (Phase A error threshold). Maximum cyclomati...

Files:

  • src/specfact_cli/utils/ide_setup.py
  • src/specfact_cli/registry/module_packages.py
  • src/specfact_cli/utils/env_manager.py
src/specfact_cli/**/*.py

⚙️ CodeRabbit configuration file

src/specfact_cli/**/*.py: Focus on modular CLI architecture: lazy module loading, registry/bootstrap patterns, and
dependency direction. Flag breaking changes to public APIs, Pydantic models, and resource
bundling. Verify @icontract + @beartype on public surfaces; prefer centralized logging
(get_bridge_logger) over print().

Files:

  • src/specfact_cli/utils/ide_setup.py
  • src/specfact_cli/registry/module_packages.py
  • src/specfact_cli/utils/env_manager.py
scripts/**/*.py

⚙️ CodeRabbit configuration file

scripts/**/*.py: Deterministic tooling: subprocess safety, Hatch integration, and parity with documented
quality gates (format, type-check, module signing).

Files:

  • scripts/runtime_discovery_smoke.py
🔀 Multi-repo context nold-ai/specfact-cli-modules

Linked repositories findings

[::nold-ai/specfact-cli-modules::] packages/specfact-codebase/src/specfact_codebase/validators/sidecar/specmatic_runner.py:15,74

  • Calls detect_env_manager(repo_path) and uses build_tool_command; will observe changed EnvManager behavior and new AUTO semantics.

[::nold-ai/specfact-cli-modules::] packages/specfact-codebase/src/specfact_codebase/validators/sidecar/crosshair_runner.py:16,74

  • Calls detect_env_manager and passes result to build_tool_command; ensure consumers handle EnvManager.AUTO and the new command_prefix/message fields.

[::nold-ai/specfact-cli-modules::] packages/specfact-codebase/src/specfact_codebase/validators/sidecar/orchestrator.py:19,399

  • Calls detect_env_manager(config.repo_path) and relies on returned env_info for selecting python/venv commands; verify logic remains compatible with monorepo/path fallback changes.

[::nold-ai/specfact-cli-modules::] packages/specfact-codebase/src/specfact_codebase/validators/sidecar/dependency_installer.py:16,97

  • Calls detect_env_manager(repo_path) before installing dependencies; PATH-only selection (uv/pip) and UNKNOWN handling changes may affect installation flows and displayed messages.

[::nold-ai/specfact-cli-modules::] packages/specfact-codebase/src/specfact_codebase/validators/repro_checker.py:872,882

  • Conditionally imports detect_env_manager and uses env_info; updated detection depth and PATH fallback could change behavior in rootless monorepos.

[::nold-ai/specfact-cli-modules::] packages/specfact-codebase/src/specfact_codebase/repro/commands.py:23,285,483,511

  • Multiple detect_env_manager call sites and usage of build_tool_command; these call sites should be reviewed for assumptions about EnvManager values, availability flag, command_prefix shape, and message handling.

[::nold-ai/specfact-cli-modules::] packages/specfact-spec/src/specfact_spec/generate/commands.py:22,1142,1271,1364

  • Uses detect_env_manager and build_tool_command for running compile/test commands; ensure new command_prefix semantics (e.g., ["uv","run"]) and AUTO/UNKNOWN cases are handled.

[::nold-ai/specfact-cli-modules::] scripts/check-bundle-imports.py:42

  • Lists specfact_cli.utils.env_manager as an allowed import; no direct call but flagged as a consumer.

Summary observation

  • Many packages in specfact-cli-modules call detect_env_manager and/or build_tool_command. The PR changes (EnvManager.AUTO addition, restructured detect_env_manager with monorepo scanning and PATH fallback, and altered env_info fields) are likely to affect these callers; they should be reviewed to ensure they correctly handle:
    • EnvManager.AUTO and ENV_INFO returned for AUTO (caller should not pass AUTO into env_info_from_tool_choice).
    • Presence/shape of env_info fields: available, command_prefix, message.
    • PATH-only detection cases (uv selected from PATH, hatch/poetry not selected without markers, pip as final fallback).
    • Any user-facing message expectations (e.g., "No Compatible Environment Manager Detected").

Comment thread scripts/runtime_discovery_smoke.py
Comment thread scripts/runtime_discovery_smoke.py Outdated
Comment thread src/specfact_cli/registry/module_packages.py Outdated
Comment thread src/specfact_cli/registry/module_packages.py Outdated
Comment thread src/specfact_cli/registry/module_packages.py Outdated
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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/unit/specfact_cli/registry/test_module_packages.py`:
- Line 273: Replace the direct mutation sys.modules.pop("specfact_project",
None) with the pytest-friendly monkeypatch API by calling
monkeypatch.delitem(sys.modules, "specfact_project", raising=False); ensure the
test function accepts the monkeypatch fixture (add a monkeypatch parameter to
the test if missing) so pytest will restore sys.modules after the test
completes.
- Around line 39-46: The autouse fixture _reset_registry currently clears
CommandRegistry and load-failure caches but doesn't reset
module_packages_impl._ACTIVE_MODULE_SRC_DIRS, causing cross-test leakage; update
the fixture to also clear/reset module_packages_impl._ACTIVE_MODULE_SRC_DIRS
(e.g., set it to an empty list) both before yielding and after the test
completes so each test starts with a fresh _ACTIVE_MODULE_SRC_DIRS state
alongside CommandRegistry._clear_for_testing() and clear_module_load_failures().
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f53ddfc9-5fd5-42ae-9722-5de3a0e6a206

📥 Commits

Reviewing files that changed from the base of the PR and between cb567fd and 47ebc42.

📒 Files selected for processing (1)
  • tests/unit/specfact_cli/registry/test_module_packages.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Tests (Python 3.12)
🧰 Additional context used
📓 Path-based instructions (5)
**/test_*.py

📄 CodeRabbit inference engine (.cursor/rules/python-github-rules.mdc)

**/test_*.py: Write tests first in test-driven development (TDD) using the Red-Green-Refactor cycle
Ensure each test is independent and repeatable with no shared state between tests
Organize Python imports in tests using unittest.mock for Mock and patch
Use setup_method() for test initialization and Arrange-Act-Assert pattern in test files
Use @pytest.mark.asyncio decorator for async test functions in Python
Organize test files in structure: tests/unit/, tests/integration/, tests/e2e/ by module

Files:

  • tests/unit/specfact_cli/registry/test_module_packages.py
**/*.py

📄 CodeRabbit inference engine (.cursor/rules/python-github-rules.mdc)

**/*.py: Maintain minimum 80% test coverage, with 100% coverage for critical paths in Python code
Use clear naming and self-documenting code, preferring clear names over comments
Ensure each function/class has a single clear purpose (Single Responsibility Principle)
Extract common patterns to avoid code duplication (DRY principle)
Apply SOLID object-oriented design principles in Python code
Use type hints everywhere in Python code and enable basedpyright strict mode
Use Pydantic models for data validation and serialization in Python
Use async/await for I/O operations in Python code
Use context managers for resource management in Python
Use dataclasses for simple data containers in Python
Enforce maximum line length of 120 characters in Python code
Use 4 spaces for indentation in Python code (no tabs)
Use 2 blank lines between classes and 1 blank line between methods in Python
Organize imports in order: Standard library → Third party → Local in Python files
Use snake_case for variables and functions in Python
Use PascalCase for class names in Python
Use UPPER_SNAKE_CASE for constants in Python
Use leading underscore (_) for private methods in Python classes
Use snake_case for Python file names
Enable basedpyright strict mode with strict type checking configuration in Python
Use Google-style docstrings for functions and classes in Python
Include comprehensive exception handling with specific exception types in Python code
Use logging with structured context (extra parameters) instead of print statements
Use retry logic with tenacity decorators (@retry) for operations that might fail
Use Pydantic BaseSettings for environment-based configuration in Python
Validate user input using Pydantic validators in Python models
Use @lru_cache and Redis-based caching for expensive calculations in Python
Run code formatting with Black (120 character line length) and isort in Python
Run type checking with basedpyright on all Python files
Run linting with ruff and pylint on all Pyth...

Files:

  • tests/unit/specfact_cli/registry/test_module_packages.py
tests/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/spec-fact-cli-rules.mdc)

Tests must be meaningful and test actual functionality, cover both success and failure cases, be independent and repeatable, and have clear, descriptive names. NO EXCEPTIONS - no placeholder or empty tests.

tests/**/*.py: Trim low-value unit tests when a contract covers the same assertion (type/shape/raises on negative checks)
Delete tests that only assert input validation, datatype/shape enforcement, or raises on negative conditions now guarded by contracts and runtime typing
Convert repeated edge-case permutations into one Hypothesis property with contracts acting as oracles

Secret redaction via LoggerSetup.redact_secrets must be covered by unit tests

Files:

  • tests/unit/specfact_cli/registry/test_module_packages.py

⚙️ CodeRabbit configuration file

tests/**/*.py: Contract-first testing: meaningful scenarios, not redundant assertions already covered by
contracts. Flag flakiness, environment coupling, and missing coverage for changed behavior.

Files:

  • tests/unit/specfact_cli/registry/test_module_packages.py
@(src|tests)/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/spec-fact-cli-rules.mdc)

Linting must pass with no errors using: pylint src tests

Files:

  • tests/unit/specfact_cli/registry/test_module_packages.py
**/*.{py,pyi}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{py,pyi}: After any code changes, follow these steps in order: (1) Apply linting and formatting to ensure code quality: hatch run format, (2) Type checking: hatch run type-check (basedpyright), (3) Contract-first approach: Run hatch run contract-test for contract validation, (4) Run full test suite: hatch test --cover -v, (5) Verify all tests pass and contracts are satisfied, (6) Fix any issues and repeat steps until all tests pass
All public APIs must have @icontract decorators and @beartype type checking
Use Pydantic models for all data structures with data validation
Only write high-value comments if at all. Avoid talking to the user through comments

Files:

  • tests/unit/specfact_cli/registry/test_module_packages.py
🔀 Multi-repo context nold-ai/specfact-cli-modules

Linked repositories findings

nold-ai/specfact-cli-modules

  • Multiple callers of detect_env_manager(env) and build_tool_command(env_info, ...):

    • packages/specfact-codebase/src/specfact_codebase/validators/sidecar/specmatic_runner.py — imports build_tool_command, detect_env_manager and calls detect_env_manager(repo_path) then uses build_tool_command to construct runner commands. [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/sidecar/specmatic_runner.py:15,74]
    • packages/specfact-codebase/src/specfact_codebase/validators/sidecar/crosshair_runner.py — imports build_tool_command, detect_env_manager and calls detect_env_manager(repo_path) and build_tool_command when composing commands. [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/sidecar/crosshair_runner.py:16,74]
    • packages/specfact-codebase/src/specfact_codebase/validators/sidecar/orchestrator.py — imports detect_env_manager and calls env detection at runtime (env_info = detect_env_manager(config.repo_path)). [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/sidecar/orchestrator.py:19,399]
    • packages/specfact-codebase/src/specfact_codebase/validators/sidecar/dependency_installer.py — imports detect_env_manager and calls it before installing dependencies. [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/sidecar/dependency_installer.py:16,97]
    • packages/specfact-codebase/src/specfact_codebase/validators/repro_checker.py — imports detect_env_manager and build_tool_command; uses build_tool_command extensively to wrap tool invocations based on env_info. [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/validators/repro_checker.py:873,915,936,949,973,995,1005]
    • packages/specfact-codebase/src/specfact_codebase/repro/commands.py — imports detect_env_manager and build_tool_command in several places and uses env_info for install/run commands. [::nold-ai/specfact-cli-modules::packages/specfact-codebase/src/specfact_codebase/repro/commands.py:23,285,483,511,514]
    • packages/specfact-spec/src/specfact_spec/generate/commands.py — imports detect_env_manager and build_tool_command and uses them when composing compile/test commands. [::nold-ai/specfact-cli-modules::packages/specfact-spec/src/specfact_spec/generate/commands.py:22,23,1142,1144,1271,1292,1364,1366]
  • Summary observation (from the code locations above):

    • These modules consume detect_env_manager and env_info to build tool commands and control behavior. They will observe any changes to detect_env_manager semantics (e.g., new AUTO value, PATH-fallback selection behavior, altered EnvManagerInfo fields such as command_prefix, available, and message) and to build_tool_command behavior. Reviewers should validate callers correctly handle the new AUTO/UNKNOWN cases, PATH-only uv/pip selection rules, and any change in command_prefix shape (e.g., ["uv","run"]). [::nold-ai/specfact-cli-modules::]

Comment thread tests/unit/specfact_cli/registry/test_module_packages.py
Comment thread tests/unit/specfact_cli/registry/test_module_packages.py Outdated
@djm81
Copy link
Copy Markdown
Collaborator Author

djm81 commented May 7, 2026

Review follow-up pushed in 0e7f8db.

Verified and fixed still-valid comments:

  • scripts/runtime_discovery_smoke.py: prepends checkout src/ locally and sets PYTHONPATH for launcher subprocesses so smoke runs against PR code; creates a fresh rootless demo per launcher while keeping the registry build shared.
  • src/specfact_cli/registry/module_packages.py: preserves package-wide load failure diagnostics while sibling command failures remain; removes stale active module src paths from sys.path during registry re-registration; normalizes -, _, and . when matching dist-info/egg-info names.
  • tests/unit/specfact_cli/registry/test_module_packages.py: fixture now clears _ACTIVE_MODULE_SRC_DIRS; uses monkeypatch.delitem for sys.modules; added regressions for dist metadata normalization, stale sys.path cleanup, and per-command load-failure clearing.
  • tests/integration/scripts/test_runtime_discovery_smoke.py: added regression proving fresh demo per launcher and single shared registry build.

Validation:

  • hatch run pytest tests/unit/specfact_cli/registry/test_module_packages.py tests/unit/specfact_cli/registry/test_module_availability.py -q -> 56 passed
  • hatch run pytest tests/integration/scripts/test_runtime_discovery_smoke.py -q -> 3 passed
  • hatch run lint -> clean
  • hatch run type-check -> 0 errors, existing warnings only
  • hatch run specfact code review run --scope changed -> PASS / exit 0
  • openspec validate runtime-01-discovery-reliability --strict -> valid

No requested comment was skipped; all were still valid against current code.

@djm81 djm81 merged commit 469af46 into dev May 7, 2026
23 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in SpecFact CLI May 7, 2026
djm81 added a commit that referenced this pull request Jun 2, 2026
* docs: align core docs and sync pending changes (#377)

* docs: align core docs and sync pending changes

* fix: preserve partial staging in markdown autofix hook

---------

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

* fix: stabilize release test suite after module migration

* Update module

* Fix module install

* Fix module install

* Fix failed tests

* Fix marketplace client regression

* Fix install regression for specfact-cli (#380)

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

* Add changes to improve runtime validation and backlog module remaining migration to module

* refactor: remove backlog ownership from core cli (#384)

* refactor: remove backlog ownership from core cli

* fix: align CI marketplace validation paths

* test: stabilize command audit validation and add command-surface change

---------

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

* Add new command alignment change

* fix: finalize cli runtime validation regressions (#387)

* fix: finalize cli runtime validation regressions

* test: align satisfied dependency logging assertions

---------

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

* docs: archive cli-val-07 change

* Archive changes and update specs

* Add code-review change proposals

* test: align command surface regression coverage

* docs: add OpenSpec change for backlog-core commands migration (#390)

* feat: add OpenSpec change for backlog-core commands migration

Change: backlog-02-migrate-core-commands
- Add proposal, design, tasks, specs
- Add TDD_EVIDENCE.md with implementation progress
- GitHub Issue: #389

Rules applied: AGENTS.md Git Worktree Policy, TDD Hard Gate

Made-with: Cursor

* docs: update TDD_EVIDENCE and tasks for quality gate results

Made-with: Cursor

* docs: update TDD_EVIDENCE with test fix results

Made-with: Cursor

* docs: update TDD_EVIDENCE with all test fixes complete

Made-with: Cursor

---------

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

* fix: use POST instead of PATCH for ADO work item creation (#391)

* fix: use POST instead of PATCH for ADO work item creation

Azure DevOps API requires POST (not PATCH) for creating work items.

Also fixed category grouping to always register group commands.

Made-with: Cursor

* docs: add changelog entry for ADO POST fix

Made-with: Cursor

* chore: bump version to 0.40.4

Made-with: Cursor

* fix: update test mocks from PATCH to POST for ADO create

- Reverted incorrect unconditional _mount_installed_category_groups call

- Updated test_create_issue mocks to use requests.post instead of requests.patch

Made-with: Cursor

* test: skip category group test when bundles not installed

The test_bootstrap_with_category_grouping_disabled_registers_flat_commands test

expects bundles like specfact-codebase to be installed, but in CI they may not be.

Added pytest.skip() when 'code' command is not available.

Made-with: Cursor

---------

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

* docs: archive backlog-02-migrate-core-commands change

- Archived backlog-02-migrate-core-commands change

- Updated CHANGE_ORDER.md with implementation status

- Updated main specs with backlog-add, backlog-analyze-deps, backlog-delta, backlog-sync, backlog-verify-readiness

Made-with: Cursor

* feat: document code-review module scaffold (#410)

* feat: document code-review module scaffold

* chore: sync 0.41.0 release version artifacts

---------

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

* Add change for project codebase ownership

* Realign code import ownership surface (#412)

* Realign code import ownership surface

* Harden temp registry command audit test

---------

Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>
Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>

* Update code review changes

* docs: update reward ledger OpenSpec tracking (#413)

Link the existing change issue, record TDD evidence, and align the OpenSpec artifacts with the bundle-owned DDL and paired worktree implementation flow.

Made-with: Cursor

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

* Track house-rules skill OpenSpec changes (#414)

Made-with: Cursor

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

* docs: Update change-proposal for code-review-07 (#415)

* Track house-rules skill OpenSpec changes

Made-with: Cursor

* Cursor: Apply local changes for cloud agent

---------

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

* Finalize code-review-07 status

* Finalize code-review-08 status

* feat: apply code-review-09 pre-commit integration

* fix: fall back when cached hatch test env is broken

* fix: avoid hatch env for coverage xml export

* fix: install type-check and lint tools directly in CI

* fix: install pytest fallback deps in test job

* fix: install pytest-cov for test fallback path

* Finalize code-review-09 status

* [Change] Align core docs with modules site ownership (#419)

* Align core docs with modules site ownership

* Close docs portal change PR task

---------

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

* fix: harden docs parity URL assertions

* Archive finished changes and update specs

* docs: fix command syntax parity after lean-core/modules split (v0.42.2) (#421)

Replace all stale CLI syntax families in authored docs with current
shipped commands. Adds docs parity tests that guard against regression.

Removed syntax families corrected:
- specfact project plan → project devops-flow / project snapshot / govern enforce sdd
- project import from-bridge → code import from-bridge
- specfact backlog policy → backlog verify-readiness / backlog refine
- specfact spec contract → spec validate / spec generate-tests / spec mock
- specfact spec sdd constitution → govern enforce sdd [BUNDLE]
- spec generate <prompt-subcommands> → AI IDE skills or removed

Updated docs: README.md, docs/index.md, docs/README.md,
docs/reference/commands.md (+4 reference docs),
docs/getting-started/ (4 files), docs/guides/ (21 files),
docs/examples/ (5 files), docs/prompts/ (2 files).

Added 11 new docs parity tests in test_release_docs_parity.py:
- 7 tests asserting removed syntax families stay absent
- 4 tests asserting current command families remain documented

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Archive finished changes and update specs

- Archive docs-03-command-syntax-parity (2026-03-18)
- Sync delta specs: cli-output + documentation-alignment updated with
  post-split command-surface alignment requirements and scenarios
- Update CHANGE_ORDER.md: mark docs-03 as archived

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update evidence

* Potential fix for pull request finding 'Unused global variable'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>

* docs: align core docs ownership and parity (#424)

* docs: fix command syntax parity after lean-core/modules split (v0.42.2)

Replace all stale CLI syntax families in authored docs with current
shipped commands. Adds docs parity tests that guard against regression.

Removed syntax families corrected:
- specfact project plan → project devops-flow / project snapshot / govern enforce sdd
- project import from-bridge → code import from-bridge
- specfact backlog policy → backlog verify-readiness / backlog refine
- specfact spec contract → spec validate / spec generate-tests / spec mock
- specfact spec sdd constitution → govern enforce sdd [BUNDLE]
- spec generate <prompt-subcommands> → AI IDE skills or removed

Updated docs: README.md, docs/index.md, docs/README.md,
docs/reference/commands.md (+4 reference docs),
docs/getting-started/ (4 files), docs/guides/ (21 files),
docs/examples/ (5 files), docs/prompts/ (2 files).

Added 11 new docs parity tests in test_release_docs_parity.py:
- 7 tests asserting removed syntax families stay absent
- 4 tests asserting current command families remain documented

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: align core docs ownership and parity

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: fix quickstart install guidance

* docs: remove generated project plan docs

* Add code-review change

* fix: preserve native backlog import payloads (#429)

* fix: preserve native backlog import payloads

* fix: preserve imported proposal ids on reimport

---------

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

* fix: add docs review workflow and repair docs links (#428)

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

* fix: keep imported change ids stable across title changes (#431)

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

* fix: remove conflicting pages file copies

* Add docs sync changs

* docs: update openspec clean-code planning

* Update change status

* fix: code-review-zero-findings dogfood remediation (v0.42.3) (#435)

* fix: continue code review remediation and align module signing

* fix: complete code-review-zero-findings dogfood remediation (v0.42.3)

Eliminates full-scope code review findings (types, Radon CC, contracts, lint) and records OpenSpec change code-review-zero-findings with tests and CHANGELOG. Module manifests may need re-signing before merge per project policy.

Made-with: Cursor

* chore: re-sign bundled modules after content changes

* fix: resolve review follow-up regressions

* fix: run ci smart-test directly

* fix: restore ci test progress output

* fix: stabilize command audit ci test

---------

Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>
Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>

* Add docs refactoring changes

* Add bug change tracking for encoding and resources

* docs: restructure core site IA to 6-section progressive nav (#442)

* docs: restructure core site IA from 5 flat sections to 6 progressive sections

Restructure docs.specfact.io from a flat 5-section sidebar to a 6-section
progressive navigation: Getting Started, Core CLI, Module System, Architecture,
Reference, Migration.

- Create docs/core-cli/, docs/module-system/, docs/migration/ directories
- Move 12 files to correct new sections with jekyll-redirect-from entries
- Write 3 new CLI reference pages: init.md, module.md, upgrade.md
- Replace first-steps.md with focused 5-minute quickstart
- Rewrite index.md as portal landing with core vs modules delineation
- Rewrite getting-started/README.md to link module tutorials to modules site
- Update sidebar navigation in _layouts/default.html
- Delete 6 obsolete files (competitive-analysis, ux-features, common-tasks,
  workflows, testing-terminal-output, guides/README)
- Add documentation-alignment delta spec for core-only focus policy

Implements: #438
OpenSpec: docs-05-core-site-ia-restructure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: fix broken internal links after IA restructure

Update all relative links across 40 files to point to new file locations:
- ../reference/architecture.md → ../architecture/overview.md
- ../reference/debug-logging.md → ../core-cli/debug-logging.md
- ../reference/modes.md → ../core-cli/modes.md
- guides/ sibling links → ../module-system/ or ../migration/
- module-system/ back-links → ../guides/
- Remove links to deleted files (common-tasks, workflows)
- first-steps.md → quickstart.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update test path for moved bootstrap-checklist and fix remaining broken links

- Update test_module_bootstrap_checklist_uses_current_bundle_ids to use
  new path docs/module-system/bootstrap-checklist.md
- Fix 2 remaining command-chains.md anchor links in migration-guide.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden cross-platform runtime and IDE resource discovery (#443)

* fix: harden cross-platform runtime and IDE resource discovery

* fix: bump patch version to 0.42.4

* fix: restore init lifecycle compatibility

---------

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

* fix: resolve review type-safety findings

* Improve clarity and scope of ide prompt change

* feat(init): IDE prompt source catalog, --prompts, namespaced exports (#445)

* feat(init): IDE prompt source catalog, --prompts, namespaced exports

Implement init-ide-prompt-source-selection: discover core + module prompts,
default export all sources, interactive multi-select, non-interactive --prompts,
source-namespaced IDE paths. Fix project module roots to use metadata source
project. Extend discovery roots with user/marketplace. Update startup_checks
for nested exports. Bump init module to 0.1.14 with signed manifest.

Made-with: Cursor

* fix(init): scope VS Code prompt recommendations to exported sources

- Pass prompts_by_source into create_vscode_settings from copy_prompts_by_source_to_ide
- Strip prior .github/prompts/* recommendations on selective export to avoid stale paths
- Extract helpers for catalog paths and fallbacks; keep code review clean

Made-with: Cursor

---------

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

* fix tests

* release: bump version to 0.42.5 and update CHANGELOG

- Remove [Unreleased] sections; fold historical arch-08 notes under [0.34.0]
- Document init ide catalog, VS Code recommendations, integration test isolation

Made-with: Cursor

* Fix review findings

* feat(init): selective IDE prompt export cleanup and VS Code recommendation strip

- Prune stale exports and unselected catalog segments in copy_prompts_by_source_to_ide
- Strip only specfact*.prompt.md under .github/prompts/ when merging VS Code settings
- Tighten e2e missing-templates assertions to match CLI output
- Add unit tests for prompt path helper and selective export behavior

Made-with: Cursor

* Fix review findings

* Add missing import

* Bump patch version and changelog

* Fix failed tests

* Fix review findings

* docs: core vs modules URL contract and OpenSpec alignment (#448)

* docs: add core vs modules URL contract and OpenSpec alignment

Document cross-site permalink rules in docs/reference, extend documentation-alignment
and module-docs-ownership specs, update docs-07 and openspec config, and note the
dependency on modules URL policy in CHANGE_ORDER.

Made-with: Cursor

* docs: convert core handoff pages to modules canonical links (docs-07)

- Replace 20 duplicate guides/tutorials with thin summaries, prerequisites,
  and links to modules.specfact.io per URL contract
- Add docs/reference/core-to-modules-handoff-urls.md mapping table
- Align OpenSpec documentation-alignment spec delta with ADDED Requirements
- Complete docs-07-core-handoff-conversion tasks checklist

Refs: #439
Made-with: Cursor

---------

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

* feat(docs-12): docs command validation and cross-site link checks (#449)

* feat(docs-12): docs command validation and cross-site link checks

- Add check-docs-commands (Typer CliRunner prefix + --help) and exclusions for migration/illustrative pages
- Add check-cross-site-links with robust URL extraction; warn-only in docs-validate and CI while live site may lag
- Extend docs-review: Hatch env, validation steps, pytest tests/unit/docs/
- Opt-in handoff map HTTP test (SPECFACT_RUN_HANDOFF_URL_CHECK=1)
- OpenSpec deltas, TDD_EVIDENCE, tasks complete; CHANGELOG [Unreleased]

Made-with: Cursor

* fix(docs-validate): strip leading global flags before command path

- Parse --mode/--input-format/--output-format + value, then other root flags
- Add test for specfact --mode copilot import from-code …
- Fix showcase docs: hatch run contract-test-exploration (not specfact)

Made-with: Cursor

* fix(docs-12): harden link/command validators and spec wording

- Capitalize Markdown in cross-site link spec requirement
- Cross-site: redirect-only HTTP success, UTF-8 read failures, URL delimiter/trim fixes
- Docs commands: catch Typer exceptions on --help, UTF-8 read failures
- Tests: shared loader for check-cross-site-links module

Made-with: Cursor

---------

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

* fix(scripts): CliRunner without mix_stderr for Click 8.3+ compatibility (#451)

Default CliRunner() merges stderr into stdout; read stdout only so
accessing result.stderr does not raise when streams are combined.

Made-with: Cursor

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

* fix: review gates (semgrep print, radon CC, icontract, questionary types) (#452)

* fix: satisfy review gates for docs scripts and module_lifecycle typing

- Replace print() with Rich Console in docs validation scripts (semgrep)
- Split HTTP URL checks and doc scans to reduce cyclomatic complexity (radon)
- Add icontract require/ensure on public helpers; use CliRunner() without mix_stderr
- Cast questionary API for basedpyright reportUnknownMemberType

Made-with: Cursor

* fix(scripts): address #452 review (HTTP helpers, icontract, CLI streams)

- _http_success_code: use int directly after None guard
- _response_status: safe getcode via getattr/callable
- check-docs: drop @require preconditions duplicated by beartype
- _cli_invoke_streams_text: merge stdout + stderr for not-installed detection

Made-with: Cursor

---------

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

* Add speckit adapter alignment change and update affected change specs

* feat(adapters): spec-kit v0.4.x adapter alignment (#454)

* feat(adapters): spec-kit v0.4.x adapter alignment — extensions, presets, hooks, version detection, 7-command presets

Update SpecKitAdapter, ToolCapabilities, BridgeConfig presets, and
SpecKitScanner for spec-kit v0.4.3 compatibility:

- ToolCapabilities: 5 new optional fields (extensions, extension_commands,
  presets, hook_events, detected_version_source)
- SpecKitScanner: scan_extensions(), scan_presets(), scan_hook_events()
  with .extensionignore support and defensive JSON parsing
- SpecKitAdapter: 3-tier version detection (CLI → heuristic → None),
  refactored get_capabilities() with reduced cyclomatic complexity
- BridgeConfig: all 3 speckit presets expanded from 2 to 7 command
  mappings (specify, plan, tasks, implement, constitution, clarify, analyze)
- 42 new tests across 4 test files (110 targeted, 2248 full suite pass)
- Docs updated: comparison matrix, journey guide, integrations overview,
  adapter development guide

Closes #453

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address CodeRabbit review findings

- Use get_bridge_logger instead of logging.getLogger in speckit adapter
  and scanner (production command path convention)
- Narrow except Exception to except OSError in _load_extensionignore
- Simplify redundant base_path conditional in get_capabilities
- Use SimpleNamespace instead of dynamic type() in tests
- Add subprocess.TimeoutExpired and OSError exception tests for CLI
  version detection
- Fix duplicate MD heading in bridge-adapter spec
- Add blank lines after markdown headings in proposal (MD022)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* chore: bump version to 0.43.0 for spec-kit v0.4.x alignment (#455)

* chore: bump version to 0.43.0 and add changelog entry

Minor version bump for spec-kit v0.4.x adapter alignment feature.
Syncs version across pyproject.toml, setup.py, and __init__.py.
Adds changelog entry documenting new capabilities.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Sync deps and fix changelog

* Sync deps and fix changelog

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix(packaging): remove workflow prompts from core wheel (packaging-02 #441, v0.43.1) (#456)

* fix(packaging): drop duplicate workflow prompts from core wheel (packaging-02 3.5)

Remove resources/prompts from wheel force-include and repo tree; canonical
copies remain in specfact-cli-modules bundles. Align startup IDE drift
checks and init template resolution with discover_prompt_template_files.
Bump to 0.43.1; re-sign init module 0.1.19. Update CHANGELOG, docs, OpenSpec.

Made-with: Cursor

* fix: address PR review (changelog, TDD evidence, startup checks, tests)

- Changelog 0.43.1 header uses Unreleased until release tag
- TDD_EVIDENCE: pre-fail block for Task 3.5 before passing verification
- TemplateCheckResult.sources_available; skip last_checked_version bump when no
  discoverable prompts; drift missing only when source exists
- Integration _fake_discover respects include_package_fallback
- test_validate_all_prompts uses tmp_path; re-enable file in default test run
- test_print_startup_checks_version_update_no_type uses stale version timestamp

Made-with: Cursor

* fix: address follow-up PR review (startup metadata, tests)

- Use ide_dir directly in TemplateCheckResult when IDE folder exists
- Set last_checked_version only after successful template-source checks
- Integration test: assert discover_prompt_template_files fallback + stable startup patches
- validate_all_prompts test: valid vs invalid specfact.*.md outcomes

Made-with: Cursor

---------

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

* Potential fix for pull request finding 'Empty except'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>

* Fix changelog version

* docs: unify core docs portal UX (#459)

* docs: unify core docs portal UX

* Fix docs-13 core review findings

* Address docs-13 PR review feedback

* Address follow-up docs review feedback

---------

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

* Harden docs home URL test assertion

* feat: doc frontmatter validation, v0.43.2 review JSON gate, and pre-commit review UX (#463)

* chore(release): v0.43.2 pre-commit review JSON + OpenSpec dogfood rules

- Pre-commit gate writes ReviewReport JSON to .specfact/code-review.json
- openspec/config.yaml: require fresh review JSON and remediate findings
- Docs and unit tests updated

Made-with: Cursor

* fix: CodeRabbit — changelog, openspec TDD_EVIDENCE freshness, review hook timeout

- CHANGELOG 0.43.2: expanded entries, line wrap
- openspec/config.yaml: exclude TDD_EVIDENCE.md from review JSON staleness
- pre_commit_code_review: timeout 300s, TimeoutExpired handling
- tests: exact cwd, timeout assertion and timeout failure test

Made-with: Cursor

* Add code review to pre-commit and frontmatter docs validation

* Improve pre-commit script output

* Improve specfact code review findings output

* Fix review findings

* Improve pre-commit hook output

* Enable dev branch code review

* Update code review hook

* Fix contract review findings

* Fix review findings

* Fix review warnings

* feat: doc frontmatter hardening and code-review gate fixes

- Typer CLI for doc-frontmatter-check; safer owner resolution (split helpers for CC)
- Strict exempt handling; pre-commit hook matches USAGE-FAQ.md; review script JSON typing
- Shared test fixtures/types; integration/unit test updates; OpenSpec tasks and TDD evidence
- Changelog: pre-commit code-review-gate UX note

Made-with: Cursor

* Fix test failures and add docs review to github action runner

* Fix test failure due to UTF8 encoding

* Apply review findings

* Optimize pr orchestrator runtime

* Optimize pr orchestrator runtime

* Fix caching on pr-orchestrator

---------

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

* docs: archive doc-frontmatter-schema openspec change

* Apply suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>

* fix: restore protocol stubs for type checking

* Add frontamtter check

* fix: harden protocol stubs for code quality

* Add PR test hardening change

* fix: remediate review findings and harden review gates

* fix: rebuild review report model for pydantic

* Add story and onboarding change

* Update change tracking

* Improve scope for ci/cd requirements

* docs: sharpen first-contact story and onboarding (#467)

* docs: sharpen first-contact story and onboarding

* docs: address first-contact review feedback

* docs: address onboarding review fixes

* test: accept default-filtered site tokens in docs parity

* docs: record completed onboarding quality gates

* test: improve first-contact assertion failures

---------

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

* fix: harden review blockers and bump patch version

* test: harden modules docs url assertions

* fix: harden trustworthy green checks (#469)

* fix: harden trustworthy green checks

* fix: restore contract-first ci repro command

* fix: apply CodeRabbit auto-fixes

Fixed 3 file(s) based on 3 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>

* fix: resolve CI failures for trustworthy green checks PR

- Use hatch run contract-test instead of specfact code repro in CI
  (CLI bundle not available in CI environment)
- Allow test_bundle_import.py in migration cleanup legacy-import check
  (_bundle_import is an internal helper, not a removed module package)
- Fix formatting in test_trustworthy_green_checks.py (CodeRabbit commit
  was unformatted)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address CodeRabbit review findings

- Add trailing newline to TDD_EVIDENCE.md (MD047)
- Make _load_hooks() search for repo: local instead of assuming index 0
- Replace fragile multi-line string assertion in actionlint test with
  semantic line-by-line checks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address CodeRabbit review findings for ci-02 (#471)

- Widen workflow_changed filter to include scripts/run_actionlint.sh
  and scripts/yaml-tools.sh so Workflow Lint triggers on script changes
- Pin actionlint default to v1.7.11 (matches CI) instead of latest
- Fix run_actionlint.sh conflating "not installed" with "lint failures"
  by separating availability check from execution
- Restore sys.path after test_bundle_import to avoid cross-test leakage
- Normalize CHANGE_ORDER.md status format to semicolon convention

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix: propagate docker actionlint exit code instead of masking failures (#472)

Simplify run_actionlint.sh control flow so both local and docker
execution paths propagate actionlint's exit code via `exit $?`. Previously
the docker path used `if run_with_docker; then exit 0; fi` which treated
lint errors as "docker unavailable" and fell through to install guidance.

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix: assert hook id stability and cd to repo root for local actionlint (#473)

- Assert hook id == "specfact-smart-checks" to prevent silent renames
- cd to REPO_ROOT before running local actionlint so it finds workflows
  regardless of caller's cwd

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: clean-code-01-principle-gates — 7-principle charter gates, v0.44.0 (#474)

* feat: clean-code-01-principle-gates — 7-principle charter gates, v0.44.0

Implements openspec/changes/clean-code-01-principle-gates:

- Rewrote .cursor/rules/clean-code-principles.mdc as a canonical alias
  surface for the 7-principle clean-code charter (naming, kiss, yagni,
  dry, solid) defined in nold-ai/specfact-cli-modules. Documents Phase A
  KISS thresholds (>80 warning / >120 error LOC), nesting-depth and
  parameter-count checks active, and Phase B (>40/80) explicitly deferred.
- Added Clean-Code Review Gate sections to AGENTS.md and CLAUDE.md listing
  all 5 expanded review categories and the Phase A thresholds.
- Created .github/copilot-instructions.md as a lightweight alias (< 30 lines)
  referencing the canonical charter without duplicating it inline.
- Added unit tests (test_clean_code_principle_gates.py) covering all three
  spec scenarios: charter references, compliance gate, LOC/nesting thresholds.
- TDD evidence recorded in openspec/changes/clean-code-01-principle-gates/TDD_EVIDENCE.md.
- Bumped version 0.43.3 → 0.44.0 (minor — feature branch).
- Updated CHANGELOG.md and openspec/CHANGE_ORDER.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: clean-code-01-principle-gates review findings and broad exception handling\n\n- Fix coderabbitai review findings:\n  - Clarify T20 and W0718 are aspirational in clean-code-principles.mdc\n  - Add language specifier to TDD_EVIDENCE.md fenced code block\n  - Update test to check all 7 canonical principles\n  - Make LOC threshold assertion more specific\n- Improve exception handling throughout codebase:\n  - Replace broad except Exception with specific exceptions\n  - Apply SOLID principle for better error handling\n- Update tasks.md to reflect completion status\n\nFixes #434\n\nGenerated by Mistral Vibe.\nCo-Authored-By: Mistral Vibe <vibe@mistral.ai>

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: archive completed openspec changes and update main specs

Archive 11 completed OpenSpec changes:
- bugfix-02-ado-import-payload-slugging
- ci-02-trustworthy-green-checks
- clean-code-01-principle-gates
- code-review-zero-findings
- docs-04-docs-review-gate-and-link-integrity
- docs-05-core-site-ia-restructure
- docs-07-core-handoff-conversion
- docs-12-docs-validation-ci
- docs-13-core-nav-search-theme-roles
- docs-14-first-contact-story-and-onboarding
- init-ide-prompt-source-selection
- packaging-02-cross-platform-runtime-and-module-resources
- speckit-02-v04-adapter-alignment

Fix spec validation errors:
- Add proper delta headers (ADDED/MODIFIED/REMOVED/RENAMED)
- Use correct scenario format with GIVEN/WHEN/THEN bullets
- Ensure requirement headers match between delta and main specs
- Use correct operation type based on existing requirements

Update main specs with archived changes:
- backlog-adapter: various updates
- bridge-adapter: Spec-Kit v0.4.x capabilities
- bridge-registry: BridgeConfig preset updates
- code-review-module: new requirements
- debug-logging: enhancements
- devops-sync: improvements
- documentation-alignment: core vs modules separation
- review-cli-contracts: new contracts
- review-run-command: command updates

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

* Add new user onboarding change

* docs & tooling: new user onboarding + smart-test and pre-commit review fixes (#477)

* Fix content for install, sync, uninstallä

* test(docs): align first-contact contracts and stabilize module CLI tests

- docs/index: restore Why does it exist?, tagline, OpenSpec, canonical core CLI story
- Update init profile tests for solo-developer + install all (code-review, six bundles)
- Lean help test accepts uvx init hint; upgrade/core_compatibility tests match runtime
- Autouse fixture re-bootstraps CommandRegistry after category-group tests
- Rebase tasks conflict resolved; TDD_EVIDENCE + tasks for gates 7.1/7.2/12.1/12.2

Made-with: Cursor

* fix(tools): smart-test baseline and pre-commit single code-review run

- Run full suite when smart-test cache has no last_full_run; force+auto falls back to full when incremental is a no-op
- Pre-commit: invoke pre_commit_code_review.py once (no xargs split) so .specfact/code-review.json is not clobbered
- Tests and OpenSpec tasks for docs-new-user-onboarding

Made-with: Cursor

* test: fix CI backlog copy assertions and module install test isolation

- Align backlog not-installed tests with solo-developer init guidance (no <profile> placeholder)
- Autouse: reset CommandRegistry, register_builtin_commands, rebuild_root_app_from_registry so module install tests work after registry-only clears

Made-with: Cursor

* docs: README wow path + tests locking entrypoint with docs

- README leads with uvx init + code review run --scope full; pip install secondary
- Unit contract tests: README and docs/index.md share canonical uvx strings and order
- E2E: init --profile solo-developer in temp git repo; registry ready for step two with mock bundles

Made-with: Cursor

* feat(init): solo-developer includes code-review bundle and marketplace install

- Add specfact-code-review to canonical bundles and solo-developer preset
- Install marketplace module nold-ai/specfact-code-review via install_bundles_for_init
- Docs index: core CLI story and default starting point copy for parity tests
- CLI: missing-module hint references solo-developer profile
- smart_test_coverage: icontract requires use (self, test_level) for method contracts
- Re-sign init and module_registry manifests; tests and registry updates

Made-with: Cursor

* fix(tools): align _run_changed_only with tuple return and baseline full run

- Return (success, ran_any) from _run_changed_only; run full suite when no last_full_run
- run_smart_tests(auto, force): fall back to full tests when incremental ran nothing
- Fix wow e2e fixture typing (Iterator[None]) for basedpyright

Unblocks PR #477 CI: type-check, tests, lint job.

Made-with: Cursor

* chore(release): bump to 0.45.1 and update OpenSpec tasks status

- Sync version across pyproject.toml, setup.py, and __init__ modules
- Changelog: 0.45.1 entry for dependency profiles, smart-test baseline, CI, UX
- openspec: rolling status snapshot and task checkboxes for PR verification
- Includes prior branch work: init/profile, module registry, docs entry path, workflows

Made-with: Cursor

---------

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

* fix: code-review gate (Typer params), typer<0.24 vs semgrep, module upgrade tests (#479)

* fix: code-review gate (Typer params), typer<0.24 vs semgrep, module upgrade tests

- Split root/install Typer callbacks into merged param stubs (KISS param count).
- Patch typer.main via importlib; merge install param specs in module_registry.
- Cap typer<0.24 to stay compatible with semgrep click~=8.1.8.
- Invoke module_registry app directly in upgrade CLI tests (root app may lack module group).
- Refactors for first_run_selection, module_packages, registry tests, semgrep README.

Worktree: specfact-cli-worktrees/bugfix/code-review-cli-tests
Made-with: Cursor

* docs: use code import in examples (flat import removed from CLI)

Replace specfact [--flags] import from-code with specfact [--flags] code import
from-code so check-docs-commands matches the nested Typer path after removing
the flat import shim.

Made-with: Cursor

* Fix review findings

---------

Co-authored-by: Dom <djm81@users.noreply.github.com>

* docs: restructure README for star conversion (#480)

* docs: restructure readme for star conversion

Co-authored-by: Dom <djm81@users.noreply.github.com>

* docs: sync readme change tracking

Co-authored-by: Dom <djm81@users.noreply.github.com>

* docs: relocate readme support artifacts

Co-authored-by: Dom <djm81@users.noreply.github.com>

* docs: fix readme workflow snippet and pin demo capture

Co-authored-by: Dom <djm81@users.noreply.github.com>

* docs: address remaining readme review findings

Co-authored-by: Dom <djm81@users.noreply.github.com>

---------

Co-authored-by: Dom <djm81@users.noreply.github.com>

* archived implemented changes

* Archive and remove outdated changes

* Split and refactor change proposals between both repos

* Archive alignment change

* Add changes and github hierarchy scripts

* feat: add GitHub hierarchy cache sync (#492)

* feat: add github hierarchy cache sync

* Backport improvements from modules scripts

* Fix review findings

* Make github sync script executable

---------

Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>
Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>

* [codex] Compact agent governance loading (#493)

* feat: compact agent governance loading

* docs: mark governance PR task complete

* docs: sync governance-03 github issue metadata

* fix: restore dev branch governance block

* Apply review findings

* docs: add sibling internal wiki context for OpenSpec design

Point AGENTS.md, Claude/Copilot/Cursor surfaces, and the OpenSpec rule at
docs/agent-rules/40-openspec-and-tdd.md to read-only wiki paths (hot.md,
graph.md, concepts) via absolute paths when specfact-cli-internal is present.
Update INDEX applicability notes and extend governance tests.

Made-with: Cursor

---------

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

* Archived github hierarchy change

* Update rules for openspec archive

* Potential fix for pull request finding 'Unused local variable'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>

* Add wiki update notes

* Archive governance-03 change, format markdown, add wiki instructions for update

* Fix review findings

* Fix type errors

* fix: safe VS Code settings merge and project artifact writes (#490) (#496)

* fix: safe merge for VS Code settings.json on init ide (profile-04)

- Add project_artifact_write.merge_vscode_settings_prompt_recommendations with fail-safe
  on invalid JSON / bad chat shape; --force backs up to .specfact/recovery/ then replaces.
- Route ide_setup create_vscode_settings through helper; thread force; catch errors for CLI exit.
- Lint gate: scripts/verify_safe_project_writes.py blocks json.load/dump in ide_setup.py.
- Tests, installation docs, 0.45.2 changelog and version pins.

OpenSpec: profile-04-safe-project-artifact-writes
Made-with: Cursor

* fix(profile-04): satisfy review gate, pin setuptools for semgrep

- Refactor project_artifact_write merge path (KISS); icontract predicates
- Deduplicate ide_setup prompt helpers; import from project_artifact_write
- verify_safe_project_writes: ast.walk, contracts, beartype
- Pin setuptools<82 for Semgrep pkg_resources chain
- Update TDD_EVIDENCE and tasks checklist

Made-with: Cursor

* ci: run safe-write verifier in PR orchestrator lint job

Match hatch run lint by invoking scripts/verify_safe_project_writes.py
after ruff/basedpyright/pylint. Use set -euo pipefail so the first lint
failure is not masked by later commands.

Made-with: Cursor

* fix(profile-04): address CodeRabbit review (docs, guard, contracts, tests)

- Wrap installation.md VS Code merge paragraph to <=120 chars per line
- tasks 4.7 + TDD_EVIDENCE: openspec validate --strict sign-off
- verify_safe_project_writes: detect from-json import and aliases
- settings_relative_nonblank: reject absolute paths and .. segments
- ide_setup: _handle_structured_json_document_error for duplicate handlers
- ProjectWriteMode docstring (reserved policy surface); backup stamp + collision loop
- Tests: malformed settings preserved on init ide exit; force+chat coercion; AST guard tests

Made-with: Cursor

* fix(profile-04): JSON5 settings, repo containment, review follow-ups

- merge_vscode_settings: resolve containment before mkdir/write; JSON5 load/dump
  (JSONC comments; trailing_commas=False for strict JSON output)
- ide_setup: empty prompts_by_source skips catalog fallback (_finalize allow_empty_fallback)
- verify_safe_project_writes: detect import json as js attribute calls
- contract_predicates: prompt_files_all_strings accepts list[Any] for mixed-type checks
- Tests: symlink escape, JSONC merge, empty export strip, import-json-as-js guard
- tasks.md / TDD_EVIDENCE: wrap lines to <=120 chars; CHANGELOG + json5 dep + setup.py sync

Made-with: Cursor

* docs(profile-04): tasks pre-flight + full pytest; narrow icontract ensure

- tasks 1.1: hatch env create then smart-test-status and contract-test-status
- tasks 4.3: add hatch test --cover -v to quality gates
- TDD_EVIDENCE: shorter module-signatures and report lines (<=120 cols)
- project_artifact_write: isinstance(result, Path) in @ensure postconditions

Made-with: Cursor

* fix: clear specfact code review on safe-write modules

- verify_safe_project_writes: flatten json binding helpers; stderr writes
  instead of print; inline Import/ImportFrom loops to drop duplicate-shape DRY
- project_artifact_write: _VscodeChatMergeContext dataclass (KISS param count);
  typed chat_body cast before .get for pyright

Made-with: Cursor

* docs(profile-04): record hatch test --cover -v in TDD_EVIDENCE

Align passing evidence with tasks.md 4.3 full-suite coverage gate.

Made-with: Cursor

* fix: reduce KISS blockers (bridge sync contexts, tools, partial adapters)

Refactors high-parameter call sites into dataclasses/context objects and splits hot spots (export devops pipeline, smart_test_coverage incremental run, suggest_frontmatter, crosshair summary loop).

API: BridgeSync.export_change_proposals_to_devops(adapter_type, ExportChangeProposalsOptions | None); LoggerSetup.create_logger(name, LoggerCreateOptions | None); run_crosshair(path, CrosshairRunOptions | None).

Full specfact code review --scope full still reports error-severity kiss/radon findings (remaining nesting/LOC and param counts in ADO, analyzers, generators, source_scanner, module_installer, bundle-mapper, etc.). Gate PASS requires follow-up.

Made-with: Cursor

* Fix review findings and sign modules

* fix(tests): register dynamic check_doc_frontmatter module; align _update_cache tests

- Insert check_doc_frontmatter into sys.modules before exec_module so
  dataclasses can resolve string annotations (fixes Docs Review / agent
  rules governance fixture).
- Call SmartCoverageManager._update_cache with _SmartCacheUpdate after
  signature refactor (fixes basedpyright reportCallIssue).

Made-with: Cursor

* fix(tests): align install_module mocks with InstallModuleOptions; register verify_bundle script

- Monkeypatch/patch fakes now accept (module_id, options=None) matching
  install_module(module_id, InstallModuleOptions(...)).
- Read install_root, trust_non_official, non_interactive, reinstall from
  InstallModuleOptions in CLI command tests.
- Dynamic load of verify-bundle-published registers sys.modules before
  exec_module (same dataclass annotation issue as check_doc_frontmatter).

Made-with: Cursor

---------

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

* Fix review findings (#498)

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

* feat(openspec): add marketplace-06-ci-module-signing change proposal

Moves module signing from local interactive requirement to CI step
triggered by PR approval (pull_request_review). Eliminates local private
key dependency for non-interactive development on feature/dev branches.
Trust boundary remains at main.

Scope:
- NEW .github/workflows/sign-modules-on-approval.yml
- MODIFY scripts/pre-commit-smart-checks.sh (branch-aware policy)
- MODIFY .github/workflows/pr-orchestrator.yml (split verify by target)
- MODIFY .github/workflows/sign-modules.yml (main-only enforcement)

GitHub: #500
Parent Feature: #353 (Marketplace Module Distribution) → #194 (Architecture Epic)
Paired modules change: specfact-cli-modules#185

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(pre-commit): modular hooks + branch-aware module verify (#501)

* chore(pre-commit): modular hooks aligned with specfact-cli-modules

- Add scripts/pre-commit-quality-checks.sh (block1 stages + block2; all for manual/shim)
- Replace monolithic smart-checks with shim to quality-checks all
- .pre-commit-config: fail_fast, verify-module-signatures + check-version-sources,
  cli-block1-* hooks, cli-block2, doc frontmatter
- Match modules: hatch run lint when Python staged; scoped code review paths
- CLI extras: Markdown fix/lint, workflow actionlint (no packages/ bundle-import gate)
- Bump to 0.46.1; docs: README, CONTRIBUTING, code-review.md, agent-rules/70

Made-with: Cursor

* fix(pre-commit): branch-aware module verify hook (marketplace-06 policy)

- Add scripts/pre-commit-verify-modules.sh and git-branch-module-signature-flag.sh
- Point verify-module-signatures hook at wrapper (script); skip when no staged module paths
- pre-commit-quality-checks all: delegate module step to wrapper; safe-change allowlist
- Tests + CONTRIBUTING/CHANGELOG alignment

Made-with: Cursor

* fix(pre-commit): address review — portable quality checks and signature policy

- Emit require/omit from git-branch-module-signature-flag; pass --require-signature only on main
- Resolve repo root in pre-commit-smart-checks via git rev-parse for .git/hooks copies
- Harden pre-commit-quality-checks: ACMR staged paths, pipefail, no xargs -r, safe loops
- CHANGELOG/CONTRIBUTING: Added vs Changed; document verifier CLI (no --allow-unsigned)
- Tests: omit/require expectations, detached HEAD; shim asserts repo-root exec

Made-with: Cursor

* docs: align signing and verification docs with verifier CLI

- Document checksum-only vs --require-signature; clarify --allow-unsigned is sign-modules.py only
- Add pre-commit and CI branch policy to module-security, signing guide, publishing, agent gates
- Refresh marketplace-06 OpenSpec proposal/design/tasks/spec delta; openspec validate --strict OK
- CHANGELOG: note doc and OpenSpec alignment

Made-with: Cursor

* fix(pre-commit): address review — sig_policy guard, DRY contract check, tests

- Validate require|omit from git-branch-module-signature-flag; error on unknown policy
- check_contract_script_exists for tools/contract_first_smart_test.py (run_block2 + run_all)
- Comment why contract-test-status stdout/stderr are discarded
- Tests: run_all-scoped markdown order; fake hatch integration for verify wrapper; 8s flag timeout

Made-with: Cursor

* fix(pre-commit): review follow-ups — Block 2 scope, git diff errors, skip test

- check_safe_change: do not exempt pre-commit wrapper scripts from Block 2 when staged
- pre-commit-verify-modules: fail if git diff --cached fails (no || true)
- test: no-module-tree fast path; touch hatch log so skip path can assert empty
- CHANGELOG: reflow + note git-diff failure handling and Block 2 exemption removal

Made-with: Cursor

* fix(pre-commit): classify changelog, harden format diff, extend verify tests

- Move pre-commit follow-ups under 0.46.1 ### Fixed; note git diff exit >1 handling
- run_format_safety: fail only when git diff exit code > 1 (keep diff=1 as success)
- Test: fake git fails on diff --cached; skip-path uses staged docs/notes.txt only

Made-with: Cursor

* fix(pre-commit): legacy verify shim, mdc markdown, safe-change parity

- Add pre-commit-verify-modules-signature.sh delegating to canonical verify
- run_module_signature_verification: prefer canonical, fallback legacy, log path
- Treat staged *.mdc like *.md; replace mapfile for Bash 3.2; drop pyproject/setup
  from Block 2 safe-change skip; extend tests for bundled module tree + legacy
- Split pre-commit layout assertions to satisfy code-review complexity gate

Made-with: Cursor

---------

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

* apply code review fixes

* apply code review fixes

* fix(pre-commit): include staged deletions in staged_files() for Block 2

Use diff-filter ACMRD so deletion-only commits are not treated as empty
safe changes. Restrict markdown and code-review paths to existing files.

Made-with: Cursor

* Fix review findings

* Fix code review findings

* feat(ci): module signing on PR approval and manual workflow_dispatch (#503)

* feat(ci): sign modules on PR approval and manual dispatch

- Add sign-modules-on-approval workflow (approved reviews, dev/main base)
- Extend sign-modules.yml with workflow_dispatch inputs and sign-and-push job
- Document flows in module-security.md; update CHANGELOG and tests

Made-with: Cursor

* Fix sign review and process

---------

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

* Feature/ci module sign on approval (#504)

* feat(ci): sign modules on PR approval and manual dispatch

- Add sign-modules-on-approval workflow (approved reviews, dev/main base)
- Extend sign-modules.yml with workflow_dispatch inputs and sign-and-push job
- Document flows in module-security.md; update CHANGELOG and tests

Made-with: Cursor

* Fix sign review and process

* Fix signature flow

* Fix review gate findings

* Fix review gate findings

---------

Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>
Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>

* feat(ci): workflow_dispatch for sign-modules-on-approval (#505)

- Add sign-on-dispatch job with base_branch/version_bump inputs and merge-base signing
- Rename approval job to sign-on-approval; fix concurrency for manual runs
- Document default-branch vs Run workflow on dev; update tests and CHANGELOG
- Refactor workflow tests to satisfy code-review complexity gate

Made-with: Cursor

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

* fix(ci): module signing workflows, PyPI version check, and review gate

Align VERIFY_ARGS order; use immutable PR base SHA and branch checkout for
approval signing; make PyPI ahead-of-registry check lenient on network failures
in PR jobs. Refactor workflow policy tests for radon complexity; add beartype and
icontract to the PyPI check script; restore init manifest signature field where
applicable.

Made-with: Cursor

* fix(modules): bump init to 0.1.28 for enforce-version-bump on dev

The prior commit added integrity.signature without incrementing the module
version, so sign-modules verify failed (same 0.1.27 vs HEAD~1). Refresh checksum;
CI will re-add signatures via Module Signature Hardening workflow_dispatch.

Made-with: Cursor

* chore(release): v0.46.2 — require signatures on all PRs to main

Bump patch version across canonical sources. Tighten pr-orchestrator and
sign-modules verify so every PR targeting main uses --require-signature,
matching the post-merge main push gate.

Made-with: Cursor

* sign changed package

* fix(modules): bump init to 0.1.29 for dev→main PR version gate

enforce-version-bump compares changed manifests to origin/main; signing-only
changes on 0.1.28 still failed. Re-sign integrity.signature locally after pull.

Made-with: Cursor

* Signed modules and bumped version

* Signed modules and bumped version

* Fix sign flow

* feat: dep-security-cleanup (license gate, pycg, commentjson, review env) (#507)

* feat(openspec): add dep-security-cleanup change artifacts

Proposal, design, specs (call-graph-analysis, dependency-resolution,
dep-license-gate), and tasks for removing GPL/wrong deps and introducing
proactive license + CVE gates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dep-security-cleanup (license gate, pycg, commentjson, review env)

Implements openspec/dep-security-cleanup: pip-licenses-style compliance script,
call graph via pycg, commentjson for VS Code JSONC, optional-deps hygiene,
subprocess-only SPECFACT_MODULES_REPO for pre-commit code review, docs and CI.

Made-with: Cursor

* docs(openspec): source tracking for dep-security-cleanup and CHANGE_ORDER row

Link PR #507 in proposal Source Tracking; register dep-security-cleanup under
openspec/CHANGE_ORDER.md (deps module).

Made-with: Cursor

* docs(openspec): link dep-security-cleanup to GitHub issue #508

Register tracking issue in proposal Source Tracking and CHANGE_ORDER.

Made-with: Cursor

* Fix code review findings and add version check

* Fix review findings

* Fix module sign logic

* feat(deps): remove GPL/wrong packages, add license-gate and security-audit (#508)

* fix(versioning): enforce packaged artifact bump policy (#508)

* Bump registry version

* Fix review findings and test failurs

* Fix validation script

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* apply review findings

* Fix publish module and security gate findings

* Fix findings and publish bug

* Fix review findings and publish modules flow

* Update publish and sign flows

* Update publish and sign flows

* chore(modules): auto-sign bundled manifests [skip ci] (#510)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Apply code review findings

* Fix failed tests

* [codex] Add five-pillar governance OpenSpec wave (#531)

* 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>

* [codex] stabilize module install and init state (#535)

* 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>

* chore(modules): auto-sign bundled manifests [skip ci] (#536)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: remove unused checksum tuple in verifier

* chore: reduce low-signal coderabbit review noise

* fix: address codex review findings

* fix: tighten local gate scope and module verification

* Make `specfact upgrade` install-method-aware (uv/uvx support, pipx/pip detection) (#539)

* refactor(upgrade): resolve clean-code warnings in upgrade detection flow

* chore(modules): bump upgrade manifest checksum and version

* fix(upgrade): address review findings for openspec evidence and path-safe detection

* chore(release): bump version artifacts to 0.46.10

* fix(upgrade): pin uv pip upgrades to detected interpreter

* fix(upgrade): quote pip executable and suppress uvx check-only command hint

* fix(cli): gracefully handle missing lazy command groups in help/delegation

* fix(cli,upgrade): handle runtime lazy-command errors and uv tool detection

* Fix: failing tests

* fix(cli): handle stale flat lazy shims

---------

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

* chore(modules): auto-sign bundled manifests [skip ci] (#540)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix(upgrade): prefer pipx before uv tool detection

* fix(upgrade): address PR 541 review findings

* fix(cli,upgrade): address PR 541 critical findings

* chore(modules): auto-sign bundled manifests [skip ci] (#546)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Fix module upgrade signature and version bump

* chore(modules): auto-sign bundled manifests [skip ci] (#548)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix(ci): terminate module publish output list

* fix(cli): forward bare lazy subcommands (#549)

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

* chore(openspec): park 21 deferred proposals + simplify CHANGE_ORDER (#551)

* chore(openspec): park 21 deferred change proposals

Move proposals that are awaiting external signal (paying enterprise customer,
third-party publisher, evidence corpus, etc.) from openspec/changes/ into
a new openspec/parking-lot/ directory, preserving full content and history.

This restores focus on the active core thesis (full-chain traceability for
agile DevOps + AI IDEs) without abandoning prior thinking. Each parked
proposal has an explicit un-park trigger documented in
openspec/parking-lot/README.md.

Parked groups:
- enterprise-01..04 (4): no paying enterprise customer yet
- finops-01..02 (2): no internal LLM workload to optimise yet
- knowledge-01..02 (2): insufficient evidence corpus for distillation
- marketplace-03..06 (4): no third-party publishers to onboard
- security-01..02 (2): no customer-driven security review demand
- review-resiliency-01-contracts (1): code-review module gap unproven
- profile-02..03 (2): profile-01 not yet shipped
- cli-val-01,02,05,06 (4): infrastructure ahead of demand;
  cli-val-03 and cli-val-04 remain active

Active changes drop from 45 to 24. No CI workflows or production code
referenced the parked directories; only comment-level references remain
in already-shipped marketplace-06 helper scripts. openspec list is clean.

Also adds a missing fenced-code language tag to a parked design.md
to satisfy the markdownlint pre-commit hook.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(openspec): rewrite CHANGE_ORDER.md to reflect parked roadmap

Reduce from 647 to 214 lines and reorganise around five active tracks
instead of ten plan-derived addenda. The previous file accumulated
historical narrative ("plan-derived addendum 2026-02-15", "addendum
2026-03-22", etc.) that belonged in git history, and listed many
changes that no longer exist as folders here (moved to modules repo
or already archived).

New structure:
- Status snapshot: 24 active / 21 parked / 104 archived with paths
- Five active tracks (full-chain, AI IDE, profile, CLI reliability, other)
- Modify queue: explicit list of proposals needing scope adjustment
  before implementation begins
- Five waves (1: adjust scope, 2: foundations, 3: chain assembly,
  4: evidence + AI surface, 5: proof + extensions) with auditable
  exit gates
- Ownership authority table (kept; still load-bearing)
- Pointers to parking-lot, archive, and the modules-repo companion plan

Stale content removed: old "Implemented" table (51 archived items
already in changes/archive/), four separate addendum sections, tables
for backlog-scrum/kanban/safe that just said "moved to modules", a
GitHub blocked-by relationships table that duplicated each track's
own Blocked-by column, and references to changes that don't exist as
active folders.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(openspec): fix Modify queue count "Five" -> "Six"

PR #551 review caught the prose/table mismatch: the Modify queue
intro said "Five active changes" but the table lists six
(integration-01, architecture-02, telemetry-01, ai-integration-02,
ai-integration-04, openspec-01). The table is the canonical list;
all six adjustments are still required before implementation.

Other count wording verified consistent:
- "five independent tracks" (line 28) refers to Tracks A-E - correct.
- Wave 1 references in the wave plan name the queue by reference,
  not by count.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(openspec): archive marketplace-06 (incorrectly parked, already shipped)

Re-validation of parked changes against git history found that
marketplace-06-ci-module-signing was substantially implemented in dev
(PRs #501, #503, #504, #505 + commit a1dda6d7) before the 2026-05-05
parking triage, but its tasks.md still read 0/N done so it was placed
in parking-lot/ by mistake.

Move the change to openspec/changes/archive/2026-05-06-marketplace-06-ci-module-signing/,
mark all tasks [x] in bulk, and add an "Implementation history" banner
documenting the actual merging PRs and verified on-disk deliverables
(sign-modules-on-approval.yml, git-branch-module-signature-flag.sh,
branch-aware verify-module-signatures gating).

Update parking-lot/README.md (remove marketplace-06 row) and
CHANGE_ORDER.md status snapshot (parked 21 -> 20, archived 104 -> 105).

All 20 other core parked changes and all 9 modules-side parked changes
were re-validated and have no implementation traces; they remain
correctly parked.

* fix(openspec): sync specs from archived marketplace-06 via openspec archive

The previous commit (8443297b) moved marketplace-06-ci-module-signing
into the archive directory manually, which skipped the
`openspec archive` step that syncs delta specs into main specs.

Re-ran the proper flow:
1. Move change back to openspec/changes/marketplace-06-ci-module-signing/
2. Run `openspec archive marketplace-06-ci-module-signing --yes`

That command applied the delta specs to:
- openspec/specs/ci-integration/spec.md (3 added)
- openspec/specs/ci-module-signing-on-approval/spec.md (3 added, new file)

Net effect on this PR is the proper inclusion of those spec updates;
the archive folder content from 8443297b is unchanged (banner +
checked tasks preserved).

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>

* Ignore claude settings.json

* docs: refine telemetry change to active opt-in (#555)

* Refine telemetry change to active opt-in

* Address telemetry opt-in review annotations

* Align telemetry payload field names

* Clarify telemetry semantic payload contract

* Align telemetry sanitizer transition spec

* Track modules telemetry docs rollout

* Tighten telemetry implementation tasks

---------

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

* fix runtime module discovery reliability (#558)

* fix runtime module discovery reliability

* fix runtime discovery review findings

* fix installed module loader test fixture

* fix review feedback on runtime discovery state isolation

---------

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

* chore(modules): auto-sign bundled manifests [skip ci] (#559)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* [codex] Add module scope version diagnostics (#566)

* Add module scope version diagnostics

* Fix CI checks for module diagnostics

* Address module diagnostics review findings

* fix: apply CodeRabbit auto-fixes

Fixed 5 file(s) based on 4 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>

* fix: tighten dependency fast-path identity checks

* test: cover registry-id mismatch dependency path

* style: run hatch format and apply formatter output

* fix: resolve header typing regressions in strict type-check

* test: require registry id file for already-satisfied bundle dependency assertion

Bundle dependency installs now log at info only when the dependency
directory includes .specfact-registry-id matching the marketplace id.
Update the test fixture to mirror a normal install so CI matches installer
behavior.

Co-authored-by: Dom <djm81@users.noreply.github.com>

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>

* chore(modules): auto-sign bundled manifests [skip ci] (#567)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: address module dependency review findings

* fix: address dependency review follow-ups

* Fix dependency resolver bounds and bundle dependency validation

* Fix bundled module publish summary quoting

* fix(upgrade): suppress benign pipx spaced-home warning (#574)

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

* chore(bundled-modules): snapshot from dev@3f74602 (#576)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore(modules): auto-sign bundled manifests [skip ci] (#575)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Dom <39115308+djm81@users.noreply.github.com>

* fix(upgrade): tolerate undecodable child output

* chore(modules): auto-sign bundled manifests [skip ci] (#578)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore(bundled-modules): snapsho…
djm81 added a commit that referenced this pull request Jun 2, 2026
* Fix module install

* Fix module install

* Fix failed tests

* Fix marketplace client regression

* Fix install regression for specfact-cli (#380)

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

* Add changes to improve runtime validation and backlog module remaining migration to module

* refactor: remove backlog ownership from core cli (#384)

* refactor: remove backlog ownership from core cli

* fix: align CI marketplace validation paths

* test: stabilize command audit validation and add command-surface change

---------

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

* Add new command alignment change

* fix: finalize cli runtime validation regressions (#387)

* fix: finalize cli runtime validation regressions

* test: align satisfied dependency logging assertions

---------

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

* docs: archive cli-val-07 change

* Archive changes and update specs

* Add code-review change proposals

* test: align command surface regression coverage

* docs: add OpenSpec change for backlog-core commands migration (#390)

* feat: add OpenSpec change for backlog-core commands migration

Change: backlog-02-migrate-core-commands
- Add proposal, design, tasks, specs
- Add TDD_EVIDENCE.md with implementation progress
- GitHub Issue: #389

Rules applied: AGENTS.md Git Worktree Policy, TDD Hard Gate

Made-with: Cursor

* docs: update TDD_EVIDENCE and tasks for quality gate results

Made-with: Cursor

* docs: update TDD_EVIDENCE with test fix results

Made-with: Cursor

* docs: update TDD_EVIDENCE with all test fixes complete

Made-with: Cursor

---------

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

* fix: use POST instead of PATCH for ADO work item creation (#391)

* fix: use POST instead of PATCH for ADO work item creation

Azure DevOps API requires POST (not PATCH) for creating work items.

Also fixed category grouping to always register group commands.

Made-with: Cursor

* docs: add changelog entry for ADO POST fix

Made-with: Cursor

* chore: bump version to 0.40.4

Made-with: Cursor

* fix: update test mocks from PATCH to POST for ADO create

- Reverted incorrect unconditional _mount_installed_category_groups call

- Updated test_create_issue mocks to use requests.post instead of requests.patch

Made-with: Cursor

* test: skip category group test when bundles not installed

The test_bootstrap_with_category_grouping_disabled_registers_flat_commands test

expects bundles like specfact-codebase to be installed, but in CI they may not be.

Added pytest.skip() when 'code' command is not available.

Made-with: Cursor

---------

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

* docs: archive backlog-02-migrate-core-commands change

- Archived backlog-02-migrate-core-commands change

- Updated CHANGE_ORDER.md with implementation status

- Updated main specs with backlog-add, backlog-analyze-deps, backlog-delta, backlog-sync, backlog-verify-readiness

Made-with: Cursor

* feat: document code-review module scaffold (#410)

* feat: document code-review module scaffold

* chore: sync 0.41.0 release version artifacts

---------

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

* Add change for project codebase ownership

* Realign code import ownership surface (#412)

* Realign code import ownership surface

* Harden temp registry command audit test

---------

Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>
Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>

* Update code review changes

* docs: update reward ledger OpenSpec tracking (#413)

Link the existing change issue, record TDD evidence, and align the OpenSpec artifacts with the bundle-owned DDL and paired worktree implementation flow.

Made-with: Cursor

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

* Track house-rules skill OpenSpec changes (#414)

Made-with: Cursor

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

* docs: Update change-proposal for code-review-07 (#415)

* Track house-rules skill OpenSpec changes

Made-with: Cursor

* Cursor: Apply local changes for cloud agent

---------

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

* Finalize code-review-07 status

* Finalize code-review-08 status

* feat: apply code-review-09 pre-commit integration

* fix: fall back when cached hatch test env is broken

* fix: avoid hatch env for coverage xml export

* fix: install type-check and lint tools directly in CI

* fix: install pytest fallback deps in test job

* fix: install pytest-cov for test fallback path

* Finalize code-review-09 status

* [Change] Align core docs with modules site ownership (#419)

* Align core docs with modules site ownership

* Close docs portal change PR task

---------

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

* fix: harden docs parity URL assertions

* Archive finished changes and update specs

* docs: fix command syntax parity after lean-core/modules split (v0.42.2) (#421)

Replace all stale CLI syntax families in authored docs with current
shipped commands. Adds docs parity tests that guard against regression.

Removed syntax families corrected:
- specfact project plan → project devops-flow / project snapshot / govern enforce sdd
- project import from-bridge → code import from-bridge
- specfact backlog policy → backlog verify-readiness / backlog refine
- specfact spec contract → spec validate / spec generate-tests / spec mock
- specfact spec sdd constitution → govern enforce sdd [BUNDLE]
- spec generate <prompt-subcommands> → AI IDE skills or removed

Updated docs: README.md, docs/index.md, docs/README.md,
docs/reference/commands.md (+4 reference docs),
docs/getting-started/ (4 files), docs/guides/ (21 files),
docs/examples/ (5 files), docs/prompts/ (2 files).

Added 11 new docs parity tests in test_release_docs_parity.py:
- 7 tests asserting removed syntax families stay absent
- 4 tests asserting current command families remain documented

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Archive finished changes and update specs

- Archive docs-03-command-syntax-parity (2026-03-18)
- Sync delta specs: cli-output + documentation-alignment updated with
  post-split command-surface alignment requirements and scenarios
- Update CHANGE_ORDER.md: mark docs-03 as archived

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update evidence

* Potential fix for pull request finding 'Unused global variable'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>

* docs: align core docs ownership and parity (#424)

* docs: fix command syntax parity after lean-core/modules split (v0.42.2)

Replace all stale CLI syntax families in authored docs with current
shipped commands. Adds docs parity tests that guard against regression.

Removed syntax families corrected:
- specfact project plan → project devops-flow / project snapshot / govern enforce sdd
- project import from-bridge → code import from-bridge
- specfact backlog policy → backlog verify-readiness / backlog refine
- specfact spec contract → spec validate / spec generate-tests / spec mock
- specfact spec sdd constitution → govern enforce sdd [BUNDLE]
- spec generate <prompt-subcommands> → AI IDE skills or removed

Updated docs: README.md, docs/index.md, docs/README.md,
docs/reference/commands.md (+4 reference docs),
docs/getting-started/ (4 files), docs/guides/ (21 files),
docs/examples/ (5 files), docs/prompts/ (2 files).

Added 11 new docs parity tests in test_release_docs_parity.py:
- 7 tests asserting removed syntax families stay absent
- 4 tests asserting current command families remain documented

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: align core docs ownership and parity

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: fix quickstart install guidance

* docs: remove generated project plan docs

* Add code-review change

* fix: preserve native backlog import payloads (#429)

* fix: preserve native backlog import payloads

* fix: preserve imported proposal ids on reimport

---------

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

* fix: add docs review workflow and repair docs links (#428)

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

* fix: keep imported change ids stable across title changes (#431)

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

* fix: remove conflicting pages file copies

* Add docs sync changs

* docs: update openspec clean-code planning

* Update change status

* fix: code-review-zero-findings dogfood remediation (v0.42.3) (#435)

* fix: continue code review remediation and align module signing

* fix: complete code-review-zero-findings dogfood remediation (v0.42.3)

Eliminates full-scope code review findings (types, Radon CC, contracts, lint) and records OpenSpec change code-review-zero-findings with tests and CHANGELOG. Module manifests may need re-signing before merge per project policy.

Made-with: Cursor

* chore: re-sign bundled modules after content changes

* fix: resolve review follow-up regressions

* fix: run ci smart-test directly

* fix: restore ci test progress output

* fix: stabilize command audit ci test

---------

Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>
Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>

* Add docs refactoring changes

* Add bug change tracking for encoding and resources

* docs: restructure core site IA to 6-section progressive nav (#442)

* docs: restructure core site IA from 5 flat sections to 6 progressive sections

Restructure docs.specfact.io from a flat 5-section sidebar to a 6-section
progressive navigation: Getting Started, Core CLI, Module System, Architecture,
Reference, Migration.

- Create docs/core-cli/, docs/module-system/, docs/migration/ directories
- Move 12 files to correct new sections with jekyll-redirect-from entries
- Write 3 new CLI reference pages: init.md, module.md, upgrade.md
- Replace first-steps.md with focused 5-minute quickstart
- Rewrite index.md as portal landing with core vs modules delineation
- Rewrite getting-started/README.md to link module tutorials to modules site
- Update sidebar navigation in _layouts/default.html
- Delete 6 obsolete files (competitive-analysis, ux-features, common-tasks,
  workflows, testing-terminal-output, guides/README)
- Add documentation-alignment delta spec for core-only focus policy

Implements: #438
OpenSpec: docs-05-core-site-ia-restructure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: fix broken internal links after IA restructure

Update all relative links across 40 files to point to new file locations:
- ../reference/architecture.md → ../architecture/overview.md
- ../reference/debug-logging.md → ../core-cli/debug-logging.md
- ../reference/modes.md → ../core-cli/modes.md
- guides/ sibling links → ../module-system/ or ../migration/
- module-system/ back-links → ../guides/
- Remove links to deleted files (common-tasks, workflows)
- first-steps.md → quickstart.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update test path for moved bootstrap-checklist and fix remaining broken links

- Update test_module_bootstrap_checklist_uses_current_bundle_ids to use
  new path docs/module-system/bootstrap-checklist.md
- Fix 2 remaining command-chains.md anchor links in migration-guide.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden cross-platform runtime and IDE resource discovery (#443)

* fix: harden cross-platform runtime and IDE resource discovery

* fix: bump patch version to 0.42.4

* fix: restore init lifecycle compatibility

---------

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

* fix: resolve review type-safety findings

* Improve clarity and scope of ide prompt change

* feat(init): IDE prompt source catalog, --prompts, namespaced exports (#445)

* feat(init): IDE prompt source catalog, --prompts, namespaced exports

Implement init-ide-prompt-source-selection: discover core + module prompts,
default export all sources, interactive multi-select, non-interactive --prompts,
source-namespaced IDE paths. Fix project module roots to use metadata source
project. Extend discovery roots with user/marketplace. Update startup_checks
for nested exports. Bump init module to 0.1.14 with signed manifest.

Made-with: Cursor

* fix(init): scope VS Code prompt recommendations to exported sources

- Pass prompts_by_source into create_vscode_settings from copy_prompts_by_source_to_ide
- Strip prior .github/prompts/* recommendations on selective export to avoid stale paths
- Extract helpers for catalog paths and fallbacks; keep code review clean

Made-with: Cursor

---------

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

* fix tests

* release: bump version to 0.42.5 and update CHANGELOG

- Remove [Unreleased] sections; fold historical arch-08 notes under [0.34.0]
- Document init ide catalog, VS Code recommendations, integration test isolation

Made-with: Cursor

* Fix review findings

* feat(init): selective IDE prompt export cleanup and VS Code recommendation strip

- Prune stale exports and unselected catalog segments in copy_prompts_by_source_to_ide
- Strip only specfact*.prompt.md under .github/prompts/ when merging VS Code settings
- Tighten e2e missing-templates assertions to match CLI output
- Add unit tests for prompt path helper and selective export behavior

Made-with: Cursor

* Fix review findings

* Add missing import

* Bump patch version and changelog

* Fix failed tests

* Fix review findings

* docs: core vs modules URL contract and OpenSpec alignment (#448)

* docs: add core vs modules URL contract and OpenSpec alignment

Document cross-site permalink rules in docs/reference, extend documentation-alignment
and module-docs-ownership specs, update docs-07 and openspec config, and note the
dependency on modules URL policy in CHANGE_ORDER.

Made-with: Cursor

* docs: convert core handoff pages to modules canonical links (docs-07)

- Replace 20 duplicate guides/tutorials with thin summaries, prerequisites,
  and links to modules.specfact.io per URL contract
- Add docs/reference/core-to-modules-handoff-urls.md mapping table
- Align OpenSpec documentation-alignment spec delta with ADDED Requirements
- Complete docs-07-core-handoff-conversion tasks checklist

Refs: #439
Made-with: Cursor

---------

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

* feat(docs-12): docs command validation and cross-site link checks (#449)

* feat(docs-12): docs command validation and cross-site link checks

- Add check-docs-commands (Typer CliRunner prefix + --help) and exclusions for migration/illustrative pages
- Add check-cross-site-links with robust URL extraction; warn-only in docs-validate and CI while live site may lag
- Extend docs-review: Hatch env, validation steps, pytest tests/unit/docs/
- Opt-in handoff map HTTP test (SPECFACT_RUN_HANDOFF_URL_CHECK=1)
- OpenSpec deltas, TDD_EVIDENCE, tasks complete; CHANGELOG [Unreleased]

Made-with: Cursor

* fix(docs-validate): strip leading global flags before command path

- Parse --mode/--input-format/--output-format + value, then other root flags
- Add test for specfact --mode copilot import from-code …
- Fix showcase docs: hatch run contract-test-exploration (not specfact)

Made-with: Cursor

* fix(docs-12): harden link/command validators and spec wording

- Capitalize Markdown in cross-site link spec requirement
- Cross-site: redirect-only HTTP success, UTF-8 read failures, URL delimiter/trim fixes
- Docs commands: catch Typer exceptions on --help, UTF-8 read failures
- Tests: shared loader for check-cross-site-links module

Made-with: Cursor

---------

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

* fix(scripts): CliRunner without mix_stderr for Click 8.3+ compatibility (#451)

Default CliRunner() merges stderr into stdout; read stdout only so
accessing result.stderr does not raise when streams are combined.

Made-with: Cursor

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

* fix: review gates (semgrep print, radon CC, icontract, questionary types) (#452)

* fix: satisfy review gates for docs scripts and module_lifecycle typing

- Replace print() with Rich Console in docs validation scripts (semgrep)
- Split HTTP URL checks and doc scans to reduce cyclomatic complexity (radon)
- Add icontract require/ensure on public helpers; use CliRunner() without mix_stderr
- Cast questionary API for basedpyright reportUnknownMemberType

Made-with: Cursor

* fix(scripts): address #452 review (HTTP helpers, icontract, CLI streams)

- _http_success_code: use int directly after None guard
- _response_status: safe getcode via getattr/callable
- check-docs: drop @require preconditions duplicated by beartype
- _cli_invoke_streams_text: merge stdout + stderr for not-installed detection

Made-with: Cursor

---------

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

* Add speckit adapter alignment change and update affected change specs

* feat(adapters): spec-kit v0.4.x adapter alignment (#454)

* feat(adapters): spec-kit v0.4.x adapter alignment — extensions, presets, hooks, version detection, 7-command presets

Update SpecKitAdapter, ToolCapabilities, BridgeConfig presets, and
SpecKitScanner for spec-kit v0.4.3 compatibility:

- ToolCapabilities: 5 new optional fields (extensions, extension_commands,
  presets, hook_events, detected_version_source)
- SpecKitScanner: scan_extensions(), scan_presets(), scan_hook_events()
  with .extensionignore support and defensive JSON parsing
- SpecKitAdapter: 3-tier version detection (CLI → heuristic → None),
  refactored get_capabilities() with reduced cyclomatic complexity
- BridgeConfig: all 3 speckit presets expanded from 2 to 7 command
  mappings (specify, plan, tasks, implement, constitution, clarify, analyze)
- 42 new tests across 4 test files (110 targeted, 2248 full suite pass)
- Docs updated: comparison matrix, journey guide, integrations overview,
  adapter development guide

Closes #453

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address CodeRabbit review findings

- Use get_bridge_logger instead of logging.getLogger in speckit adapter
  and scanner (production command path convention)
- Narrow except Exception to except OSError in _load_extensionignore
- Simplify redundant base_path conditional in get_capabilities
- Use SimpleNamespace instead of dynamic type() in tests
- Add subprocess.TimeoutExpired and OSError exception tests for CLI
  version detection
- Fix duplicate MD heading in bridge-adapter spec
- Add blank lines after markdown headings in proposal (MD022)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* chore: bump version to 0.43.0 for spec-kit v0.4.x alignment (#455)

* chore: bump version to 0.43.0 and add changelog entry

Minor version bump for spec-kit v0.4.x adapter alignment feature.
Syncs version across pyproject.toml, setup.py, and __init__.py.
Adds changelog entry documenting new capabilities.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Sync deps and fix changelog

* Sync deps and fix changelog

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix(packaging): remove workflow prompts from core wheel (packaging-02 #441, v0.43.1) (#456)

* fix(packaging): drop duplicate workflow prompts from core wheel (packaging-02 3.5)

Remove resources/prompts from wheel force-include and repo tree; canonical
copies remain in specfact-cli-modules bundles. Align startup IDE drift
checks and init template resolution with discover_prompt_template_files.
Bump to 0.43.1; re-sign init module 0.1.19. Update CHANGELOG, docs, OpenSpec.

Made-with: Cursor

* fix: address PR review (changelog, TDD evidence, startup checks, tests)

- Changelog 0.43.1 header uses Unreleased until release tag
- TDD_EVIDENCE: pre-fail block for Task 3.5 before passing verification
- TemplateCheckResult.sources_available; skip last_checked_version bump when no
  discoverable prompts; drift missing only when source exists
- Integration _fake_discover respects include_package_fallback
- test_validate_all_prompts uses tmp_path; re-enable file in default test run
- test_print_startup_checks_version_update_no_type uses stale version timestamp

Made-with: Cursor

* fix: address follow-up PR review (startup metadata, tests)

- Use ide_dir directly in TemplateCheckResult when IDE folder exists
- Set last_checked_version only after successful template-source checks
- Integration test: assert discover_prompt_template_files fallback + stable startup patches
- validate_all_prompts test: valid vs invalid specfact.*.md outcomes

Made-with: Cursor

---------

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

* Potential fix for pull request finding 'Empty except'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>

* Fix changelog version

* docs: unify core docs portal UX (#459)

* docs: unify core docs portal UX

* Fix docs-13 core review findings

* Address docs-13 PR review feedback

* Address follow-up docs review feedback

---------

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

* Harden docs home URL test assertion

* feat: doc frontmatter validation, v0.43.2 review JSON gate, and pre-commit review UX (#463)

* chore(release): v0.43.2 pre-commit review JSON + OpenSpec dogfood rules

- Pre-commit gate writes ReviewReport JSON to .specfact/code-review.json
- openspec/config.yaml: require fresh review JSON and remediate findings
- Docs and unit tests updated

Made-with: Cursor

* fix: CodeRabbit — changelog, openspec TDD_EVIDENCE freshness, review hook timeout

- CHANGELOG 0.43.2: expanded entries, line wrap
- openspec/config.yaml: exclude TDD_EVIDENCE.md from review JSON staleness
- pre_commit_code_review: timeout 300s, TimeoutExpired handling
- tests: exact cwd, timeout assertion and timeout failure test

Made-with: Cursor

* Add code review to pre-commit and frontmatter docs validation

* Improve pre-commit script output

* Improve specfact code review findings output

* Fix review findings

* Improve pre-commit hook output

* Enable dev branch code review

* Update code review hook

* Fix contract review findings

* Fix review findings

* Fix review warnings

* feat: doc frontmatter hardening and code-review gate fixes

- Typer CLI for doc-frontmatter-check; safer owner resolution (split helpers for CC)
- Strict exempt handling; pre-commit hook matches USAGE-FAQ.md; review script JSON typing
- Shared test fixtures/types; integration/unit test updates; OpenSpec tasks and TDD evidence
- Changelog: pre-commit code-review-gate UX note

Made-with: Cursor

* Fix test failures and add docs review to github action runner

* Fix test failure due to UTF8 encoding

* Apply review findings

* Optimize pr orchestrator runtime

* Optimize pr orchestrator runtime

* Fix caching on pr-orchestrator

---------

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

* docs: archive doc-frontmatter-schema openspec change

* Apply suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>

* fix: restore protocol stubs for type checking

* Add frontamtter check

* fix: harden protocol stubs for code quality

* Add PR test hardening change

* fix: remediate review findings and harden review gates

* fix: rebuild review report model for pydantic

* Add story and onboarding change

* Update change tracking

* Improve scope for ci/cd requirements

* docs: sharpen first-contact story and onboarding (#467)

* docs: sharpen first-contact story and onboarding

* docs: address first-contact review feedback

* docs: address onboarding review fixes

* test: accept default-filtered site tokens in docs parity

* docs: record completed onboarding quality gates

* test: improve first-contact assertion failures

---------

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

* fix: harden review blockers and bump patch version

* test: harden modules docs url assertions

* fix: harden trustworthy green checks (#469)

* fix: harden trustworthy green checks

* fix: restore contract-first ci repro command

* fix: apply CodeRabbit auto-fixes

Fixed 3 file(s) based on 3 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>

* fix: resolve CI failures for trustworthy green checks PR

- Use hatch run contract-test instead of specfact code repro in CI
  (CLI bundle not available in CI environment)
- Allow test_bundle_import.py in migration cleanup legacy-import check
  (_bundle_import is an internal helper, not a removed module package)
- Fix formatting in test_trustworthy_green_checks.py (CodeRabbit commit
  was unformatted)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address CodeRabbit review findings

- Add trailing newline to TDD_EVIDENCE.md (MD047)
- Make _load_hooks() search for repo: local instead of assuming index 0
- Replace fragile multi-line string assertion in actionlint test with
  semantic line-by-line checks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address CodeRabbit review findings for ci-02 (#471)

- Widen workflow_changed filter to include scripts/run_actionlint.sh
  and scripts/yaml-tools.sh so Workflow Lint triggers on script changes
- Pin actionlint default to v1.7.11 (matches CI) instead of latest
- Fix run_actionlint.sh conflating "not installed" with "lint failures"
  by separating availability check from execution
- Restore sys.path after test_bundle_import to avoid cross-test leakage
- Normalize CHANGE_ORDER.md status format to semicolon convention

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix: propagate docker actionlint exit code instead of masking failures (#472)

Simplify run_actionlint.sh control flow so both local and docker
execution paths propagate actionlint's exit code via `exit $?`. Previously
the docker path used `if run_with_docker; then exit 0; fi` which treated
lint errors as "docker unavailable" and fell through to install guidance.

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix: assert hook id stability and cd to repo root for local actionlint (#473)

- Assert hook id == "specfact-smart-checks" to prevent silent renames
- cd to REPO_ROOT before running local actionlint so it finds workflows
  regardless of caller's cwd

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: clean-code-01-principle-gates — 7-principle charter gates, v0.44.0 (#474)

* feat: clean-code-01-principle-gates — 7-principle charter gates, v0.44.0

Implements openspec/changes/clean-code-01-principle-gates:

- Rewrote .cursor/rules/clean-code-principles.mdc as a canonical alias
  surface for the 7-principle clean-code charter (naming, kiss, yagni,
  dry, solid) defined in nold-ai/specfact-cli-modules. Documents Phase A
  KISS thresholds (>80 warning / >120 error LOC), nesting-depth and
  parameter-count checks active, and Phase B (>40/80) explicitly deferred.
- Added Clean-Code Review Gate sections to AGENTS.md and CLAUDE.md listing
  all 5 expanded review categories and the Phase A thresholds.
- Created .github/copilot-instructions.md as a lightweight alias (< 30 lines)
  referencing the canonical charter without duplicating it inline.
- Added unit tests (test_clean_code_principle_gates.py) covering all three
  spec scenarios: charter references, compliance gate, LOC/nesting thresholds.
- TDD evidence recorded in openspec/changes/clean-code-01-principle-gates/TDD_EVIDENCE.md.
- Bumped version 0.43.3 → 0.44.0 (minor — feature branch).
- Updated CHANGELOG.md and openspec/CHANGE_ORDER.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: clean-code-01-principle-gates review findings and broad exception handling\n\n- Fix coderabbitai review findings:\n  - Clarify T20 and W0718 are aspirational in clean-code-principles.mdc\n  - Add language specifier to TDD_EVIDENCE.md fenced code block\n  - Update test to check all 7 canonical principles\n  - Make LOC threshold assertion more specific\n- Improve exception handling throughout codebase:\n  - Replace broad except Exception with specific exceptions\n  - Apply SOLID principle for better error handling\n- Update tasks.md to reflect completion status\n\nFixes #434\n\nGenerated by Mistral Vibe.\nCo-Authored-By: Mistral Vibe <vibe@mistral.ai>

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: archive completed openspec changes and update main specs

Archive 11 completed OpenSpec changes:
- bugfix-02-ado-import-payload-slugging
- ci-02-trustworthy-green-checks
- clean-code-01-principle-gates
- code-review-zero-findings
- docs-04-docs-review-gate-and-link-integrity
- docs-05-core-site-ia-restructure
- docs-07-core-handoff-conversion
- docs-12-docs-validation-ci
- docs-13-core-nav-search-theme-roles
- docs-14-first-contact-story-and-onboarding
- init-ide-prompt-source-selection
- packaging-02-cross-platform-runtime-and-module-resources
- speckit-02-v04-adapter-alignment

Fix spec validation errors:
- Add proper delta headers (ADDED/MODIFIED/REMOVED/RENAMED)
- Use correct scenario format with GIVEN/WHEN/THEN bullets
- Ensure requirement headers match between delta and main specs
- Use correct operation type based on existing requirements

Update main specs with archived changes:
- backlog-adapter: various updates
- bridge-adapter: Spec-Kit v0.4.x capabilities
- bridge-registry: BridgeConfig preset updates
- code-review-module: new requirements
- debug-logging: enhancements
- devops-sync: improvements
- documentation-alignment: core vs modules separation
- review-cli-contracts: new contracts
- review-run-command: command updates

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

* Add new user onboarding change

* docs & tooling: new user onboarding + smart-test and pre-commit review fixes (#477)

* Fix content for install, sync, uninstallä

* test(docs): align first-contact contracts and stabilize module CLI tests

- docs/index: restore Why does it exist?, tagline, OpenSpec, canonical core CLI story
- Update init profile tests for solo-developer + install all (code-review, six bundles)
- Lean help test accepts uvx init hint; upgrade/core_compatibility tests match runtime
- Autouse fixture re-bootstraps CommandRegistry after category-group tests
- Rebase tasks conflict resolved; TDD_EVIDENCE + tasks for gates 7.1/7.2/12.1/12.2

Made-with: Cursor

* fix(tools): smart-test baseline and pre-commit single code-review run

- Run full suite when smart-test cache has no last_full_run; force+auto falls back to full when incremental is a no-op
- Pre-commit: invoke pre_commit_code_review.py once (no xargs split) so .specfact/code-review.json is not clobbered
- Tests and OpenSpec tasks for docs-new-user-onboarding

Made-with: Cursor

* test: fix CI backlog copy assertions and module install test isolation

- Align backlog not-installed tests with solo-developer init guidance (no <profile> placeholder)
- Autouse: reset CommandRegistry, register_builtin_commands, rebuild_root_app_from_registry so module install tests work after registry-only clears

Made-with: Cursor

* docs: README wow path + tests locking entrypoint with docs

- README leads with uvx init + code review run --scope full; pip install secondary
- Unit contract tests: README and docs/index.md share canonical uvx strings and order
- E2E: init --profile solo-developer in temp git repo; registry ready for step two with mock bundles

Made-with: Cursor

* feat(init): solo-developer includes code-review bundle and marketplace install

- Add specfact-code-review to canonical bundles and solo-developer preset
- Install marketplace module nold-ai/specfact-code-review via install_bundles_for_init
- Docs index: core CLI story and default starting point copy for parity tests
- CLI: missing-module hint references solo-developer profile
- smart_test_coverage: icontract requires use (self, test_level) for method contracts
- Re-sign init and module_registry manifests; tests and registry updates

Made-with: Cursor

* fix(tools): align _run_changed_only with tuple return and baseline full run

- Return (success, ran_any) from _run_changed_only; run full suite when no last_full_run
- run_smart_tests(auto, force): fall back to full tests when incremental ran nothing
- Fix wow e2e fixture typing (Iterator[None]) for basedpyright

Unblocks PR #477 CI: type-check, tests, lint job.

Made-with: Cursor

* chore(release): bump to 0.45.1 and update OpenSpec tasks status

- Sync version across pyproject.toml, setup.py, and __init__ modules
- Changelog: 0.45.1 entry for dependency profiles, smart-test baseline, CI, UX
- openspec: rolling status snapshot and task checkboxes for PR verification
- Includes prior branch work: init/profile, module registry, docs entry path, workflows

Made-with: Cursor

---------

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

* fix: code-review gate (Typer params), typer<0.24 vs semgrep, module upgrade tests (#479)

* fix: code-review gate (Typer params), typer<0.24 vs semgrep, module upgrade tests

- Split root/install Typer callbacks into merged param stubs (KISS param count).
- Patch typer.main via importlib; merge install param specs in module_registry.
- Cap typer<0.24 to stay compatible with semgrep click~=8.1.8.
- Invoke module_registry app directly in upgrade CLI tests (root app may lack module group).
- Refactors for first_run_selection, module_packages, registry tests, semgrep README.

Worktree: specfact-cli-worktrees/bugfix/code-review-cli-tests
Made-with: Cursor

* docs: use code import in examples (flat import removed from CLI)

Replace specfact [--flags] import from-code with specfact [--flags] code import
from-code so check-docs-commands matches the nested Typer path after removing
the flat import shim.

Made-with: Cursor

* Fix review findings

---------

Co-authored-by: Dom <djm81@users.noreply.github.com>

* docs: restructure README for star conversion (#480)

* docs: restructure readme for star conversion

Co-authored-by: Dom <djm81@users.noreply.github.com>

* docs: sync readme change tracking

Co-authored-by: Dom <djm81@users.noreply.github.com>

* docs: relocate readme support artifacts

Co-authored-by: Dom <djm81@users.noreply.github.com>

* docs: fix readme workflow snippet and pin demo capture

Co-authored-by: Dom <djm81@users.noreply.github.com>

* docs: address remaining readme review findings

Co-authored-by: Dom <djm81@users.noreply.github.com>

---------

Co-authored-by: Dom <djm81@users.noreply.github.com>

* archived implemented changes

* Archive and remove outdated changes

* Split and refactor change proposals between both repos

* Archive alignment change

* Add changes and github hierarchy scripts

* feat: add GitHub hierarchy cache sync (#492)

* feat: add github hierarchy cache sync

* Backport improvements from modules scripts

* Fix review findings

* Make github sync script executable

---------

Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>
Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>

* [codex] Compact agent governance loading (#493)

* feat: compact agent governance loading

* docs: mark governance PR task complete

* docs: sync governance-03 github issue metadata

* fix: restore dev branch governance block

* Apply review findings

* docs: add sibling internal wiki context for OpenSpec design

Point AGENTS.md, Claude/Copilot/Cursor surfaces, and the OpenSpec rule at
docs/agent-rules/40-openspec-and-tdd.md to read-only wiki paths (hot.md,
graph.md, concepts) via absolute paths when specfact-cli-internal is present.
Update INDEX applicability notes and extend governance tests.

Made-with: Cursor

---------

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

* Archived github hierarchy change

* Update rules for openspec archive

* Potential fix for pull request finding 'Unused local variable'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>

* Add wiki update notes

* Archive governance-03 change, format markdown, add wiki instructions for update

* Fix review findings

* Fix type errors

* fix: safe VS Code settings merge and project artifact writes (#490) (#496)

* fix: safe merge for VS Code settings.json on init ide (profile-04)

- Add project_artifact_write.merge_vscode_settings_prompt_recommendations with fail-safe
  on invalid JSON / bad chat shape; --force backs up to .specfact/recovery/ then replaces.
- Route ide_setup create_vscode_settings through helper; thread force; catch errors for CLI exit.
- Lint gate: scripts/verify_safe_project_writes.py blocks json.load/dump in ide_setup.py.
- Tests, installation docs, 0.45.2 changelog and version pins.

OpenSpec: profile-04-safe-project-artifact-writes
Made-with: Cursor

* fix(profile-04): satisfy review gate, pin setuptools for semgrep

- Refactor project_artifact_write merge path (KISS); icontract predicates
- Deduplicate ide_setup prompt helpers; import from project_artifact_write
- verify_safe_project_writes: ast.walk, contracts, beartype
- Pin setuptools<82 for Semgrep pkg_resources chain
- Update TDD_EVIDENCE and tasks checklist

Made-with: Cursor

* ci: run safe-write verifier in PR orchestrator lint job

Match hatch run lint by invoking scripts/verify_safe_project_writes.py
after ruff/basedpyright/pylint. Use set -euo pipefail so the first lint
failure is not masked by later commands.

Made-with: Cursor

* fix(profile-04): address CodeRabbit review (docs, guard, contracts, tests)

- Wrap installation.md VS Code merge paragraph to <=120 chars per line
- tasks 4.7 + TDD_EVIDENCE: openspec validate --strict sign-off
- verify_safe_project_writes: detect from-json import and aliases
- settings_relative_nonblank: reject absolute paths and .. segments
- ide_setup: _handle_structured_json_document_error for duplicate handlers
- ProjectWriteMode docstring (reserved policy surface); backup stamp + collision loop
- Tests: malformed settings preserved on init ide exit; force+chat coercion; AST guard tests

Made-with: Cursor

* fix(profile-04): JSON5 settings, repo containment, review follow-ups

- merge_vscode_settings: resolve containment before mkdir/write; JSON5 load/dump
  (JSONC comments; trailing_commas=False for strict JSON output)
- ide_setup: empty prompts_by_source skips catalog fallback (_finalize allow_empty_fallback)
- verify_safe_project_writes: detect import json as js attribute calls
- contract_predicates: prompt_files_all_strings accepts list[Any] for mixed-type checks
- Tests: symlink escape, JSONC merge, empty export strip, import-json-as-js guard
- tasks.md / TDD_EVIDENCE: wrap lines to <=120 chars; CHANGELOG + json5 dep + setup.py sync

Made-with: Cursor

* docs(profile-04): tasks pre-flight + full pytest; narrow icontract ensure

- tasks 1.1: hatch env create then smart-test-status and contract-test-status
- tasks 4.3: add hatch test --cover -v to quality gates
- TDD_EVIDENCE: shorter module-signatures and report lines (<=120 cols)
- project_artifact_write: isinstance(result, Path) in @ensure postconditions

Made-with: Cursor

* fix: clear specfact code review on safe-write modules

- verify_safe_project_writes: flatten json binding helpers; stderr writes
  instead of print; inline Import/ImportFrom loops to drop duplicate-shape DRY
- project_artifact_write: _VscodeChatMergeContext dataclass (KISS param count);
  typed chat_body cast before .get for pyright

Made-with: Cursor

* docs(profile-04): record hatch test --cover -v in TDD_EVIDENCE

Align passing evidence with tasks.md 4.3 full-suite coverage gate.

Made-with: Cursor

* fix: reduce KISS blockers (bridge sync contexts, tools, partial adapters)

Refactors high-parameter call sites into dataclasses/context objects and splits hot spots (export devops pipeline, smart_test_coverage incremental run, suggest_frontmatter, crosshair summary loop).

API: BridgeSync.export_change_proposals_to_devops(adapter_type, ExportChangeProposalsOptions | None); LoggerSetup.create_logger(name, LoggerCreateOptions | None); run_crosshair(path, CrosshairRunOptions | None).

Full specfact code review --scope full still reports error-severity kiss/radon findings (remaining nesting/LOC and param counts in ADO, analyzers, generators, source_scanner, module_installer, bundle-mapper, etc.). Gate PASS requires follow-up.

Made-with: Cursor

* Fix review findings and sign modules

* fix(tests): register dynamic check_doc_frontmatter module; align _update_cache tests

- Insert check_doc_frontmatter into sys.modules before exec_module so
  dataclasses can resolve string annotations (fixes Docs Review / agent
  rules governance fixture).
- Call SmartCoverageManager._update_cache with _SmartCacheUpdate after
  signature refactor (fixes basedpyright reportCallIssue).

Made-with: Cursor

* fix(tests): align install_module mocks with InstallModuleOptions; register verify_bundle script

- Monkeypatch/patch fakes now accept (module_id, options=None) matching
  install_module(module_id, InstallModuleOptions(...)).
- Read install_root, trust_non_official, non_interactive, reinstall from
  InstallModuleOptions in CLI command tests.
- Dynamic load of verify-bundle-published registers sys.modules before
  exec_module (same dataclass annotation issue as check_doc_frontmatter).

Made-with: Cursor

---------

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

* Fix review findings (#498)

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

* feat(openspec): add marketplace-06-ci-module-signing change proposal

Moves module signing from local interactive requirement to CI step
triggered by PR approval (pull_request_review). Eliminates local private
key dependency for non-interactive development on feature/dev branches.
Trust boundary remains at main.

Scope:
- NEW .github/workflows/sign-modules-on-approval.yml
- MODIFY scripts/pre-commit-smart-checks.sh (branch-aware policy)
- MODIFY .github/workflows/pr-orchestrator.yml (split verify by target)
- MODIFY .github/workflows/sign-modules.yml (main-only enforcement)

GitHub: #500
Parent Feature: #353 (Marketplace Module Distribution) → #194 (Architecture Epic)
Paired modules change: specfact-cli-modules#185

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(pre-commit): modular hooks + branch-aware module verify (#501)

* chore(pre-commit): modular hooks aligned with specfact-cli-modules

- Add scripts/pre-commit-quality-checks.sh (block1 stages + block2; all for manual/shim)
- Replace monolithic smart-checks with shim to quality-checks all
- .pre-commit-config: fail_fast, verify-module-signatures + check-version-sources,
  cli-block1-* hooks, cli-block2, doc frontmatter
- Match modules: hatch run lint when Python staged; scoped code review paths
- CLI extras: Markdown fix/lint, workflow actionlint (no packages/ bundle-import gate)
- Bump to 0.46.1; docs: README, CONTRIBUTING, code-review.md, agent-rules/70

Made-with: Cursor

* fix(pre-commit): branch-aware module verify hook (marketplace-06 policy)

- Add scripts/pre-commit-verify-modules.sh and git-branch-module-signature-flag.sh
- Point verify-module-signatures hook at wrapper (script); skip when no staged module paths
- pre-commit-quality-checks all: delegate module step to wrapper; safe-change allowlist
- Tests + CONTRIBUTING/CHANGELOG alignment

Made-with: Cursor

* fix(pre-commit): address review — portable quality checks and signature policy

- Emit require/omit from git-branch-module-signature-flag; pass --require-signature only on main
- Resolve repo root in pre-commit-smart-checks via git rev-parse for .git/hooks copies
- Harden pre-commit-quality-checks: ACMR staged paths, pipefail, no xargs -r, safe loops
- CHANGELOG/CONTRIBUTING: Added vs Changed; document verifier CLI (no --allow-unsigned)
- Tests: omit/require expectations, detached HEAD; shim asserts repo-root exec

Made-with: Cursor

* docs: align signing and verification docs with verifier CLI

- Document checksum-only vs --require-signature; clarify --allow-unsigned is sign-modules.py only
- Add pre-commit and CI branch policy to module-security, signing guide, publishing, agent gates
- Refresh marketplace-06 OpenSpec proposal/design/tasks/spec delta; openspec validate --strict OK
- CHANGELOG: note doc and OpenSpec alignment

Made-with: Cursor

* fix(pre-commit): address review — sig_policy guard, DRY contract check, tests

- Validate require|omit from git-branch-module-signature-flag; error on unknown policy
- check_contract_script_exists for tools/contract_first_smart_test.py (run_block2 + run_all)
- Comment why contract-test-status stdout/stderr are discarded
- Tests: run_all-scoped markdown order; fake hatch integration for verify wrapper; 8s flag timeout

Made-with: Cursor

* fix(pre-commit): review follow-ups — Block 2 scope, git diff errors, skip test

- check_safe_change: do not exempt pre-commit wrapper scripts from Block 2 when staged
- pre-commit-verify-modules: fail if git diff --cached fails (no || true)
- test: no-module-tree fast path; touch hatch log so skip path can assert empty
- CHANGELOG: reflow + note git-diff failure handling and Block 2 exemption removal

Made-with: Cursor

* fix(pre-commit): classify changelog, harden format diff, extend verify tests

- Move pre-commit follow-ups under 0.46.1 ### Fixed; note git diff exit >1 handling
- run_format_safety: fail only when git diff exit code > 1 (keep diff=1 as success)
- Test: fake git fails on diff --cached; skip-path uses staged docs/notes.txt only

Made-with: Cursor

* fix(pre-commit): legacy verify shim, mdc markdown, safe-change parity

- Add pre-commit-verify-modules-signature.sh delegating to canonical verify
- run_module_signature_verification: prefer canonical, fallback legacy, log path
- Treat staged *.mdc like *.md; replace mapfile for Bash 3.2; drop pyproject/setup
  from Block 2 safe-change skip; extend tests for bundled module tree + legacy
- Split pre-commit layout assertions to satisfy code-review complexity gate

Made-with: Cursor

---------

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

* apply code review fixes

* apply code review fixes

* fix(pre-commit): include staged deletions in staged_files() for Block 2

Use diff-filter ACMRD so deletion-only commits are not treated as empty
safe changes. Restrict markdown and code-review paths to existing files.

Made-with: Cursor

* Fix review findings

* Fix code review findings

* feat(ci): module signing on PR approval and manual workflow_dispatch (#503)

* feat(ci): sign modules on PR approval and manual dispatch

- Add sign-modules-on-approval workflow (approved reviews, dev/main base)
- Extend sign-modules.yml with workflow_dispatch inputs and sign-and-push job
- Document flows in module-security.md; update CHANGELOG and tests

Made-with: Cursor

* Fix sign review and process

---------

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

* Feature/ci module sign on approval (#504)

* feat(ci): sign modules on PR approval and manual dispatch

- Add sign-modules-on-approval workflow (approved reviews, dev/main base)
- Extend sign-modules.yml with workflow_dispatch inputs and sign-and-push job
- Document flows in module-security.md; update CHANGELOG and tests

Made-with: Cursor

* Fix sign review and process

* Fix signature flow

* Fix review gate findings

* Fix review gate findings

---------

Signed-off-by: Dom <39115308+djm81@users.noreply.github.com>
Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>

* feat(ci): workflow_dispatch for sign-modules-on-approval (#505)

- Add sign-on-dispatch job with base_branch/version_bump inputs and merge-base signing
- Rename approval job to sign-on-approval; fix concurrency for manual runs
- Document default-branch vs Run workflow on dev; update tests and CHANGELOG
- Refactor workflow tests to satisfy code-review complexity gate

Made-with: Cursor

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

* fix(ci): module signing workflows, PyPI version check, and review gate

Align VERIFY_ARGS order; use immutable PR base SHA and branch checkout for
approval signing; make PyPI ahead-of-registry check lenient on network failures
in PR jobs. Refactor workflow policy tests for radon complexity; add beartype and
icontract to the PyPI check script; restore init manifest signature field where
applicable.

Made-with: Cursor

* fix(modules): bump init to 0.1.28 for enforce-version-bump on dev

The prior commit added integrity.signature without incrementing the module
version, so sign-modules verify failed (same 0.1.27 vs HEAD~1). Refresh checksum;
CI will re-add signatures via Module Signature Hardening workflow_dispatch.

Made-with: Cursor

* chore(release): v0.46.2 — require signatures on all PRs to main

Bump patch version across canonical sources. Tighten pr-orchestrator and
sign-modules verify so every PR targeting main uses --require-signature,
matching the post-merge main push gate.

Made-with: Cursor

* sign changed package

* fix(modules): bump init to 0.1.29 for dev→main PR version gate

enforce-version-bump compares changed manifests to origin/main; signing-only
changes on 0.1.28 still failed. Re-sign integrity.signature locally after pull.

Made-with: Cursor

* Signed modules and bumped version

* Signed modules and bumped version

* Fix sign flow

* feat: dep-security-cleanup (license gate, pycg, commentjson, review env) (#507)

* feat(openspec): add dep-security-cleanup change artifacts

Proposal, design, specs (call-graph-analysis, dependency-resolution,
dep-license-gate), and tasks for removing GPL/wrong deps and introducing
proactive license + CVE gates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: dep-security-cleanup (license gate, pycg, commentjson, review env)

Implements openspec/dep-security-cleanup: pip-licenses-style compliance script,
call graph via pycg, commentjson for VS Code JSONC, optional-deps hygiene,
subprocess-only SPECFACT_MODULES_REPO for pre-commit code review, docs and CI.

Made-with: Cursor

* docs(openspec): source tracking for dep-security-cleanup and CHANGE_ORDER row

Link PR #507 in proposal Source Tracking; register dep-security-cleanup under
openspec/CHANGE_ORDER.md (deps module).

Made-with: Cursor

* docs(openspec): link dep-security-cleanup to GitHub issue #508

Register tracking issue in proposal Source Tracking and CHANGE_ORDER.

Made-with: Cursor

* Fix code review findings and add version check

* Fix review findings

* Fix module sign logic

* feat(deps): remove GPL/wrong packages, add license-gate and security-audit (#508)

* fix(versioning): enforce packaged artifact bump policy (#508)

* Bump registry version

* Fix review findings and test failurs

* Fix validation script

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* apply review findings

* Fix publish module and security gate findings

* Fix findings and publish bug

* Fix review findings and publish modules flow

* Update publish and sign flows

* Update publish and sign flows

* chore(modules): auto-sign bundled manifests [skip ci] (#510)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Apply code review findings

* Fix failed tests

* [codex] Add five-pillar governance OpenSpec wave (#531)

* 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>

* [codex] stabilize module install and init state (#535)

* 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>

* chore(modules): auto-sign bundled manifests [skip ci] (#536)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: remove unused checksum tuple in verifier

* chore: reduce low-signal coderabbit review noise

* fix: address codex review findings

* fix: tighten local gate scope and module verification

* Make `specfact upgrade` install-method-aware (uv/uvx support, pipx/pip detection) (#539)

* refactor(upgrade): resolve clean-code warnings in upgrade detection flow

* chore(modules): bump upgrade manifest checksum and version

* fix(upgrade): address review findings for openspec evidence and path-safe detection

* chore(release): bump version artifacts to 0.46.10

* fix(upgrade): pin uv pip upgrades to detected interpreter

* fix(upgrade): quote pip executable and suppress uvx check-only command hint

* fix(cli): gracefully handle missing lazy command groups in help/delegation

* fix(cli,upgrade): handle runtime lazy-command errors and uv tool detection

* Fix: failing tests

* fix(cli): handle stale flat lazy shims

---------

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

* chore(modules): auto-sign bundled manifests [skip ci] (#540)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix(upgrade): prefer pipx before uv tool detection

* fix(upgrade): address PR 541 review findings

* fix(cli,upgrade): address PR 541 critical findings

* chore(modules): auto-sign bundled manifests [skip ci] (#546)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Fix module upgrade signature and version bump

* chore(modules): auto-sign bundled manifests [skip ci] (#548)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix(ci): terminate module publish output list

* fix(cli): forward bare lazy subcommands (#549)

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

* chore(openspec): park 21 deferred proposals + simplify CHANGE_ORDER (#551)

* chore(openspec): park 21 deferred change proposals

Move proposals that are awaiting external signal (paying enterprise customer,
third-party publisher, evidence corpus, etc.) from openspec/changes/ into
a new openspec/parking-lot/ directory, preserving full content and history.

This restores focus on the active core thesis (full-chain traceability for
agile DevOps + AI IDEs) without abandoning prior thinking. Each parked
proposal has an explicit un-park trigger documented in
openspec/parking-lot/README.md.

Parked groups:
- enterprise-01..04 (4): no paying enterprise customer yet
- finops-01..02 (2): no internal LLM workload to optimise yet
- knowledge-01..02 (2): insufficient evidence corpus for distillation
- marketplace-03..06 (4): no third-party publishers to onboard
- security-01..02 (2): no customer-driven security review demand
- review-resiliency-01-contracts (1): code-review module gap unproven
- profile-02..03 (2): profile-01 not yet shipped
- cli-val-01,02,05,06 (4): infrastructure ahead of demand;
  cli-val-03 and cli-val-04 remain active

Active changes drop from 45 to 24. No CI workflows or production code
referenced the parked directories; only comment-level references remain
in already-shipped marketplace-06 helper scripts. openspec list is clean.

Also adds a missing fenced-code language tag to a parked design.md
to satisfy the markdownlint pre-commit hook.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(openspec): rewrite CHANGE_ORDER.md to reflect parked roadmap

Reduce from 647 to 214 lines and reorganise around five active tracks
instead of ten plan-derived addenda. The previous file accumulated
historical narrative ("plan-derived addendum 2026-02-15", "addendum
2026-03-22", etc.) that belonged in git history, and listed many
changes that no longer exist as folders here (moved to modules repo
or already archived).

New structure:
- Status snapshot: 24 active / 21 parked / 104 archived with paths
- Five active tracks (full-chain, AI IDE, profile, CLI reliability, other)
- Modify queue: explicit list of proposals needing scope adjustment
  before implementation begins
- Five waves (1: adjust scope, 2: foundations, 3: chain assembly,
  4: evidence + AI surface, 5: proof + extensions) with auditable
  exit gates
- Ownership authority table (kept; still load-bearing)
- Pointers to parking-lot, archive, and the modules-repo companion plan

Stale content removed: old "Implemented" table (51 archived items
already in changes/archive/), four separate addendum sections, tables
for backlog-scrum/kanban/safe that just said "moved to modules", a
GitHub blocked-by relationships table that duplicated each track's
own Blocked-by column, and references to changes that don't exist as
active folders.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(openspec): fix Modify queue count "Five" -> "Six"

PR #551 review caught the prose/table mismatch: the Modify queue
intro said "Five active changes" but the table lists six
(integration-01, architecture-02, telemetry-01, ai-integration-02,
ai-integration-04, openspec-01). The table is the canonical list;
all six adjustments are still required before implementation.

Other count wording verified consistent:
- "five independent tracks" (line 28) refers to Tracks A-E - correct.
- Wave 1 references in the wave plan name the queue by reference,
  not by count.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(openspec): archive marketplace-06 (incorrectly parked, already shipped)

Re-validation of parked changes against git history found that
marketplace-06-ci-module-signing was substantially implemented in dev
(PRs #501, #503, #504, #505 + commit a1dda6d7) before the 2026-05-05
parking triage, but its tasks.md still read 0/N done so it was placed
in parking-lot/ by mistake.

Move the change to openspec/changes/archive/2026-05-06-marketplace-06-ci-module-signing/,
mark all tasks [x] in bulk, and add an "Implementation history" banner
documenting the actual merging PRs and verified on-disk deliverables
(sign-modules-on-approval.yml, git-branch-module-signature-flag.sh,
branch-aware verify-module-signatures gating).

Update parking-lot/README.md (remove marketplace-06 row) and
CHANGE_ORDER.md status snapshot (parked 21 -> 20, archived 104 -> 105).

All 20 other core parked changes and all 9 modules-side parked changes
were re-validated and have no implementation traces; they remain
correctly parked.

* fix(openspec): sync specs from archived marketplace-06 via openspec archive

The previous commit (8443297b) moved marketplace-06-ci-module-signing
into the archive directory manually, which skipped the
`openspec archive` step that syncs delta specs into main specs.

Re-ran the proper flow:
1. Move change back to openspec/changes/marketplace-06-ci-module-signing/
2. Run `openspec archive marketplace-06-ci-module-signing --yes`

That command applied the delta specs to:
- openspec/specs/ci-integration/spec.md (3 added)
- openspec/specs/ci-module-signing-on-approval/spec.md (3 added, new file)

Net effect on this PR is the proper inclusion of those spec updates;
the archive folder content from 8443297b is unchanged (banner +
checked tasks preserved).

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>

* Ignore claude settings.json

* docs: refine telemetry change to active opt-in (#555)

* Refine telemetry change to active opt-in

* Address telemetry opt-in review annotations

* Align telemetry payload field names

* Clarify telemetry semantic payload contract

* Align telemetry sanitizer transition spec

* Track modules telemetry docs rollout

* Tighten telemetry implementation tasks

---------

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

* fix runtime module discovery reliability (#558)

* fix runtime module discovery reliability

* fix runtime discovery review findings

* fix installed module loader test fixture

* fix review feedback on runtime discovery state isolation

---------

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

* chore(modules): auto-sign bundled manifests [skip ci] (#559)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* [codex] Add module scope version diagnostics (#566)

* Add module scope version diagnostics

* Fix CI checks for module diagnostics

* Address module diagnostics review findings

* fix: apply CodeRabbit auto-fixes

Fixed 5 file(s) based on 4 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>

* fix: tighten dependency fast-path identity checks

* test: cover registry-id mismatch dependency path

* style: run hatch format and apply formatter output

* fix: resolve header typing regressions in strict type-check

* test: require registry id file for already-satisfied bundle dependency assertion

Bundle dependency installs now log at info only when the dependency
directory includes .specfact-registry-id matching the marketplace id.
Update the test fixture to mirror a normal install so CI matches installer
behavior.

Co-authored-by: Dom <djm81@users.noreply.github.com>

---------

Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>

* chore(modules): auto-sign bundled manifests [skip ci] (#567)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: address module dependency review findings

* fix: address dependency review follow-ups

* Fix dependency resolver bounds and bundle dependency validation

* Fix bundled module publish summary quoting

* fix(upgrade): suppress benign pipx spaced-home warning (#574)

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

* chore(bundled-modules): snapshot from dev@3f74602 (#576)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore(modules): auto-sign bundled manifests [skip ci] (#575)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Dom <39115308+djm81@users.noreply.github.com>

* fix(upgrade): tolerate undecodable child output

* chore(modules): auto-sign bundled manifests [skip ci] (#578)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore(bundled-modules): snapshot from dev@717c74d (#579)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Dom <39115308+djm81@users.noreply.github.com>

* fix: keep core bundled registry URLs scoped (#580)

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

* chore(relea…
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

Projects

Status: Done

1 participant