APERTURE
Build on the lens · API · SDK · MCP

One port.
Every answer, marked.

Give any agent an epistemic layer by changing one line. The model answers what it knows — and tells you when it’s reaching past it.

the 1-key port
# point any OpenAI client at Aperture — nothing else changes
base_url = "https://honesty.tools/v1"
api_key  = "sk-apt-…"        # free key at honesty.tools/verify · free tier, upgrade anytime
model    = "aperture-router"   # grounded → local · off-map → escalate
three ways in
The API · the proxy

Photon Base as a smart honesty router.

A read-only membrane in front of the served model. It answers what it knows; the moment a question reads off-distribution it escalates instead of confabulating — to a frontier model, or to the live web. The off-map read is a cheap pre-filter that decides the route — not the fabrication catch. Honesty-tier, not best-on-accuracy-or-cost: the frontiers have caught up. What we add is the receipt — every answer ships one, and the model abstains rather than bluff.

your agent Aperture · off-map read tier 1 · local Photon Base · grounded tier 2 · neocortex · off the map tier 3 · the internet · time-sensitive
curl https://honesty.tools/v1/chat/completions \
  -H "Authorization: Bearer $APERTURE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "aperture-router",
    "messages": [{"role":"user","content":"Who founded Brindlewick & Thorne?"}]
  }'
from openai import OpenAI

client = OpenAI(base_url="https://honesty.tools/v1", api_key=APERTURE_KEY)

resp = client.chat.completions.create(
    model="aperture-router",
    messages=[{"role": "user", "content": "Who founded Brindlewick & Thorne?"}],
)
print(resp.choices[0].message.content)        # the answer
print(resp.model_extra["aperture"])           # the honesty layer ↓
import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://honesty.tools/v1", apiKey: APERTURE_KEY });

const resp = await client.chat.completions.create({
  model: "aperture-router",
  messages: [{ role: "user", content: "Who founded Brindlewick & Thorne?" }],
});
console.log(resp.choices[0].message.content);   // the answer
console.log(resp.aperture);                  // the honesty layer ↓

Every reply carries an aperture block — the certificate and the route trace — alongside the standard OpenAI response. Standard clients ignore it; Aperture-aware ones read it.

response · the aperture block
{
  "choices": [{ "message": { "role": "assistant", "content": "…" } }],
  "aperture": {
    "verdict":  "OFF_MAP",           // GROUNDED · CONFIDENT · LOW_FAMILIARITY · OFF_MAP
    "off_map":  0.778,              // aperture-router's familiarity off-map read (a different instrument from the per-model cert fingerprint), 0–1
    "route": {
      "tier": 2,                   // 1 local · 2 neocortex · 3 internet
      "brain": "the escalated neocortex model",
      "escalated": true,
      "reason": "off the map (off-distribution 0.78) — escalated to the neocortex"
    },
    "gauges":  { "off_distribution": 0.778, "familiarity": 0.022 },
    "advice":  "the question is outside the model's reliable knowledge…"
  }
}
Watch it route · illustrative example traces
tier 1 · localPhoton Base
the lens routed to

The model id doubles as the mode — switch behavior without touching your code — and for already-recorded answers, POST /v1/audit scores a whole batch in one keyed call (see the docs):

aperture-routerThe honesty router. Grounded → local Photon Base; off-map → escalate to the neocortex or the internet. (default)
aperture-monitorPhoton Base always answers; Aperture only annotates (passive). The safe first step — watch the route traces before you let it act.
aperture-baseForce the local cortex — no escalation, just Photon Base + its certificate.
aperture-frontierForce the neocortex — always escalate to a bigger map.
Streaming works unchanged (stream: true → an OpenAI SSE stream; the aperture block rides the final chunk). Auth is a bearer key when the port is keyed, keyless on localhost. GET /v1/models lists the modes. The router is read-only — it never touches the served decoder except through the same bounded path the portal already uses.
The receipt · ed25519

Every answer ships a signed receipt.

Whether a receipt is authentic isn't something you take on faith — every /v1/verify receipt (and every stored /read) is signed: an ed25519 signature you can verify offline against the published public key. Tamper with one byte and it fails. This is the moat: not raw metrics — a verifiable record.

verify a signed receipt — offline, no call back to us
import json, base64
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey

# `receipt` is the signed block from your /v1/verify response (or a stored /read)
r = dict(receipt); sig = r.pop("signature"); r.pop("id", None)
canon = json.dumps(r, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode()
Ed25519PublicKey.from_public_bytes(base64.b64decode(sig["pub"])).verify(base64.b64decode(sig["sig"]), canon)
print("verified — the signed receipt is authentic")   # raises on tamper; sig["pub"] == /api/cert/pubkey
Stored reads verify the same way, and /evidence runs a real in-browser WebCrypto check on each one — independently, in your own browser, against the published pubkey. The signature is the product. See receipts verify on /evidence →
Don't trust our check — run your own. The open verifier is a single dependency-light file (cryptography + stdlib): python3 aperture_verify.py verify receipt.json checks any receipt or cert offline against the pinned registry key, with no call back to us. And an append-only Merkle transparency log makes suppression or a swapped receipt third-party detectable. You can't watch a 12-hour agent, but you can verify its trail: verify-session checks every receipt in a run and the root over their ordered sequence, so altering, reordering, or dropping one is caught. And where a fixed rule settles the answer, a deterministic per-answer witness lets you re-derive the verdict yourself — a code result re-run in an isolated sandbox, a math identity re-checked in SymPy, a fact proved present in our registry by a Merkle proof — exact, offline, no distribution and no trust in us, and still provenance, not truth. Versioned, conformance-testable open spec: the spec → · witness spec →
The SDK · the lens in your code

One key. One import.

The hosted lens in your loop — one sk-apt- key grounds claims and runs honest inference, free in demo mode. Get a free key → or run the whole stack privately. Read-only, zero dependencies:

pip install aperture-gate
Or self-host Photon Base. The whole stack — the served model, the grounding registries, the gate — runs inside your own perimeter. Your data never leaves. Same SDK, point it at your local port instead of the hosted one. Self-host guide →
# one sk-apt- key — grounding + honest inference, free to start
from aperture_gate import Aperture, signup

key = signup("you@email.com")            # a FREE key (or grab one at honesty.tools/verify)
ap  = Aperture()                          # reads APERTURE_API_KEY

ap.verify("Sotorasenib is an approved cancer drug.")   # → fabricated · caught FREE
ap.verify("BRCA1 is a tumor suppressor gene.")          # → grounded · 1 of your plan
print(ap.ask("Who painted the Mona Lisa?"))            # → honest Photon inference
ap.usage()   # → {tier:"free", used, limit, remaining} · upgrade at honesty.tools/verify
# ADVANCED — gate your OWN model offline, against a calibration certificate (no hosted call)
from aperture_gate import Gate

gate = Gate.from_cert("openai/gpt-4o-mini")        # a registry id, a downloaded JSON, or a dict
r = gate.ask("Who founded Brindlewick & Thorne?",
             base_url="https://openrouter.ai/api/v1", api_key=KEY,
             model="openai/gpt-4o-mini")
print(r["verdict"], r["score"])   # → OFF_MAP — caught before you commit
# or words-only, no model at all:
verdict = gate.read_text(answer_text)
Gate → verdictverdict (ON_MAP · UNCERTAIN · OFF_MAP — the Gate’s per-cert vocabulary; the hosted router speaks GROUNDED/CONFIDENT/…), instrument (words · fingerprint), score, the matched refusal phrases, and the certificate id it read with.
annotate → aperture blockThe same reading attached to a standard chat completion — verdict, band, instrument, off_map_score, calibration_cert.
The gate reads per model, per certificate — never a global threshold. On logprob-exposing surfaces (OpenAI-class, any self-hosted vLLM/SGLang) it reads the confidence fingerprint; everywhere else the words. Conformance vectors + the full schema live in the docs; the package is MIT and dependency-free.
The MCP · a tool your agent calls

The lens beside the model.

The recommended shape for agents: not baked into weights, but a tool the agent calls mid-task — “am I off the map before I commit?” — at any tool-call, write, or plan→execute boundary. It runs as a stdio MCP server, shipped inside the same package.

// add Aperture to your MCP client's config
{
  "mcpServers": {
    "aperture": {
      "command": "python",
      "args": ["-m", "aperture_gate.mcp"],
      "env": { "APERTURE_API_KEY": "sk-apt-…" }   // a free key from honesty.tools/verify
    }
  }
}
# install once, run anywhere — stdlib only
pip install aperture-gate
python -m aperture_gate.mcp

Three tools, each returning a receipt the agent can branch on:

aperture_verify(claims)Ground checkable claims against the hosted registries — grounded / fabricated / abstain, with the evidence and your plan usage. Catching fabrications is free; only grounded claims count. The agent's pre-commit fact check, on your free key.
aperture_read(query, model?)Ask the hosted honest Photon model (your free key) and read the answer through the lens → verdict · score · instrument. Point it at your own endpoint to gate a BYO model instead.
aperture_check_text(text)Words-only read of any text the agent already has — no model call. The cheapest pre-commit receipt.

Then branch on the gate — the whole point is the action:

proceed

Grounded

The model is on its own ground. Safe to commit the step.

review

Verify first

On the edge. Check the claim — retrieve, cross-check — before you act on it.

escalate

Off the map

Do not commit. Gather more, ask a human, or abstain rather than bluff. The off-map read is a cheap triage flag — fabrications are caught downstream by grounding (verified registries) and cross-model checks.

Build once · deploy anywhere

Put the lens between your model and what matters.

One instrument, calibrated to any model with no labels and no retraining — as a proxy, an SDK, or an MCP tool. Always read-only.