Skip to content

Commit d90e72c

Browse files
authored
Merge pull request #1 from MacFall7/claude/setup-project-structure-3YeiT
Claude/setup project structure 3 yei t
2 parents 9d81921 + 9e65986 commit d90e72c

33 files changed

Lines changed: 2809 additions & 1 deletion

‎.gitattributes‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
* text=auto eol=lf
2+
*.py text eol=lf
3+
*.toml text eol=lf
4+
*.yml text eol=lf
5+
*.yaml text eol=lf
6+
*.md text eol=lf
7+
*.bat text eol=crlf
8+
*.cmd text eol=crlf
9+
*.png binary
10+
*.jpg binary
11+
*.jpeg binary
12+
*.gif binary
13+
*.ico binary

‎.github/workflows/ci.yml‎

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, "claude/**"]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
concurrency:
11+
group: ci-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
permissions:
15+
contents: read
16+
17+
jobs:
18+
lint:
19+
name: Lint and format
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v4
23+
- uses: astral-sh/setup-uv@v3
24+
with:
25+
enable-cache: true
26+
- name: Set up Python
27+
run: uv python install 3.12
28+
- name: Install dependencies
29+
run: uv sync --all-extras --dev
30+
- name: Ruff lint
31+
run: uv run ruff check .
32+
- name: Ruff format check
33+
run: uv run ruff format --check .
34+
35+
typecheck:
36+
name: Typecheck
37+
runs-on: ubuntu-latest
38+
steps:
39+
- uses: actions/checkout@v4
40+
- uses: astral-sh/setup-uv@v3
41+
with:
42+
enable-cache: true
43+
- name: Set up Python
44+
run: uv python install 3.12
45+
- name: Install dependencies
46+
run: uv sync --all-extras --dev
47+
- name: Mypy
48+
run: uv run mypy src tests
49+
50+
test:
51+
name: Test py${{ matrix.python }} on ${{ matrix.os }}
52+
runs-on: ${{ matrix.os }}
53+
strategy:
54+
fail-fast: false
55+
matrix:
56+
os: [ubuntu-latest, macos-latest, windows-latest]
57+
python: ["3.11", "3.12", "3.13"]
58+
steps:
59+
- uses: actions/checkout@v4
60+
- uses: astral-sh/setup-uv@v3
61+
with:
62+
enable-cache: true
63+
- name: Set up Python
64+
run: uv python install ${{ matrix.python }}
65+
- name: Install dependencies
66+
run: uv sync --all-extras --dev
67+
- name: Pytest with coverage
68+
run: uv run pytest --cov=spine_lite --cov-report=term-missing --cov-report=xml --cov-fail-under=95
69+
- name: Upload coverage
70+
if: matrix.os == 'ubuntu-latest' && matrix.python == '3.12'
71+
uses: actions/upload-artifact@v4
72+
with:
73+
name: coverage-xml
74+
path: coverage.xml
75+
if-no-files-found: error
76+
77+
docs-build:
78+
name: Build docs (strict)
79+
runs-on: ubuntu-latest
80+
steps:
81+
- uses: actions/checkout@v4
82+
- uses: astral-sh/setup-uv@v3
83+
with:
84+
enable-cache: true
85+
- name: Set up Python
86+
run: uv python install 3.12
87+
- name: Install dependencies
88+
run: uv sync --all-extras --dev
89+
- name: Build site
90+
run: uv run mkdocs build --strict

‎.github/workflows/docs.yml‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Deploy docs
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: pages-${{ github.ref }}
15+
cancel-in-progress: false
16+
17+
jobs:
18+
build:
19+
name: Build site
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v4
23+
- uses: astral-sh/setup-uv@v3
24+
with:
25+
enable-cache: true
26+
- name: Set up Python
27+
run: uv python install 3.12
28+
- name: Install dependencies
29+
run: uv sync --all-extras --dev
30+
- name: Build site
31+
run: uv run mkdocs build --strict
32+
- uses: actions/upload-pages-artifact@v3
33+
with:
34+
path: site
35+
36+
deploy:
37+
name: Deploy to GitHub Pages
38+
needs: build
39+
runs-on: ubuntu-latest
40+
environment:
41+
name: github-pages
42+
url: ${{ steps.deployment.outputs.page_url }}
43+
steps:
44+
- id: deployment
45+
uses: actions/deploy-pages@v4

‎.gitignore‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
dist/
9+
*.egg-info/
10+
*.egg
11+
.eggs/
12+
13+
# Virtual environments
14+
.venv/
15+
venv/
16+
env/
17+
.nox/
18+
.tox/
19+
20+
# Testing and coverage
21+
.pytest_cache/
22+
.coverage
23+
.coverage.*
24+
coverage.xml
25+
htmlcov/
26+
.hypothesis/
27+
28+
# Type and lint caches
29+
.mypy_cache/
30+
.ruff_cache/
31+
32+
# IDE / editor
33+
.vscode/
34+
.idea/
35+
*.swp
36+
*.swo
37+
38+
# OS
39+
.DS_Store
40+
Thumbs.db
41+
42+
# Docs build output
43+
site/
44+
45+
# uv tool cache (uv.lock IS tracked; see docs/design-rationale.md)
46+
.uv/

‎CHANGELOG.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Changelog
2+
3+
All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4+
5+
## [Unreleased]
6+
7+
## [0.1.0a0] — 2026-05-08
8+
9+
### Added
10+
11+
- Closed six-class effects taxonomy: `READ`, `WRITE`, `NETWORK`, `EXECUTE`, `SPAWN`, `DESTRUCTIVE`. Canonical precedence ordering and `most_restrictive()` collapse function.
12+
- Public exception hierarchy rooted at `SpineLiteError` with `ManifestError`, `ClassificationError`, `PostureError`, and `HookError` subclasses.
13+
- Scaffolds for `classifier`, `manifest`, `posture`, `receipt`, and `hook` modules — implementations land in Phases 2 and 3.
14+
- `spine-lite` console script with a `version` subcommand.
15+
- CI matrix across Python 3.11/3.12/3.13 on Linux, macOS, and Windows.
16+
- MkDocs documentation with `mkdocstrings`, deployable to GitHub Pages.
17+
- Repo governance file (`CLAUDE.md`) and build-progress receipt log (`RECEIPTS.md`).
18+
19+
[Unreleased]: https://github.com/MacFall7/spine-lite-python/compare/v0.1.0a0...HEAD
20+
[0.1.0a0]: https://github.com/MacFall7/spine-lite-python/releases/tag/v0.1.0a0

‎CLAUDE.md‎

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# CLAUDE.md
2+
3+
Operating manual for Claude Code sessions in this repo.
4+
5+
## Mission
6+
7+
Python port of M87-Spine-lite (TypeScript). Deterministic policy and effects runtime for LLM tool calls. Public API and observable semantics must mirror the TypeScript reference within the closed six-class taxonomy.
8+
9+
## Authority
10+
11+
You decide:
12+
13+
- File contents, signatures, types, tests, commit messages.
14+
- Refactors that don't change the public API.
15+
- Lint, format, and typecheck rule application.
16+
17+
Mac decides — halt and ask:
18+
19+
- Anything in `src/spine_lite/__init__.py`'s `__all__`.
20+
- New dependencies beyond `pyproject.toml`.
21+
- Phase boundary transitions (1→2, 2→3).
22+
- Semantic divergence from the TypeScript reference.
23+
- PyPI publish, repo visibility, GitHub Pages enablement.
24+
25+
## Architectural invariants
26+
27+
1. Closed effects taxonomy. Six members: `READ`, `WRITE`, `NETWORK`, `EXECUTE`, `SPAWN`, `DESTRUCTIVE`. No additions without project sign-off.
28+
2. Precedence: `DESTRUCTIVE > SPAWN > EXECUTE > NETWORK > WRITE > READ`. `most_restrictive()` returns the highest.
29+
3. Determinism. No timestamps, UUIDs, or randomness in `effects.py`, `classifier.py`, `posture.py`, `manifest.py`, `receipt.py`. Inject entropy where you need it.
30+
4. No I/O in those five modules. I/O lives in `hook.py`, `cli.py`, and tests.
31+
5. `mypy --strict` clean on every commit. No `Any` without a comment justifying it.
32+
6. Public API gate. Anything not in `__all__` is private. Private names start with `_`.
33+
7. This file ≤ 150 lines. Refactor before letting it sprawl.
34+
35+
## Style
36+
37+
- Python 3.11+. `from __future__ import annotations` at the top of every module.
38+
- Frozen, slotted, kw-only dataclasses by default.
39+
- Google-style docstrings on every public symbol.
40+
- `logging.getLogger(__name__)` with a `NullHandler` at package init. Library never configures logging.
41+
- Conventional Commits. Subject ≤ 72 chars, imperative mood, no trailing period.
42+
- Direct prose. No marketing tone, no LLM boilerplate, no performative empathy.
43+
44+
## Verification gates
45+
46+
Before any commit:
47+
48+
```
49+
nox -s lint typecheck test
50+
```
51+
52+
All three green or no commit. Before any push, also `coverage` and `docs`. Coverage ≥ 95% on touched files. Docs build with `--strict`.
53+
54+
## Stop conditions
55+
56+
Halt and report when:
57+
58+
- A phase exit gate item is unclear.
59+
- Python and TS reference diverge semantically and you can't tell which is right.
60+
- A test fails you can't explain in 15 minutes.
61+
- You're about to add a dependency.
62+
- You're about to modify `__all__`.
63+
- Two consecutive CI runs fail on the same root cause.
64+
65+
Halt format:
66+
67+
```
68+
HALT: <one-line reason>
69+
Context: <what surfaced>
70+
Options: <2-3 with tradeoffs>
71+
Recommendation: <pick + reasoning>
72+
Awaiting: <decision needed>
73+
```
74+
75+
## Phase plan
76+
77+
- **Phase 1** — scaffold + CI + docs deploy. Tags `v0.1.0a0`.
78+
- **Phase 2** — `manifest` and `classifier` complete. Pydantic v2 models, parity tests against TS reference fixtures, `hypothesis` for invariants. Tags `v0.2.0a0`.
79+
- **Phase 3** — `posture`, `receipt`, `hook`, `cli` complete. End-to-end PreToolUse integration with Claude Code. Tags `v0.3.0a0`.
80+
81+
Phase exit gates and receipts live in `RECEIPTS.md`.
82+
83+
## Scope
84+
85+
- In-repo only. Don't touch the TypeScript reference (read-only spec).
86+
- Don't invoke Patronus, Braintrust, or Arize SDKs (operator-decision pending).
87+
- No network calls in tests. No LLM calls anywhere in the runtime.
88+
89+
## Run registry
90+
91+
Append to `RECEIPTS.md` after every phase day or major milestone. Never edit prior entries. Mac mirrors entries to the canonical run-registry on his side.

