Skip to content

unpingable/nlai

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

About

Evidence-gated claims, continuity anchors, and deterministic receipts for agent workflows. Language is a proposal, not an authority.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages