Skip to content

fix: promote core bundled registry URL scope to main#581

Merged
djm81 merged 471 commits into
mainfrom
dev
May 20, 2026
Merged

fix: promote core bundled registry URL scope to main#581
djm81 merged 471 commits into
mainfrom
dev

Conversation

@djm81
Copy link
Copy Markdown
Collaborator

@djm81 djm81 commented May 20, 2026

Summary

Promotes the merged dev fix for the bundled registry pipeline to main.

Included Change

Impact

  • Core bundled module snapshots now point at nold-ai/specfact-cli release URLs instead of nold-ai/specfact-cli-modules.
  • scripts/update-registry-index.py now fail-closes for core bundled module entries unless they use the canonical core repository download URL prefix.
  • Workflow regression coverage verifies both bundled publish paths use the explicit core download base.

Local Preflight

  • Refreshed origin/dev and origin/main.
  • Compared 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 -q
  • hatch run format
  • hatch run workflows-lint
  • hatch run yaml-lint
  • git diff --check
  • Pre-commit on amended commit: passed, SpecFact code review 0 findings.

djm81 and others added 30 commits March 4, 2026 20:17
* 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>
* 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
github-actions Bot and others added 20 commits May 8, 2026 00:39
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-security
Copy link
Copy Markdown

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.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Review Change Stack

📝 Walkthrough

Registry URL Scope Enforcement for Core Bundled Modules

This PR promotes a registry URL-scope fix from dev to main. The functional change enforces that core bundled modules (init, upgrade, module-registry, bundle-mapper) must download from the canonical nold-ai/specfact-cli repository, not from alternative sources.

User-Visible Behavior & CLI Surface

  • No changes to user-facing CLI commands or options.
  • The bundled registry snapshot (loaded by specfact bundle install and related workflows) now references downloads from https://github.com/nold-ai/specfact-cli/releases/download/ for all core bundled modules.
  • The GitHub Actions publish-modules workflow now explicitly passes --download-base-url https://github.com/nold-ai/specfact-cli/releases/download to the module publishing script, ensuring bundled modules are packaged with the correct registry URL.

Contract & API Impact

New module-level constants in scripts/update-registry-index.py:

  • CORE_BUNDLED_MODULE_IDS: frozenset[str] — defines the set of core bundled module identifiers.
  • CORE_REPOSITORY_DOWNLOAD_URL_PREFIX: str — canonical repository download URL prefix for core modules.

Registry entry validation:

  • Added internal _validate_entry_scope() function that is invoked during entry loading. If a core bundled module entry is provided with a download_url not matching the core repository prefix, the update fails with a ValueError and exits with code 1, leaving the registry index unchanged.
  • No changes to public CLI behavior; validation is transparent during normal update-registry-index.py operation.

Testing & Quality Gates

New test coverage:

  • Added parametrized test test_main_rejects_core_module_entry_from_unexpected_repository() in tests/unit/scripts/test_update_registry_index.py that verifies core module entries are rejected when pointing to nold-ai/specfact-cli-modules or unrelated repositories.
  • Refactored existing registry update tests to use a new _write_entry_fragment() helper, reducing boilerplate.
  • Added dynamic module loading via Protocol pattern (UpdateRegistryIndexModule) for type-safe test interaction with the script.
  • Added workflow regression test test_publish_modules_bundled_snapshot_targets_core_repository() in tests/unit/workflows/test_trustworthy_green_checks.py that validates the workflow passes --download-base-url correctly and does not reference marketplace/modules registry paths.

Module Signing & Registry Updates

  • Bundled registry index entries for init (v0.1.33), upgrade (v0.1.19), and module-registry (v0.1.26) have been updated to reference the core repository with correct checksums.
  • The bundle-mapper entry remains in the index (currently without versioned download URL, flagged for future completion).
  • Workflow enforces this scope via environment variable BUNDLED_REGISTRY_DOWNLOAD_BASE_URL, propagated to both single-module and batch publishing paths.

Walkthrough

This PR enforces repository scope for core bundled modules by validating that init, upgrade, and module-registry entries in the registry must download from nold-ai/specfact-cli rather than nold-ai/specfact-cli-modules. The implementation adds scope validation to update-registry-index.py, updates registry entries and workflow base URLs, and adds comprehensive test coverage.

Changes

Core Module Repository Scope Enforcement

Layer / File(s) Summary
Scope validation contract and implementation
scripts/update-registry-index.py
Module-level constants define CORE_BUNDLED_MODULE_IDS and CORE_REPOSITORY_DOWNLOAD_URL_PREFIX; _validate_entry_scope() rejects core module entries whose download_url does not target the correct repository and is invoked during _load_entry().
Registry index data update
resources/bundled-module-registry/index.json
Module entries for init, upgrade, and module-registry redirect their download_url from the modules repository to the CLI repository; upgrade version bumped from 0.1.17 to 0.1.19 with updated checksum.
Workflow environment and module publishing
.github/workflows/publish-modules.yml
Adds BUNDLED_REGISTRY_DOWNLOAD_BASE_URL environment variable to both publish and auto-publish jobs; --download-base-url parameter passed to publish-module.py in single-module and batch staging paths.
Test infrastructure and scope validation tests
tests/unit/scripts/test_update_registry_index.py
Typed Protocol for script loading, shared _write_entry_fragment() helper, refactored existing tests, and new parametrized test asserting rejection of core module entries with mismatched repositories.
Workflow content assertion test
tests/unit/workflows/test_trustworthy_green_checks.py
Validates publish-modules workflow uses BUNDLED_REGISTRY_DOWNLOAD_BASE_URL consistently in all publish-module.py blocks and excludes alternate marketplace URLs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

bug, security

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Title uses Conventional Commits format (fix:) and clearly describes the main change: promoting the bundled registry URL scope fix from dev to main.
Description check ✅ Passed Description comprehensively documents the included change, impact, and validation approach, though it deviates from the template structure without completing required contract/test sections.
Docstring Coverage ✅ Passed Docstring coverage is 90.91% which is sufficient. The required threshold is 80.00%.
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 dev

Comment @coderabbitai help to get the list of available commands and usage tips.

@djm81 djm81 self-assigned this May 20, 2026
@djm81 djm81 added the bug Something isn't working label May 20, 2026
@djm81 djm81 moved this to In Progress in SpecFact CLI May 20, 2026

def main(self, argv: list[str]) -> int:
"""Run the script entry point."""
...
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.

🧹 Nitpick comments (1)
tests/unit/workflows/test_trustworthy_green_checks.py (1)

236-250: ⚡ Quick win

Harden this policy test by asserting workflow structure, not raw text blocks.

raw.count(...) plus split("\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

📥 Commits

Reviewing files that changed from the base of the PR and between e932413 and b58f924.

📒 Files selected for processing (5)
  • .github/workflows/publish-modules.yml
  • resources/bundled-module-registry/index.json
  • scripts/update-registry-index.py
  • tests/unit/scripts/test_update_registry_index.py
  • tests/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_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:

  • scripts/update-registry-index.py
  • tests/unit/workflows/test_trustworthy_green_checks.py
  • tests/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: 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:

  • scripts/update-registry-index.py
  • tests/unit/workflows/test_trustworthy_green_checks.py
  • tests/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.asyncio decorator 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.py
  • tests/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 oracles

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

Files:

  • tests/unit/workflows/test_trustworthy_green_checks.py
  • tests/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.py
  • tests/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.py
  • tests/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-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/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

@djm81 djm81 merged commit b96b955 into main May 20, 2026
39 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in SpecFact CLI May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant