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
37 changes: 30 additions & 7 deletions .github/workflows/docs-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,49 @@ concurrency:

jobs:
build:
name: Build GitHub Pages
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Pages
uses: actions/configure-pages@v5
- name: Setup Ruby (for Jekyll)
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.2"
bundler-cache: false
working-directory: ./docs

- name: Install Jekyll dependencies
run: |
cd docs
bundle config set --local path 'vendor/bundle'
bundle install --jobs 1 --retry 3

- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
with:
source: ./docs
destination: ./docs/_site
run: |
cd docs
bundle exec jekyll build --destination ../_site
# Fix CSS path: Jekyll outputs main.css at main/index.css due to permalink pattern
# Copy it to assets/main.css where the HTML expects it
if [ -f ../_site/main/index.css ]; then
cp ../_site/main/index.css ../_site/assets/main.css
fi
env:
JEKYLL_ENV: production

- name: Setup Pages
uses: actions/configure-pages@v5

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./docs/_site
path: _site

deploy:
name: Deploy to GitHub Pages
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
Expand Down
62 changes: 62 additions & 0 deletions .github/workflows/docs-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
# yamllint disable rule:line-length rule:truthy
name: Docs Review

on:
pull_request:
branches: [main, dev]
paths:
- "**/*.md"
- "**/*.mdc"
- "docs/**"
- "tests/unit/docs/test_docs_review.py"
- ".github/workflows/docs-review.yml"
push:
branches: [main, dev]
paths:
- "**/*.md"
- "**/*.mdc"
- "docs/**"
- "tests/unit/docs/test_docs_review.py"
- ".github/workflows/docs-review.yml"
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
docs-review:
name: Docs Review
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"

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

- name: Run docs review suite
run: |
mkdir -p logs/docs-review
DOCS_REVIEW_LOG="logs/docs-review/docs-review_$(date -u +%Y%m%d_%H%M%S).log"
python -m pytest tests/unit/docs/test_docs_review.py -q 2>&1 | tee "$DOCS_REVIEW_LOG"
exit "${PIPESTATUS[0]:-$?}"

- name: Upload docs review logs
if: always()
uses: actions/upload-artifact@v4
with:
name: docs-review-logs
path: logs/docs-review/
if-no-files-found: ignore
101 changes: 101 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project

`specfact-cli-modules` hosts official nold-ai bundle packages and the module registry used by SpecFact CLI. Bundle packages import from `specfact_cli` (models, runtime, validators). The core CLI lives in a sibling repo (`specfact-cli`).

## Local Setup

```bash
hatch env create
hatch run dev-deps # installs specfact-cli from $SPECFACT_CLI_REPO or ../specfact-cli
```

In worktrees, `dev-deps` prefers a matching `specfact-cli-worktrees/<branch>` checkout before falling back to the canonical sibling repo.

## Quality Gates

Run in this order:

```bash
hatch run format
hatch run type-check
hatch run lint
hatch run yaml-lint
hatch run verify-modules-signature --require-signature --payload-from-filesystem --enforce-version-bump
hatch run contract-test
hatch run smart-test
hatch run test
```

Run a single test file: `hatch run test tests/path/to/test_file.py`
Run a single test: `hatch run test tests/path/to/test_file.py::TestClass::test_name`

Pre-commit hooks mirror CI: `pre-commit install && pre-commit run --all-files`

CI runs in `.github/workflows/pr-orchestrator.yml` — matrix quality gates on Python 3.11/3.12/3.13.

## Architecture

### Bundle packages (`packages/<bundle-name>/`)

Six official bundles: `specfact-backlog`, `specfact-codebase`, `specfact-code-review`, `specfact-govern`, `specfact-project`, `specfact-spec`. Each bundle has:
- `module-package.yaml` — name, version, commands, core_compatibility, integrity checksums
- `src/<python_package>/` — bundle source code

### Import policy (`ALLOWED_IMPORTS.md`)

- Only allowed `specfact_cli.*` prefixes may be imported in bundle code (CORE/SHARED APIs only)
- Cross-bundle lateral imports are forbidden except specific allowed pairs (e.g. `specfact_spec` -> `specfact_project`)
- Enforced by `hatch run check-bundle-imports`

### Registry (`registry/`)

- `index.json` — published bundle metadata (versions, artifact URLs, checksums)
- `modules/` and `signatures/` — published artifacts

### Repo tooling

- `tools/` — development infrastructure (type-checker wrapper, smart test coverage, contract-first testing, manifest validation, core dependency bootstrapping)
- `scripts/` — publishing, signing, import checking, pre-commit hooks
- `src/specfact_cli_modules/` — shared repo-level Python package

### OpenSpec workflow (`openspec/`)

- `openspec/specs/` — canonical specifications
- `openspec/changes/` — active change proposals (proposal, design, delta specs, tasks, TDD evidence)
- `openspec/changes/archive/` — completed changes
- `openspec/CHANGE_ORDER.md` — tracks change sequencing and dependencies

## Development Workflow

### Branch protection

`dev` and `main` are protected — never work directly on them. Use feature branches: `feature/*`, `bugfix/*`, `hotfix/*`, `chore/*`. PRs go to `dev` unless release workflow requires `main`.

