v0.28.0
Tesserae v0.28.0 — hooks that cannot spend your money by accident
한국어 · 中文 · 日本語 · Русский · Español · Français · Deutsch
Released 2026-07-27 · PyPI · GitHub release · pip install --upgrade tesserae==0.28.0
Upgrade for the first item. It is a spend bug, and it was reproduced on a real machine.
The $HOME trap
A knowledge base at ~/.tesserae makes $HOME look like a project root. The
plugin's resolve_project_root() walked up from the working directory to
the first .tesserae/ it found — so any session started outside a registered
project resolved to $HOME, and the PostToolUse hook backgrounded
tesserae compile --changed-only over the entire home directory.
15k files, a 795 MB graph, roughly 10 hours of LLM spend, from a setsid'd
process that outlived the session that spawned it. It fired on every Edit/Write.
The fallback made it worse than it looks. When no .tesserae/ was found the
resolver did this:
echo "$PWD"
return 0It claimed any directory was a project. Callers then tested
-d "$root/.tesserae" — which passed for any working directory under $HOME.
That test was the last line of defence and the fallback walked straight through
it.
Two refusals now. $HOME is never a project root, by either the walk-up or the
git-root path. And a no-match returns empty with a non-zero status, so callers
no-op instead of guessing.
Hooks that spend are opt-in. TESSERAE_HOOK_AUTOCOMPILE=1 enables automatic
recompiles; absent, they do nothing. Applied only to the two that actually
spend — posttooluse-edit.sh and session-end.sh. session-start.sh runs
deterministic code sync and pretooluse-compile.sh only intercepts a compile
you typed, so neither is gated.
A hook that backgrounds model work should be switched on deliberately, not
switched off after the bill arrives.
The Python CLI never had this bug: ProjectWiki.load() uses the path it is
given and does not walk up, so a manual tesserae compile outside a project
fails cleanly. The trap was only ever in the shell hooks.
OKF v0.2
Google's Open Knowledge Format
v0.2 makes provenance, trust, lifecycle and attestation first-class. Tesserae now
emits v0.2 and still consumes v0.1.
Emitted: generated: {by, at} from extractor and agent markers; sources with
the credibility signals (usage_count from session counts, usage_window,
last_modified, and author only where exactly one authored_by Person
exists); status: deprecated and stale_after derived from supersedes edges.
Not emitted: verified, and therefore no trust tier above unverified.
Tesserae has no recorded verification event with an actor and a timestamp. Its
four provenance classes are edge properties — how strongly the graph
licenses a triple — while OKF's trust family is a per-concept verification
event. Different axes; mapping one onto the other would launder trust through a
spec. Verified over 5,193 real concepts: verified emitted 0 times,
generated.by claims human: 0 times.
Three consumer bugs are fixed, all found by importing the spec's Appendix A
verbatim through the real CLI, where it previously crashed: unquoted YAML
timestamps resolve to datetime and broke serialization; the v0.1 timestamp
fallback silently no-opped on that same unquoted form; and §6.1's recommended
bundle-relative link (/tables/customers.md) produced zero edges, so a
spec-following bundle imported as disconnected nodes.
A validator written from the spec's own clauses passes a 5,193-concept export
with zero failures, losslessly and byte-idempotently.
Tautological verdicts are named
About 40% of verify_claim's SUPPORTED verdicts were evidenced_by edges
whose cited span is the edge's own target — "C evidenced_by S", confirmed by
reading S. True, uninformative, and previously indistinguishable from a genuine
document-backed verdict.
The payload now says which it is. Across all 15,284 edges: every evidenced_by
SUPPORTED flagged, nothing else flagged, and no verdict changed truth value.
Additive, so v0.27.0's seven-verdict contract is unchanged.
Upgrading from v0.27.0
Drop-in for the library. Reinstall the plugin to get the hook fix, and if you
want automatic recompiles back, set TESSERAE_HOOK_AUTOCOMPILE=1.
If a stray .tesserae exists at $HOME from an earlier accidental compile, it
is now inert — but it is also large, and removing it is safe once you have
confirmed your registry and config live elsewhere.