Skip to main content

evidence-gap-router

Route work by missing evidence, not by agent count.

A small Python SDK that chooses the next acquisition or verification from missing evidence and unfinished checks in a finite, host-declared action set.

Python 3.12+ · Apache-2.0 · 日本語 · Documentation

When to use it

Use it when permitted work depends on the material already obtained, verification results, prerequisites, costs or changed rules. It retains evidence, issued checks, failures, expenses and unresolved requirements across explicit continuation.

A fixed pipeline is usually sufficient when every input and step is already known. The SDK does not supply agents, models, a network gateway or a scheduler. Tracking verification history does not guarantee semantic truth. Separate calls to the same model do not establish statistically independent judgments.

Install and check

python -m pip install evidence-gap-router==0.3.0
egr --version
egr demo --json

These commands need no model or network after installation. The demo uses artificial data. Getting started creates actual UTF-8 CSV/JSON files, including quoted paths with spaces and Japanese characters, then checks them with egr check-data.

Connect a callback

This complete ordinary-wheel example parses the supplied content, selects a check, records its actual result and shows the remaining blocking issues:

from hashlib import sha256
from evidence_gap_router import (
    ActionCandidate,
    Budget,
    CallbackView,
    CheckerPermission,
    CompletionContract,
    DependencyRequirement,
    declare_completion,
    Evidence,
    HandlerRegistration,
    Obligation,
    Policy,
    Resources,
    State,
    plan,
    run,
)

content = "4"
evidence = Evidence(
    id="answer",
    obligation_id="sum",
    scope="example",
    digest=sha256(content.encode()).hexdigest(),
    content=content,
    producer="calculator",
    source="local-calculation",
    provenance_group="calculator",
)
state = State(
    obligations=(
        Obligation(
            id="sum",
            description="Check arithmetic",
            scope="example",
            acceptance="Parsed answer equals 2 + 2",
        ),
    ),
    evidence=(evidence,),
)
obligation = state.obligations[0]
state = declare_completion(
    state,
    CompletionContract(
        id="fixed-arithmetic-1",
        obligation_id=obligation.id,
        scope=obligation.scope,
        obligation_fingerprint=obligation.contract_fingerprint,
        target=DependencyRequirement(
            evidence_id="answer", obligation_id=obligation.id, scope=obligation.scope
        ),
        declared_scope="not_applicable",
        scope_reason="Fixed supplied arithmetic; no retrieval.",
    ),
)
action = ActionCandidate(
    id="check-answer",
    obligation_id="sum",
    scope="example",
    kind="verify",
    handler_id="check",
    target_evidence_id="answer",
    target_digest=evidence.digest,
    checker_id="arithmetic-check",
    resources=Resources(actions=1, verifications=1, tokens=0),
)
policy = Policy(
    trusted_verifiers=("arithmetic-check",),
    handlers=(
        HandlerRegistration(
            handler_id="check",
            roles=("verify",),
            checkers=(
                CheckerPermission(
                    checker_id="arithmetic-check",
                    completion_kinds=("content",),
                    completion_scopes=("example",),
                ),
            ),
        ),
    ),
)


def check(view: CallbackView):
    passed = int(view.inputs[0].content or "") == 2 + 2
    return view.result(
        actual_resources=Resources(actions=1, verifications=1, tokens=0),
        checks=(view.check(status="PASS" if passed else "FAIL", reason="Compared with 2 + 2"),),
    )


budget = Budget(limits=Resources(actions=1, verifications=1, tokens=0))
next_step = plan(state, (action,), budget, policy)
assert next_step.action is not None
assert any(r.code == "completion_check_missing" for r in next_step.completion[0].residuals)
print(next_step.action.id)  # check-answer

report = run(
    state,
    (action,),
    budget,
    policy,
    {"check": check},
    max_steps=8,
)
print(report.state.checks[-1].status)  # PASS
print(report.decision.stop_reason)  # satisfied
print([r.code for r in report.decision.residuals if r.blocking])  # []

Before the callback, completion_check_missing names the unfinished condition. The host registers checker permission; view.check binds the issued target, contract and inputs. An ID supplied by an output grants no authority. step invokes at most one callback; run has a finite step limit. Runner stops and unresolved domain requirements are separate. Pending attempts and unknown budgeted consumption block automatic continuation.

See Concepts, API and snapshot/migration for acquisition, invalidation, rechecking, selectors and retained costs. Limited callback views are application disclosures, not a Python sandbox. The host owns input trust, effects, costs and single-writer use.

Completion and local-file examples

An observation PASS, current applicability, and finite goal completion are separate. The host explicitly declares required materials, scope/catalogue revision and permitted check kinds. Empty/unspecified scope remains incomplete; fixed arithmetic uses a reasoned not_applicable. Checker permissions default to advisory. Names, JSON syntax and repeated aliases do not establish authority or independence. A new permission cannot upgrade an old advisory receipt.

python -m evidence_gap_router.completion_example partial
python -m evidence_gap_router.completion_example pooled
python -m evidence_gap_router.completion_example continuation

These create/read actual UTF-8 integer files, record issued receipts and preserve costs. Partial M-only PASS leaves N missing; acquiring N does not upgrade that old basis. A full-input qualified check completes the finite contract. Pooling can legitimately use one fixed callback. Continuation invalidates used N, saves and reloads, reads replacement N and rechecks while retaining the original PASS and reusing M. A user directory may contain spaces and Unicode; existing files are not overwritten. See completion contracts.

Schema 3 requires explicit schema-1/2 migration. Original history and bases remain; imported states lack invented completion authority. Decision.completion reports exact missing conditions and external completeness as unknown. Observation coverage is diagnostic and never substitutes for it.

Historical results and current limits

The v0.2.4 frozen local experiment found A below B: answerable completion was Qwen A/B/C 0/8/12 of 12, Gemma 3/8/10 of 12. Qwen A false acceptance was 15/16. These negative results motivate contracts and role separation; they do not show that v0.3.0 fixes empirical performance. Original report.

v0.3.0: new LLM requests 0, new efficacy/performance experiments 0; empirical utility unmeasured. This is a contract/control implementation, with no learned weights or routing-weight tuning. Historical experiments require their original tag, wheel and harness; the current experiment CLI rejects SDK mismatch before network or server operations. Archived Ollama guide.

Metadata

Release files for evidence-gap-router 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for evidence-gap-router 0.3.0
File Size Uploaded
evidence_gap_router-0.3.0.tar.gz 884.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for evidence-gap-router 0.3.0
File Interpreter ABI Platform
evidence_gap_router-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 957.5 kB

Release files / evidence_gap_router-0.3.0.tar.gz

Download URL evidence_gap_router-0.3.0.tar.gz
Size 884.3 kB
Tags Source
SHA-256 checksum
How to use checksums
b5ac65d04aa6fc683aeb39cc50010dba1bed572e1c6c6555e60c9cec78de8d46
BLAKE2b-256 checksum
How to use checksums
99f04f202704dec40c8ebb9f0fbfe09a38d44208e9cd687d5fb2d77dc925b95a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / evidence_gap_router-0.3.0-py3-none-any.whl

Download URL evidence_gap_router-0.3.0-py3-none-any.whl
Size 73.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
442335a442c0d2afd814e4708e1ab154c2d53b12a3629118c310192bfd913d99
BLAKE2b-256 checksum
How to use checksums
f002d30d87f6aa9184867d84a94e6f419ea56caa1dab74f8bd5afcf803af093a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page