Trunkit — proof-carrying code and deterministic automata middleware on PostgreSQL, with Porter agent context handoff
Project description
Trunkit
The smallest elephant in the room that's not too Coq-y and doesn't Lean too heavily on your system.
Proof-carrying code middleware on PostgreSQL. Trunkit is a self-contained schema stack that attaches verifiable claims to mathematical objects, chains proofs compositionally, and lets consumers re-verify results without trusting the producer — all inside a database you already operate, with no specialist toolchain required.
No 3 GB compiler. No gigabytes of cached proof objects. No new runtime to learn. Just PostgreSQL, Python, and ~1 MB of schemas that describe, attest, and verify themselves.
Stack
+------------------------------------------------------------------+
| Porter -- agent context handoff |
| Precacher * Sources * close_session() * open_session() |
| cybernetic DFAs * composite pattern detection |
+------------------------------------------------------------------+
| Nerode -- deterministic automata engine |
| DFA construction * minimization * product * session DFAs |
| sequence cache * cert-signed handoff envelopes |
+--------------------------+---------------------------------------+
| cert | kan |
| proof-carrying | category theory meta-layer |
| attestation | (monoidal, NTs, Kan, profunctors) |
+--------------------------+---------------------------------------+
| curry | calx |
| versioned provenance | integer arithmetic bedrock |
| + immutable constants | (primes, CRT, dynamics, OEIS) |
+--------------------------+---------------------------------------+
Trunkit DB postgresql://trunk:trunk@localhost:5434/trunk
Nerode DB postgresql://nerode:nerode@localhost:5435/nerode
| Layer | Role |
|---|---|
| calx | Dense prime factorisation of Z[1..N]; aliquot/derivative dynamics; CRT; OEIS sequence matching |
| curry | Immutable versioned constants and functions; append-only computational provenance |
| kan | Category-theory meta-layer: base categories, monoidal, NTs, Kan extensions, enrichment, profunctors, adjunctions |
| cert | Proof-carrying attestation: five method tiers, structured witness storage, proof composition DAG, portable bundle export, consumer re-verification |
| Nerode | DFA/automata engine on PostgreSQL: construction, minimization, product, session DFAs, sequence cache, certified handoff envelopes |
| Porter | Agent context handoff: pre-pack external data, certify session boundaries, hand verified context to a new model with zero tool calls |
Quick start
# 1. Start both PostgreSQL instances
docker compose up -d db-trunkit db-nerode
# 2. Apply all schemas (idempotent)
make apply
# 3. Trunkit: populate integers and run reflexive closure
trunkit generate --limit 10000
trunkit close --write
# 4. Porter: pre-pack a morning brief and open it as Model B
python scripts/morning_brief_demo.py
# Install
pip install trunkit # proof kernel
pip install nerode # automata + Porter layer
Environment variables:
CALX_DSN=postgresql://trunk:trunk@localhost:5434/trunkNERODE_DSN=postgresql://nerode:nerode@localhost:5435/nerode
Porter — model-to-model context handoff
Porter solves the cold-start problem for LLM agents. Each new model call starts with no memory of what the previous call proved, fetched, or decided. Porter pre-packs that context into a certified envelope before the session ends; the next model opens the envelope and has everything it needs with zero tool calls.
from nerode.precache import Precacher
from nerode.sources import WeatherSource, TickerSource, HNSource
today = "2026-05-19"
# Model A -- pack context before closing
with Precacher(f"brief-{today}") as pc:
pc.fetch(f"weather:london:{today}", WeatherSource(51.5, -0.1, label="London"))
pc.fetch(f"ticker:AAPL:{today}", TickerSource("AAPL"))
pc.fetch(f"news:hn:top5:{today}", HNSource(5))
# Model B -- arrive with full context, cert verified, zero tool calls
ctx = Precacher.open(pc.envelope, "model-b-001")
resolved = ctx["resolved"] # all three values, ready to use
Cybernetic monitoring
Porter includes DFA-based pattern detectors that fire over metric and control streams:
| DFA | Pattern | Meaning |
|---|---|---|
metric_rise_3 |
U{3,} |
3+ consecutive rises |
metric_oscillate |
(UD){3,} |
oscillation / gain too high |
dead_time_k |
A_{k,} |
action without response in k steps |
homeostasis_alarm_5 |
O{5,} |
5+ steps outside target band |
dead_time_5_x_metric_oscillate |
composite | oscillating AND unresponsive |
# Log a paired (metric, control) event and scan all relevant DFAs
conn.execute(
"SELECT nerode.log_cybernetic(%s, 'metric_x_control', %s, %s)",
(session_id, "UA", json.dumps({"src": "sensor"}))
)
# pg_notify('nerode_control_warn', ...) fires if any pattern matches
cert method tiers
| Method | Trust root | Use |
|---|---|---|
comp_sql |
In-DB probe | Computational facts about integers or categorical counts |
struct_kan |
Existing kan invariant | Naturality, triangle identities, faithfulness checks |
formal_external |
SHA256-pinned external artifact | Python/Lean/Agda proof scripts |
empirical_corpus |
Provenance only | Corpus document assertions |
witness_carry |
In-DB witness term | Structured proof terms stored alongside certificates; consumer-replayable |
CLI
Trunkit ships a dual-surface CLI. Consumer commands are read-only and safe for LLM use.
Prover commands require --write to record; they dry-run without it.
# Consumer (read-only)
trunkit verify <claim_id> # re-verify without inserting
trunkit standing [--method M] [--status S] # list claims by status
trunkit export <id> [<id> ...] # portable JSONB proof bundle to stdout
# Prover (dry-run without --write)
trunkit check <claim_id> [--write]
trunkit attest [--write]
trunkit close [--write]
trunkit witness <claim_id> --kind KIND --body JSON [--write]
# calx data
trunkit generate --limit N
trunkit validate [--limit N]
trunkit oeis-load / oeis-match / compose-match
Repository layout
src/
calx/ -- Trunkit Python package (calx + kan + curry + cert)
nerode/ -- Nerode/Porter Python package
sql/ -- 18 idempotent SQL schema files (00_bootstrap to 97_composite_dfa)
precache.py -- Precacher context manager (Porter API)
sources.py -- WeatherSource, TickerSource, HNSource, TickerHistorySource
adapters.py -- HttpSource, CallableSource, resolve(), with_retry()
db.py -- connection utilities + SCHEMA_FILES list
scripts/
morning_brief_demo.py -- end-to-end Porter demo
tests/
test_sources.py -- network tests (pytest -m network)
test_cybernetic.py -- cybernetic DFA tests
test_composite_dfa.py -- paired-alphabet composite DFA tests
test_dead_time_factory.py
test_*.py -- unit tests for all schema layers
proofs/
*.py -- Trunkit proof scripts
tools/
kan_in_kan.py -- Trunkit reflexive closure tool
Bundle size
| Component | Size |
|---|---|
| SQL schemas (calx + nerode) | ~300 KB |
| Python source | ~330 KB |
| Proof scripts | ~175 KB |
| Tests + config | ~130 KB |
| Total (no virtualenv) | ~1.1 MB |
Compare: Lean 4 toolchain ~2.9 GB; Mathlib compiled ~4-10 GB.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file trunkit-0.2.0.tar.gz.
File metadata
- Download URL: trunkit-0.2.0.tar.gz
- Upload date:
- Size: 382.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1af2ee99b5bad7dcca11731b51aa2a97460c4d1fdc9a06d54af56f825537e4c
|
|
| MD5 |
c37c486ac718778c1080ab7e86f0467d
|
|
| BLAKE2b-256 |
1ff85c3c7b61e5d9f1e70dadb8e3f11f251ee1320be9c90ba5db31f00d3f6748
|
Provenance
The following attestation bundles were made for trunkit-0.2.0.tar.gz:
Publisher:
python-package-conda.yml on Athena-Pro/Trunkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
trunkit-0.2.0.tar.gz -
Subject digest:
f1af2ee99b5bad7dcca11731b51aa2a97460c4d1fdc9a06d54af56f825537e4c - Sigstore transparency entry: 1573517015
- Sigstore integration time:
-
Permalink:
Athena-Pro/Trunkit@d2bd99f73be409fce0135e90055f086521ac4ee7 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Athena-Pro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-package-conda.yml@d2bd99f73be409fce0135e90055f086521ac4ee7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file trunkit-0.2.0-py3-none-any.whl.
File metadata
- Download URL: trunkit-0.2.0-py3-none-any.whl
- Upload date:
- Size: 218.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71697138d46bd9c19b5a90a2b34ab0099378df129bc43819a4857dc8727a2466
|
|
| MD5 |
8b60c5a251aba1ab15e53236572a82e6
|
|
| BLAKE2b-256 |
7589c92fe5ae2055d20daa9114a243ab61be8415c79154e7782a0cc5e0649269
|
Provenance
The following attestation bundles were made for trunkit-0.2.0-py3-none-any.whl:
Publisher:
python-package-conda.yml on Athena-Pro/Trunkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
trunkit-0.2.0-py3-none-any.whl -
Subject digest:
71697138d46bd9c19b5a90a2b34ab0099378df129bc43819a4857dc8727a2466 - Sigstore transparency entry: 1573517039
- Sigstore integration time:
-
Permalink:
Athena-Pro/Trunkit@d2bd99f73be409fce0135e90055f086521ac4ee7 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Athena-Pro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-package-conda.yml@d2bd99f73be409fce0135e90055f086521ac4ee7 -
Trigger Event:
push
-
Statement type: