The Causal Seal is an open format — implement it in any language. The fastest way to start is the zero-dependency Python reference implementation.
pip install causal-seal
One module, standard library only, Python 3.10+. View on PyPI.
Attach a seal to any generated output. Put in the causal state only what genuinely governed the decision — the causality criterion: had it been different, the output could have been different.
# emit.py
from causal_seal import emit_seal
seal = emit_seal(
emitter="my-app/1.0",
causal_state={
"identity.expert": "legal-assistant",
"engine.model": "gpt-4o",
"shaping.guard": "nominal",
"context.memory_state": "awake",
},
output_text="The statute of limitations is six years.",
dictionary="https://my-app.example/causal-dictionary.json",
)
print(seal["fingerprint"])
# verify.py from causal_seal import verify_seal ok, reason = verify_seal(seal, "The statute of limitations is six years.") print(ok, reason) # True seal verified (Level 1 + output binding)
causal-seal demo # emit + self-verify a sample seal causal-seal verify seal.json --output-file out.txt causal-seal selftest # check against the test vectors
Don't want to touch your app at all? Put the Causal Seal Gateway in front of your model — a drop-in, OpenAI-compatible proxy. Every response comes back sealed (streaming included), with no code change:
docker run -p 8080:8080 -e CAUSAL_UPSTREAM=https://api.openai.com causal-seal-gateway # then point your app at it: OPENAI_BASE_URL=http://localhost:8080
Non-streaming responses carry the seal in an X-Causal-Seal header; streaming responses get a final event: causal-seal just before [DONE]. A proxy seals what it observes from the outside (a thin seal); a rich seal needs a governance layer upstream.
Auditors and reviewers can check any seal with zero setup — the browser verifier runs entirely client-side and sends nothing anywhere.
Nothing here is Python-specific. The format is: canonicalize the seal with RFC 8785 (JCS), hash with SHA-256. To implement an emitter or verifier in your stack, validate it against the schema and the computed test vectors:
Questions, issues, or a domain profile to propose? Open an issue on GitHub. Contributions welcome — see the neutrality charter for how the standard stays a common good.