nlai
Evidence-gated claims, continuity anchors, and receipts for agent workflows.
Language is a proposal, not an authority. When an AI agent says "tests pass" or
"the code is thread-safe," those are claims — not facts. nlai provides the
irreducible mechanism for tracking what was claimed, checking it against
constraints, and producing content-addressed receipts that prove the decision.
10-second demo
from nlai import gate, Anchor
# Gate agent output — extract claims, produce receipt
result = gate("The tests definitely pass and the code is thread-safe.")
print(result.verdict) # "pass" (no anchors to violate)
print(result.claims) # [Claim("definitely", assertive), ...]
print(result.receipt.receipt_id) # "sha256:..."
# Add constraints
anchors = [
Anchor(id="no-thread-claims", description="Don't claim thread safety",
forbidden=("thread-safe", "thread safe")),
]
result = gate("The code is thread-safe.", anchors=anchors)
print(result.verdict) # "block"
print(result.violations) # [Violation("no-thread-claims", ...)]
Evidence and contradictions
Claims start as unsupported. Attach evidence to promote them.
Contradictions between claims are detected and tracked.
from nlai import gate, Evidence, attach_evidence
# 1. Gate extracts unsupported claims (sentence-level text)
result = gate("The system definitely passes all tests.")
claim = result.claims[0]
print(claim.text) # "The system definitely passes all tests"
print(claim.status) # "unsupported"
# 2. Attach evidence — promotes to "supported"
evidence = Evidence(kind="test_result", reference="pytest exit 0")
claim = attach_evidence(claim, evidence)
print(claim.status) # "supported"
# 3. Later, gate new text against the prior supported claim
result2 = gate(
"The system definitely fails all tests.",
prior_claims=[claim],
)
contested = result2.contested_claims
print(contested[0].status) # "contested"
print(contested[0].conflicts_with) # ("The system definitely passes all tests",)
# verdict is still "pass" — contradictions don't block, they contest
print(result2.verdict) # "pass"
Claim status semantics
| Status | Meaning |
|---|---|
unsupported |
No evidence attached. Default state for extracted claims. |
supported |
Evidence record(s) attached. Not independently validated — the kernel records, it doesn't verify. |
contested |
Conflicting claims detected. Sticky — only humans resolve. Evidence doesn't un-contest. |
Status transitions:
unsupported+ evidence →supportedsupported+ conflict →contestedunsupported+ conflict →contestedcontested+ evidence →contested(sticky)
What this is
The kernel that Agent Governor builds on. Same law, smaller jurisdiction.
- Claims require evidence
- Decisions produce receipts
- Anchors enforce continuity
- Contradictions are tracked, not resolved
- Violations resolve deterministically
Why not just a regex?
A regex hook can block dangerous strings. But the moment someone asks:
- What exactly was checked? The receipt records the subject hash.
- What policy was violated? The violation names the anchor, with evidence.
- Can I verify the result later?
verify_receipt()works offline, anytime. - Can I trust the checker? The gate is deterministic — same inputs, same receipt_id.
A regex detects patterns. nlai attests decisions. That's the difference.
# Regex: "was it blocked?"
blocked = bool(re.search(r"rm -rf", agent_output))
# nlai: "what happened, provably?"
result = gate(agent_output, anchors=my_policy)
# result.verdict, result.receipt, result.violations, result.claims
# — all content-addressed, all verifiable, all auditable
What this is NOT
- No daemon, no socket, no RPC
- No adaptive policy, no orchestration
- No external dependencies (stdlib only)
- No "lite mode" weaker enforcement
Install
pip install nlai
Requires Python 3.10+. Zero dependencies.
API
# The gate function
gate(text, *, anchors=None, prior_claims=None) -> GateResult
# Data types
GateResult(verdict, receipt, claims, violations)
Receipt(receipt_id, schema_version, timestamp, gate, verdict, subject_hash, evidence_hash)
Anchor(id, description, required, forbidden, severity, constraint_class)
Claim(text, strength, status, span, evidence, conflicts_with) # text = surrounding sentence
Violation(anchor_id, severity, description, evidence)
Evidence(kind, reference, source)
# Evidence operations
attach_evidence(claim, evidence) -> Claim # Promote UNSUPPORTED → SUPPORTED
contest_claim(claim, conflicting_text) -> Claim # Mark as CONTESTED
find_contradictions(claims, prior_claims) -> list[Claim] # Opposing-pair detection
# Utilities
canonical_json(obj) -> bytes
content_hash(data: bytes) -> str
verify_receipt(receipt) -> bool
extract_claims(text) -> list[Claim]
assertiveness_score(text) -> float
Verdicts
| Verdict | Meaning |
|---|---|
pass |
No violations |
warn |
Violations found, but only at warn severity |
block |
Violations at correct or reject severity |
observe |
Informational only (used by infrastructure) |
Receipts
Every gate() call produces a content-addressed receipt:
receipt_id = H(schema_version + gate + subject_hash + evidence_hash)
Same inputs = same receipt_id. Timestamp is metadata, not identity.
Receipts can be verified offline with verify_receipt().
Relationship to Agent Governor
nlai (kernel)
^
agent_gov (runtime + policy + orchestration)
^
plugins / clerk / phosphor (distribution surfaces)
nlai is the foundation. Agent Governor adds regime detection, lane routing,
multi-agent coordination, and everything else needed for production governance.
License
Apache-2.0
Metadata
Release files for nlai 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| nlai-0.3.0.tar.gz | 27.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nlai-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.8 kB
Release files / nlai-0.3.0.tar.gz
| Download URL | nlai-0.3.0.tar.gz |
|---|---|
| Size | 27.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
367f9ae59a52ab5a9aa691f5924dbebda5d99c2f281bd5bcfff026e95874bb54
|
|
BLAKE2b-256 checksum How to use checksums |
8cccfa0f8ca3e7bdc3ca417ec21cf08b490c1dda19325f41dd869f5141573e29
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / nlai-0.3.0-py3-none-any.whl
| Download URL | nlai-0.3.0-py3-none-any.whl |
|---|---|
| Size | 19.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ac965c17acb19f4aba26a82a7424cc2215f5a00c5540e2cd5a463e844c017b26
|
|
BLAKE2b-256 checksum How to use checksums |
764fbd2e252c29fe3404ed83be7f725bc8136b56959c81b8306c98c1813f9802
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Security for nlai 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.