New:Microsoft Teams Notifications Are Now Available in Socket.Learn more →
Get Started

groundlens

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

groundlens

GroundLens: the verification and evidence layer for AI.

Source
pipPyPI
Version
5.3.0
Weekly downloads
190
726.09%
Maintainers
1
Weekly downloads
 
Created

GroundLens

Execution verification runtime for AI systems and agents


License

PyPI Docs Rust Python OpenSSF Best Practices OpenSSF Scorecard REUSE status SLSA


What it is · Quick start · Architecture · How it works · Engine · Runtime · Records · MCP server · Determinism · Examples · Docs · FAQ · Roadmap


What GroundLens is

GroundLens is an execution verification runtime for AI systems and agents. It turns observable AI execution into deterministic, policy-governed evidence that can be independently verified.

GroundLens provides a vendor-neutral runtime and evidence protocol for observing AI executions, evaluating claims, tool calls, actions and outcomes against composable verifiers and policies, and producing signed, reproducible evidence records.

The unit is the execution: an ordered sequence of steps an AI system or agent takes, from a model call and a retrieval to a tool call, an action with side effects and a human approval. GroundLens records each step, checks it, decides, and seals the run into a signed record anyone can verify offline. Verifying a single answer is the smallest case, a run with one claim.

  • an answer, and the claims inside it → PASS, REVIEW or FAIL
  • a tool call or an action → ALLOW, REVIEW or DENY

Where a guardrail blocks or scores an output in the moment and leaves nothing behind, GroundLens leaves signed, hash-chained evidence a third party can check without trusting you. It runs locally, needs no access to your weights, prompts or architecture, and is built for teams shipping AI answers and agents into regulated or high-stakes workflows who need proof, not a score.


Quick start

pip install groundlens

The package installs the engine, the groundlens and glv commands, and needs no other dependency. Numbers and rules are checked out of the box; the model-based verifiers need one optional download, shown at the end.

Verify an answer

Check a model's answer against the sources it was given, under a policy, and get a record you can keep.

from groundlens import verify

question = "What is the invoice total?"
source   = "The total amount due is 10,000 dollars, payable within 30 days of receipt."
answer   = "The invoice total is 1,000 dollars, due in 30 days."

record = verify(answer, [("invoice.pdf#p1", source)], question=question)

print(record.decision)     # 'FAIL'
print(record.report())
FAIL  policy=groundlens_default_v1  record=rec_350455f44e60_4dbfea8eb79c
  c2   groundlens.numeric   contradicted   0.00   nearest in invoice.pdf#p1: '10,000 dollars'

Ten thousand is not one thousand. A similarity score would rate the right answer and the wrong one alike; the numeric verifier compares the quantities exactly and points at the source number the answer lost to. The 30 days are supported in both, so they do not appear in the report: it shows only what a reviewer needs to look at.

Every verification is sealed:

record.content_hash            # 'sha256:…' — same input, policy and bundle → same hash, any machine
record.verify()                # recompute every hash and the Ed25519 signature, offline; raises if altered
record.regulatory_mapping      # the articles this decision concerns, under the policy

Verify a run

Give GroundLens an MCP execution trace and an execution policy. It records the run as a hash-linked event log, gates it, and seals a signed run record.

from groundlens import verify_run

record = verify_run(
    "examples/run/trace.jsonl",            # an MCP session, as JSON-RPC lines
    "examples/run/execution-policy.yaml",  # the rules for what the agent may do
    run_id="run_demo",
    system="invoice-agent",
)

print(record.gate)         # 'DENY'  — the run called shell.exec, which the policy forbids
print(record.breaches)     # ()      — nothing *ran* against the policy; the call was denied, not executed
print(record.record_hash)  # 'sha256:…'  — signed and chained, like an answer record

gate is the verdict over the whole run: ALLOW, REVIEW or DENY, rolled up from the strictest step. breaches is different and narrower: it lists actions that actually executed against the policy, an action the policy forbade or one that needed a human approval that never came. Here the forbidden tool was stopped, so the run is DENY with no breach. The same thing on the command line, with the real output:

glv run verify --trace examples/run/trace.jsonl --policy examples/run/execution-policy.yaml \
  --run-id run_demo --system invoice-agent --log runs.jsonl
# exit code 1  (0 ALLOW · 3 REVIEW · 1 DENY)

glv run check runs.jsonl
# ok  1 run records, chain intact, all signatures verify

A runnable version of both is under examples/run.

Enable the model-based verifiers

The numeric and rules verifiers need nothing. The lexical, semantic and NLI verifiers need the base bundle: the multilingual encoder and a multilingual entailment model, their tokenizers, and a manifest of hashes.

groundlens bundle pull base      # downloaded once; the only command that uses the network

With the bundle installed, the lexical verifier runs (one row per content word, each anchored to the source word it was scored against), and so do the semantic verifier (sentence similarity to the nearest source) and groundlens.nli (entailment, neutral or contradiction for each statement). The download is verified against a hash pinned in the engine.

