You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 31104d6
Browse filesBrowse the repository at this point in the historyBrowse files
docs: rewrite README, add SECURITY, point CONTRIBUTING at the docs site
README: status grid with phase + version + ship date, repository layout,
copy-paste install, today-vs-later capability matrix, deep links into
the published docs site, badges that resolve.
SECURITY.md: vulnerability-reporting process, supported-version policy,
trust model (what the runtime guarantees vs. what it doesn't), threat
model in scope vs. out of scope, dependency policy.
CONTRIBUTING.md: trimmed to a quick-start that points at the long-form
guide in docs/how-to/contribute.md.
CHANGELOG: [Unreleased] entry for the documentation expansion.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+11Lines changed: 11 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,17 @@ All notable changes to this project are documented here. The format follows [Kee
4
4
5
5
## [Unreleased]
6
6
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.
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
+
3
5
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.
- 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:
40
33
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
+
```
42
41
43
-
## Tests
42
+
## Style at a glance
44
43
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.
- Direct prose. No marketing tone, no LLM boilerplate.
46
49
47
-
## Reviewing
50
+
## Architecture rules
48
51
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.
50
53
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.
55
55
56
-
## Releases
56
+
## Where to read more
57
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.
Deterministic policy and effects runtime for LLM tool calls.
4
9
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.
6
17
7
18
## Status
8
19
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.
> 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.
12
27
13
28
## Install
14
29
30
+
PyPI publish lands at the end of Phase 3. Until then, install from source:
|`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 |
43
79
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.
52
81
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.
54
83
55
-
## What this is not
84
+
## What this isn't
56
85
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.
60
90
61
91
## Documentation
62
92
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.
├── 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
+
```
64
121
65
122
## Contributing
66
123
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).
Email `security@m87.studio` with details. Don't open a public issue for a vulnerability; security issues stay private until a fix is shipped and disclosed.
6
+
7
+
Include in the report:
8
+
9
+
- A description of the vulnerability and its impact.
10
+
- Steps to reproduce, ideally with a minimal example.
11
+
- The version(s) affected (commit SHA is fine).
12
+
- Your preferred disclosure timeline (the default is 90 days).
13
+
14
+
Expect an acknowledgement within 5 business days. We'll coordinate disclosure and CVE assignment if applicable.
15
+
16
+
## Supported versions
17
+
18
+
Alpha. Phase 1 is the only shipped version.
19
+
20
+
| Version | Status | Security fixes |
21
+
|---------|--------|----------------|
22
+
|`0.1.0aN` (Phase 1) | Current | Yes |
23
+
|`0.2.0aN` (Phase 2) | Pending | Will be supported when shipped |
24
+
|`0.3.0aN` (Phase 3) | Pending | Will be supported when shipped |
25
+
26
+
Once `v1.0.0` ships, we support the latest two minor lines (`v1.N` and `v1.N-1`) for security fixes.
27
+
28
+
## Trust model
29
+
30
+
The runtime is deterministic and offline. It contains:
31
+
32
+
- No LLM calls.
33
+
- No network calls.
34
+
- No filesystem access in the pure modules.
35
+
- No subprocess invocation in the pure modules.
36
+
37
+
Trust questions live entirely in your **manifest**. The manifest declares which tools the LLM can invoke, what effects each tool produces, and which postures permit which calls. If your manifest is wrong, the runtime will faithfully classify a wrong call as a wrong call — the runtime is not the safety net for a bad manifest.
38
+
39
+
### What the hook does and doesn't do
40
+
41
+
When `v0.3.0a0` ships:
42
+
43
+
-`spine-lite hook` reads stdin, classifies, decides, writes stdout. It does not execute the tool itself; that's Claude Code's job.
44
+
- An exit code of 0 from the hook is a permission, not an action. Whether the tool actually runs is the host's decision.
45
+
- A non-zero exit deny is final on the host's side. spine-lite has no way to override its own deny.
46
+
47
+
### What you trust the runtime for
48
+
49
+
- Correctly classifying a tool call against a manifest.
50
+
- Producing a deterministic, content-addressable receipt.
51
+
- Never silently widening permissions (e.g. classifying a `WRITE` as a `READ`).
52
+
53
+
### What you don't trust the runtime for
54
+
55
+
- Validating that the tool itself behaves as the manifest claims. The manifest is a contract, not a proof.
56
+
- Sandboxing the tool's execution. The hook decides; the host enforces.
57
+
- Detecting model jailbreaks or prompt injection. That's a separate layer.
58
+
59
+
### Threat model
60
+
61
+
In scope:
62
+
63
+
- A misconfigured manifest that leaks more permission than intended.
64
+
- A tool call that classifies differently in TypeScript and Python (parity bug).
65
+
- A receipt that doesn't reproduce on replay (determinism bug).
66
+
- A path-handling bug on Windows that doesn't surface on Linux.
67
+
68
+
Out of scope:
69
+
70
+
- Adversarial LLM output that the manifest does not constrain.
71
+
- Compromise of the operator's machine (the hook reads files; if those files are tampered with, classification follows the tampered input).
72
+
- Side-channel attacks via posture transitions in shared environments.
73
+
74
+
## Dependencies
75
+
76
+
We run `pip-audit` (manually for now, automated in CI for Phase 2+) against the `uv.lock` and respond to CVEs in dependencies within 30 days. The dependency surface is intentionally small: `pydantic`, `typer`, and the dev/docs tooling.
77
+
78
+
## Cryptographic guarantees
79
+
80
+
Receipts are content-addressable via `hashlib.sha256` (Phase 3). Two receipts with the same SHA-256 represent the same decision over the same inputs. We rely on the standard-library implementation; no custom crypto.
81
+
82
+
## Disclosure history
83
+
84
+
None yet.
85
+
86
+
## See also
87
+
88
+
-[Explanation / Invariants](docs/explanation/invariants.md) — what the runtime guarantees.
89
+
-[Explanation / FAQ](docs/explanation/faq.md) — common questions about the design.
90
+
-[How-To / Wire into Claude Code](docs/how-to/wire-claude-code.md) — the hook contract.
0 commit comments