|
| 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. |
0 commit comments