from groundlens import verify

record = verify(
    "El importe de la factura es de 10.000 euros, pagaderos en 30 días.",
    [("factura", "El importe total asciende a 10.000 euros, pagaderos en un plazo de 30 días.")],
    locale="es",
)

for e in record.evidence:
    if e.verifier_id == "groundlens.lexical":
        print(e.result, round(e.score, 2), e.source_text)
# for example — scores are a 0–1 contextual support from the frozen encoder
supported  0.93  importe
supported  0.90  pagaderos
supported  0.88  factura

The score is a contextual similarity, so the same word used differently scores lower, and the weakest anchor is what a reviewer reads first. In an isolated environment, copy the bundle directory by hand and point GROUNDLENS_BUNDLE_DIR at it.

The command line

Everything except the model-based verifiers works with the base install alone.

groundlens verify --answer answer.txt --question question.txt \
  --source "invoice.pdf#p1=invoice.txt" --policy eu_ai_act_high_risk_v1 --log records.jsonl
groundlens record verify records.jsonl        # every hash, every link, every signature
groundlens report records.jsonl --out report  # report.md, report.json, README-auditor.md
groundlens policy lint policies/eu_ai_act_high_risk_v1.yaml
groundlens bundle status                      # is the base bundle installed, where, which hash

Exit codes: 0 PASS, 1 FAIL, 2 error, 3 REVIEW. The Rust binary glv exposes the same commands and adds execution verification: glv run verify seals an agent run (exit 0 / 3 / 1 on ALLOW / REVIEW / DENY) and glv run check verifies a log of run records offline.

Full documentation, including the API reference and concept guides, is at groundlens.readthedocs.io.


Architecture

Verifying a single answer is the smallest case, a run with one claim, so one contract covers both ends of the range:

  • an answer, and the claims inside it, gets PASS, REVIEW or FAIL from verifiers and a policy;
  • a tool call or an action gets ALLOW, REVIEW or DENY from an execution policy.

Either way the run is sealed into a signed, chained record. What the record keeps of the world is hashes, not content, so it is safe to hold in a regulated place while staying independently verifiable.

GroundLens sits beside your AI system, not inside it. It observes what the system produces and does, and never sees your weights, your prompts or your internal architecture, so independent verification is possible even in a bank or a sensitive deployment.

It reads a run from what an agent already emits. An agent driving its tools speaks the Model Context Protocol (MCP); GroundLens ingests those JSON-RPC messages and turns them into a run, recording hashes of the arguments and results, never the content itself. Recording a run needs no change to how the agent is built.

The engine and runtime are a Rust workspace, wrapped for Python, with no runtime dependencies; glv is the same code as a binary. No engine or runtime crate depends on an HTTP or TLS library, and a CI job fails the build if one ever appears. The only network operation in the project is one explicit command, bundle pull, which fetches the optional model bundle. Verification never reaches the network.

For the full design, the crate-by-crate layout, the core contracts (verifier, evidence, claim, policy, record, run) and the data flow, see ARCHITECTURE.md.


How it works

How a verification works

A verifier produces evidence, not truth: it reports what it measured and how sure it is, and none of them decides. A policy interprets the evidence and reaches the decision. The whole chain becomes a record: the input hashes, the verifiers and model hashes that ran, the evidence, the policy and its hash, the decision, the regulatory mapping, and the hash of the previous record, sealed with an Ed25519 signature. A log of records is an audit trail you can hand over as a file.


Engine

The engine verifies an answer and the claims inside it. A verifier produces evidence; a policy turns it into PASS, REVIEW or FAIL. What an agent did, its tool calls and actions, is decided by the execution policy in the Runtime.

verifierwhat it doesexample
groundlens.numericnumbers, currencies, percentages and physical units, compared exactly in base unitsanswer 1,000 vs source 10,000 → contradicted; 1.2 km = 1200 m; 212 °F = 100 °C; $37.35 billion = a cell 37,350 under "in millions"
groundlens.rulesyour own symbolic rules, run as a verifierrule "an APR must be a percentage" → an APR written as a bare number is contradicted
groundlens.lexicalwhether each word of the answer is anchored in the sources, by contextual token similarity, reported as the weakest anchorword pagaderos anchored to the source and scored 0.90; a word with no support scores low and surfaces first
groundlens.nliwhether a source entails, contradicts or is neutral to each statement in the answerstatement "the fee is 0.75%" against a source saying 0.50% → contradiction at high confidence
semantic.cosinehow close each statement in the answer is, in the encoder's meaning space, to the nearest source, as cosine similaritystatement paraphrasing a source scores near 1.0; one on an unrelated topic scores low and surfaces for review

groundlens.numeric and groundlens.rules are exact (bit-identical on any machine) and need no download. groundlens.lexical, groundlens.nli and semantic.cosine are reproducible (a pinned model, scores within a declared tolerance across machines) and run from the base bundle: lexical and semantic on its encoder, nli on its entailment model. groundlens bundle pull base installs all three. Similarity is not entailment, so semantic.cosine reports support but never a contradiction. Geometric (SGI, DGI) and LLM-judge verifiers are planned; every one plugs into the same contract.

