Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b43a9f1
docs: add openspec change arch-05 bridge registry
djm81 Feb 8, 2026
2cecae5
Merge dev into feature/arch-05-bridge-registry
djm81 Feb 9, 2026
af02db3
feat: apply arch-05 bridge registry workflow
djm81 Feb 9, 2026
1f150a2
docs: update arch-05 apply task execution state
djm81 Feb 9, 2026
c0e4c61
fix: resolve arch-05 protocol reporting and duplicate lifecycle logs
djm81 Feb 9, 2026
afcc3c7
fix: close arch-05 review gaps for protocol reporting
djm81 Feb 9, 2026
3e88347
docs: mark arch-05 PR task complete
djm81 Feb 9, 2026
695fdee
fix: complete arch-05 module io contract migration
djm81 Feb 9, 2026
62648da
fix: make module protocol startup reporting user-friendly
djm81 Feb 9, 2026
99cac02
fix: make debug logging work for eager cli flags
djm81 Feb 9, 2026
0e932a1
fix: print active debug log path on debug startup
djm81 Feb 9, 2026
25d379f
fix: harden repro output and telemetry fallback behavior
djm81 Feb 9, 2026
9fb4b30
test: fix service bridge metadata typing in unit tests
djm81 Feb 9, 2026
8b99df1
fix: add strict crosshair mode and clearer repro diagnostics
djm81 Feb 9, 2026
f531a16
fix: remove contracts import side-effects for crosshair
djm81 Feb 9, 2026
3a1e869
fix: make crosshair exploration output specific and deduplicated
djm81 Feb 9, 2026
7407e26
fix: make crosshair exploration skip noisy signature-limited files
djm81 Feb 9, 2026
301dea1
ci: reduce specfact workflow env setup overhead
djm81 Feb 9, 2026
beb05d0
ci: avoid hatch env sync in specfact validation workflow
djm81 Feb 9, 2026
e48bcef
fix: stabilize crosshair exploration for side-effectful modules
djm81 Feb 9, 2026
b3264a1
fix: improve crosshair compatibility for backlog converters
djm81 Feb 9, 2026
3465e96
ci: require crosshair in specfact repro workflows
djm81 Feb 9, 2026
8f38055
Apply fixes on crosshair tests
djm81 Feb 9, 2026
471d232
ci: speed up workflow setup with cache and lean hatch installs
djm81 Feb 9, 2026
e510eaf
ci: pin contract scenario test env to py3.12
djm81 Feb 9, 2026
dca401f
ci: improve contract test progress logging
djm81 Feb 9, 2026
7ed9277
ci: increase and expose smart test timeout for scenario runs
djm81 Feb 9, 2026
a9ca32e
Fix test failure logic
djm81 Feb 10, 2026
f9d721e
Fix test failure logic
djm81 Feb 10, 2026
de852d7
Reformat files
djm81 Feb 10, 2026
3b9ca97
Fix contract test findings
djm81 Feb 10, 2026
efa6374
Update docs integrity
djm81 Feb 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 99 additions & 14 deletions .github/workflows/pr-orchestrator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ concurrency:
permissions:
contents: read

env:
PIP_PREFER_BINARY: "1"

jobs:
changes:
name: Detect code changes
Expand Down Expand Up @@ -95,6 +98,18 @@ jobs:
python -m pip install --upgrade pip
pip install hatch coverage

- name: Cache hatch environments
if: needs.changes.outputs.skip_tests_dev_to_main != 'true'
uses: actions/cache@v4
with:
path: |
~/.local/share/hatch
~/.cache/uv
key: ${{ runner.os }}-hatch-tests-py312-${{ hashFiles('pyproject.toml') }}
restore-keys: |
${{ runner.os }}-hatch-tests-py312-
${{ runner.os }}-hatch-

- name: Create test output directories
if: needs.changes.outputs.skip_tests_dev_to_main != 'true'
shell: bash
Expand Down Expand Up @@ -126,15 +141,39 @@ jobs:
env:
CONTRACT_FIRST_TESTING: "true"
TEST_MODE: "true"
HATCH_TEST_ENV: "py3.12"
SMART_TEST_TIMEOUT_SECONDS: "1800"
PYTEST_ADDOPTS: "-r fEw"
run: |
echo "πŸ§ͺ Running contract-first test suite (3.12)..."
echo "Contract validation..." && hatch run contract-test-contracts || echo "⚠️ Contract validation incomplete"
echo "Contract exploration..." && hatch run contract-test-exploration || echo "⚠️ Contract exploration incomplete"
echo "Scenario tests..." && hatch run contract-test-scenarios || echo "⚠️ Scenario tests incomplete"
echo "E2E tests..." && hatch run contract-test-e2e || echo "⚠️ E2E tests incomplete"
echo "ℹ️ HATCH_TEST_ENV=${HATCH_TEST_ENV}"
run_layer() {
local label="$1"
shift
local start_ts
start_ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
echo "▢️ [${start_ts}] Starting ${label}"
echo " Command: $*"
if "$@"; then
local end_ts
end_ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
echo "βœ… [${end_ts}] ${label} completed"
else
local end_ts
end_ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
echo "⚠️ [${end_ts}] ${label} incomplete"
fi
}

