Conversation
* feat: remove flat command shims from grouped registry * Finalize change module-migration-04 implementation --------- Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
…R merge (#345) * Implement blockers to prepare for module-migration-03 change. * Update migration change * docs(openspec): close migration-05 PR tracking and change order --------- Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
* feat(migration-06): core decoupling cleanup - boundary tests and inventory - Add test_core_does_not_import_from_bundle_packages boundary regression test - Update spec with ownership boundary and migration acceptance criteria - Add CORE_DECOUPLING_INVENTORY.md (keep/move/interface classification) - Record TDD evidence in TDD_EVIDENCE.md - Update docs/reference/architecture.md with core vs modules-repo boundary - Update openspec/CHANGE_ORDER.md status No move candidates identified; core already decoupled from bundle packages. Boundary test prevents future core->bundle coupling. Refs #338 Made-with: Cursor * chore(migration-06): mark all tasks complete Made-with: Cursor * feat(migration-06): extend scope - migrate package-specific artifacts per #338 - Add MIGRATION_REMOVAL_PLAN.md with phased removal of MIGRATE-tier code - Add test_core_modules_do_not_import_migrate_tier boundary test - Remove templates.bridge_templates (dead code; only tests used it) - Remove tests/unit/templates/test_bridge_templates.py - Update CORE_DECOUPLING_INVENTORY.md with removal status - Update spec with MIGRATE-tier enforcement and package-specific removal Phase 1 complete. Further MIGRATE-tier removal documented in plan. Refs #338 Made-with: Cursor * test(migration-06): move legacy sync tests out of core --------- Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
* test: finalize module-migration-07 core test ownership cleanup * docs: mark module-migration-07 quality and PR tasks complete * test: fix CI isolation failures for project and persona merge * test: narrow migrated skips and restore core registry guardrails * test: stabilize core CI by refining skips and bootstrap checks * test: fix remaining PR failures via targeted core filtering * fix: harden module package checks against import-mode class identity * test: stabilize core slimming integration assertions --------- Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
#376) - Create openspec/changes/agile-01-feature-hierarchy/ with proposal.md and tasks.md - Add Epics #256 (Architecture Layer Integration), #257 (AI IDE Integration), and #258 (Integration Governance and Dogfooding) to CHANGE_ORDER.md parent issues table - 25 GitHub Feature issues created (#351-#375), linked to their parent Epics - Feature label created; issue #185 closed (ceremony-cockpit-01, archived 2026-02-18) Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* 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>
Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
…g migration to module
* 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>
# Conflicts: # openspec/CHANGE_ORDER.md # openspec/changes/module-migration-10-bundle-command-surface-alignment/proposal.md
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* 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>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Dom <39115308+djm81@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Dom <39115308+djm81@users.noreply.github.com>
Co-authored-by: Dominikus Nold <djm81@users.noreply.github.com>
|
Strix is installed on this repository, but we could not run this PR security review because this workspace does not have an active plan. If you'd like to continue receiving code reviews, you can add a payment method or manage billing here. |
📝 WalkthroughRegistry URL Scope Enforcement for Core Bundled ModulesThis PR promotes a registry URL-scope fix from dev to main. The functional change enforces that core bundled modules ( User-Visible Behavior & CLI Surface
Contract & API ImpactNew module-level constants in
Registry entry validation:
Testing & Quality GatesNew test coverage:
Module Signing & Registry Updates
WalkthroughThis PR enforces repository scope for core bundled modules by validating that ChangesCore Module Repository Scope Enforcement
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
|
||
| def main(self, argv: list[str]) -> int: | ||
| """Run the script entry point.""" | ||
| ... |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/unit/workflows/test_trustworthy_green_checks.py (1)
236-250: ⚡ Quick winHarden this policy test by asserting workflow structure, not raw text blocks.
raw.count(...)plussplit("\n\n")is formatting-sensitive and can miss/misattribute publish invocations; this can make the gate flaky or falsely green on non-functional edits.Suggested refactor
def test_publish_modules_bundled_snapshot_targets_core_repository() -> None: """Bundled snapshot entries for core modules must not inherit the marketplace URL base.""" - raw = PUBLISH_MODULES.read_text(encoding="utf-8") - expected_base = "BUNDLED_REGISTRY_DOWNLOAD_BASE_URL: https://github.com/nold-ai/specfact-cli/releases/download" - assert raw.count(expected_base) == 2 - assert ( - "BUNDLED_REGISTRY_DOWNLOAD_BASE_URL: https://github.com/nold-ai/specfact-cli-modules/releases/download" - not in raw - ) - - publish_blocks = [block for block in raw.split("\n\n") if "scripts/publish-module.py" in block] - assert publish_blocks, "Expected publish-modules workflow to package module artifacts" - for block in publish_blocks: - assert "--download-base-url" in block, "Bundled publish calls must set the snapshot URL base" - assert "${BUNDLED_REGISTRY_DOWNLOAD_BASE_URL}" in block - if "--index-fragment" in block: - assert "--download-base-url" in block, "Registry fragments must set the bundled snapshot URL base" - assert "${BUNDLED_REGISTRY_DOWNLOAD_BASE_URL}" in block + workflow = _load_yaml(PUBLISH_MODULES) + jobs = cast(dict[str, Any], workflow.get("jobs")) + expected_base = "https://github.com/nold-ai/specfact-cli/releases/download" + + for job_name in ("publish", "auto-publish"): + job = cast(dict[str, Any], jobs.get(job_name)) + env = cast(dict[str, Any], job.get("env")) + assert env.get("BUNDLED_REGISTRY_DOWNLOAD_BASE_URL") == expected_base + + publish_runs: list[str] = [] + for job_name in ("publish", "auto-publish"): + steps = cast(list[dict[str, Any]], cast(dict[str, Any], jobs[job_name]).get("steps", [])) + for step in steps: + run_clause = step.get("run") + if isinstance(run_clause, str) and "scripts/publish-module.py" in run_clause: + publish_runs.append(run_clause) + + assert len(publish_runs) == 2 + for run_clause in publish_runs: + assert '--download-base-url "${BUNDLED_REGISTRY_DOWNLOAD_BASE_URL}"' in run_clause🤖 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/unit/workflows/test_trustworthy_green_checks.py` around lines 236 - 250, The test currently inspects raw text (variables raw, expected_base, publish_blocks) which is fragile; instead parse the workflow YAML (use yaml.safe_load_all or similar) and assert structure: locate workflow jobs and their steps that invoke "scripts/publish-module.py", verify the environment or inputs contain the BUNDLED_REGISTRY_DOWNLOAD_BASE_URL value (replace raw.count(expected_base) with an assertion that the env/variable is defined in two expected places), and for each publish step assert the step's args/with/command includes "--download-base-url" and the literal "${BUNDLED_REGISTRY_DOWNLOAD_BASE_URL}", and if a step has an "--index-fragment" entry assert it also contains "--download-base-url" and the bundled URL; update the publish_blocks logic to collect step dicts from parsed YAML rather than splitting raw by blank lines.
🤖 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.
Nitpick comments:
In `@tests/unit/workflows/test_trustworthy_green_checks.py`:
- Around line 236-250: The test currently inspects raw text (variables raw,
expected_base, publish_blocks) which is fragile; instead parse the workflow YAML
(use yaml.safe_load_all or similar) and assert structure: locate workflow jobs
and their steps that invoke "scripts/publish-module.py", verify the environment
or inputs contain the BUNDLED_REGISTRY_DOWNLOAD_BASE_URL value (replace
raw.count(expected_base) with an assertion that the env/variable is defined in
two expected places), and for each publish step assert the step's
args/with/command includes "--download-base-url" and the literal
"${BUNDLED_REGISTRY_DOWNLOAD_BASE_URL}", and if a step has an "--index-fragment"
entry assert it also contains "--download-base-url" and the bundled URL; update
the publish_blocks logic to collect step dicts from parsed YAML rather than
splitting raw by blank lines.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 482f0683-6965-4338-9c53-6d4e71d72ca3
📒 Files selected for processing (5)
.github/workflows/publish-modules.ymlresources/bundled-module-registry/index.jsonscripts/update-registry-index.pytests/unit/scripts/test_update_registry_index.pytests/unit/workflows/test_trustworthy_green_checks.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). (9)
- GitHub Check: Linting (ruff, pylint, safe-write guard)
- GitHub Check: Type Checking (basedpyright)
- GitHub Check: Compatibility (Python 3.11)
- GitHub Check: Tests (Python 3.12)
- GitHub Check: Contract-First CI
- GitHub Check: Workflow Lint
- GitHub Check: Analyze (python)
- GitHub Check: Tests (Python 3.12)
- GitHub Check: Compatibility (Python 3.11)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.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_cacheand 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:
scripts/update-registry-index.pytests/unit/workflows/test_trustworthy_green_checks.pytests/unit/scripts/test_update_registry_index.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: Runhatch run contract-testfor 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@icontractdecorators and@beartypetype 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:
scripts/update-registry-index.pytests/unit/workflows/test_trustworthy_green_checks.pytests/unit/scripts/test_update_registry_index.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/update-registry-index.py
**/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.asynciodecorator for async test functions in Python
Organize test files in structure: tests/unit/, tests/integration/, tests/e2e/ by module
Files:
tests/unit/workflows/test_trustworthy_green_checks.pytests/unit/scripts/test_update_registry_index.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 oraclesSecret redaction via
LoggerSetup.redact_secretsmust be covered by unit tests
Files:
tests/unit/workflows/test_trustworthy_green_checks.pytests/unit/scripts/test_update_registry_index.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/workflows/test_trustworthy_green_checks.pytests/unit/scripts/test_update_registry_index.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/workflows/test_trustworthy_green_checks.pytests/unit/scripts/test_update_registry_index.py
.github/workflows/*.{yml,yaml}
📄 CodeRabbit inference engine (.cursor/rules/testing-and-build-guide.mdc)
Validate GitHub workflow files using
hatch run lint-workflowsbefore committing
.github/workflows/*.{yml,yaml}: Use actionlint for semantic validation of GitHub Actions workflows
Format GitHub Actions workflows usinghatch run workflows-fmtand lint them withhatch run workflows-lintafter editing
Files:
.github/workflows/publish-modules.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/publish-modules.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/publish-modules.yml
🔀 Multi-repo context nold-ai/specfact-cli-modules
[::nold-ai/specfact-cli-modules::] .github/workflows/publish-modules.yml — workflow invokes python scripts/publish-module.py (multiple places) and contains code that sets registry entry download URLs (e.g. entry["download_url"] = f"modules/{artifact_name}"). Relevant blocks shown in the file around lines: publish job resolve & publish steps. (search hits: .github/workflows/publish-modules.yml:289, .github/workflows/publish-modules.yml:387)
[::nold-ai/specfact-cli-modules::] registry/index.json — repository maintains a registry with module entries that use download_url values of the form modules/<bundle>-<version>.tar.gz (examples at registry/index.json lines shown by ripgrep).
[::nold-ai/specfact-cli-modules::] tools/validate_repo_manifests.py — contains validation enforcing download_url format and expected pattern (functions _validate_registry_download_url and _validate_registry_sidecar) and references download_url as required for manifests (lines ~109–127 and usage at ~204–210). Tests in tests/unit reference this pattern (multiple test files).
[::nold-ai/specfact-cli-modules::] scripts and docs referencing publish-module.py — multiple scripts/docs reference scripts/publish-module.py (e.g., docs/authoring/publishing-modules.md, openspec notes). Tests and code paths in this repo expect the publish workflow and scripts to produce registry download_url entries pointing to the modules/.tar.gz path.
Assessment: the repo contains the publish workflow, registry, validators, and tests that consume and assert on module download_url values and publish behavior. The PR’s changes that require core bundled module download URLs to point at a different GitHub repo (and the workflow passing a new --download-base-url) are directly relevant to this repository’s workflow, registry entries, and validation logic — these files should be updated/consistent here.
🔇 Additional comments (4)
scripts/update-registry-index.py (1)
20-21: LGTM!Also applies to: 58-59, 62-70
resources/bundled-module-registry/index.json (1)
5-5: LGTM!Also applies to: 10-13, 17-17
.github/workflows/publish-modules.yml (1)
44-45: LGTM!Also applies to: 118-120, 207-208, 275-277
tests/unit/scripts/test_update_registry_index.py (1)
8-10: LGTM!Also applies to: 13-18, 21-22, 29-33, 37-40, 48-60, 91-97, 108-134
Summary
Promotes the merged
devfix for the bundled registry pipeline tomain.Included Change
fix: keep core bundled registry URLs scopedImpact
nold-ai/specfact-clirelease URLs instead ofnold-ai/specfact-cli-modules.scripts/update-registry-index.pynow fail-closes for core bundled module entries unless they use the canonical core repository download URL prefix.Local Preflight
origin/devandorigin/main.origin/main..origin/dev; net diff is the registry URL-scope fix set.Validation From Source PR
hatch run pytest tests/unit/scripts/test_update_registry_index.py tests/unit/workflows/test_trustworthy_green_checks.py -qhatch run formathatch run workflows-linthatch run yaml-lintgit diff --check