Skip to main content

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)

Source distribution for sumac-home 0.1.5
File Size Uploaded
sumac_home-0.1.5.tar.gz 871.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sumac-home 0.1.5
File Interpreter ABI Platform
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}

Release history Release notifications | RSS feed

0.2.0

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page