Skip to content

Commit bcfa478

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

29 files changed

Lines changed: 1890 additions & 176 deletions

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ All notable changes to this project are documented here. The format follows [Kee
44

55
## [Unreleased]
66

7+
### Added
8+
9+
- `SECURITY.md` with vulnerability-reporting process, supported-version policy, and the runtime trust model.
10+
- Documentation site restructured into Diátaxis quadrants (Tutorial / How-To / Reference / Explanation) plus a History section. New pages: getting-started, concepts/{overview,effects-taxonomy,posture-and-hooks}, how-to/{use-the-api,wire-claude-code,contribute,release}, reference/{cli,exceptions,glossary}, explanation/{invariants,faq}, history/phase-1.
11+
- Iron-clad README with status grid, repository layout, and links into the docs site.
12+
13+
### Changed
14+
15+
- `docs/architecture.md`, `docs/design-rationale.md`, `docs/porting-notes.md`, `docs/integration-claude-code.md`, and `docs/api.md` moved under `docs/explanation/`, `docs/how-to/`, and `docs/reference/`.
16+
- `CONTRIBUTING.md` reduced to a quick-start that points at the long form in the docs site.
17+
718
## [0.1.0a0] — 2026-05-08
819

920
### Added

CONTRIBUTING.md

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# Contributing
22

3+
The quick-start. The full contributor guide lives at [docs/how-to/contribute.md](https://macfall7.github.io/spine-lite-python/how-to/contribute/).
4+
35
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.
46

5-
## Local setup
7+
## Setup
68

79
```bash
810
git clone https://github.com/MacFall7/spine-lite-python
@@ -11,7 +13,7 @@ uv venv
1113
uv sync --all-extras --dev
1214
```
1315

14-
## Verification
16+
## Verify
1517

1618
Before every commit:
1719

@@ -25,34 +27,37 @@ Before every push, also:
2527
nox -s coverage docs
2628
```
2729

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
30+
Coverage stays ≥ 95%; docs build with `--strict`.
3131

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
32+
If you don't have nox, the underlying tools work directly:
4033

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.
34+
```bash
35+
uv run ruff check .
36+
uv run ruff format --check .
37+
uv run mypy src tests
38+
uv run pytest --cov=spine_lite --cov-fail-under=95
39+
uv run mkdocs build --strict
40+
```
4241

43-
## Tests
42+
## Style at a glance
4443

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.
44+
- Python 3.11+. `from __future__ import annotations` everywhere.
45+
- `mypy --strict` clean. No `Any` without a justifying comment.
46+
- Google-style docstrings on every public symbol.
47+
- Conventional Commits, subject ≤ 72 chars, imperative mood, no trailing period.
48+
- Direct prose. No marketing tone, no LLM boilerplate.
4649

47-
## Reviewing
50+
## Architecture rules
4851

49-
The build operates under explicit phase gates documented in `CLAUDE.md`. Reviews should focus on:
52+
The closed six-class effects taxonomy and the precedence ordering are the spec. The five pure modules (`effects.py`, `manifest.py`, `classifier.py`, `posture.py`, `receipt.py`) contain no I/O, no clocks, no randomness. I/O lives in `hook.py`, `cli.py`, and tests.
5053

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.
54+
If your change cannot be made within those rules, that's an issue for discussion — not a PR.
5555

56-
## Releases
56+
## Where to read more
5757

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.
58+
- [Full contributor guide](https://macfall7.github.io/spine-lite-python/how-to/contribute/)
59+
- [Architecture](https://macfall7.github.io/spine-lite-python/explanation/architecture/)
60+
- [Invariants](https://macfall7.github.io/spine-lite-python/explanation/invariants/)
61+
- [Design Rationale](https://macfall7.github.io/spine-lite-python/explanation/design-rationale/)
62+
- [Release process](https://macfall7.github.io/spine-lite-python/how-to/release/)
63+
- [`CLAUDE.md`](CLAUDE.md) — repo governance for Claude Code sessions.

README.md

Lines changed: 89 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,34 @@
11
# spine-lite
22

3+
[![CI](https://github.com/MacFall7/spine-lite-python/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/MacFall7/spine-lite-python/actions/workflows/ci.yml)
4+
[![docs](https://img.shields.io/badge/docs-mkdocs--material-blue)](https://macfall7.github.io/spine-lite-python/)
5+
[![python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue)](https://github.com/MacFall7/spine-lite-python)
6+
[![license](https://img.shields.io/badge/license-MIT-green)](LICENSE)
7+
38
Deterministic policy and effects runtime for LLM tool calls.
49

5-
A Python port of [M87-Spine-lite](https://github.com/MacFall7/M87-Spine-lite). Same closed effects taxonomy, same precedence rules, same posture state machine — typed, tested, and shipped as a `pip`-installable package.
10+
A Python port of [M87-Spine-lite](https://github.com/MacFall7/M87-Spine-lite). Same closed effects taxonomy, same precedence rules, same posture state machine — typed, tested, packaged.
11+
12+
## What it does
13+
14+
You give it a tool call and a manifest of declared effects. It returns a deterministic decision: which effects fire, what the dominant class is, and a structured receipt you can replay by SHA. Built to wire into Claude Code as a PreToolUse hook; usable anywhere you can shell out to a subprocess.
15+
16+
The runtime is offline by design — no clocks, no randomness, no network, no LLM calls inside the runtime itself.
617

718
## Status
819

9-
Alpha. Phase 1 ships the scaffold, the closed effects taxonomy, and the public exception hierarchy. The classifier, posture state machine, hook adapter, and the rest of the CLI land in Phases 2 and 3. See `RECEIPTS.md` for build progress and `docs/architecture.md` for the plan.
20+
| Phase | Scope | Version | State |
21+
|-------|-------|---------|-------|
22+
| 1 | Scaffold, taxonomy, exceptions, CLI surface, CI matrix, docs | `v0.1.0a0` | Shipped 2026-05-08 |
23+
| 2 | Manifest schema, classifier with parity tests | `v0.2.0a0` | Pending |
24+
| 3 | Posture state machine, receipts, hook adapter, end-to-end | `v0.3.0a0` | Pending |
1025

11-
> PyPI release lands at the end of Phase 3. Until then, install from source.
26+
See [`RECEIPTS.md`](RECEIPTS.md) for build progress and [docs/history/phase-1.md](https://macfall7.github.io/spine-lite-python/history/phase-1/) for the Phase 1 narrative.
1227

1328
## Install
1429

30+
PyPI publish lands at the end of Phase 3. Until then, install from source:
31+
1532
```bash
1633
git clone https://github.com/MacFall7/spine-lite-python
1734
cd spine-lite-python
@@ -26,46 +43,94 @@ uv run spine-lite version
2643
# 0.1.0a0
2744
```
2845

29-
## Quickstart
46+
Need uv? `curl -LsSf https://astral.sh/uv/install.sh | sh` (Linux/macOS) or `winget install astral-sh.uv` (Windows).
47+
48+
## Use today (Phase 1)
3049

3150
```python
32-
from spine_lite import Effect, most_restrictive
51+
from spine_lite import Effect, most_restrictive, SpineLiteError
3352

53+
# Collapse any non-empty effect set to its dominant class
3454
most_restrictive({Effect.READ, Effect.NETWORK, Effect.WRITE})
3555
# <Effect.NETWORK: 'network'>
56+
57+
# Precedence is total: DESTRUCTIVE > SPAWN > EXECUTE > NETWORK > WRITE > READ
58+
most_restrictive({Effect.READ, Effect.WRITE, Effect.DESTRUCTIVE})
59+
# <Effect.DESTRUCTIVE: 'destructive'>
60+
61+
# Every error in the package descends from SpineLiteError
62+
issubclass(SpineLiteError, Exception) # True
3663
```
3764

38-
The classifier and PreToolUse hook arrive in later phases. The taxonomy is the contract; everything else builds on top of it.
65+
The classifier and PreToolUse hook arrive in Phases 2 and 3. The taxonomy is the contract; everything else builds on it without changing it.
66+
67+
## What this gives you
3968

40-
## What this is
69+
The closed six-class effects taxonomy:
4170

42-
A six-class taxonomy of side effects every tool call falls into:
71+
| Effect | Meaning | Examples |
72+
|--------|---------|----------|
73+
| `READ` | observation only | reading a file, listing a dir, querying without writing |
74+
| `WRITE` | persistent state change to caller-owned storage | writing a file, updating a row, appending a log |
75+
| `NETWORK` | outbound network call | HTTP request, DNS lookup, Slack message |
76+
| `EXECUTE` | subprocess invocation, no fork | `subprocess.run`, `os.system`, shell pipeline |
77+
| `SPAWN` | subprocess that may fork-and-detach | `Popen` with no `wait`, daemon launch, `nohup` |
78+
| `DESTRUCTIVE` | irreversible state change | `rm -rf`, `git push --force`, dropping a table |
4379

44-
| Effect | Meaning |
45-
| --- | --- |
46-
| `READ` | observation only |
47-
| `WRITE` | persistent state change to caller-owned storage |
48-
| `NETWORK` | outbound network call |
49-
| `EXECUTE` | subprocess invocation |
50-
| `SPAWN` | fork-and-detach subprocess |
51-
| `DESTRUCTIVE` | irreversible change |
80+
Ordered by precedence: `DESTRUCTIVE > SPAWN > EXECUTE > NETWORK > WRITE > READ`. `most_restrictive()` collapses any non-empty set to the highest class.
5281

53-
Ordered by precedence: `DESTRUCTIVE > SPAWN > EXECUTE > NETWORK > WRITE > READ`. `most_restrictive()` collapses any non-empty set to the highest class. Same input produces the same output every time. No clocks, no randomness, no I/O in the core.
82+
Same input same output, every time. No clocks, no randomness, no I/O in the core.
5483

55-
## What this is not
84+
## What this isn't
5685

57-
- Not a model. No LLM calls happen inside spine-lite.
58-
- Not a sandbox. It classifies and decides; enforcement happens in the hook.
59-
- Not extensible at runtime. The taxonomy is closed by design — extending it is a project-level decision.
86+
- **Not a model.** No LLM calls happen inside the runtime.
87+
- **Not a sandbox.** It classifies and decides; enforcement happens in the hook adapter.
88+
- **Not extensible at runtime.** The taxonomy is closed by design — extending it is a project-level decision.
89+
- **Not a network library.** There are zero network calls in the runtime, ever.
6090

6191
## Documentation
6292

63-
Full docs publish to GitHub Pages once Phase 1 is signed off.
93+
Full docs at <https://macfall7.github.io/spine-lite-python/>. Quick links:
94+
95+
- [**Getting Started**](https://macfall7.github.io/spine-lite-python/getting-started/) — five-minute install + first decision.
96+
- [**Concepts / Overview**](https://macfall7.github.io/spine-lite-python/concepts/overview/) — mental model end to end.
97+
- [**How-To / Use the API**](https://macfall7.github.io/spine-lite-python/how-to/use-the-api/) — practical patterns, today.
98+
- [**How-To / Wire into Claude Code**](https://macfall7.github.io/spine-lite-python/how-to/wire-claude-code/) — operator runbook.
99+
- [**Reference / API**](https://macfall7.github.io/spine-lite-python/reference/api/) — auto-generated from docstrings.
100+
- [**Reference / Glossary**](https://macfall7.github.io/spine-lite-python/reference/glossary/) — vocabulary.
101+
- [**Explanation / Architecture**](https://macfall7.github.io/spine-lite-python/explanation/architecture/) — why it's shaped this way.
102+
- [**Explanation / Invariants**](https://macfall7.github.io/spine-lite-python/explanation/invariants/) — the rules nothing in this repo gets to break.
103+
- [**Explanation / FAQ**](https://macfall7.github.io/spine-lite-python/explanation/faq/) — common questions about the design.
104+
105+
## Repository layout
106+
107+
```
108+
spine-lite-python/
109+
├── src/spine_lite/ # the runtime (5 pure modules + hook + cli + exceptions)
110+
├── tests/ # unit + smoke tests, all offline
111+
├── docs/ # mkdocs source — Diátaxis-structured
112+
├── .github/workflows/ # CI matrix + Pages deploy
113+
├── CLAUDE.md # repo governance for Claude Code sessions (≤ 150 lines)
114+
├── CONTRIBUTING.md # contributor quick-start
115+
├── CHANGELOG.md # what shipped in each version
116+
├── RECEIPTS.md # append-only phase-day completion log
117+
├── SECURITY.md # vulnerability reporting + trust model
118+
├── pyproject.toml # hatchling build, deps pinned via uv.lock
119+
└── uv.lock # tracked; CI cache keys against it
120+
```
64121

65122
## Contributing
66123

67-
See `CONTRIBUTING.md`. The closed effects taxonomy and the public API are non-negotiable; proposals to change either need a written rationale on an issue first.
124+
See [CONTRIBUTING.md](CONTRIBUTING.md) for the quick-start and [docs/how-to/contribute.md](https://macfall7.github.io/spine-lite-python/how-to/contribute/) for the long form. The closed effects taxonomy and the public API are non-negotiable; proposals to change either need a written rationale on an issue first.
125+
126+
## Security
127+
128+
See [SECURITY.md](SECURITY.md). The runtime is deterministic and offline; trust questions live in your manifest.
129+
130+
## Governance
131+
132+
This repo runs under M87 Studio with explicit phase boundaries. Authority split, halt conditions, and verification gates are in [`CLAUDE.md`](CLAUDE.md). Phase exit gates and receipts are in [`RECEIPTS.md`](RECEIPTS.md).
68133

69134
## License
70135

71-
MIT. See `LICENSE`.
136+
[MIT](LICENSE). Maintained by Mac McFall.

RECEIPTS.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,61 @@ Append-only build log for spine-lite-python. Mirrored to the canonical M87 run-r
5454
- Three exit-gate items (1, 2, 3) require operator action: confirm CI green on the 9-cell matrix, flip repo visibility to public, enable GitHub Pages.
5555

5656
**Next:** Halt for Mac at the Phase 1 exit gate. Phase 2 (manifest + classifier, ~5 working days) does not start without an explicit go.
57+
58+
---
59+
60+
### Phase 1 Day 2 Receipt — 2026-05-08
61+
62+
**Repo:** spine-lite-python branch `claude/setup-project-structure-3YeiT`, ahead of `main` by the docs-expansion commits below.
63+
**Duration:** ~1.5 hours (continuation of the same Claude Code Web session).
64+
65+
**Tasks completed:**
66+
67+
- **CI fix.** Two commits resolving the `setup-uv@v3` cache-key failure: untrack `uv.lock` from `.gitignore` (with the `design-rationale.md` entry inverted), then commit the lockfile (1,396 lines, 68 packages). Operator confirmed all 9 matrix cells green and merged via PR #1 (`d90e72c`). Repo now public; GitHub Pages live at <https://macfall7.github.io/spine-lite-python/>.
68+
- **Documentation expansion to archivist grade.** Restructured `docs/` into Diátaxis quadrants (Tutorial / How-To / Reference / Explanation) plus a History section. Twelve new pages, three substantial rewrites of moved pages, mkdocs nav updated, mkdocs --strict clean.
69+
- **Top-level prose rewritten.** Iron-clad README (status grid, repository layout, copy-paste install, today-vs-later capability matrix, deep links into the docs site), SECURITY.md added (vulnerability reporting, supported versions, trust model, threat model, dependency policy), CONTRIBUTING.md reduced to a quick-start that points at the long-form guide in `docs/how-to/contribute.md`.
70+
71+
**New documentation surface (counts):**
72+
73+
- 1 landing page (`docs/index.md`, rewritten).
74+
- 1 tutorial (`docs/getting-started.md`).
75+
- 3 concept pages (overview, effects-taxonomy, posture-and-hooks).
76+
- 4 how-to pages (use-the-api, wire-claude-code, contribute, release).
77+
- 4 reference pages (api refined, cli, exceptions, glossary).
78+
- 5 explanation pages (architecture refined, design-rationale moved, porting-notes expanded, invariants new, faq new).
79+
- 1 history page (phase-1).
80+
- 1 SECURITY.md.
81+
- README + CONTRIBUTING + CHANGELOG updated.
82+
83+
**Verification (local, in sandbox):**
84+
85+
- `ruff check`: pass
86+
- `ruff format --check`: pass
87+
- `mypy --strict src tests`: pass, 13 source files clean
88+
- `pytest`: 35 / 35 passed
89+
- Coverage: 100% (45 statements, 4 branches, 0 misses)
90+
- `mkdocs build --strict`: pass
91+
- CI on the previous push (commits up to `9e65986`): all 9 matrix cells + lint + typecheck + docs-build green; confirmed by operator.
92+
93+
**Phase 1 exit gate (final):**
94+
95+
| # | Item | State |
96+
|---|------|-------|
97+
| 1 | Repo public on GitHub ||
98+
| 2 | CI green on all 9 matrix cells ||
99+
| 3 | Docs deployed to GitHub Pages ||
100+
| 4 | `pip install -e .` works in fresh venv ||
101+
| 5 | `spine_lite.__version__ == "0.1.0a0"` ||
102+
| 6 | `tests/unit/test_effects.py` passes | ✓ (20/20 incl. hypothesis) |
103+
| 7 | CHANGELOG entry for `v0.1.0a0` ||
104+
| 8 | CLAUDE.md ≤ 150 lines | ✓ (91 lines) |
105+
| 9 | All commits in Conventional Commits format ||
106+
| 10 | Receipt appended ||
107+
108+
All 10 items clear. **Phase 1 closed.**
109+
110+
**Open items / halts:**
111+
112+
- None. Phase 2 (manifest + classifier, ~5 working days, target `v0.2.0a0`) is gated on operator go per `CLAUDE.md`.
113+
114+
**Next:** Halt for Mac at the Phase 1 → Phase 2 transition. Per blueprint §11, completion of Phase 1 unblocks the Braintrust application thread on the operator's side.

0 commit comments

Comments
 (0)