Skip to content

Commit 61cbdd9

Browse files
authored
Merge pull request #103 from nold-ai/dev
Release: docs IA restructure and OpenSpec changes
2 parents a5293dc + 8ef8748 commit 61cbdd9

70 files changed

Lines changed: 2210 additions & 145 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/docs-pages.yml

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,49 @@ concurrency:
1919

2020
jobs:
2121
build:
22+
name: Build GitHub Pages
2223
runs-on: ubuntu-latest
2324
steps:
2425
- name: Checkout
2526
uses: actions/checkout@v4
27+
with:
28+
fetch-depth: 0
2629

27-
- name: Setup Pages
28-
uses: actions/configure-pages@v5
30+
- name: Setup Ruby (for Jekyll)
31+
uses: ruby/setup-ruby@v1
32+
with:
33+
ruby-version: "3.2"
34+
bundler-cache: false
35+
working-directory: ./docs
36+
37+
- name: Install Jekyll dependencies
38+
run: |
39+
cd docs
40+
bundle config set --local path 'vendor/bundle'
41+
bundle install --jobs 1 --retry 3
2942
3043
- name: Build with Jekyll
31-
uses: actions/jekyll-build-pages@v1
32-
with:
33-
source: ./docs
34-
destination: ./docs/_site
44+
run: |
45+
cd docs
46+
bundle exec jekyll build --destination ../_site
47+
# Fix CSS path: Jekyll outputs main.css at main/index.css due to permalink pattern
48+
# Copy it to assets/main.css where the HTML expects it
49+
if [ -f ../_site/main/index.css ]; then
50+
cp ../_site/main/index.css ../_site/assets/main.css
51+
fi
52+
env:
53+
JEKYLL_ENV: production
54+
55+
- name: Setup Pages
56+
uses: actions/configure-pages@v5
3557

3658
- name: Upload artifact
3759
uses: actions/upload-pages-artifact@v3
3860
with:
39-
path: ./docs/_site
61+
path: _site
4062

4163
deploy:
64+
name: Deploy to GitHub Pages
4265
environment:
4366
name: github-pages
4467
url: ${{ steps.deployment.outputs.page_url }}

.github/workflows/docs-review.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
2+
# yamllint disable rule:line-length rule:truthy
3+
name: Docs Review
4+
5+
on:
6+
pull_request:
7+
branches: [main, dev]
8+
paths:
9+
- "**/*.md"
10+
- "**/*.mdc"
11+
- "docs/**"
12+
- "tests/unit/docs/test_docs_review.py"
13+
- ".github/workflows/docs-review.yml"
14+
push:
15+
branches: [main, dev]
16+
paths:
17+
- "**/*.md"
18+
- "**/*.mdc"
19+
- "docs/**"
20+
- "tests/unit/docs/test_docs_review.py"
21+
- ".github/workflows/docs-review.yml"
22+
workflow_dispatch:
23+
24+
concurrency:
25+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
26+
cancel-in-progress: true
27+
28+
permissions:
29+
contents: read
30+
31+
jobs:
32+
docs-review:
33+
name: Docs Review
34+
runs-on: ubuntu-latest
35+
steps:
36+
- uses: actions/checkout@v4
37+
38+
- name: Set up Python 3.12
39+
uses: actions/setup-python@v5
40+
with:
41+
python-version: "3.12"
42+
cache: "pip"
43+
44+
- name: Install docs review dependencies
45+
run: |
46+
python -m pip install --upgrade pip
47+
python -m pip install pytest
48+
49+
- name: Run docs review suite
50+
run: |
51+
mkdir -p logs/docs-review
52+
DOCS_REVIEW_LOG="logs/docs-review/docs-review_$(date -u +%Y%m%d_%H%M%S).log"
53+
python -m pytest tests/unit/docs/test_docs_review.py -q 2>&1 | tee "$DOCS_REVIEW_LOG"
54+
exit "${PIPESTATUS[0]:-$?}"
55+
56+
- name: Upload docs review logs
57+
if: always()
58+
uses: actions/upload-artifact@v4
59+
with:
60+
name: docs-review-logs
61+
path: logs/docs-review/
62+
if-no-files-found: ignore

