sumac
🍋 sumac: home grocery inventory app
Encrypted-at-rest grocery inventory for a household sharing one git repo and one passphrase.
Locations, products, and quantities are never visible to someone holding the repo without the
passphrase — not even in file or directory names. See docs/FORMAT.md for the on-disk format
and threat model, and docs/LAYOUT.md for what's read-only vs mutable.
Install
Published on PyPI as sumac-home (sumac was taken); the command is still sumac.
uv tool install sumac-home # or: pip install sumac-home
For development (this checkout):
uv sync
Depends on sealedlog (the encrypted append-only log
primitive) from PyPI.
Passphrase
Set SUMAC_PASSPHRASE, or sumac will prompt interactively. The passphrase is shared by every
user of the household's vault.
Usage
sumac init # once, creates data/
sumac config add-location "Fridge" --id fridge
sumac config add-location "Pantry" --id pantry
sumac config show
sumac add purchase milk 2 l --to fridge
sumac add consumption milk 1 l --from fridge
sumac add movement rice 1 kg --from pantry --to fridge
sumac snapshot fridge "milk=1/l" "eggs=6/ct" # reconciliation: resets fridge's products
sumac status # current inventory, all locations
sumac status fridge # current inventory, one location
sumac find milk # where is milk right now?
sumac log # full ordered event log
sumac verify # re-authenticate every line; check actors
All commands take --data-dir (default data, or $SUMAC_DATA_DIR).
Locations nest
A location can have a parent, so shelves, doors, bins, drawers — anything — nest under a
container to arbitrary depth. There's no separate "shelf" or "grid" type; a sub-location is just
another location with --parent set.
sumac config add-location "Door" --id fridge-door --parent fridge
sumac config add-array "Shelf" --parent fridge --count 4 # Shelf 1..4 under fridge
sumac config add-grid "Bin" --parent pantry --rows 3 --cols 4 # Bin R1C1..R3C4 under pantry
sumac config show # renders the tree
sumac status <location> and sumac find both include everything nested under a location, not
just that exact node — sumac status fridge sums the fridge itself, its door, and its shelves in
one pass. Query a sub-location directly (e.g. sumac status fridge-door) to scope to just that
node and its own descendants.
Evaluating agent behavior
sumac ask's agent (below) has a behavioural eval suite — a seeded inventory and a set of
find/add/remove/reject scenarios, run against either a real local model or a deployed Modal
endpoint. It's how a prompt or model change actually gets checked, not just tried once by hand.
uv run pytest evals -v --eval-model qwen3.5-4b
See evals/README.md for the full guide (comparing models, comparing prompt variants, reading the
output) and docs/MODAL.md if you want faster iteration against a deployed Modal endpoint instead
of local inference.
Development
See docs/DEVELOPMENT.md.
Optional: natural-language input (sumac ask)
sumac ask parses freeform text ("consume 1 jar of jam") into structured commands using a local
LLM via mistralrs. It's an optional dependency
group, the rest of sumac works without it.
uv sync --group ask # CPU/Metal — no GPU required
NVIDIA GPU acceleration
uv sync --no-group ask --group ask-cuda
Known upstream issue: mistral.rs's published CUDA wheels for 0.9.1/0.9.2 have a broken
RPATH that prevents the extension from loading at all (tracked upstream:
EricLBuehler/mistral.rs#2411). Until
that's fixed upstream, ask-cuda uses a wheel built from source with a local patch — see
scripts/build-mistralrs-cuda.sh.
To (re)build it:
./scripts/build-mistralrs-cuda.sh v0.9.2
This clones mistral.rs into .build/ (gitignored), builds with maturin against whatever CUDA
compute capability is present on the machine you run it on (confirm with cuobjdump --list-elf <extension>.so | grep sm_ if you need to check), and patches the resulting wheel to embed a real
copy of libcuda.so.1 from the system driver instead of the incorrectly-vendored one the build
produces by default — uv doesn't preserve symlinks from wheel zips on install, so it's a full
copy, not a link. The patched wheel lands in vendor/wheels/ (gitignored — too large for git)
and pyproject.toml's ask-cuda group points at it via a local path source.
This wheel is tied to the host machine, in two separate ways. The compiled extension is built
for whichever GPU's compute capability was present at build time — it is not portable to a
different GPU architecture. And the embedded libcuda.so.1 is a byte-for-byte copy of this
machine's driver — if you update the NVIDIA driver, reinstall the OS, swap GPUs, or move to a
different machine, rebuild rather than reuse the wheel. Requires the CUDA toolkit and a Rust
toolchain (rustc >= 1.94) to build; neither is needed just to run sumac.
To verify a build run uv run python -c "import mistralrs" which should import silently without
erroring.
Metadata
Release files for sumac-home 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sumac_home-0.1.5.tar.gz | 871.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sumac_home-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 948.7 kB
Release files / sumac_home-0.1.5.tar.gz
| Download URL | sumac_home-0.1.5.tar.gz |
|---|---|
| Size | 871.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
10c22b8fb6bc2e010a963cd2129524c42f5c3d561551c75456920072dbc4032c
|
|
BLAKE2b-256 checksum How to use checksums |
b88efa760cfc14aa31d3f47aa655234902e1d86c66b481ff9d7bb306762a6a23
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22","id":"wilma","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / sumac_home-0.1.5-py3-none-any.whl
| Download URL | sumac_home-0.1.5-py3-none-any.whl |
|---|---|
| Size | 77.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1186ce8e646b7686ebd6d5d333191f473d1cddefaf6f0b302f542988c7b30f03
|
|
BLAKE2b-256 checksum How to use checksums |
fe50804a3320397a6e1ae66a9197199b1d309aca291d2f24b65ae14d0189b46b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22","id":"wilma","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|