Skip to main content

NLAI: evidence-gated claims, continuity anchors, and receipts for agent workflows

Project description

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 → supported
  • supported + conflict → contested
  • unsupported + conflict → contested
  • contested + 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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nlai-0.3.0.tar.gz (27.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nlai-0.3.0-py3-none-any.whl (19.7 kB view details)

Uploaded Python 3

File details

Details for the file nlai-0.3.0.tar.gz.

File metadata

  • Download URL: nlai-0.3.0.tar.gz
  • Upload date:
  • Size: 27.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for nlai-0.3.0.tar.gz
Algorithm Hash digest
SHA256 367f9ae59a52ab5a9aa691f5924dbebda5d99c2f281bd5bcfff026e95874bb54
MD5 a1e1c42d4398aee18967fc6991e12321
BLAKE2b-256 8cccfa0f8ca3e7bdc3ca417ec21cf08b490c1dda19325f41dd869f5141573e29

See more details on using hashes here.

File details

Details for the file nlai-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: nlai-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 19.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for nlai-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ac965c17acb19f4aba26a82a7424cc2215f5a00c5540e2cd5a463e844c017b26
MD5 b54471cacf93b8e7e45425e29a983450
BLAKE2b-256 764fbd2e252c29fe3404ed83be7f725bc8136b56959c81b8306c98c1813f9802

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page