Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions .github/workflows/specfact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ jobs:
hatch env create || true
pip install -e .

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

- name: Set validation parameters
id: validation
run: |
Expand Down
3 changes: 3 additions & 0 deletions .markdownlintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
docs/_site/
docs/vendor/
docs/project-plans/
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ All notable changes to this project will be documented in this file.

---

## [0.30.0] - 2026-02-08

### Added (0.30.0)

- ModuleIOContract protocol for formal module interfaces.
- Static analysis enforcement of core-module isolation.
- ProjectBundle schema versioning (`schema_version` field).
- ValidationReport model for structured validation results.
- Protocol compliance tracking in module metadata.

### 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.
- Reference: `(fixes #206)`.

---

## [0.29.0] - 2026-02-06

### Added (0.29.0)
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ SpecFact now has a lifecycle-managed module system:

This lifecycle model is the baseline for future granular module updates and enhancements. Module installation from third-party or open-source community providers is planned, but not implemented yet.

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.

---

## Developer Note: Command Layout
Expand Down
2 changes: 2 additions & 0 deletions docs/_layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ <h2 class="docs-sidebar-title">
<li><a href="{{ '/architecture/' | relative_url }}">Architecture</a></li>
<li><a href="{{ '/modes/' | relative_url }}">Operational Modes</a></li>
<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="{{ '/guides/integrations-overview/' | relative_url }}">Integrations Overview</a></li>
</ul>

Expand Down
22 changes: 22 additions & 0 deletions docs/reference/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,28 @@ transitions:

### 2. Contract Layer

## Contract-First Module Development

SpecFact module development follows a contract-first pattern:

- `ModuleIOContract` formalizes module IO on top of `ProjectBundle`.
- `ValidationReport` standardizes module validation output.
- Registration validates supported protocol operations and declared schema compatibility.

### Core-Module Isolation Principle

Core runtime paths (`cli.py`, `registry/`, `models/`, `utils/`, `contracts/`) must not import from
`specfact_cli.modules.*` directly.

- Core invokes module capabilities through `CommandRegistry`.
- Modules are discovered and loaded lazily.
- Static isolation tests enforce this boundary in CI.

See also:

- [Module Contracts](module-contracts.md)
- [ProjectBundle Schema](projectbundle-schema.md)

#### Runtime Contracts (icontract)

```python
Expand Down
55 changes: 55 additions & 0 deletions docs/reference/module-contracts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
layout: default
title: Module Contracts
permalink: /reference/module-contracts/
description: ModuleIOContract protocol, validation output model, and isolation rules for module developers.
---

# Module Contracts

SpecFact modules integrate through a protocol-first interface and inversion-of-control loading.

## ModuleIOContract

`ModuleIOContract` defines four operations:

- `import_to_bundle(source: Path, config: dict) -> ProjectBundle`
- `export_from_bundle(bundle: ProjectBundle, target: Path, config: dict) -> None`
- `sync_with_bundle(bundle: ProjectBundle, external_source: str, config: dict) -> ProjectBundle`
- `validate_bundle(bundle: ProjectBundle, rules: dict) -> ValidationReport`

Implementations should use runtime contracts (`@icontract`) and runtime type validation (`@beartype`).

## ValidationReport

`ValidationReport` provides structured validation output:

- `status`: `passed | failed | warnings`
- `violations`: list of maps with `severity`, `message`, `location`
- `summary`: counts (`total_checks`, `passed`, `failed`, `warnings`)

## Inversion of Control

Core code must not import module code directly.

- Allowed: core -> `CommandRegistry`
- Forbidden: core -> `specfact_cli.modules.*`

Module discovery and loading are done through registry-driven lazy loading.

## Example Implementation

```python
@beartype
@require(lambda source: source.exists())
@ensure(lambda result: isinstance(result, ProjectBundle))
def import_to_bundle(source: Path, config: dict[str, Any]) -> ProjectBundle:
return ProjectBundle.load_from_directory(source)
```

## Guidance for 3rd-Party Modules

- Declare module metadata in `module-package.yaml`.
- Implement as many protocol operations as your module supports.
- Declare `schema_version` when you depend on a specific bundle IO schema.
- Keep module logic isolated from core; rely on registry entrypoints.
46 changes: 46 additions & 0 deletions docs/reference/projectbundle-schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
layout: default
title: ProjectBundle Schema
permalink: /reference/projectbundle-schema/
description: ProjectBundle fields, schema_version semantics, and compatibility guidance.
---

# ProjectBundle Schema

`ProjectBundle` is the canonical IO contract used by core and module integrations.

## Key Fields

- `manifest`: bundle metadata and indexes (`BundleManifest`)
- `bundle_name`: logical bundle identifier
- `schema_version`: module-IO schema version string (default: `"1"`)
- `idea`, `business`, `product`, `features`, `clarifications`: project content

## Schema Versioning Strategy

`schema_version` is a compatibility signal for module IO behavior.

- Major compatibility checks in module registration compare module-declared schema version with current ProjectBundle schema.
- Missing module schema version is treated as compatible with the current schema.
- Incompatible module schema versions are skipped at registration time.

## Example

```yaml
bundle_name: legacy-api
schema_version: "1"
manifest:
versions:
schema: "1.0"
project: "0.1.0"
product:
themes: []
releases: []
features: {}
```

## Backward Compatibility

- Existing bundles without explicit module metadata remain usable.
- Registration keeps legacy modules enabled when protocol methods are absent.
- New protocol and schema checks are additive and designed for gradual migration.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-08
Loading
Loading