Structured decision memory for Claude Code. Captures why decisions were made as markdown files with SQLite FTS5 search — stdlib only, no external dependencies.
git clone https://github.com/zimalabs/code-decisions.git
cd code-decisions
uv sync # install dev deps
make check # ruff + mypy + shellcheck + pytestRequirements: Python 3.9+, uv
To test the plugin end-to-end in Claude Code:
make dev # symlink into Claude Code's plugin cacheRestart Claude Code (or run /reload-plugins) to load the plugin.
- Fork the repo and create a branch:
git checkout -b feat/my-feature - Make your changes
- Run
make check(must pass) - Commit with a clear message
- Open a PR
- Linting: ruff (format + lint), mypy for type checking, shellcheck for bash
- Plugin is stdlib only — no external dependencies in
src/ - Dev tooling (pytest, ruff, mypy) lives in
pyproject.tomlat the repo root - Functions prefixed with
_are private helpers - YAML frontmatter with
---delimiters
Decisions are markdown files in .claude/decisions/ in the repo. SQLite FTS5 provides a derived search index — delete it and everything rebuilds from markdown.
src/
decision/ # Core library (stdlib only)
utils/ # Pure helpers and constants
core/ # Decision dataclass and quality scoring
store/ # File-based storage, FTS5 index, keyword search
policy/ # 14 policies for capture, validation, context, review
hooks/ # Shell dispatcher + hook registration
skills/ # /decision — single skill, intent-routed (see SKILL.md)
tests/ # pytest with tmp_path fixtures, no mocks
dispatch.sh short-circuits common cases (observe mode, short messages, skip-pattern files) in bash before spawning Python, keeping hook latency low.
Tests use pytest with tmp_path fixtures. Each test creates its own decisions dir in a temp dir. No mocks.
make test # pytest only
make check # full suite (ruff + mypy + shellcheck + pytest)- Add the function to the appropriate subpackage (
utils/,core/,store/, orpolicy/) - Add tests to the relevant test file
- Wire into hooks via a new policy in
policy/defs.pyif needed - Run
make check
- Write a condition function in a new file under
src/decision/policy/(e.g.my_policy.py) - Import the condition in
src/decision/policy/defs.py - Add a
Policy(...)instance toALL_POLICIESwith name, level, events, matchers - Add tests to
tests/test_policy.py - Run
make check— nohooks.jsonchanges needed
This project uses its own plugin to track decisions. When you make a non-trivial choice (architecture, API design, trade-off), capture it with /decision. Future contributors inherit that context automatically.
Use GitHub issues for bugs and feature requests. See the issue templates for bug reports and feature requests.