Deponent
·
· Apache-2.0 · check the mark yourself:
python3 -m deponent.badge verify --kernel deponent
A deny-by-default gate, macOS Seatbelt jail, and tamper-evident ledger for local agent tool calls. Standard-library only: zero third-party runtime dependencies.
Install: pip install deponent
import tempfile
from deponent import Cell
cell = Cell(tempfile.mkdtemp(), use_jail=False)
print(cell.act("write_file", {"path": "notes.txt", "content": "hello"}).output)
print(cell.act("run_cmd", {"cmd": "rm -rf ./blocked-example"}).output)
print(cell.act("exfiltrate", {"to": "evil.example"}).output)
Refuses: unknown tools, out-of-sandbox paths, destructive commands; in gate-only mode, interpreters and command chains unless you opt them in.
Why it exists: docs/WHY.md. Limits: docs/BOUNDARIES.md.
Quickstart
import tempfile
from deponent import Cell
cell = Cell(tempfile.mkdtemp(), use_jail=False) # use_jail=True on macOS adds the Seatbelt jail
print(cell.act("write_file", {"path": "notes.txt", "content": "hello"}).output) # ALLOW
print(cell.act("read_file", {"path": "notes.txt"}).output) # ALLOW
print(cell.act("run_cmd", {"cmd": "rm -rf ./blocked-example"}).output) # BLOCK (destructive)
print(cell.act("exfiltrate", {"to": "evil.example"}).output) # BLOCK (deny-by-default)
ok, msg = cell.verify()
print(f"chain intact: {ok} — {msg}")
That is examples/minimal.py. Run it (python3 examples/minimal.py). No model. No network.
Containment
Containment boundary: the live-verified jail is macOS Seatbelt (OS confinement) only. Cell() defaults to use_jail=True; when the jail is unavailable it fail-closes (records ALLOW, refuses execution) rather than silently switching to gate-only. On other hosts you supply confinement or opt into gate-only (use_jail=False): the deny-by-default gate and the ledger still run, but there is no OS confinement; argument paths are containment-checked whether spaced, glued to a flag (-o/tmp/x, --output=/tmp/x), dash-prefixed after -- (cat -- -secret), or reached through a symlink that already exists inside the sandbox. In gate-only mode only a small safe set of heads runs by default; other heads need allow_unjailed_heads on both the Cell and its Gate (the Cell heads kwarg alone does not opt in a foreign gate). Interpreters need both knobs: membership in allow_unjailed_heads and allow_unjailed_interpreters=True on both the Cell and its Gate (the Cell interpreter kwarg alone does not opt in a foreign gate, and an interpreter listed only in allow_unjailed_heads is still refused), and gate-only commands run without a shell, one command at a time. Playground ClassifyCell is gate-only, so a chain such as echo a && echo b is chain-unjailed BLOCK (jail-mode would ALLOW). Gate-only runs are policy evidence, not sandbox evidence. The ledger is tamper-evident for edits, deletions and reordering; truncation and re-chaining are caught only against a head published outside the ledger (Ledger.head() / receipt ledger_head).
The live-verified jail is macOS Seatbelt (OS confinement). jail.py also contains a DRAFT Docker backend; do not read DRAFT as proven. On other hosts you supply confinement or opt into gate-only (use_jail=False). In gate-only mode only a small safe set of heads runs by default; other heads need allow_unjailed_heads on both the Cell and its Gate (the Cell heads kwarg alone does not opt in a foreign gate). Interpreters need both knobs: membership in allow_unjailed_heads and allow_unjailed_interpreters=True on both the Cell and its Gate (the Cell interpreter kwarg alone does not opt in a foreign gate, and an interpreter listed only in allow_unjailed_heads is still refused), and gate-only commands run without a shell, one command at a time. Playground ClassifyCell is gate-only, so a chain such as echo a && echo b is chain-unjailed BLOCK (jail-mode would ALLOW). The gate and ledger are platform-independent.
deny-by-default gate -> Seatbelt jail -> tamper-evident ledger -> verifiable evidence record
- The Gate checks which programs may run, which paths may be touched, and whether a command chains or substitutes its way out of policy. Deny-by-default and fail-closed. Optional
ReachOracle: a write can be checked on its reverse-dependency closure. - The Jail confines the code inside an allowed command. On macOS the native primitive is
sandbox-exec(Seatbelt). - The Ledger is an append-only sha256 hash chain. Mutating or reordering any past entry breaks the re-link.
- The evidence record (
deponent.receipts) recomputes the chain from genesis and recomputes its own content hash.persist()runs that check as a write-time round-trip and raises on failure.
Subclass Cell and override _execute to wrap your own tool surface — gate + jail + ledger wrapping is inherited.
What it does NOT do
Full text: docs/BOUNDARIES.md.
- Reference kernel, not a certified security product.
- Live-verified jail is macOS Seatbelt only. Docker in
jail.pyis DRAFT. - Tamper-evident, not tamper-proof. Keyless sha256 chain; optional verification-only ed25519 overlay (
operator_attest.py, extradeponent[attest]) checks a maintainer's out-of-band signature over a run and signs nothing the agent does. - Default policy is a coding-agent sandbox. Override with
deny=/allow_heads=.
Proven
The suite exercises the gate, live macOS Seatbelt confinement, ledger integrity, evidence records, reconciliation, claims, build profiles, the public playground, and the conformance harness. Platform- or optional-capability checks skip explicitly when their real backend is unavailable; they are never replaced with a passing mock.
Run python3 -m pytest -q to get the current count and host-specific skip set.
make self-gate-live drives a real local build through the same gate, jail, and
ledger path and emits evidence records for inspection.
The GAK-conformant mark (self-evaluated). The mark is self-evaluated against GAK v0.x: deponent.badge certify scores the kernel against a standard its own author wrote, and it stays self-evaluated until a second, independent implementer passes the same harness. python3 -m deponent.badge certify --kernel deponent emits a self-contained badge (the SVG above), a markdown snippet, and a JSON record carrying a sha256 clauses_digest over the per-clause results. Re-derive it yourself, fail-closed:
python3 -m deponent.badge verify --kernel deponent # exit 0 only when the mark is earned
Any kernel that implements the small adapter and passes the clause set earns the same mark; a kernel that fails gets a red "not conformant" badge and a non-zero exit. The badge is generated locally — no shields.io, no network.
Seatbelt escape-proofs — two kinds, kept separate so the claim is exactly as strong as the evidence. (1) Committed live canaries (canaries/CANARIES.md, J1–J8): network exfil, raw-socket egress, writes outside the sandbox, child-process escape, memory-bomb, and wall-clock runaway — each a real test run against the live macOS sandbox, 0 through; if a canary stops holding, the suite goes red. (2) Manual development review — during development Seatbelt bypasses (osascript 'do shell script', launchctl submit, loopback /dev/tcp, DNS, symlink/hardlink/rename writes-out) were hand-run and blocked; these shaped the gate denylist and the Seatbelt profile but are not committed tests — take them as reported, not reproducible from the repo.
Recompute-not-trust evidence records: the verifier does not read a stored boolean. It re-links the chain from genesis and recomputes the record's content hash over its canonical body. persist() runs that verifier on write and raises on failure. Self-reported health is never the evidence.
Example agent team
examples/governed_team.py shows an Architect, a gated Builder, and an advisory
Reviewer sharing one ledger. The example is model-agnostic through
examples/backends.py; use an Ollama or MLX backend, or add your own. Closure is
an out-of-band test run plus an intact ledger—not the Builder saying “done.”
# Ollama (any tool-capable coder)
python3 examples/governed_team.py --backend ollama --model qwen3-coder:30b \
--goal "Implement reverse_words(s): reverse word order, collapse runs of spaces."
# Local MLX North Mini Code (Apple Silicon)
DEPONENT_MLX_MODEL=mlx-community/North-Mini-Code-1.0-4bit \
python3 examples/governed_team.py --backend mlx --goal "..."
Install + run the tests
git clone <repo> deponent && cd deponent
python3 -m pip install -e . # or just run from the repo — the core needs no install
make test # current suite; real-backend skips are host-dependent
make demo # the minimal demo, no model needed
The kernel has zero third-party dependencies. Only the example team needs a model runtime; the kernel does not.
Run it in Docker (any platform)
docker build -t deponent .
docker run --rm deponent # scores the kernel against its own GAK standard -> CONFORMANT
docker run --rm deponent make test # run the suite in-container
The gate, ledger, and evidence records are platform-independent. Live-verified OS confinement is macOS Seatbelt. The Docker backend in jail.py is DRAFT; tests/test_jail_backends.py gates those tests. Do not read DRAFT as proven.
Stewardship
Deponent is an open-source project from Centennial Defense Systems, maintained by Christopher “CJ” Chanhnourack. The repository is the complete public reference kernel; its claims are limited to behavior you can reproduce from the source.
Support
Report vulnerabilities through SECURITY.md. General support and contributions are best-effort; no response-time SLA is offered.
License
Apache-2.0 — including the patent grant.
The license applies to the public source and includes the Apache 2.0 patent grant.
Metadata
Release files for deponent 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| deponent-0.1.2.tar.gz | 174.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| deponent-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 248.5 kB
Release files / deponent-0.1.2.tar.gz
| Download URL | deponent-0.1.2.tar.gz |
|---|---|
| Size | 174.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
03fa9303a15c18ba1c51f4329e5009a1ccd38a7d703a27ad3a47df6a0348a5f4
|
|
BLAKE2b-256 checksum How to use checksums |
21c867257367a4c58f98f0d0f33830fbc65d6dabe3252ede5045ac334e8b3fe6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / deponent-0.1.2-py3-none-any.whl
| Download URL | deponent-0.1.2-py3-none-any.whl |
|---|---|
| Size | 73.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
906817b9afd93907223a7788df31062feb32fd55e68637efed61b3afd58c5587
|
|
BLAKE2b-256 checksum How to use checksums |
69aa9c1fdf0d2e132c87e6a3937c74af60e3a1791ed5f22166786869230da148
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|