run_layer "Contract validation" hatch run contract-test-contracts
run_layer "Contract exploration" hatch run contract-test-exploration
run_layer "Scenario tests" hatch run contract-test-scenarios
run_layer "E2E tests" hatch run contract-test-e2e

- name: Run unit tests with coverage (3.12)
if: needs.changes.outputs.skip_tests_dev_to_main != 'true' && env.RUN_UNIT_COVERAGE == 'true'
env:
PYTEST_ADDOPTS: "-r fEw"
run: |
echo "πŸ§ͺ Running unit tests with coverage (3.12)..."
hatch -e hatch-test.py3.12 run run-cov
Expand Down Expand Up @@ -168,12 +207,22 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install hatch
- name: Cache hatch environments
uses: actions/cache@v4
with:
path: |
~/.local/share/hatch
~/.cache/uv
key: ${{ runner.os }}-hatch-compat-py311-${{ hashFiles('pyproject.toml') }}
restore-keys: |
${{ runner.os }}-hatch-compat-py311-
${{ runner.os }}-hatch-
- name: Run Python 3.11 compatibility tests (hatch-test matrix env)
run: |
echo "πŸ” Python 3.11 compatibility checks"
# Run a subset of tests to verify Python 3.11 compatibility
# Focus on unit tests and integration tests (skip slow E2E tests)
hatch -e hatch-test.py3.11 test tests/unit tests/integration || echo "⚠️ Some tests failed (advisory)"
hatch -e hatch-test.py3.11 test -- -r fEw tests/unit tests/integration || echo "⚠️ Some tests failed (advisory)"
hatch -e hatch-test.py3.11 run xml || true

contract-first-ci:
Expand All @@ -195,13 +244,21 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install hatch coverage icontract beartype crosshair hypothesis icontract-hypothesis
hatch env create
pip install hatch
- name: Cache hatch environments
uses: actions/cache@v4
with:
path: |
~/.local/share/hatch
~/.cache/uv
key: ${{ runner.os }}-hatch-contract-first-py312-${{ hashFiles('pyproject.toml') }}
restore-keys: |
${{ runner.os }}-hatch-contract-first-py312-
${{ runner.os }}-hatch-
- name: Run contract validation and exploration
run: |
echo "πŸ” Validating runtime contracts..."
echo "Running contract-test-contracts..." && hatch run contract-test-contracts || echo "Contracts failed"
echo "Running contract-test-exploration..." && hatch run contract-test-exploration || echo "Exploration found issues"
echo "Running specfact repro with required CrossHair..." && hatch run specfact repro --verbose --crosshair-required --budget 120 || echo "SpecFact repro found issues"

cli-validation:
name: CLI Command Validation
Expand All @@ -216,11 +273,9 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install hatch
hatch env create
cache: "pip"
cache-dependency-path: |
pyproject.toml
- name: Install CLI
run: |
echo "Installing SpecFact CLI..."
Expand All @@ -244,6 +299,9 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"
cache-dependency-path: |
pyproject.toml
- name: Download coverage artifacts from Tests
uses: actions/download-artifact@v4
with:
Expand Down Expand Up @@ -289,6 +347,16 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install hatch
- name: Cache hatch environments
uses: actions/cache@v4
with:
path: |
~/.local/share/hatch
~/.cache/uv
key: ${{ runner.os }}-hatch-typecheck-py312-${{ hashFiles('pyproject.toml') }}
restore-keys: |
${{ runner.os }}-hatch-typecheck-py312-
${{ runner.os }}-hatch-
- name: Run type checking
run: |
echo "πŸ” Running basedpyright type checking..."
Expand All @@ -310,12 +378,26 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"
cache-dependency-path: |
pyproject.toml

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install hatch

- name: Cache hatch environments
uses: actions/cache@v4
with:
path: |
~/.local/share/hatch
~/.cache/uv
key: ${{ runner.os }}-hatch-lint-py312-${{ hashFiles('pyproject.toml') }}
restore-keys: |
${{ runner.os }}-hatch-lint-py312-
${{ runner.os }}-hatch-

- name: Run linting
run: |
echo "πŸ” Running linting checks..."
Expand All @@ -336,6 +418,9 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"
cache-dependency-path: |
pyproject.toml

- name: Install build tools
run: |
Expand Down
12 changes: 8 additions & 4 deletions .github/workflows/specfact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ on:
- warn
- log

env:
PIP_PREFER_BINARY: "1"

jobs:
specfact-validation:
name: Contract Validation
Expand All @@ -49,21 +52,22 @@ jobs:
with:
python-version: "3.12"
cache: "pip"
cache-dependency-path: |
pyproject.toml

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install hatch
pip install pytest

- name: Install SpecFact CLI
run: |
echo "πŸ“¦ Installing SpecFact CLI..."
hatch env create || true
pip install -e .

- name: Enforce Core-Module Isolation
run: |
hatch run pytest tests/unit/test_core_module_isolation.py -v
pytest tests/unit/test_core_module_isolation.py -v

- name: Set validation parameters
id: validation
Expand All @@ -79,7 +83,7 @@ jobs:
id: repro
continue-on-error: true
run: |
hatch run specfact repro --verbose --budget ${{ steps.validation.outputs.budget }} || true
specfact repro --verbose --crosshair-required --budget ${{ steps.validation.outputs.budget }} || true
echo "exit_code=$?" >> "$GITHUB_OUTPUT"

- name: Find latest repro report
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,27 @@ All notable changes to this project will be documented in this file.
- ProjectBundle schema versioning (`schema_version` field).
- ValidationReport model for structured validation results.
- Protocol compliance tracking in module metadata.
- Bridge registry architecture (`arch-05-bridge-registry`) for module-declared service converters.
- Backlog bridge converter modules for ADO, Jira, Linear, and GitHub with manifest-based registration.
- Reference and guide docs for bridge registry and custom bridge creation.

### Changed (0.30.0)

- Updated modules `backlog`, `sync`, `plan`, `generate`, and `enforce` to expose ModuleIOContract operations.
- Added module contracts documentation and ProjectBundle schema reference docs.
- Module lifecycle now parses and validates `service_bridges`, registers valid converters, and skips invalid declarations non-fatally.
- Protocol compliance reporting now uses effective runtime interfaces and emits a single aggregate summary line for full/partial/legacy status.
- Modernized module-system docs across README and docs hub pages to reflect module-first architecture, clear module boundaries, and migration guidance from legacy command coupling.
- Standardized command examples for current CLI syntax (notably `specfact init ide` and positional bundle arguments for `plan init`, `import from-code`, and `plan review`).
- Added `docs/reference/command-syntax-policy.md` and linked it from docs reference navigation for consistent command documentation going forward.
- Reference: `(fixes #206)`.
- Reference: `(fixes #207)`.

### Fixed (0.30.0)

- Fixed pytest reporting integration for smart-test and contract-test wrappers to emit concise failure/error/warning summaries via `-r fEw` without breaking Hatch argument parsing.
- Updated CI (`.github/workflows/pr-orchestrator.yml`) to pass pytest report flags correctly through Hatch test invocations, improving copy-paste failure summaries in pipeline logs.
- Fixed suite-mode model identity mismatches causing `beartype` return violations and nested Pydantic validation errors by normalizing model-like inputs and relaxing brittle class-identity checks in targeted loaders/constructors.

---

Expand Down
31 changes: 7 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,32 +158,15 @@ Contract-first module architecture highlights:
- `ModuleIOContract` formalizes module IO operations (`import`, `export`, `sync`, `validate`) on `ProjectBundle`.
- Core-module isolation is enforced by static analysis (`core` never imports `specfact_cli.modules.*` directly).
- Registration tracks protocol operation coverage and schema compatibility metadata.
- Bridge registry support allows module manifests to declare `service_bridges` converters (for example ADO/Jira/Linear/GitHub) loaded at lifecycle startup without direct core-to-module imports.
- Protocol reporting classifies modules from effective runtime interfaces with a single aggregate summary (`Full/Partial/Legacy`).

---

## Developer Note: Command Layout

- Primary command implementations live in `src/specfact_cli/modules/<module>/src/commands.py`.
- Legacy imports from `src/specfact_cli/commands/*.py` are compatibility shims and only guarantee `app` re-exports.
- Preferred imports for module code:
- `from specfact_cli.modules.<module>.src.commands import app`
- `from specfact_cli.modules.<module>.src.commands import <symbol>`
- Shim deprecation timeline:
- Legacy shim usage is deprecated for non-`app` symbols now.
- Shim removal is planned no earlier than `v0.30` (or the next major migration window).
Why this matters:

---

## Developer Note: Command Layout

- Primary command implementations live in `src/specfact_cli/modules/<module>/src/commands.py`.
- Legacy imports from `src/specfact_cli/commands/*.py` are compatibility shims and only guarantee `app` re-exports.
- Preferred imports for module code:
- `from specfact_cli.modules.<module>.src.commands import app`
- `from specfact_cli.modules.<module>.src.commands import <symbol>`
- Shim deprecation timeline:
- Legacy shim usage is deprecated for non-`app` symbols now.
- Shim removal is planned no earlier than `v0.30` (or the next major migration window).
- Feature areas can evolve independently without repeatedly modifying core CLI wiring.
- Module teams can ship at different speeds while preserving stable core behavior.
- Clear IO contracts reduce coupling and make future migrations (e.g., new adapters/modules) lower risk.
- Core remains focused on lifecycle, registry, and validation orchestration rather than tool-specific command logic.

---

Expand Down
19 changes: 19 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,25 @@ SpecFact CLI uses a lifecycle-managed module system:

This is the baseline for future granular module updates and enhancements. Third-party/community module installation is planned, but not available yet.

### Why the Module System Is the Foundation

This architecture intentionally separates the CLI core from feature modules:

- Core provides lifecycle, registry, contracts, and orchestration.
- Modules provide feature-specific command logic and integrations.
- Compatibility shims preserve legacy import paths during migration windows.

Practical outcomes:

- Feature modules can be developed and released at different speeds.
- Module teams can iterate without repeatedly rebuilding core command wiring.
- Stable contracts/interfaces keep migrations predictable and reduce regressions.

For implementation details, see:

- [Architecture](reference/architecture.md)
- [Module Contracts](reference/module-contracts.md)

---

## Documentation Sections
Expand Down
2 changes: 2 additions & 0 deletions docs/_layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ <h2 class="docs-sidebar-title">
<ul>
<li><a href="{{ '/guides/command-chains/' | relative_url }}">Command Chains</a></li>
<li><a href="{{ '/guides/agile-scrum-workflows/' | relative_url }}">Agile/Scrum Workflows</a></li>
<li><a href="{{ '/guides/creating-custom-bridges/' | relative_url }}">Creating Custom Bridges</a></li>
<li><a href="{{ '/brownfield-engineer/' | relative_url }}">Working With Existing Code</a></li>
<li><a href="{{ '/brownfield-journey/' | relative_url }}">Existing Code Journey</a></li>
<li><a href="{{ '/guides/sidecar-validation/' | relative_url }}">Sidecar Validation</a></li>
Expand Down Expand Up @@ -173,6 +174,7 @@ <h2 class="docs-sidebar-title">
<li><a href="{{ '/directory-structure/' | relative_url }}">Directory Structure</a></li>
<li><a href="{{ '/reference/projectbundle-schema/' | relative_url }}">ProjectBundle Schema</a></li>
<li><a href="{{ '/reference/module-contracts/' | relative_url }}">Module Contracts</a></li>
<li><a href="{{ '/reference/bridge-registry/' | relative_url }}">Bridge Registry</a></li>
<li><a href="{{ '/guides/integrations-overview/' | relative_url }}">Integrations Overview</a></li>
</ul>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ cd /tmp/specfact-integration-tests/example1_vscode
specfact init

# Or specify IDE explicitly:
# specfact init --ide cursor
# specfact init --ide vscode
# specfact init ide --ide cursor
# specfact init ide --ide vscode
```

**⚠️ Important**: `specfact init` copies templates to the directory where you run it (e.g., `/tmp/specfact-integration-tests/example1_vscode/.cursor/commands/`). For slash commands to work correctly:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ Before starting, ensure you have:
specfact init

# Or specify IDE explicitly:
# specfact init --ide cursor
# specfact init --ide vscode
# specfact init ide --ide cursor
# specfact init ide --ide vscode
```

**⚠️ Important**: `specfact init` copies templates to the directory where you run the command (e.g., `/tmp/specfact-integration-tests/example1_vscode/.cursor/commands/`). However, for slash commands to work correctly with `--repo .`, you must:
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/quick-examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,13 @@ specfact repro --fix --budget 120

```bash
# Initialize Cursor integration
specfact init --ide cursor
specfact init ide --ide cursor

# Initialize VS Code integration
specfact init --ide vscode
specfact init ide --ide vscode

# Force reinitialize
specfact init --ide cursor --force
specfact init ide --ide cursor --force

```

Expand Down
Loading
Loading