CLAUDE.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project
6+
7+
`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`).
8+
9+
## Local Setup
10+
11+
```bash
12+
hatch env create
13+
hatch run dev-deps # installs specfact-cli from $SPECFACT_CLI_REPO or ../specfact-cli
14+
```
15+
16+
In worktrees, `dev-deps` prefers a matching `specfact-cli-worktrees/<branch>` checkout before falling back to the canonical sibling repo.
17+
18+
## Quality Gates
19+
20+
Run in this order:
21+
22+
```bash
23+
hatch run format
24+
hatch run type-check
25+
hatch run lint
26+
hatch run yaml-lint
27+
hatch run verify-modules-signature --require-signature --payload-from-filesystem --enforce-version-bump
28+
hatch run contract-test
29+
hatch run smart-test
30+
hatch run test
31+
```
32+
33+
Run a single test file: `hatch run test tests/path/to/test_file.py`
34+
Run a single test: `hatch run test tests/path/to/test_file.py::TestClass::test_name`
35+
36+
Pre-commit hooks mirror CI: `pre-commit install && pre-commit run --all-files`
37+
38+
CI runs in `.github/workflows/pr-orchestrator.yml` — matrix quality gates on Python 3.11/3.12/3.13.
39+
40+
## Architecture
41+
42+
### Bundle packages (`packages/<bundle-name>/`)
43+
44+
Six official bundles: `specfact-backlog`, `specfact-codebase`, `specfact-code-review`, `specfact-govern`, `specfact-project`, `specfact-spec`. Each bundle has:
45+
- `module-package.yaml` — name, version, commands, core_compatibility, integrity checksums
46+
- `src/<python_package>/` — bundle source code
47+
48+
### Import policy (`ALLOWED_IMPORTS.md`)
49+
50+
- Only allowed `specfact_cli.*` prefixes may be imported in bundle code (CORE/SHARED APIs only)
51+
- Cross-bundle lateral imports are forbidden except specific allowed pairs (e.g. `specfact_spec` -> `specfact_project`)
52+
- Enforced by `hatch run check-bundle-imports`
53+
54+
### Registry (`registry/`)
55+
56+
- `index.json` — published bundle metadata (versions, artifact URLs, checksums)
57+
- `modules/` and `signatures/` — published artifacts
58+
59+
### Repo tooling
60+
61+
- `tools/` — development infrastructure (type-checker wrapper, smart test coverage, contract-first testing, manifest validation, core dependency bootstrapping)
62+
- `scripts/` — publishing, signing, import checking, pre-commit hooks
63+
- `src/specfact_cli_modules/` — shared repo-level Python package
64+
65+
### OpenSpec workflow (`openspec/`)
66+
67+
- `openspec/specs/` — canonical specifications
68+
- `openspec/changes/` — active change proposals (proposal, design, delta specs, tasks, TDD evidence)
69+
- `openspec/changes/archive/` — completed changes
70+
- `openspec/CHANGE_ORDER.md` — tracks change sequencing and dependencies
71+
72+
## Development Workflow
73+
74+
### Branch protection
75+
76+
`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`.
77+
78+
### Git worktrees
79+
80+
Use worktrees for parallel branch work. Keep primary checkout as canonical `dev` workspace. Worktree paths: `../specfact-cli-modules-worktrees/<branch-type>/<branch-slug>`.
81+
82+
### OpenSpec (required before code changes)
83+
84+
Verify an active OpenSpec change covers the requested scope before changing code. If missing: create or extend a change first.
85+
86+
Follow strict TDD order: spec delta -> failing tests -> implementation -> passing tests -> quality gates. Record TDD evidence in `openspec/changes/<change-id>/TDD_EVIDENCE.md`.
87+
88+
### OpenSpec archive rule (hard requirement)
89+
90+
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.
91+
92+
## Bundle Versioning
93+
94+
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`.
95+
96+
## Linting Scope
97+
98+
- `ruff` runs on the full repo
99+
- `basedpyright` and `pylint` are scoped to `src/`, `tests/`, and `tools/`
100+
- Line length: 120 characters
101+
- Python target: 3.11+

docs/Gemfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# frozen_string_literal: true
2+
3+
source "https://rubygems.org"
4+
5+
gem "jekyll", "~> 4.3"
6+
gem "minima", "~> 2.5"
7+
gem "jekyll-feed", "~> 0.12"
8+
gem "jekyll-redirect-from", "~> 0.16"
9+
gem "jekyll-relative-links", "~> 0.7"
10+
gem "jekyll-sitemap", "~> 1.4"
11+
12+
platforms :mingw, :x64_mingw, :mswin, :jruby do
13+
gem "tzinfo", ">= 1", "< 3"
14+
gem "tzinfo-data"
15+
end
16+
17+
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]

docs/Gemfile.lock

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
GEM
2+
remote: https://rubygems.org/
3+
specs:
4+
addressable (2.8.7)
5+
public_suffix (>= 2.0.2, < 7.0)
6+
base64 (0.3.0)
7+
colorator (1.1.0)
8+
concurrent-ruby (1.3.5)
9+
csv (3.3.5)
10+
em-websocket (0.5.3)
11+
eventmachine (>= 0.12.9)
12+
http_parser.rb (~> 0)
13+
eventmachine (1.2.7)
14+
ffi (1.17.2)
15+
forwardable-extended (2.6.0)
16+
google-protobuf (3.25.8-x86_64-linux)
17+
http_parser.rb (0.8.0)
18+
i18n (1.14.7)
19+
concurrent-ruby (~> 1.0)
20+
jekyll (4.4.1)
21+
addressable (~> 2.4)
22+
base64 (~> 0.2)
23+
colorator (~> 1.0)
24+
csv (~> 3.0)
25+
em-websocket (~> 0.5)
26+
i18n (~> 1.0)
27+
jekyll-sass-converter (>= 2.0, < 4.0)
28+
jekyll-watch (~> 2.0)
29+
json (~> 2.6)
30+
kramdown (~> 2.3, >= 2.3.1)
31+
kramdown-parser-gfm (~> 1.0)
32+
liquid (~> 4.0)
33+
mercenary (~> 0.3, >= 0.3.6)
34+
pathutil (~> 0.9)
35+
rouge (>= 3.0, < 5.0)
36+
safe_yaml (~> 1.0)
37+
terminal-table (>= 1.8, < 4.0)
38+
webrick (~> 1.7)
39+
jekyll-feed (0.17.0)
40+
jekyll (>= 3.7, < 5.0)
41+
jekyll-redirect-from (0.16.0)
42+
jekyll (>= 3.3, < 5.0)
43+
jekyll-relative-links (0.7.0)
44+
jekyll (>= 3.3, < 5.0)
45+
jekyll-sass-converter (3.0.0)
46+
sass-embedded (~> 1.54)
47+
jekyll-seo-tag (2.8.0)
48+
jekyll (>= 3.8, < 5.0)
49+
jekyll-sitemap (1.4.0)
50+
jekyll (>= 3.7, < 5.0)
51+
jekyll-watch (2.2.1)
52+
listen (~> 3.0)
53+
json (2.17.1.2)
54+
kramdown (2.5.1)
55+
rexml (>= 3.3.9)
56+
kramdown-parser-gfm (1.1.0)
57+
kramdown (~> 2.0)
58+
liquid (4.0.4)
59+
listen (3.9.0)
60+
rb-fsevent (~> 0.10, >= 0.10.3)
61+
rb-inotify (~> 0.9, >= 0.9.10)
62+
mercenary (0.4.0)
63+
minima (2.5.2)
64+
jekyll (>= 3.5, < 5.0)
65+
jekyll-feed (~> 0.9)
66+
jekyll-seo-tag (~> 2.1)
67+
pathutil (0.16.2)
68+
forwardable-extended (~> 2.6)
69+
public_suffix (6.0.2)
70+
rake (13.3.1)
71+
rb-fsevent (0.11.2)
72+
rb-inotify (0.11.1)
73+
ffi (~> 1.0)
74+
rexml (3.4.4)
75+
rouge (4.6.1)
76+
safe_yaml (1.0.5)
77+
sass-embedded (1.69.5)
78+
google-protobuf (~> 3.23)
79+
rake (>= 13.0.0)
80+
terminal-table (3.0.2)
81+
unicode-display_width (>= 1.1.1, < 3)
82+
unicode-display_width (2.6.0)
83+
webrick (1.9.1)
84+
85+
PLATFORMS
86+
x86_64-linux
87+
88+
DEPENDENCIES
89+
jekyll (~> 4.3)
90+
jekyll-feed (~> 0.12)
91+
jekyll-redirect-from (~> 0.16)
92+
jekyll-relative-links (~> 0.7)
93+
jekyll-sitemap (~> 1.4)
94+
minima (~> 2.5)
95+
tzinfo (>= 1, < 3)
96+
tzinfo-data
97+
wdm (~> 0.1.1)
98+
99+
BUNDLED WITH
100+
2.3.5

docs/_config.yml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ markdown: kramdown
1212
highlighter: rouge
1313
plugins:
1414
- jekyll-feed
15+
- jekyll-redirect-from
1516
- jekyll-relative-links
1617
- jekyll-sitemap
1718

@@ -28,8 +29,6 @@ exclude:
2829
- tests
2930
- tools
3031
- packages
31-
- tests
32-
- tools
3332
- scripts
3433
- registry
3534

@@ -62,6 +61,26 @@ defaults:
6261
path: "reference"
6362
values:
6463
layout: default
64+
- scope:
65+
path: "bundles"
66+
values:
67+
layout: default
68+
- scope:
69+
path: "workflows"
70+
values:
71+
layout: default
72+
- scope:
73+
path: "integrations"
74+
values:
75+
layout: default
76+
- scope:
77+
path: "team-and-enterprise"
78+
values:
79+
layout: default
80+
- scope:
81+
path: "authoring"
82+
values:
83+
layout: default
6584
theme: minima
6685
minima:
6786
social:

0 commit comments

Comments
 (0)