‎CONTRIBUTING.md‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Contributing
2+
3+
This repo is governed under M87 Studio. External PRs are welcome, but the closed six-class effects taxonomy and the public API surface are non-negotiable — proposals to change either need a written rationale on an issue before code lands.
4+
5+
## Local setup
6+
7+
```bash
8+
git clone https://github.com/MacFall7/spine-lite-python
9+
cd spine-lite-python
10+
uv venv
11+
uv sync --all-extras --dev
12+
```
13+
14+
## Verification
15+
16+
Before every commit:
17+
18+
```bash
19+
nox -s lint typecheck test
20+
```
21+
22+
Before every push, also:
23+
24+
```bash
25+
nox -s coverage docs
26+
```
27+
28+
Coverage must stay at or above 95% on every commit and at 100% on the modules a phase implements at its exit gate. Docs build with `--strict`.
29+
30+
## Style
31+
32+
- Python 3.11+. `from __future__ import annotations` at the top of every module.
33+
- `mypy --strict` clean. No `Any` without a comment explaining why.
34+
- Google-style docstrings on every public symbol.
35+
- Frozen, slotted, kw-only dataclasses by default. Mutable only with explicit justification.
36+
- Conventional Commits: `feat:`, `fix:`, `docs:`, `chore:`, `test:`, `refactor:`, `ci:`. Subject ≤ 72 chars, imperative mood, no trailing period.
37+
- Direct prose. No marketing copy, no LLM boilerplate, no performative empathy.
38+
39+
## Architecture rules
40+
41+
The closed six-class effects taxonomy and the precedence ordering are the spec. The five core modules — `effects.py`, `classifier.py`, `posture.py`, `manifest.py`, `receipt.py` — are pure: no I/O, no timestamps, no randomness. I/O lives in `hook.py`, `cli.py`, and tests.
42+
43+
## Tests
44+
45+
`pytest` for everything. `hypothesis` for invariants and determinism. The TypeScript reference fixtures (added in Phase 2) are used as-is — no mocking. No network calls in tests; the runtime is offline by design.
46+
47+
## Reviewing
48+
49+
The build operates under explicit phase gates documented in `CLAUDE.md`. Reviews should focus on:
50+
51+
1. Public API stability (anything in `__all__`).
52+
2. Determinism in the pure modules.
53+
3. Parity with the TypeScript reference where applicable.
54+
4. Test coverage on the modules touched.
55+
56+
## Releases
57+
58+
Versioning is SemVer with explicit phase tags: `0.1.0a0` (Phase 1), `0.2.0a0` (Phase 2), `0.3.0a0` (Phase 3). PyPI publishing is gated on a project-level sign-off, not on CI alone.

0 commit comments

Comments
 (0)