Locales matter for numbers: 1.234 is one thousand in Spanish and one and a bit in English. GroundLens reads en, es, ca, de, fr, it, pt, nl and Swiss formats, knows short and long scale words, and keeps every legitimate reading of an ambiguous numeral instead of guessing. The base bundle's encoder covers about a hundred languages.

A policy is a short YAML file you control. Two policies over the same evidence can reach different decisions, and both are correct: that is where your risk appetite lives, not in the engine. The bundled eu_ai_act_high_risk_v1 maps outcomes to Art. 15(1) (accuracy and robustness), Art. 14(4)(a) (human oversight) and Art. 12(1) (record keeping) of Regulation (EU) 2024/1689; every policy has a version and a hash, and the hash goes into every record it decides. Scores from statistical verifiers drift slightly between machines, so each threshold carries a guard band, and a score inside it is REVIEW everywhere.

record = verify(answer, sources, policy="eu_ai_act_high_risk_v1")
record.decision              # 'FAIL'
record.regulatory_mapping    # [{'article': 'Art. 15(1)', ...}, {'article': 'Art. 12(1)', ...}]

Runtime

The runtime verifies an execution. It records each step of a run as an event in a hash-linked log, a model call, a retrieval, a tool request and its result, an action, a human approval, and an execution policy decides what the agent may do.

An execution policy is a short, ordered list of rules. Each rule matches a tool call or an action and carries an effect: DENY stops the step, REVIEW holds it for a human, ALLOW lets it proceed. The first rule that matches decides; when none does, the default applies, so a conservative deployment denies anything it did not explicitly allow. The gate is pure rule matching, with the same exact guarantee as the numeric verifier.

id: eu_high_risk_v1
rules:
  - id: no-shell          # a shell tool is never allowed, from any server
    match: tool
    name: shell.exec
    effect: DENY
  - id: high-risk         # any action at or above high risk needs a human
    match: risk_at_least
    risk: high
    effect: REVIEW
default: ALLOW

After a run, GroundLens audits the whole log against the policy, rolls it up to a single verdict, and flags any action that ran against it: one the policy forbade, or one that needed a human approval that never came. The verdict and the breaches go into the signed record, so an auditor can replay a run and see whether the policy was honoured.


Evidence records

Whether GroundLens checked one answer or a whole run, the result is the same kind of artefact: a signed record, chained to the one before it, that anyone can verify offline.

record.content_hash     # same input, policy and bundle → same hash, on any machine
record.verify()         # recompute every hash and the Ed25519 signature, offline
Record.verify_chain(Record.read_log("records.jsonl"))

Change one byte anywhere in a record and verification fails. Append records to a JSON Lines log and each one carries the hash of the previous one. groundlens report turns a log into a human-readable report with a one-page guide for auditors.


MCP server

The same verification is available as an MCP server, so an agent (or any Model Context Protocol client, including Claude) can call GroundLens as a tool: check an answer, gate an execution, or verify a log of records. It is a thin layer over the engine and runs over stdio.

It is an optional extra, so the base package keeps its zero dependencies:

pip install "groundlens[mcp]"
groundlens-mcp                     # runs the server over stdio

Three tools:

toolwhat it does
verify_answerverify an answer against its sources under a policy; returns the decision, the evidence and the signed record
verify_rungate an MCP execution trace under an execution policy; returns ALLOW / REVIEW / DENY, any breaches and the run record
verify_recordsverify a log of records offline: every hash, every link, every signature

Point an MCP client at the groundlens-mcp command. See the docs for a client configuration example.


Determinism

GroundLens is deterministic where it can be, and reproducible where it cannot.

exact verifiers and the execution gate use no floating point: the same input gives the same result, bit for bit, on any machine. reproducible verifiers run a pinned model in f32 on a pure-Rust inference engine, and their scores stay within a declared tolerance across machines. Anything non_deterministic, such as an LLM judge, is recorded with its model, prompt hash and settings, and decides only if the policy allows it.

This is tested, not asserted: CI runs the invoice example, with and without the model bundle, on Linux, macOS and Windows under a Turkish locale and a Pacific timezone, and compares the record hash with a committed value.


Examples

Two notebooks under examples/notebooks run in Google Colab:

  • Verify an AI answer against its sources: one example in English, German, French, Spanish and Italian, from pip install to a signed record, with a wrong number, a paraphrase and a policy change. Open In Colab

  • Evidence records for auditors: a log of verifications, chain verification, tamper detection, the EU AI Act mapping and the report an auditor receives. Open In Colab

And a shell example of a whole agent run under examples/run: a trace, an execution policy and a signed run record.


Contributions are welcome; see CONTRIBUTING.md and SECURITY.md.


groundlens.dev · Javier Marín, 2026 (javier@groundlens.dev)

Keywords

verification

FAQs

Related posts