### Git worktrees

Use worktrees for parallel branch work. Keep primary checkout as canonical `dev` workspace. Worktree paths: `../specfact-cli-modules-worktrees/<branch-type>/<branch-slug>`.

### OpenSpec (required before code changes)

Verify an active OpenSpec change covers the requested scope before changing code. If missing: create or extend a change first.

Follow strict TDD order: spec delta -> failing tests -> implementation -> passing tests -> quality gates. Record TDD evidence in `openspec/changes/<change-id>/TDD_EVIDENCE.md`.

### OpenSpec archive rule (hard requirement)

Never manually move folders under `openspec/changes/` into `archive/`. Archiving MUST use `openspec archive <change-id>` (or equivalent workflow command). Update `openspec/CHANGE_ORDER.md` when archive status changes.

## Bundle Versioning

SemVer: patch (bug fix), minor (new command/option/API), major (breaking change/removal). When bumping a version, review and update `core_compatibility` in both `module-package.yaml` and `registry/index.json`.

## Linting Scope

- `ruff` runs on the full repo
- `basedpyright` and `pylint` are scoped to `src/`, `tests/`, and `tools/`
- Line length: 120 characters
- Python target: 3.11+
17 changes: 17 additions & 0 deletions docs/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

source "https://rubygems.org"

gem "jekyll", "~> 4.3"
gem "minima", "~> 2.5"
gem "jekyll-feed", "~> 0.12"
gem "jekyll-redirect-from", "~> 0.16"
gem "jekyll-relative-links", "~> 0.7"
gem "jekyll-sitemap", "~> 1.4"

platforms :mingw, :x64_mingw, :mswin, :jruby do
gem "tzinfo", ">= 1", "< 3"
gem "tzinfo-data"
end

gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
100 changes: 100 additions & 0 deletions docs/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
base64 (0.3.0)
colorator (1.1.0)
concurrent-ruby (1.3.5)
csv (3.3.5)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
eventmachine (1.2.7)
ffi (1.17.2)
forwardable-extended (2.6.0)
google-protobuf (3.25.8-x86_64-linux)
http_parser.rb (0.8.0)
i18n (1.14.7)
concurrent-ruby (~> 1.0)
jekyll (4.4.1)
addressable (~> 2.4)
base64 (~> 0.2)
colorator (~> 1.0)
csv (~> 3.0)
em-websocket (~> 0.5)
i18n (~> 1.0)
jekyll-sass-converter (>= 2.0, < 4.0)
jekyll-watch (~> 2.0)
json (~> 2.6)
kramdown (~> 2.3, >= 2.3.1)
kramdown-parser-gfm (~> 1.0)
liquid (~> 4.0)
mercenary (~> 0.3, >= 0.3.6)
pathutil (~> 0.9)
rouge (>= 3.0, < 5.0)
safe_yaml (~> 1.0)
terminal-table (>= 1.8, < 4.0)
webrick (~> 1.7)
jekyll-feed (0.17.0)
jekyll (>= 3.7, < 5.0)
jekyll-redirect-from (0.16.0)
jekyll (>= 3.3, < 5.0)
jekyll-relative-links (0.7.0)
jekyll (>= 3.3, < 5.0)
jekyll-sass-converter (3.0.0)
sass-embedded (~> 1.54)
jekyll-seo-tag (2.8.0)
jekyll (>= 3.8, < 5.0)
jekyll-sitemap (1.4.0)
jekyll (>= 3.7, < 5.0)
jekyll-watch (2.2.1)
listen (~> 3.0)
json (2.17.1.2)
kramdown (2.5.1)
rexml (>= 3.3.9)
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.4)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.4.0)
minima (2.5.2)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (6.0.2)
rake (13.3.1)
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
rexml (3.4.4)
rouge (4.6.1)
safe_yaml (1.0.5)
sass-embedded (1.69.5)
google-protobuf (~> 3.23)
rake (>= 13.0.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
unicode-display_width (2.6.0)
webrick (1.9.1)

PLATFORMS
x86_64-linux

DEPENDENCIES
jekyll (~> 4.3)
jekyll-feed (~> 0.12)
jekyll-redirect-from (~> 0.16)
jekyll-relative-links (~> 0.7)
jekyll-sitemap (~> 1.4)
minima (~> 2.5)
tzinfo (>= 1, < 3)
tzinfo-data
wdm (~> 0.1.1)

BUNDLED WITH
2.3.5
23 changes: 21 additions & 2 deletions docs/_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ markdown: kramdown
highlighter: rouge
plugins:
- jekyll-feed
- jekyll-redirect-from
- jekyll-relative-links
- jekyll-sitemap

Expand All @@ -28,8 +29,6 @@ exclude:
- tests
- tools
- packages
- tests
- tools
- scripts
- registry

Expand Down Expand Up @@ -62,6 +61,26 @@ defaults:
path: "reference"
values:
layout: default
- scope:
path: "bundles"
values:
layout: default
- scope:
path: "workflows"
values:
layout: default
- scope:
path: "integrations"
values:
layout: default
- scope:
path: "team-and-enterprise"
values:
layout: default
- scope:
path: "authoring"
values:
layout: default
theme: minima
minima:
social:
Expand Down
Loading
Loading