{"categories":[{"id":"request","label":"Request records","summary":"One row per call: which model and provider answered, how many tokens, what it cost and when. Never the text of the call."},{"id":"billing","label":"Billing","summary":"Balances, the append-only ledger, spending holds, per-call payment quotes and what providers are owed."},{"id":"receipts","label":"Receipts & proofs","summary":"Signing keys, anchors and the transparency log that let anyone check a receipt without asking us."},{"id":"keys","label":"Keys & auth","summary":"API keys (stored as hashes), teams with their passkey and wallet members and audit log, agent sessions, keys you bring, and the issuer and gateway keys behind blind tokens and Oblivious HTTP."},{"id":"providers","label":"Providers & attestation","summary":"The provider registry and model catalogue, attestation results, measurements, disclosure profiles and the day-zero model lane."},{"id":"chain","label":"Chain","summary":"Blockchain events the router has read, escrow deposits, pay-with sessions and swaps, provider payouts and slashes."},{"id":"operations","label":"Operations","summary":"Settings you save (routes, presets, spend alerts) and the router's own key-value state."}],"format":"anyroute.data-inventory/1","outside_postgres":{"address_readers":[{"evidence":[{"contains":"export function socketAddress","file":"src/hardening/client.ts"},{"contains":"hops[hops.length - (cfg?.trustProxyHops ?? 1)]","file":"src/hardening/client.ts"}],"file":"src/hardening/client.ts","kept":"Address held in request memory and anonymous Redis counter keys for 61 seconds. Existing limit families retain their lifetimes. No database or log address field.","reads":"The socket address, trusted X-Forwarded-For hop selected from the right by TRUST_PROXY_HOPS, and CF-Connecting-IP only when the enabled origin lock secret matches. The socket is also read to exempt direct private-network callers without forwarding headers from ingress guards.","then":"Validates IP syntax, selects the trusted client address for existing limiters, and rejects public forwarding traffic from private-socket exemptions. No caller address is read for authenticated Tor ingress."},{"evidence":[{"contains":"const from = addressBucket(c, ctx.cfg)","file":"src/hardening/middleware.ts"}],"file":"src/hardening/middleware.ts","kept":"Counter only; 61 seconds in Redis or until the memory limiter sweep. Never a prompt, key, header, secret or address in logs.","reads":"Existing per-address bucket for anonymous public API reads and MCP messages; all Tor callers use onion.","then":"Counts against anon with the configured minute limit. Keyed requests, health and readiness, and internal callers are exempt. Redis failure permits the call and logs a fixed warning."},{"evidence":[{"contains":"const from = addressBucket(c, ctx.cfg);","file":"src/facilitator/routes.ts"}],"file":"src/facilitator/routes.ts","kept":"Raw address in the limiter key for 61 seconds in Redis, or until the memory limiter sweeps; never in a settlement, listing, receipt or log line.","reads":"The caller address bucket on every /facilitator route; over Tor the shared onion bucket.","then":"Counts requests in the facilitator's own per-address limiter; trusted proxy and onion rules apply."},{"evidence":[{"contains":"const from = addressBucket(c, ctx.cfg);","file":"src/api/network-hosts.ts"}],"file":"src/api/network-hosts.ts","kept":"Raw address in the limiter key for 61 seconds in Redis, or until the memory limiter sweeps; never in the host row or application log.","reads":"The caller address bucket on host signup and credential writes.","then":"Counts attempts through the existing per-address limiter; trusted proxy and onion rules apply."},{"evidence":[{"contains":"const from = addressBucket(c, ctx.cfg);","file":"src/network/waitlist.ts"}],"file":"src/network/waitlist.ts","kept":"Only a minute-specific keyed digest and counter: 61 seconds in Redis, or up to six minutes without Redis until the memory limiter sweeps old windows. No raw IP or user agent, and no address-derived value in the waitlist table.","reads":"Address bucket for a waitlist POST or DELETE; onion requests use the shared onion bucket.","then":"A secret-keyed HMAC of the address and current minute is passed to the existing limiter; onion stays the word onion."},{"evidence":[{"contains":"const from = addressBucket(c, ctx.cfg);","file":"src/api/e2ee.ts"}],"file":"src/api/e2ee.ts","kept":"Only the counter key, for 61 seconds; no address in a generation, receipt or log.","reads":"The address only for encrypted calls without a key outside the Oblivious HTTP gateway; over Tor the fixed onion bucket is used.","then":"Uses the existing blind-ip rate-limit family."},{"evidence":[{"contains":"export function clientIp(c: Context, trustProxy = false)","file":"src/api/common.ts"},{"contains":"return { id: \"onion\", onion: true","file":"src/api/common.ts"}],"file":"src/api/common.ts","kept":"Not written to Postgres and not logged. It exists in Redis only as part of the rate-limit keys listed above, for at most an hour.","reads":"The selected client address from the shared ingress helper: socket by default, the trusted hop counted from the right when TRUST_PROXY is on, or CF-Connecting-IP when the enabled origin lock secret is valid.","then":"Returned to a caller as the key of a per-address rate limit. Requests that arrived over Tor get the fixed word onion instead of an address (addressBucket)."},{"evidence":[{"contains":"const from = addressBucket(c, ctx.cfg);","file":"src/api/chat.ts"}],"file":"src/api/chat.ts","kept":"Only as the Redis rate-limit key.","reads":"The caller's address, only for a call that carries no API key and did not arrive through the Oblivious HTTP gateway.","then":"Counted against ip:<address> (or blind-ip:<address> for a blind token)."},{"evidence":[{"contains":"const from = addressBucket(c, ctx.cfg);","file":"src/api/embeddings.ts"}],"file":"src/api/embeddings.ts","kept":"Only as the Redis rate-limit key.","reads":"The caller's address, only for a call without an API key.","then":"Counted against ip:<address> or blind-ip:<address>."},{"evidence":[{"contains":"const from = addressBucket(c, ctx.cfg);","file":"src/api/rerank.ts"}],"file":"src/api/rerank.ts","kept":"Only as the Redis rate-limit key.","reads":"The caller's address, only for a call without an API key.","then":"Counted against ip:<address> or blind-ip:<address>."},{"evidence":[{"contains":"await ctx.limiter.take(`newkey:${from.id}`","file":"src/api/keys.ts"},{"contains":"await ctx.limiter.take(`wallet-login:${from.id}`","file":"src/api/keys.ts"}],"file":"src/api/keys.ts","kept":"Only as the Redis rate-limit keys.","reads":"The caller's address when a key is created and when a wallet sign-in challenge is requested.","then":"Counted against newkey:<address> and wallet-login:<address>."},{"evidence":[{"contains":"await ctx.limiter.take(`team-auth:${from.id}`","file":"src/api/teams.ts"}],"file":"src/api/teams.ts","kept":"Only as the Redis rate-limit key.","reads":"The caller's address when joining a team or signing in to one with a passkey or wallet (no API key yet).","then":"Counted against team-auth:<address>."},{"evidence":[{"contains":"const from = addressBucket(c, ctx.cfg);","file":"src/api/paymaster.ts"}],"file":"src/api/paymaster.ts","kept":"Only as the Redis rate-limit key.","reads":"The caller's address on a paymaster request.","then":"Counted against pm:<address>."},{"evidence":[{"contains":"const from = addressBucket(c, ctx.cfg);","file":"src/ohttp/gateway.ts"}],"file":"src/ohttp/gateway.ts","kept":"Only as the Redis rate-limit key.","reads":"The caller's address, only for a request that did not come through an authenticated relay. A request through a relay is counted by the relay's key id instead.","then":"Counted against ohttp-gw:ip:<address>."},{"evidence":[{"contains":"const from = addressBucket(c, ctx.cfg);","file":"src/tlog/routes.ts"}],"file":"src/tlog/routes.ts","kept":"Only as the Redis rate-limit key.","reads":"The submitter's address when a witness posts a cosignature.","then":"Counted against tlog-cosign:<address>."},{"evidence":[{"contains":"addressBucket(c, ctx.cfg)","file":"src/api/creator-claims.ts"}],"file":"src/api/creator-claims.ts","kept":"Only as the Redis rate-limit keys.","reads":"The caller's address when a creator claim is issued or verified.","then":"Handed to services/creators.ts as an address bucket."},{"evidence":[{"contains":"await ctx.limiter.take(`claim-issue-ip:${from.id}`","file":"src/services/creators.ts"}],"file":"src/services/creators.ts","kept":"Only as the Redis rate-limit keys.","reads":"The address bucket it was given.","then":"Counted against claim-issue-ip:<address> and claim-verify-ip:<address>."},{"evidence":[{"contains":"const from = clientIp(c, ctx.cfg.trustProxy);","file":"src/api/responses.ts"},{"contains":"{ requestIP: () => ({ address: from }) }","file":"src/api/responses.ts"}],"file":"src/api/responses.ts","kept":"Nothing beyond what src/api/chat.ts keeps.","reads":"The caller's address, so the internal chat call it makes on the caller's behalf is limited exactly as the caller's own call would be.","then":"Passed to the chat route as an in-process value (requestIP) and then handled as in src/api/chat.ts."},{"evidence":[{"contains":"const from = clientIp(c, ctx.cfg.trustProxy);","file":"src/ollama/routes.ts"},{"contains":"{ requestIP: () => ({ address: from }) }","file":"src/ollama/routes.ts"}],"file":"src/ollama/routes.ts","kept":"Nothing beyond what src/api/chat.ts keeps.","reads":"The caller's address, so the internal chat or embeddings call it makes on the caller's behalf is limited exactly as the caller's own call would be.","then":"Passed to the chat or embeddings route as an in-process value (requestIP) and then handled as in src/api/chat.ts."},{"evidence":[{"contains":"headers.delete(name);","file":"src/onion/ingress.ts"}],"file":"src/onion/ingress.ts","kept":"Not applicable.","reads":"Nothing. It deletes every header that names a client address (X-Forwarded-For, X-Real-IP, CF-Connecting-IP and others) from requests that arrived over Tor, before any route runs.","then":"Requests over Tor therefore carry no client address for a route, a limiter or a log line to use."},{"evidence":[{"contains":"The forwarded request is built from nothing but the configured pieces and the body","file":"relay/src/relay.ts"}],"file":"relay/src/relay.ts","kept":"The relay keeps counters only: totals and fixed reason labels.","reads":"The separate Oblivious HTTP relay (run by relay operators, not by the router) forwards a request's body to a gateway without any header, address or cookie of the client.","then":"The forwarded request is built from configuration and the body only. The relay's automated checks fail if its source logs a request or reads a client address."},{"evidence":[{"contains":"Requests are forwarded by allow-list, not by deny-list","file":"sidecar/src/headers.ts"}],"file":"sidecar/src/headers.ts","kept":"Not applicable.","reads":"The model-server sidecar inside a provider's enclave forwards only allow-listed headers, so a proxy header cannot carry a client address to the model server.","then":"Forwarded by allow-list, not deny-list; a header that names a network address is refused even in configuration."}],"body_readers":[{"carries":"prompt-or-answer","evidence":[{"contains":"const reader = c.req.raw.body?.getReader()","file":"src/hardening/body.ts"}],"file":"src/hardening/body.ts","kept":"Bounded bytes in request memory only. This guard does not hide plaintext prompts from the router. No new database columns or body logging.","reads":"Request bytes before route dispatch, including ordinary plaintext inference, files and encrypted envelopes. Reads the declared Content-Length and streams up to each route's wire cap; an over-cap chunk is discarded.","then":"Rejects excess bytes with 413 before route side effects; passes a bounded replacement request to existing handlers, preserving the gateway origin record."},{"carries":"prompt-or-answer","evidence":[{"contains":"const msg = await c.req.json()","file":"src/hardening/middleware.ts"}],"file":"src/hardening/middleware.ts","kept":"Parsed message in request memory only; count in the anonymous limiter. No tool arguments or prompts in the counter or logs.","reads":"The bounded MCP JSON message or batch, including tool arguments and any prompt.","then":"Rejects batches over 20 messages and charges each message against the anonymous minute limit. Existing MCP tool and rulebook guards still apply."},{"carries":"settings","evidence":[{"contains":"guardDecideInput.parse(await readJson(c))","file":"src/api/guard.ts"}],"file":"src/api/guard.ts","kept":"Decision metadata and reported outcomes in agent_action_decisions, with action decisions and outcomes on agent_policy_events and action approval projections in agent_approvals. Reported amounts are not verified execution.","reads":"A strict bounded action name, optional target label and order digest, decimal amount and approval identifier, or a reported outcome.","then":"Authenticates the deciding key and serializes checks and reports with the account lock. Action and target are readable caller-chosen labels; targets can name a wallet or host. No full order details are accepted. When DECISION_TAGS_ENABLED is on and an order digest is given, the decision also reads the same agent's calls from the preceding 24 hours whose stored receipt carries that digest as decision_tag and returns their ids, model, provider and time as informed_by; GET /api/v1/guard/decisions reads decisions by digest or receipt id within the Activity scope. Neither stores anything new."},{"carries":"settings","evidence":[{"contains":"watchBody.parse(await readJson(c))","file":"src/api/deposits.ts"}],"file":"src/api/deposits.ts","kept":"deposit-watch rows in kv keep account id, lane, hash and submission time across reloads. At most 20 submitted hashes per account; removed after indexed credit, otherwise retained until operator deletion. No new Redis keys, caller-address readers or log fields.","reads":"A strict transaction hash and deposit lane only. Form amounts and sender addresses are not accepted.","then":"Authenticates the key, excludes session and agent-only roles, scopes reads and submitted hashes to its account. Chain logs determine observed amounts, senders and credit values; submission never credits funds."},{"carries":"prompt-or-answer","evidence":[{"contains":"const data = await callPaidTool(ctx, key, await readJson(c)","file":"src/tools/routes.ts"},{"contains":"requestSha256: sha256(canonicalJson({ method, url: url.toString(), body: input.body ?? null }))","file":"src/tools/call.ts"}],"file":"src/tools/routes.ts","kept":"tool_calls keeps hashes of the request and answer, amounts, the address without its query and the signed receipt; tool_listings keeps the listing. The body, the query string and the answer are not stored or logged. No new Redis family beyond the two rate limits, no caller-address reader.","reads":"A paid tool call: the tool's address, method, a JSON body of at most 64 KiB for the tool, max_price and optionally a model and prompt to hand the answer to. A tool listing: name, summary, address and a canary probe.","then":"Sends the body to the tool through the egress guard and reads its answer (2 MB at most, JSON or plain text only) in memory, returning it to the caller marked untrusted. Only when the rulebook sets tools.pass_to_models and the call asks for it is the answer sent to a model through the ordinary chat route."},{"carries":"settings","evidence":[{"contains":"payInput.parse(await readJson(c))","file":"src/api/agent-pay.ts"},{"contains":"confirmInput.parse(await readJson(c))","file":"src/api/agent-pay.ts"}],"file":"src/api/agent-pay.ts","kept":"agent_payments and the existing Agent Guard decision, outcome and decision-chain records. One new rate-limit family; no caller-address reader or log field.","reads":"A recipient (public profile id or 0x wallet), a decimal USD amount, an optional memo digest and approval id; or a transaction hash to confirm.","then":"Authenticates the agent key, decides with its rulebook through Agent Guard (action pay.agent), and returns unsigned USDG transfer instructions for the payer's own wallet. A confirmation reads that transaction's receipt, Transfer logs and block hash from Robinhood Chain and signs a receipt. The router never signs or sends the payment."},{"carries":"settings","evidence":[{"contains":"defaultsSpec.parse(await readJson(c))","file":"src/provisioning/scope.ts"}],"file":"src/provisioning/scope.ts","kept":"A boolean in accounts.inference_keys_default; keys.scope stores the issued scope and keys.include_byok_in_limit stores the compatibility selection. Existing rows retain their access. No new request text, address readers, Redis families or log fields. Model calls still pass through existing routing and billing.","reads":"A strict scope setting: inference or account. Authorization and x-api-key credentials are hashed in memory for route restrictions; receipt identifiers are checked against generation ownership.","then":"Requires a management key for account defaults; refuses inference-only keys on every route outside the model-call and own-generation/receipt allow-list. Newly minted child keys inherit the default, including sessions and team sign-ins."},{"carries":"settings","evidence":[{"contains":"export function guardInferenceModels","file":"src/provisioning/inference.ts"}],"file":"src/provisioning/inference.ts","kept":"Nothing additional: no model identifier, body, Redis family, log field or address is stored by this scope check.","reads":"Only model and fallback-model identifiers from the already parsed inference request, after per-key aliases resolve. No prompt or answer text is inspected by this check.","then":"Refuses @ references for inference-only keys before chat reads account routes, presets or character records. Catalog model calls continue through unchanged billing."},{"carries":"prompt-or-answer","evidence":[{"contains":"export function captureStructuredOutput","file":"src/structured-output/chat.ts"},{"contains":"Return corrected JSON only","file":"src/structured-output/chat.ts"}],"file":"src/structured-output/chat.ts","kept":"No new database column, Redis family or log field. Both calls keep ordinary generation hashes, token counts, costs and signed receipts. Validation errors, JSON Pointer paths, combined charges and nested call receipts are unsigned response metadata, not written to generation receipts or returned by receipt lookup. Existing batch outputs can retain that metadata with the answer. Preset json_check settings live in the existing preset_versions.config JSON. Existing optional cache and batch retention rules still apply; non-streaming repair bypasses the response cache.","reads":"Resolved chat messages and response_format schema, the final answer, and the opt-in anyroute.json_check setting when STRUCTURED_OUTPUT_CHECK_ENABLED is enabled.","then":"Reads request and answer text in router memory to check JSON and supported schema assertions. Repair may send the same provider and model one extra request containing the conversation, original answer, schema and validation errors. Each call passes the ordinary authorization, lane, agent and billing checks. Streams validate only."},{"carries":"settings","evidence":[{"contains":"create.parse(await readJson(c))","file":"src/webhooks/routes.ts"}],"file":"src/webhooks/routes.ts","kept":"URL and generated signing key are encrypted under APP_SECRET. Selected event identifiers are retained. Subsequent responses redact the path/query and omit credentials. No new Redis family, log field, prompt/answer reader or caller-address reader.","reads":"Bounded JSON containing an HTTPS destination URL and selected fixed event types.","then":"Requires an authenticated owner/admin outside agent sessions. New account-wide destinations require a management key; non-management callers see and control only destinations scoped to their own key."},{"carries":"payment-or-signature","evidence":[{"contains":"const text = await c.req.text();","file":"src/facilitator/routes.ts"}],"file":"src/facilitator/routes.ts","kept":"Settled and failed attempts in facilitator_settlements, signed listings in facilitator_sellers and float balances in seller_gas_floats. Request bodies are not stored and carry no prompts.","reads":"x402 verify and settle bodies (a payer's signed USDG authorization and the seller's payment requirements), signed seller listings, and gas float top-ups, each at most 64 KB.","then":"Checks signatures, amounts, time windows and nonces, relays a valid authorization from the payer straight to payTo with the relay key, and screens a listed payTo against the sanctions list."},{"carries":"settings","evidence":[{"contains":"profileBody.parse(await readJson(c))","file":"src/api/agent-profiles.ts"}],"file":"src/api/agent-profiles.ts","kept":"Public settings, latest selected certificate and a private key-hash association in agent_profiles until unpublish. No new address reader, Redis family or log fields. Existing receipt signing key entries are published when certificates are requested.","reads":"Owner-written public profile fields (including an optional HTTPS agent endpoint and payout wallet), explicit rulebook category selections and bounded certificate claim identifiers.","then":"Authenticates the owner or authorised account administrator, checks key ownership, validates selected record claims, strips control and Unicode format characters from bounded owner text, and publishes the card at an independent random slug. Public reads sanitize existing owner text again and project only opted fields and verify certificate signatures and expiry."},{"carries":"prompt-or-answer","evidence":[{"contains":"const requestSha = requestHash(await readJson(c));","file":"src/pay/recovery.ts"}],"file":"src/pay/recovery.ts","kept":"The two SHA-256 hashes, the payer, the nonce and the Redis key name in x402_paid_results, and the sealed answer in Redis (or the router's memory without Redis), each for 24 hours. The request text is not kept. No log field, no caller-address reader.","reads":"The body of a paid x402 call on the chat, completions, embeddings, rerank and character chat routes, and of a recovery request; and the answer's bytes once the call is answered.","then":"Hashes the request (the receipt's request_sha256) to bind the answer to it, or to compare a recovery request with it. Seals the answer's bytes with AES-256-GCM. A recovery checks the payer's EIP-191 signature first and never relays the payment again."},{"carries":"settings","evidence":[{"contains":"settingsBody.parse(await readJson(c))","file":"src/identity/routes.ts"},{"contains":"feedbackBody.parse(await readJson(c))","file":"src/identity/routes.ts"}],"file":"src/identity/routes.ts","kept":"Choices and registration progress in agent_identities, entries in agent_feedback, issued certificates in agent_track_records. Verification keeps nothing. One new account rate-limit family (agent-feedback). No prompt, answer, caller address or log field.","reads":"Owner identity choices (two booleans), a registration transaction hash, a publish flag for a track record; a reviewer's receipt id, receipt kind, 0 to 100 score and two short tags; or a track-record certificate to verify.","then":"Owner routes require an owner or administrator key of the same account, not a session key. Feedback is accepted only when the router's own receipt names the reviewer's account as payer and the agent as payee or the agent served, and never from the agent's own account. Free text is refused."},{"carries":"settings","evidence":[{"contains":"registrationSchema.parse(await readJson(c))","file":"src/api/agent-sealed.ts"}],"file":"src/api/agent-sealed.ts","kept":"Registration settings, random revision, fixed result codes, verifier names, TLS key hash and check time in the sealed-agent kv family; never inference bodies or API credentials. No new Redis family or log field.","reads":"Strict registration settings: HTTPS /attest URL without query, image digest and measured compose hash.","then":"Requires principal ownership of the active non-management key, obtains fresh quote evidence through guarded public-only pinned TLS and verifies key fingerprint and measured deployment."},{"carries":"settings","evidence":[{"contains":"await consumeCode(ctx, message.from.id, command[2]","file":"src/telegram/delivery.ts"}],"file":"src/telegram/delivery.ts","kept":"Only the link identifiers, code hash, expiry and delivery markers described under kv. No Telegram message text or inference text is copied. No new request-body or network-address reader.","reads":"Private Telegram /link and /unlink commands and approval callbacks fetched by the existing bot poller. Link codes and callback identifiers are read in memory.","then":"The link is role-checked and recorded without a key secret. Callbacks run the same approval decision as the dashboard; inference consumption is unchanged. Telegram receives approval intent metadata and alerts."},{"carries":"prompt-or-answer","evidence":[{"contains":"const upstream = upstreamBody(candidate, body, false).body;","file":"src/agreements/internal-transport.ts"}],"file":"src/agreements/internal-transport.ts","kept":"Existing agreement_jury.statement stores model reasons (which may quote evidence), signed operational receipt with request/response hashes, provider attestation and checked gateway receipt references, usage and provider-list-price operator cost estimates. Canaries have no separate operational-cost ledger. Failed calls may incur unmeasured cost. No evidence text in logs; no new Redis keys or caller-address readers. Same resolution-based jury retention applies.","reads":"Decrypted party evidence bundle and structured provider verdict text in router memory.","then":"Fixed rubric sent through attested-lane selection with fresh non-development attestation, stored provider credentials and quote-pinned TLS where configured. Gateway receipts must verify upstream attestation and exchange digests. No customer account or billing rows."},{"carries":"prompt-or-answer","evidence":[{"contains":"const reader = c.req.raw.body?.getReader();","file":"src/agreements/routes.ts"}],"file":"src/agreements/routes.ts","kept":"Evidence hash and APP_SECRET-encrypted content in agreement_evidence, up to 32 items per party. Jury statement stores per-model answer reasons, receipt references and a signed ruling; reasons can quote evidence. Router reads evidence in memory. Parties can read both parties evidence through the API. Resolution plus 30 days by default permits deletion; a fresh-index retention job removes evidence and jury rows. No new Redis family, log field or caller-address reader.","reads":"Bounded party evidence text or JSON, or a strict create-agreement preparation with payee wallet, milestone USDG amounts, terms hash and future deadline.","then":"Requires an authenticated wallet-linked account matching the indexed payer/payee. Caps streams without trusting Content-Length. Preparation checks inherited rulebooks and returns unsigned calldata; jury calls use the attested chat path with a configured API key, or the optional internal provider transport."},{"carries":"settings","evidence":[{"contains":"bodySchema.parse(await readJson(c))","file":"src/api/agent-certificates.ts"}],"file":"src/api/agent-certificates.ts","kept":"No certificate, pseudonym, claims, query or body is persisted. Only an account issuance limiter counter and the reused public receipt signing key log entry are kept; no prompt fields are accepted.","reads":"Bounded record claim identifiers for issuance; a signed certificate supplied by body or query for public verification.","then":"Checks retained generation counts and rulebook events, signs true claims with a fresh random pseudonym, or checks certificate signature and expiry. The router knows the authenticated issuing key."},{"carries":"settings","evidence":[{"contains":"createBody.parse(await readJson(c))","file":"src/api/playbooks.ts"}],"file":"src/api/playbooks.ts","kept":"The playbook in playbooks, each change with its digest and rules in playbook_changes, the following keys' copies in agent_policies with policy_set events in agent_policy_events, and team audit entries. No prompt or answer fields are accepted.","reads":"A playbook name of at most 100 characters with a strict bounded rulebook and an optional team id, or a playbook id (or null) for a key to follow.","then":"Requires the same owner/admin permissions as editing a key's rulebook; account-wide playbooks change only with a management key. A rules change is copied to every following key under the account lock."},{"carries":"settings","evidence":[{"contains":"agentPolicySchema.parse(await readJson(c))","file":"src/api/agents.ts"}],"file":"src/api/agents.ts","kept":"Current rulebooks and optional principal-written kill reasons in agent_policies; decision metadata and changes in agent_policy_events. Dry runs and replays keep nothing. No prompt or answer fields are accepted.","reads":"A strict bounded rulebook, a kill reason, a metadata-only Intent for a dry run, or a draft rulebook and a number of days (1 to 7) to replay.","then":"Requires the same owner/admin permissions as editing the target key. Evaluates dry runs deterministically without event writes or kill changes. A replay reads that key's recorded calls (model, lane, cost, tokens and time from generations, plus the linked rulebook events) and its Agent Guard checks in a read-only transaction, and evaluates the draft against them."},{"carries":"settings","evidence":[{"contains":"export function declaredTools","file":"src/agents/enforce.ts"}],"file":"src/agents/enforce.ts","kept":"Only Intent metadata and fixed decision reasons in agent_policy_events. Never arguments, descriptions, prompt or answer text; no new Redis key family or log field.","reads":"Declared tool and function names from the inference body already parsed by the router.","then":"Projects only identifiers into the rulebook Intent, alongside the resolved model, lane, token bound and cost reservation."},{"carries":"settings","evidence":[{"contains":"const reader = c.req.raw.body?.getReader();","file":"src/api/network-hosts.ts"}],"file":"src/api/network-hosts.ts","kept":"Provider name, endpoint, operator and payout wallets, requested model IDs, optional contact, status and refusal reasons. Credential stored only in existing AES-GCM api_key_enc. The router sees it in memory. No whole-body log or signature column.","reads":"Up to 8 KiB of host signup JSON or an operator-generated sidecar credential, with an existing wallet signature over the canonical JSON hash.","then":"Strictly validates signup fields, verifies the wallet and performs attestation, policy and sanctions checks. Credentials are accepted only for the recovered operator wallet."},{"carries":"settings","evidence":[{"contains":"const reader = c.req.raw.body?.getReader();","file":"src/network/waitlist.ts"}],"file":"src/network/waitlist.ts","kept":"Only sign-up fields, optional contact, id, deletion digest and time in network_waitlist. No raw deletion code, body log, IP or user agent. Free text is readable by the owner; public stats return counts only.","reads":"At most 4 KiB of JSON: waitlist fields or a deletion code.","then":"Validated strictly; a filled honeypot is discarded. The deletion code is hashed for an atomic delete."},{"carries":"settings","evidence":[{"contains":"publishPolicy: operator.input(hostPolicySchema)","file":"src/admin/trpc.ts"},{"contains":"await log.append([hostPolicyEntry(policy.version, sha256)]);","file":"src/network/publication.ts"}],"file":"src/admin/trpc.ts","kept":"The public canonical policy, hash, signature, public verifier key, version and timestamps in host_policies, and a host_policy hash entry in tlog_entries. No caller address, operator token or request headers are retained by this publication path.","reads":"For network.publishPolicy, the operator's policy document decoded by the tRPC transport and validated by hostPolicySchema. No prompt fields are accepted.","then":"Checked for consecutive version and issue time, canonically encoded, signed with the log key, and committed with its transparency-log entry and checkpoint."},{"carries":"prompt-or-answer","evidence":[{"contains":"const reader = c.req.raw.body?.getReader();","file":"src/api/e2ee.ts"},{"contains":"end_to_end_encrypted: true","file":"src/api/e2ee.ts"}],"file":"src/api/e2ee.ts","kept":"Only hashes, counts or reservation bounds, charge and timing in generations and the ledger. The signed receipt adds end_to_end_encrypted, e2ee version/suite/gateway_attested/complete/billing_basis/input_byte_bound/max_tokens/request_bytes/response_bytes and gateway_receipt (id, keyset digest, response-hash/request-hash/upstream check states and upstream session id and GPU claim). Existing retention and deletion apply. No envelope, response ciphertext, public key, replay nonce, timestamp or credential is persisted; no new log fields or Redis families.","reads":"A bounded encrypted JSON envelope and encrypted SSE or JSON response; model, roles, lengths, public keys, timestamp, nonce and clear usage remain visible. A caller must actually encrypt content; framing checks cannot prove encryption.","then":"Validates a strict text envelope, forwards the original bytes without decryption, hashes wire bytes, observes usage and completion for billing. No tools, files, search, cache, alias or content transformations."},{"carries":"prompt-or-answer","evidence":[{"contains":"const body = await readJson(c);","file":"src/api/chat.ts"},{"contains":"const bodySha = requestHash(body);","file":"src/api/chat.ts"},{"contains":"response_sha256: sha256(p.responseText),","file":"src/api/chat.ts"}],"file":"src/api/chat.ts","kept":"Not stored. Kept in memory for the length of the call. The opt-in response cache and batch content are kept sealed outside the database (see the Redis section), and a failed provider attempt can keep up to 200 characters of that provider's own error message.","reads":"The whole JSON body of a chat or text completion: the messages, the model and the parameters (readJson).","then":"Read in memory to route the call on every lane: validated, checked against guardrails, priced, then sent to the provider chosen. The request is hashed (request_sha256) and the answer is hashed (response_sha256). Streaming answers are passed through chunk by chunk."},{"carries":"prompt-or-answer","evidence":[{"contains":"const body = await readJson(c);","file":"src/api/batches.ts"},{"contains":"await batchStore(ctx).saveInputs(row, lines, storeTtl(ctx, row));","file":"src/services/batches.ts"}],"file":"src/api/batches.ts","kept":"Not in the database: the database gets counts, statuses, costs and generation ids. The sealed requests are deleted when the batch finishes and the sealed answers when its results expire (see the Redis section).","reads":"The JSON body of a batch: up to BATCH_MAX_LINES chat or embeddings requests (requests or input_jsonl).","then":"Checked line by line, then sealed at once and kept in Redis (or memory) for the worker, which runs each line through the chat or embeddings handler as the key that sent the batch."},{"carries":"prompt-or-answer","evidence":[{"contains":"const body = await readJson(c);","file":"src/api/embeddings.ts"}],"file":"src/api/embeddings.ts","kept":"Not stored; a generation row and receipt with hashes and counts are written.","reads":"The JSON body of an embeddings call: the input text.","then":"Sent to the provider chosen and the vectors returned."},{"carries":"prompt-or-answer","evidence":[{"contains":"const body = await readJson(c);","file":"src/api/rerank.ts"}],"file":"src/api/rerank.ts","kept":"Not stored; a generation row and receipt with hashes and counts are written.","reads":"The JSON body of a rerank call: the query and the documents.","then":"Sent to the provider chosen; its scores are checked and returned, with the documents' own text when asked."},{"carries":"prompt-or-answer","evidence":[{"contains":"const raw = await readJson(c);","file":"src/api/anthropic.ts"}],"file":"src/api/anthropic.ts","kept":"Nothing beyond what src/api/chat.ts keeps; token counts alone create no payment or request record.","reads":"The JSON body of an Anthropic-format messages call and free onion count requests. The router reads code, prompts and tools in memory.","then":"Converted to a chat request and sent through the router's own chat route, so it is handled and kept exactly as a chat call is."},{"carries":"prompt-or-answer","evidence":[{"contains":"chatRequestFrom(await readJson(c))","file":"src/api/responses.ts"}],"file":"src/api/responses.ts","kept":"Nothing beyond what src/api/chat.ts keeps.","reads":"The JSON body of a Responses-format call.","then":"Converted to a chat request and sent through the router's own chat route."},{"carries":"prompt-or-answer","evidence":[{"contains":"const raw = await readJson(c);","file":"src/ollama/routes.ts"}],"file":"src/ollama/routes.ts","kept":"Nothing beyond what src/api/chat.ts and src/api/embeddings.ts keep.","reads":"The JSON body of an Ollama-format chat, generate or embed call.","then":"Converted to a chat or embeddings request and sent through the router's own route, so it is handled and kept exactly as that call is."},{"carries":"prompt-or-answer","evidence":[{"contains":"msg = JSON.parse(await c.req.text())","file":"src/api/mcp.ts"}],"file":"src/api/mcp.ts","kept":"Nothing beyond what src/api/chat.ts and its existing policy enforcement keep. Rulebook reads and dry runs add no stored data.","reads":"The JSON-RPC body of a tool call for the MCP endpoint, which can include a prompt.","then":"Chat is forwarded to the router's own chat route. Rulebook tools forward caller authentication and prompt-free intent identifiers to the existing agents routes; token estimates use catalog prices. Reading and checking rules does not create policy events."},{"carries":"prompt-or-answer","evidence":[{"contains":"const raw = await readJson(c);","file":"src/api/rag.ts"},{"contains":"What is kept: nothing of the documents, the question or the answer.","file":"src/api/rag.ts"}],"file":"src/api/rag.ts","kept":"Nothing of the documents, question or answer is kept; the chunks and vectors are dropped when the request ends. The response cache is never used.","reads":"The documents and the question of a retrieval call.","then":"Cut into chunks and embedded through the router's own embeddings route, ranked in memory, and the best chunks sent to the router's chat route."},{"carries":"prompt-or-answer","evidence":[{"contains":"const body = await readCapped(raw.body, cfg.maxRequestBytes);","file":"src/ohttp/gateway.ts"}],"file":"src/ohttp/gateway.ts","kept":"Nothing beyond what the route it reaches keeps. The private key for an epoch is destroyed when its window ends.","reads":"An encapsulated request (Oblivious HTTP). The gateway opens it with its own private key, in memory.","then":"Dispatched to the router's own routes as an ordinary request without a client address."},{"carries":"prompt-or-answer","evidence":[{"contains":"Never logged: keys, message text, the bot token","file":"src/services/telegram.ts"}],"file":"src/services/telegram.ts","kept":"The message text is not stored or logged; only the user's sealed key and chosen model are (kv table).","reads":"A Telegram message a user sent to the bot (fetched from Telegram by long polling).","then":"Sent to the router's own chat route with the user's own API key, so limits, billing and receipts apply."},{"carries":"prompt-or-answer","evidence":[{"contains":"Never written to Postgres: entries live in memory (or Redis with a TTL)","file":"src/gateway/cache.ts"},{"contains":"vector: mode === \"semantic\" ? lexicalVector(textOf(body)) : undefined,","file":"src/gateway/cache.ts"}],"file":"src/gateway/cache.ts","kept":"The sealed answer, for the time-to-live the caller asked for (at most CACHE_TTL_S). A semantic cache also keeps, in memory only, a 1,024-number hashed word vector of the prompt so near-duplicates can match.","reads":"The request and the answer, only when the caller opted in.","then":"Encrypted and stored with a time-to-live (memory and, when configured, Redis). A hit is served without asking a provider."},{"carries":"settings","evidence":[{"contains":"const text = await c.req.text();","file":"src/api/common.ts"}],"file":"src/api/common.ts","kept":"Nothing.","reads":"The shared JSON body reader used by the routes below: it reads the text, checks its size (16 MB at most) and parses it.","then":"Returned to the route."},{"carries":"settings","evidence":[{"contains":"const spec = keySpec.parse(await readJson(c));","file":"src/api/keys.ts"}],"file":"src/api/keys.ts","kept":"The settings and, for a BYOK key or a tracing destination, the key or the destination URL and credentials encrypted under APP_SECRET.","reads":"Key settings (name, budget, limits, allowed models, tracing destination, scope, include_byok_in_limit and the auto top-up amounts), amounts, BYOK provider keys, team roles and wallet sign-in challenges.","then":"Validated and written to the keys, byok_keys, teams and kv tables as described above."},{"carries":"settings","evidence":[{"contains":"routeCreateSchema.parse(await readJson(c))","file":"src/api/saved-routes.ts"}],"file":"src/api/saved-routes.ts","kept":"The route in saved_routes.","reads":"A saved route: fallback models, provider preferences and sampling controls.","then":"Validated against a strict schema with no field for message text, then stored."},{"carries":"public-data","evidence":[{"contains":"importSchema.parse(await readJson(c))","file":"src/api/skills.ts"},{"contains":"new Uint8Array(await c.req.arrayBuffer())","file":"src/api/skills.ts"},{"contains":"Nothing is extracted to disk","file":"src/skills/archive.ts"}],"file":"src/api/skills.ts","kept":"The published skill, its hash and scan report in skills; installs in skill_installs.","reads":"A skill to publish: a repository URL, ref and folder, or an uploaded .tar.gz, .tar or .zip of a skill folder (SKILL.md, scripts and resources), and an optional price; an author's new price; an operator's revocation reason.","then":"The archive is read in memory under size, file-count and path limits (nothing is extracted to disk), normalised into one canonical tar, hashed and scanned; a repository is fetched at depth 1 and its tree read without a checkout."},{"carries":"settings","evidence":[{"contains":"presetDocSchema.parse(await readJson(c))","file":"src/api/presets.ts"}],"file":"src/api/presets.ts","kept":"The preset's versions in preset_versions.","reads":"A preset: fallback models, provider preferences, sampling controls and the owner's own system prompt, response_format and tool definitions.","then":"Validated against a strict schema with size caps, then stored as a new version."},{"carries":"prompt-or-answer","evidence":[{"contains":"const v = bodySchema.parse(await readJson(c));","file":"src/api/characters.ts"},{"contains":"for (const k of EXTRA_FIELDS) delete body[k]; // never forwarded to a provider","file":"src/characters/registry.ts"}],"file":"src/api/characters.ts","kept":"Public and unlisted cards in characters; for a private card only the ciphertext and hash. Nothing of a chat, its memory or a decrypted private card; public characters add one to a daily call and cost counter (character_usage).","reads":"A character card (JSON or PNG) or, for a private card, only its ciphertext and hash; and on POST /api/v1/characters/:id/chat a chat request with the conversation, the memory the client decrypted and, for a private card, the decrypted card.","then":"A public or unlisted card is normalized and stored. A chat is assembled into a prompt in memory and sent through the chat route (src/api/chat.ts), like any other call; a private card sent with it is checked against its stored hash and used for that call only."},{"carries":"settings","evidence":[{"contains":"plaintext is refused","file":"src/api/memory.ts"}],"file":"src/api/memory.ts","kept":"The ciphertext and its labels in character_memory, and the vector when the client opted in.","reads":"A memory blob the client sealed (ciphertext), its opaque scope, kind and key fingerprint, and an embedding vector only when the client opts in.","then":"Checked to be in sealed form (plaintext is refused), then stored."},{"carries":"payment-or-signature","evidence":[{"contains":"verifyRegistration(v.passkey.response, passkeyPolicy(ctx, ch.challenge!))","file":"src/api/teams.ts"}],"file":"src/api/teams.ts","kept":"The team, team_members, team_principals and team_audit tables; nothing of the proofs themselves.","reads":"Team settings (a name, an org budget, a role), invites, and the proofs members sign in with: a passkey registration or assertion (WebAuthn clientDataJSON, authenticator data, signature) or a wallet signature over a one-time message.","then":"Settings are validated and stored; passkey and wallet proofs are verified and only the passkey's public key or the wallet address is kept. Each change is appended to the team's audit log."},{"carries":"settings","evidence":[{"contains":"createBody.parse(await readJson(c))","file":"src/api/spend.ts"}],"file":"src/api/spend.ts","kept":"The rule in spend_alerts.","reads":"A spend alert rule.","then":"Validated and stored."},{"carries":"settings","evidence":[{"contains":"createSession(ctx, caller, await readJson(c))","file":"src/api/agent-sessions.ts"}],"file":"src/api/agent-sessions.ts","kept":"The session in agent_sessions.","reads":"An agent session: name, budget, lifetime and labels.","then":"Validated and stored."},{"carries":"settings","evidence":[{"contains":"laneInput.parse(await readJson(c))","file":"src/api/lane.ts"}],"file":"src/api/lane.ts","kept":"models_lane.","reads":"An operator's description of a model for the model lane: variant, status, licence and weights source.","then":"Checked for an operator token, validated and stored."},{"carries":"settings","evidence":[{"contains":"createSchema.parse(await readJson(c))","file":"src/api/status.ts"},{"contains":"updateSchema.parse(await readJson(c))","file":"src/api/status.ts"}],"file":"src/api/status.ts","kept":"status_incidents.","reads":"An operator's incident notice for the status page: title, affected lanes and surfaces, impact, status and update text.","then":"Checked for an operator token, validated against a strict schema with size caps and stored."},{"carries":"settings","evidence":[{"contains":"disclosureInput.parse(await readJson(c))","file":"src/api/disclosure.ts"}],"file":"src/api/disclosure.ts","kept":"provider_disclosure.","reads":"A provider disclosure profile written by an operator.","then":"Validated and stored."},{"carries":"settings","evidence":[{"contains":"parse(await readJson(c))","file":"src/api/dayzero.ts"}],"file":"src/api/dayzero.ts","kept":"The lane tables.","reads":"An operator's request to evaluate or approve a day-zero candidate.","then":"Validated and stored."},{"carries":"settings","evidence":[{"contains":"parse(await readJson(c))","file":"src/api/creator-claims.ts"}],"file":"src/api/creator-claims.ts","kept":"lane_claims.","reads":"A creator claim: model, wallet address and Hugging Face handle.","then":"Validated and stored."},{"carries":"public-data","evidence":[{"contains":"const body = await readJson(c);","file":"src/api/host-anchor.ts"}],"file":"src/api/host-anchor.ts","kept":"Nothing.","reads":"A request for an inclusion proof: a receipt envelope from an attested host (hashes and counts, no text) or a leaf hash.","then":"Looked up in host_anchor_leaves and answered."},{"carries":"settings","evidence":[{"contains":"const body = await readJson(c);","file":"src/api/ipx.ts"}],"file":"src/api/ipx.ts","kept":"The halt flag in the kv table.","reads":"An operator's switch that halts or resumes the index-price oracle.","then":"Checked for an operator token and stored."},{"carries":"payment-or-signature","evidence":[{"contains":"const body = await readJson(c);","file":"src/api/paymaster.ts"}],"file":"src/api/paymaster.ts","kept":"Nothing beyond the Redis rate-limit key.","reads":"A paymaster (gas sponsorship) request.","then":"Checked and answered."},{"carries":"payment-or-signature","evidence":[{"contains":"const raw = await readJson(c);","file":"src/api/public.ts"}],"file":"src/api/public.ts","kept":"The provider and pay-with tables described above.","reads":"Receipt verification requests, pay-with authorisations, provider applications and creator claim challenges.","then":"Verified and, for a provider application or a pay-with authorisation, stored."},{"carries":"payment-or-signature","evidence":[{"contains":"const body = await readJson(c);","file":"src/blind/routes.ts"}],"file":"src/blind/routes.ts","kept":"Nothing that links the buyer to the token.","reads":"A blinded token request.","then":"Signed by the issuer."},{"carries":"public-data","evidence":[{"contains":"const body = c.req.raw.body;","file":"src/tlog/routes.ts"}],"file":"src/tlog/routes.ts","kept":"tlog_cosignatures.","reads":"A signed checkpoint note from a witness (16 KB at most).","then":"Verified and stored as a cosignature."}],"browser":{"items":[{"evidence":[{"contains":"Runtime requests never populate Cache Storage.","file":"web/lib/harness-sw.js"},{"contains":"if (actual !== expected) throw new Error('Shell content changed');","file":"web/lib/harness-sw.js"}],"holds":"The installable Harness keeps only the static app shell, offline page, scripts, styles, fonts and icons in a browser cache named anyroute-shell- followed by a build digest. Each cached file must match its exported SHA-256. Requests, replies, API responses and URLs with query strings are never cached. A new active app version removes older app caches; browser settings can clear them at any time. No additional data is stored by the router.","store":"Cache Storage"},{"evidence":[{"contains":"sessionStorage.setItem(keyStore, secret);","file":"web/lib/api.js"}],"holds":"The API key you pasted into the dashboard, for the length of the tab. It is removed when the tab closes and is never written to localStorage.","store":"sessionStorage"},{"evidence":[{"contains":"localStorage.setItem(k, JSON.stringify(v));","file":"web/components/Harness.jsx"},{"contains":"Eval sets live in localStorage","file":"web/components/features/EvalLab.jsx"}],"holds":"The Harness favourite models and view preferences, and the Eval Lab evaluation sets you write. Eval Lab results are kept in IndexedDB. The router never receives them; only the requests you run do.","store":"localStorage"}],"summary":"What this website keeps in your own browser. None of it is sent to us except the requests you make."},"logs":{"caveats":["The text of an unexpected exception is logged as the library wrote it (src/app.ts unhandled error, src/lib/process-guard.ts uncaught exception, job failures). No code path puts request text into an error message on purpose, but only configured private chain RPC URLs are filtered, and a library error could quote a fragment of what it was parsing.","The hosting platform's own network layer sees connection addresses and may keep its own access logs. This inventory covers what the router's code records; it cannot describe the platform's logs."],"evidence":[{"contains":"(level === \"error\" || level === \"warn\" ? console.error : console.log)(line);","file":"src/lib/util.ts"},{"contains":"const line = JSON.stringify(redactRpcFields({ t: new Date().toISOString(), level, msg, ...fields })","file":"src/lib/util.ts"}],"format":"JSON lines: { t, level, msg, ...fields }.","never_records":[{"evidence":[{"contains":"return { id: clientIp(c, cfg.trustProxy), onion: false","file":"src/api/common.ts"}],"item":"Client network addresses. No log call passes one; addresses are used for rate limits and direct private-network ingress checks."},{"evidence":[{"contains":"log.error(\"unhandled error\", { path: new URL(c.req.url).pathname","file":"src/app.ts"}],"item":"Request or response bodies and prompts. The unhandled-error line takes the path and the error, not the body."},{"evidence":[{"contains":"Never logged: keys, message text, the bot token","file":"src/services/telegram.ts"}],"item":"Request headers, cookies and API keys. The Telegram bot states the same rule for its own lines."},{"evidence":[{"contains":".pathname, error: (err as Error)?.message","file":"src/app.ts"}],"item":"Query strings: only the pathname of a failing request is logged."}],"records":["A provisional deposit reversal logs its durable chain/lane/transaction/log identifier once when the reversing ledger entry commits. A separate durable check per reversal enters the existing operator alert notifier; notifications require an operator webhook and are at-least-once on delivery failure or a crash.","The time, the level and a message written in the code.","Anonymous limiter failure: fixed warning that a request was allowed; no exception, address, header, key or body.","Host slash dry-run intent: provider id, evidence commitment root, proposeSlash function name, whole-bond USDG amount, numeric contract reason, contract and chain id, bytes32 host id and delist flag. Logged once per evidence root; no signed bytes, key, raw quote or receipt envelope.","Sanctions refresh counts (distinct EVM entries, ignored formats and digital currency entries), publication date and source hash; screening skip/refusal reasons and provider ids. Freshness exceptions for previously paid addresses and refresh failures use fixed reason codes. No payout wallet or identity fields are added to these logs.","Identifiers and counts: provider ids, model ids, job names, hold and generation ids, epochs, block numbers, transaction hashes, hashed key ids and, on rare settlement and escrow events, an account id.","Wallet addresses of payers on pay-per-call and pay-with events (public on chain).","For an unhandled error: the path of the request without its query string, the error message and the first five lines of the stack.","Error messages from libraries and upstream services, each cut to 200 characters where a call site truncates them. Configured private chain RPC URLs, including paths and queries on the same host, are redacted before log emission; chain transport failures are redacted before callers truncate them."],"retention":"The router does not rotate or store its logs: it writes them to standard output and the hosting platform keeps them under its own retention. No log retention is set in this repository.","summary":"The router writes one JSON line per event to standard output (standard error for warnings and errors). A line is a time, a level, a fixed message and a few fields chosen at each call site. No call site writes a request or response body, a header, a client address, a query string or a prompt."},"other_stores":[{"evidence":[{"contains":"export async function readFunnel","file":"src/rush/funnel.ts"},{"contains":"export const CATALOG_TTL_MS = 30_000","file":"src/rush/cache.ts"},{"contains":"export const CREDIT_HOLD_MS = 5 * 60_000","file":"src/rush/monitor.ts"},{"contains":"c.header(\"cache-control\", \"no-store\")","file":"src/admin/trpc.ts"}],"holds":"Daily counts and dates; latest upstream USD balances, check states and hold expiry times on the operator surface only. In memory the enabled monitor reads the existing encrypted provider credential and configured headers to authenticate a documented balance check; neither credential nor upstream response text is retained in the new state or logs. API replicas refresh balances and temporary holds on health flushes; catalogue requests also refresh them before reading the cache, with starts at least five seconds apart per process. Both catalogue routes share one in-flight refresh promise and its monotonic start time in memory; failed reads preserve the previous availability state. Changed exhausted state invalidates that process’s catalogue cache. The catalogue cache holds up to 64 public catalogue JSON variants and 64 in-flight computations, keyed only by the four supported public catalogue filters. It contains catalogue metadata, prices, capabilities and provider evidence, never inference text or caller addresses. No new table, column or Redis family.","id":"rush-operations","name":"Operator capacity and daily counts","purpose":"The operator-only GET /trpc/rush reads daily aggregate milestones over at most 90 UTC days. New wallet sign-ins mean wallet accounts created with a management key at the same transaction timestamp; an account created earlier by a deposit is excluded. First credited deposits mean the first positive deposit, stock_deposit, anyr_deposit or usdg_deposit ledger row per account. First successful calls mean the first signed generation per account that was not cancelled and did not finish with an error. Earlier retained rows are checked to exclude repeats; deleted historical records cannot be reconstructed. No per-account rows leave these queries.","request_text":"none","ttl":"Aggregate responses discarded after delivery with no-store. Catalogue JSON expires after 30 seconds, successful catalogue sync or an observed exhausted-state change; process memory disappears on exit. Failure-based routing holds expire after five minutes; exhausted balance readings persist until a reading exceeds the configured threshold. Balance readings and alert delivery times are overwritten in place and remain until operator deletion. Existing source retention applies."},{"evidence":[{"contains":"const publicCache = new Map<string, { at: number; items: CatalogItem[] }>();","file":"src/tools/catalog.ts"}],"holds":"Public tool names, summaries, addresses, prices and payTo wallets. No caller data.","id":"public-tool-catalog","name":"Public tool catalog in the router's memory","purpose":"When TOOLS_PUBLIC_CATALOG_URL is set, the router fetches that public x402 catalog through the egress guard to answer tool searches.","request_text":"none","ttl":"TOOLS_PUBLIC_CATALOG_TTL_S (900 seconds by default); a failed refresh keeps the previous copy; lost on restart."},{"evidence":[{"contains":"export async function runWebhooks","file":"src/webhooks/worker.ts"},{"contains":"const wire = secret ?","file":"src/webhooks/delivery.ts"},{"contains":"export async function recordHostStatus","file":"src/webhooks/hosts.ts"},{"contains":"export async function recordApprovalWebhook","file":"src/webhooks/approvals.ts"}],"holds":"Decrypted URLs and signing secrets enter router process memory only for delivery or credential issuance. Account wallet and host operator addresses are read by the status-write hook to match operated hosts. No prompt/answer is added to deliveries, and no arbitrary response or transport error text is logged. The browser holds a newly revealed signing secret in component memory until dismissed, disconnected or navigation; it is not written to browser storage.","id":"signed-webhooks","name":"Signed account event delivery","purpose":"When WEBHOOK_SIGNING_ENABLED is enabled, a minute worker reads at most 50 destinations, one 100-row activity page per destination, and sends at most 100 due notices per tick. Activity readers retain account, key, team and wallet-party guards. It delivers metadata references, fixed types/statuses and timestamps; existing Spend Watch and agent delivery retain their original alert fields. Signing covers exact wire JSON bytes plus a timestamp. The signed body binds event_id to the header. Secrets use the existing APP_SECRET encryption helper. Legacy URLs remain unsigned until rotation. Revocation stops future deliveries; an already in-flight request can finish. The disabled flag retains original alert delivery without signing, imports or worker writes.","request_text":"none","ttl":"Activity discovery begins at destination creation, uses five minutes of overlap and durable pagination, and can miss source rows removed before discovery or commits delayed beyond the overlap. Approval requests/decisions and operated host status changes enqueue references in the transaction that records the change, so changes between worker ticks are retained. Approval references are approval ids. Direct database writes outside the router do not generate these notices. Delivery can repeat after a crash before result persistence: receivers must verify exact bytes with a five-minute timestamp tolerance and atomically deduplicate event ids. Delivery metadata is retained for 90 days; the API shows 100 attempts. Three attempts per event, five minutes apart. Owner-requested connectivity notices are limited to one per destination per minute."},{"evidence":[{"contains":"export async function noteServedCall","file":"src/services/makegood.ts"},{"contains":"export async function issueRefund","file":"src/services/makegood.ts"},{"contains":"export async function runMakegoodPayouts","file":"src/services/makegood.ts"}],"holds":"Rule decisions use token counts, prices, provider ids, error classes, lane and attestation results already in router memory. The JSON rule parses the repair answer in memory only to decide whether it is JSON; the text is not stored. Refund rows keep amounts, fixed codes, ids, transaction hashes and the payer wallet address for on-chain refunds. The treasury key stays in worker memory and is never logged or stored; signed transfers are stored encrypted.","id":"makegood-refunds","name":"Make-good refund decisions","purpose":"With MAKEGOOD_ENABLED (off by default), the call finaliser, the all-providers-failed path and the JSON repair check record a pending candidate when a call meets a refund rule; the hourly settlement job issues it as a ledger line linked to the generation, a signed refund receipt naming the original receipt, a refund.issued webhook reference and, for a network host that caused it, review-only host slashing evidence. Calls paid on-chain per call are refunded by the makegood-payouts job from MAKEGOOD_REFUND_PRIVATE_KEY, which refuses to run without that key.","request_text":"none","ttl":"Refund rows and transfers are kept with the ledger (no automatic deletion). Webhook references follow the webhook delivery retention. No new Redis family or log field carries request text or a caller address."},{"evidence":[{"contains":"redirect: \"error\", signal: AbortSignal.timeout(timeoutMs)","file":"src/identity/liveness.ts"},{"contains":"await res.body?.cancel()","file":"src/identity/liveness.ts"}],"holds":"The status code, latency and a fixed failure code in agent_liveness with a signed probe receipt. The endpoint's operator sees the router's network address and the request.","id":"agent-liveness-probes","name":"Liveness probes to listed agent endpoints","purpose":"When AGENT_IDENTITY_ENABLED is on, the agent-liveness job sends one GET a day to each listed profile's owner-declared HTTPS endpoint, to a public address only (no redirects, a ten-second timeout by default), with a fixed Anyroute-Liveness user agent and no credentials, and does not read the response body.","request_text":"none","ttl":"Each probe replaces the previous result. Nothing is kept in memory between runs."},{"evidence":[{"contains":"export function registerCall","file":"src/identity/erc8004.ts"},{"contains":"export function giveFeedbackCall","file":"src/identity/erc8004.ts"}],"holds":"Public chain data: agent ids, registration URLs, wallets, scores, tags and document hashes. No key hash, account id, receipt id or amount is placed in calldata the router prepares.","id":"erc8004-registries","name":"ERC-8004 registries on Robinhood Chain","purpose":"An identity registration (owner-sent, or sent by the isolated registrar worker) writes a public, permanent record: the registration file URL, a metadata entry pointing at the router's receipt keys, and the holding wallet. Optional feedback and validation calldata the router prepares is sent only by the reviewer's or validator's own wallet.","request_text":"none","ttl":"Permanent on chain; opting out stops the router serving the registration file and links, but cannot remove a sent transaction."},{"evidence":[{"contains":"if (trees.size >= 32) trees.delete(trees.keys().next().value!);","file":"src/identity/track-record.ts"}],"holds":"Receipt anchor leaves (hashes) and generation ids of the certified key's counted receipts.","id":"track-record-trees","name":"Track-record Merkle trees in memory","purpose":"Proof requests rebuild a certificate's tree from the router's generation records and keep at most 32 trees in process memory.","request_text":"hashes","ttl":"Until evicted by newer trees or the process exits."},{"evidence":[{"contains":"export async function readActivity","file":"src/activity/read.ts"},{"contains":"c.header(\"cache-control\", \"no-store\")","file":"src/api/activity.ts"}],"holds":"Times, fixed event titles, exact signed USDG amounts, model and provider ids, recorded lanes, key names or existing short labels, receipt references, status and approval limits. It reads account wallet addresses and existing on-chain payer/payee and deposit sender addresses to select matching records, without returning those addresses. Agreement amounts describe wallet escrow movements, not router balance changes. It reads only model and lane from stored approval/policy intents and only lane from receipts; no request body, agreement evidence, delivery targets, key secrets or full key hashes enter the response. Oracle-only events require an indexed ruling linking their key to the agreement; until then they remain in the agreement view.","id":"account-activity-reader","name":"Account activity response in memory","purpose":"GET /api/v1/activity merges existing generations, ledger entries, agent approvals, policy events, the retained agent alert feed, spending alert history, escrow deposit statuses, key auto top-up records and wallet-party agreement events. Each source and response is limited to 100 rows. Ordinary and session keys read only their own key records; management and owner/admin keys read account records. Non-management administrators retain the agent routes' team boundary. Key and model filters further restrict results. Spending alerts keep their existing management-or-own-key boundary. CSV and JSON contain the same selected page; a cursor continues the filtered range.","request_text":"none","ttl":"Discarded after the response; cache-control is no-store. No new durable storage, logs or Redis keys. Downloads stay on the caller's device. Existing source retention still applies; the agent alert feed retains at most 100 records for 90 days and spending alerts retain up to 20 firings per rule."},{"evidence":[{"contains":"export async function readStatement","file":"src/statements/read.ts"},{"contains":"c.header(\"cache-control\", \"no-store\")","file":"src/api/statements.ts"}],"holds":"Account creation date, key hashes and existing names or labels, exact pico-USDG ledger totals converted to decimal strings, movement kinds, model ids and lanes from linked generation receipts, call counts and reconciliation results. Reads only lane from receipt JSON, no request text, wallet or network addresses, key secrets, ledger descriptions or receipt content hashes. Unrecorded group values are null. Key-only balances are attributed ledger sums rather than the shared account balance. Separate fee entries are distinguished from fees embedded in usage. Call time and settlement time can differ; external payments are outside the router balance ledger.","id":"monthly-statements","name":"Signed monthly statements in memory","purpose":"With STATEMENTS_ENABLED (off by default), GET /api/v1/statements/:month aggregates the existing ledger in one SQL snapshot and signs canonical JSON with the existing receipt signer. Management and owner/admin keys see account totals; ordinary and session keys see only movements attributed to their key. The account creation month sets the earliest readable month. UTC month bounds exclude the next month; the current month ends at the read time.","request_text":"none","ttl":"Discarded after response with cache-control no-store. No new tables, columns, Redis keys or log fields. Signing uses existing receipt key storage and retention. Downloaded JSON and printed statements remain on the caller's device; the signature is the router's statement, not an independent ledger audit."},{"evidence":[{"contains":"export async function exportAccount","file":"web/lib/account-export.js"}],"holds":"Existing endpoint response data, including key hashes, wallet metadata or addresses where the endpoints expose them, policies and readable policy-event intents, session metadata, approval intents, activity and agreement projection records, owned profile settings and signed statements. Key secrets and credential-shaped fields are stripped. Chat history, private files, saved content, raw statement ledger, agreement evidence and dispute details are outside this export. Approvals are limited by the existing endpoint to 100 per stored status. Agent events and profiles retain per-agent access errors in the bundle.","id":"account-data-export","name":"Account export on the caller's device","purpose":"The account shell builds a JSON bundle in the browser by paging existing authenticated read APIs. It includes accessible account and key metadata, rulebooks, policy events, sessions, approvals, activity, signed statements, wallet-party agreements and owned profile settings. A manifest describes included sections, access failures, retention and omitted records; this is not a complete storage dump.","request_text":"none","ttl":"Kept in browser memory during export, then downloaded as JSON to the caller's device. Cancel stops requests and prevents download. No new server-side bulk endpoint, persistence or logs. Existing endpoint and source retention apply; APIs are read sequentially, not in one database snapshot."},{"evidence":[{"contains":"export async function readProofPack","file":"src/proof-pack/read.ts"},{"contains":"c.header(\"cache-control\", \"no-store\")","file":"src/api/proof-pack.ts"}],"holds":"Generation ids, call times, key hashes, model and provider ids, mode, lane, exact charged amounts, the stored signed receipt payloads and COSE claims (request and response hashes, token counts or buckets, amounts, attestation references, and the payer key hash or per-call payer wallet and payment transaction a receipt was signed with), anchor roots, indexes and Merkle paths, refund receipts with their stored evidence and any on-chain refund wallet, signed statements, public receipt keys and the manifest of listed receipt ids and leaves. No request or answer text, key secrets or network addresses; recorded provider attempts are not read.","id":"proof-pack","name":"Proof pack in memory","purpose":"With STATEMENTS_ENABLED (off by default), GET /api/v1/proof-pack?from=&to= builds one JSON file for at most 31 UTC days: the calls Activity lists for the key's scope with their stored signed receipts and Merkle paths, issued refund receipts, the signed monthly statements covering the range, the published receipt keys, a lane report of the listed calls and a manifest signed with the existing receipt signer. Management and owner/admin keys read the account; ordinary and session keys read only their own key. A range with more than 2,000 calls, or calls under more than 200 anchors, is split into parts with a cursor.","request_text":"hashes","ttl":"Discarded after the response with cache-control no-store. No new tables, columns or log fields; one rate-limit counter per key. Downloaded files remain on the caller's device. Existing receipt, refund, ledger and anchor retention apply."},{"evidence":[{"contains":"export async function readLaneReport","file":"src/lane-report/read.ts"},{"contains":"c.header(\"cache-control\", \"no-store\")","file":"src/api/lane-report.ts"}],"holds":"Lane names read from receipt JSON, provider and model ids, call counts, exact charged amounts, the range and the key hash for key-scoped reports. No request or answer text, receipt hashes, key secrets or network addresses.","id":"lane-report","name":"Lane report in memory","purpose":"With STATEMENTS_ENABLED (off by default), GET /api/v1/lane-report?from=&to= groups the calls Activity lists for the key's scope over at most 31 UTC days by the lane each receipt records, provider and model, and returns calls and charged spend per lane, the share on the attested and unlinkable lanes, and per provider and model rows for those lanes with links to the provider's public attestation record. Management and owner/admin keys read the account; ordinary and session keys read only their own key. The proof pack carries the same summary for the calls in each file.","request_text":"none","ttl":"Discarded after the response with cache-control no-store. No new tables, columns or log fields; one rate-limit counter per key."},{"evidence":[{"contains":"export async function readInsights","file":"src/insights/read.ts"},{"contains":"c.header('cache-control','no-store')","file":"src/api/insights.ts"}],"holds":"Exact decimal charges, refunds, net spending, call and token counts, model ids, recorded lanes/disclosure classes, existing key names/short labels, and historical hardware-check counts from signed v1 receipts. Missing evidence and cache calls do not count as proven. An average includes its exact numerator/denominator and a decimal truncated to 12 places. It reads key hashes internally for grouping but returns response-local key numbers. Price comparisons read live catalog capabilities, endpoint lane/disclosure availability and token/request prices at the observed input/output mix; estimates exclude royalties, account fees, cache discounts, reasoning/media/search charges and refunds. No request text, wallet addresses, key secrets, new logs, tables, columns or Redis keys are read or written.","id":"spend-insights-reader","name":"Spend insights response in memory","purpose":"GET /api/v1/insights aggregates existing call charges and ledger refunds over at most 92 days, with UTC day or Monday-week buckets. It uses Activity's account-or-own-key access, including session restrictions. Each model/key breakdown includes the first 100 by cost or calls; totals include all visible records. Refunds count when posted; linked refunds use their generation's model and lane. Unlinked refunds have unknown model/lane.","request_text":"none","ttl":"Discarded after the response; cache-control is no-store. Existing source retention applies. No durable storage added."},{"evidence":[{"contains":"const CACHE_MS = 15_000;","file":"src/data-tools/stock.ts"},{"contains":"bodySha: sha256(`GET ${new URL(c.req.url).pathname}`)","file":"src/data-tools/charge.ts"},{"contains":"export const DATA_TOOL_KIND = \"data_tool\";","file":"src/data-tools/charge.ts"},{"contains":"if (!hit || Date.now() - hit.at > 60_000)","file":"src/data-tools/routes.ts"}],"holds":"Public chain readings per token (feed answer, decimals, update time, multiplier values, pause flags) and the read time, and the public index snapshot per class and hour. Nothing about the caller is kept here; the charge is the existing ledger line and, for per-call payments, the existing quote row with the payer's wallet address. No request text: these are GET requests without a body.","id":"data-tools-readings","name":"Market-data tool readings in memory","purpose":"When DATA_TOOLS_ENABLED is on, GET /api/v1/data/stock/:symbol and /actions read a Stock Token's Chainlink feed and its uiMultiplier, newUIMultiplier, effectiveAt, paused and oraclePaused views from Robinhood Chain; GET /api/v1/data/ipx/:class reuses the inference price index snapshot. A paid call is charged once, after the reading passed its checks: a prepaid key through the ordinary hold and ledger (kind data_tool), a keyless caller through the existing per-call payment, whose quote binds the method and path.","request_text":"none","ttl":"A token reading is reused for 15 seconds and an index snapshot for 60 seconds; both are lost when the router instance exits."},{"evidence":[{"contains":"export const DECISION_TAG_HEADER = \"x-anyroute-decision-tag\";","file":"src/receipts/decision-tag.ts"},{"contains":"if (tag && lane === \"unlinkable\")","file":"src/receipts/decision-tag.ts"},{"contains":"...decisionTagFields(decisionTagOf(ctx.cfg.decisionTagsEnabled, p.c, p.disc.lane))","file":"src/api/chat.ts"},{"contains":"and g.receipt->>'decision_tag' = ${tag}","file":"src/agents/guard-links.ts"}],"holds":"The 64-hex digest as sent, inside the generation's stored receipt and receipt_v2. Never the intent itself, which the router never receives.","id":"decision-tags","name":"Decision tags in signed receipts","purpose":"When DECISION_TAGS_ENABLED is on, a chat or completion call may send X-Anyroute-Decision-Tag: a SHA-256 digest the caller computed, for example of an order intent. The router signs it into that call's v1 and v2 receipts as decision_tag, so the caller can later show which model answered before a decision. A malformed tag is refused before anything is charged, and the unlinkable lane refuses a tag because a reused tag joins calls together. An Agent Guard decision whose details_sha256 equals a tag names the same agent's tagged calls as informed_by, and a proof pack lists the tags its receipts carry; both read the stored receipts and store nothing new.","request_text":"hashes","ttl":"Kept with the generation record and its receipt, under their existing retention."},{"evidence":[{"contains":"export async function readInbox","file":"src/inbox/read.ts"},{"contains":"inArray(p.status, [\"seen\", \"final\", \"reversed\"])","file":"src/inbox/read.ts"},{"contains":"c.header(\"cache-control\", \"no-store\")","file":"src/api/inbox.ts"},{"contains":"storage.setItem(prefix + result.seen_scope","file":"web/lib/inbox.js"}],"holds":"Fixed event titles, timestamps, recorded statuses, signed credited amounts, paid USDG amounts of agent payments, key names, approval ids, expiry and spending limits. Stored approval intents are read and projected to kind, model, lane, tool names, estimated cost and output limits; no request text or Telegram messages are added. Account wallet and provider operator addresses are read in memory to match this account's operated network hosts, without returning addresses or private provider configuration. Host items show current status at the provider record's update time, which can also change for reasons other than status; no transition history is inferred. A secret-keyed visibility digest separates account, team, management and ordinary/session key bookmarks, without exposing account ids or full key hashes.","id":"account-inbox-reader","name":"Account inbox response and browser seen time","purpose":"GET /api/v1/inbox reuses Activity's account, ordinary-key, session-key, team, spending-alert and wallet-party agreement visibility. It merges retained alerts, posted deposit credits, key auto top-ups, indexed disputes/rulings and, when AGENT_PAY_ENABLED, confirmed agent payments sent by this account's keys or received by a published wallet of its agents, since the browser's seen time, with unexpired pending approvals regardless of that time. It reads up to 100 records per activity kind and up to 100 pending approvals and operated host records; capped indicates a source may have more. The count describes returned items, not an unbounded total. Owner/admin access follows the existing agent decision endpoint, which remains the sole approval writer. POST /api/v1/inbox/seen authenticates the key and echoes a validated displayed-snapshot timestamp; it does not read a body or persist state.","request_text":"none","ttl":"Responses live in memory and use cache-control no-store. The browser stores only a last-seen timestamp under anyroute-inbox-seen-v1:<visibility digest> in local storage until browser data is cleared; items and API keys are not stored there. Bookmarks do not sync between browsers. Pending approvals remain counted until decided or expired. No new database table/column, Redis key family, log field or Telegram message storage. Existing source retention still applies."},{"evidence":[{"contains":"const states = new WeakMap<HealthView, State>();","file":"src/network/routing.ts"},{"contains":"state.evidence = new Map();","file":"src/network/routing.ts"},{"contains":"evidenceMaxAgeMs: 120_000","file":"src/network/weight-config.ts"}],"holds":"Provider ids, probation deadlines, aggregate attested success and recent outcome counts, fresh canonical active bond base units matched to the host id and operator wallet, probe availability and median latency, the latest attestation failure flag and refresh time. No request text or caller address. Successful network probes also record latency in the existing health table.","id":"network-routing-evidence","name":"Network host routing evidence in memory","purpose":"When NETWORK_HOSTS_ENABLED is on, routing uses existing signed generation records, health probes and attestation outcomes to limit admitted hosts during probation and exclude unavailable hosts.","request_text":"none","ttl":"Rebuilt by health refreshes, including idle flushes; evidence older than 120 seconds is refused. Failed refreshes clear the evidence. Lost when the router instance is released or exits."},{"evidence":[{"contains":"bytes.fill(0)","file":"scripts/network-join.ts"},{"contains":"X-Wallet-Auth","file":"scripts/network-join.ts"},{"contains":"if (o[\"--dry-run\"]) {","file":"scripts/network-join.ts"},{"contains":"export const safeOutput","file":"scripts/network-join.ts"},{"contains":"info.mode & 0o044","file":"scripts/network-join-credential.ts"},{"contains":"bytes.fill(0)","file":"scripts/network-join-credential.ts"},{"contains":"credential_configured !== true","file":"scripts/network-join.ts"}],"holds":"The operator’s existing wallet and sidecar key files or environment variables are left in place. The command reads the key and signup fields in process memory; the wallet address, timestamp and signature leave as authentication. The sidecar API key leaves in the credential request body and is stored in the router’s existing AES-GCM encrypted provider-key column; the router can decrypt it to call the sidecar. The command writes no key or signup file, logs no key and redacts loaded sidecar credentials (including JSON-escaped forms) and wallet-key-shaped output. Dry runs read neither key and show a redacted credential body, with the signup-assigned provider id still unknown. File read buffers are cleared, but JavaScript strings and signing-library memory cannot be reliably erased. Signup details and resulting status are printed to the operator’s terminal; the operator controls terminal retention. The router still reads inference request text in memory on every lane.","id":"network-join-operator","name":"Host registration on the operator’s computer","purpose":"The join command reads a dedicated operator wallet key from the explicitly selected file or environment variable and signs the router’s existing wallet-auth message. It optionally reads the host-generated sidecar API key from an explicitly selected UTF-8 file or environment variable, trims and validates it, and checks POSIX file read permissions. It submits host name, sidecar endpoint, payout address, model ids and optional contact to the selected router. After successful signup, or in credential-only mode, it sends the sidecar API key and provider id over HTTPS to the router’s existing wallet-authenticated credential endpoint; an explicitly selected loopback router may use HTTP. Status polling sends a provider id without a wallet key. It sends no inference text and no transactions.","request_text":"none","ttl":"Process memory lasts until the command exits. The key source and terminal history remain under the operator’s control. Router storage for host admission is described by the admission endpoint’s inventory when available."},{"evidence":[{"contains":"NETWORK_STATS_CACHE_MS = 30_000","file":"src/network/stats.ts"},{"contains":"PUBLIC_LANE_ROWS","file":"src/network/stats.ts"},{"contains":"const get = statsCache","file":"src/network/stats.ts"}],"holds":"Only the public aggregate response: snapshot time, host status counts, fresh admitted host count, distinct eligible model IDs, 100,000-token ranges from retained public-lane generation counts, indexer total/active USDG bonds with freshness and block, waitlist counts and published policy version. Private-lane generation rows are excluded; existing router-wide DP releases cannot identify network-host totals. Database query results and public admission evidence are read temporarily to form the snapshot. The host query selects no credentials, operator wallets or contact fields. The existing bond adapter reads public on-chain projection metadata, which can include operator addresses; only aggregate amounts, freshness and indexed block enter this cache. No inference text or caller address is read. No new database rows, Redis keys or log fields.","id":"network-stats-cache","name":"Public network statistics in router memory","purpose":"When NETWORK_STATS_ENABLED is on, cache read-only network statistics and share one refresh among concurrent readers.","request_text":"none","ttl":"Cache freshness ends 30 seconds after refresh begins, with no stale-on-error serving. The single expired snapshot may remain allocated until replaced or the router exits. Query results are eligible for collection after refresh; process exit releases all cache memory."},{"evidence":[{"contains":"export const COMMERCE_STATS_CACHE_MS = 60_000;","file":"src/commerce/stats.ts"},{"contains":"const get = statsCache(() => readCommerceStats(ctx), Date.now, COMMERCE_STATS_CACHE_MS);","file":"src/commerce/stats.ts"},{"contains":"nothing it returns names a payer, a payee","file":"src/commerce/ledger.ts"}],"holds":"Only the public aggregate response: snapshot time, receipt kinds, filter settings and transfer-index position, and per window and kind the gross and filtered settlement, distinct payer and payee counts, USDG volume, median price, refund count and rate, and the count excluded by each rule. To build it, the router reads in memory the payer and payee wallet or account identifiers, amounts, times, transaction hashes, anchor status and refund flags of settled payments, and public USDG transfers; none of these enter the cache. Figures are never split by privacy lane, so a private-lane settlement cannot be told apart. No inference text or caller network address is read. No Redis keys. A failed refresh logs one warning with the first line of the error, cut to 200 characters; database errors put the query text on that line, not its parameters.","id":"commerce-stats-cache","name":"Public commerce ledger in router memory","purpose":"When COMMERCE_STATS_ENABLED is on, cache the public commerce ledger and share one refresh among concurrent readers.","request_text":"none","ttl":"Cache freshness ends 60 seconds after refresh begins, with no stale-on-error serving. The single expired snapshot may remain allocated until replaced or the router exits. Settlement rows read for a refresh are eligible for collection when it ends."},{"evidence":[{"contains":"cipher.setAAD(aad(compose))","file":"sidecar/src/agent/credential-store.ts"},{"contains":"headers.set(\"authorization\", `Bearer ${credential}`)","file":"sidecar/src/agent/runtime.ts"}],"holds":"An encrypted credential file in the VM's sealed volume. Raw credential and guest-derived key enter process memory during provisioning or boot; the API credential is sent to AnyRoute as Bearer authentication over TLS. The agent container receives no credential. Provisioning input, guest console retention and any owner-held credential copies remain the owner's responsibility. VM software and administrators can access guest memory. JavaScript strings cannot be reliably erased. No prompt or answer file is written by the sidecar.","id":"sealed-agent-sidecar","name":"Owner's sealed agent VM","purpose":"The dedicated agent sidecar uses the guest agent's application-scoped GetKey with a measured-compose-specific path to seal a provisioned AnyRoute credential with AES-256-GCM. It obtains TDX quotes committing the key fingerprint, image, measured compose, version and TLS key. The internal proxy forwards agent request and response streams to fixed paths at the configured HTTPS router origin.","request_text":"request-and-answer-text","ttl":"Ciphertext survives restarts until volume removal or replacement. Memory lasts for the sidecar process; the KMS key is scoped to app identity and a path containing the measured compose. Manifest changes require fresh provisioning. No anti-rollback guarantee is provided."},{"evidence":[{"contains":"mapping(uint256 => Agreement) public agreements","file":"contracts/src/agents/AgreementEscrow.sol"},{"contains":"event DisputeOpened","file":"contracts/src/agents/AgreementEscrow.sol"},{"contains":"uint256 disputedAt","file":"contracts/src/agents/AgreementEscrow.sol"},{"contains":"event StaleDisputeResolved","file":"contracts/src/agents/AgreementEscrow.sol"},{"contains":"struct Vote","file":"contracts/src/agents/DisputeOracle.sol"},{"contains":"event TallyRecorded","file":"contracts/src/agents/DisputeOracle.sol"},{"contains":"console2.log","file":"contracts/script/DeployAgreements.s.sol"}],"holds":"Public permanent blockchain state, transaction calldata and events: payer, payee, token, escrow, oracle, owner, panel and jury wallet addresses; agreement and milestone ids; amounts, deadline, immutable review window and dispute timeout, delivery and dispute-opening timestamps and status; terms and deliverable digests, opening evidence digest and evidence root; jury version, signer order, threshold, participation and consensus bitmaps, signed per-signer basis-point verdicts, tally digest, final verdict, neutral stale-dispute 50/50 recovery events and payouts; a panel-pending tally remains historical metadata after escrow recovery. The digest fields accept arbitrary caller-supplied bytes32 values; they do not prove the absence of encoded text or conceal low-entropy content. Evidence text is not required by the contracts, and any off-chain jury service needs its own retention disclosure. Deployment prints only escrow and oracle addresses.","id":"agreement-contracts","name":"Agreement escrow and dispute records on chain","purpose":"Agreements are switched on at anyroute.tech, with the escrow and dispute contracts deployed on Robinhood Chain. A payer funds individual milestones in USDG and an oracle can pay only that agreement's payer or payee. The optional agreements service indexes this public state, stores party evidence and model verdict statements, and prepares payer-signed funding transactions; its separate database and reader disclosures appear in this inventory.","request_text":"hashes","ttl":"Permanent public chain history; the contracts have no deletion function. When enabled, the agreement service indexes chain records into the separately described agreement tables."},{"evidence":[{"contains":"cached = { until: Date.now() + 60_000, rows: json.data }","file":"packages/private/src/messages.ts"},{"contains":"leaseBudget(budget: bigint","file":"packages/private/src/store.ts"},{"contains":"countMessageTokens(JSON.parse","file":"packages/private/src/proxy.ts"}],"holds":"The public unlinkable model directory in memory. The existing local tokens.json file atomically moves every selected bearer token to unconfirmed before sending; uncertainty keeps all members there, while a definite unserved refusal returns them. No request or answer text is written to that file or logged.","id":"messages-proxy-prices","name":"Messages proxy prices on the caller's computer","purpose":"The local proxy estimates a Messages budget using model prices fetched over Tor. The request text, code, tool schemas and results are read in memory to count tokens, then forwarded over Tor; count_tokens is answered locally without any network request.","request_text":"none","ttl":"Model prices are refreshed after one minute and lost on process exit. Local token credentials remain until expiry filtering, successful settlement or removal by the caller; uncertain sent sets are never automatically reused."},{"evidence":[{"contains":"private mem = new Map<string, { fields: Map<string, string>; expires: number }>();","file":"src/services/batches.ts"}],"holds":"The same sealed requests and answers as the Redis keys batch:<batch id>:in and :out.","id":"batch-memory","name":"Batch requests and answers in the router's memory, without Redis","purpose":"Without Redis (a single router in development), the Batch API keeps the same sealed requests and answers in the router process's memory instead.","request_text":"request-and-answer-text","ttl":"The sealed requests are deleted when the batch finishes; the sealed answers BATCH_RESULTS_TTL after that (86,400 seconds, 24 hours, unless the operator changed it). A batch that never finishes ends when its 24-hour completion window closes, so nothing outlives the window plus that time. A restart loses them."},{"evidence":[{"contains":"constructor(private secret: string, private maxEntries = 5_000","file":"src/gateway/cache.ts"},{"contains":"cache: new ResponseCache(cfg.appSecret, 5_000, redis)","file":"src/app.ts"}],"holds":"The same sealed answer as the Redis entry, and for the semantic mode a hashed word vector of the prompt.","id":"response-cache-memory","name":"Response cache in the router's memory","purpose":"The opt-in response cache also keeps each entry in the router process's memory (up to 5,000 entries), whether or not Redis is configured.","request_text":"answer-text","ttl":"An entry is not served after its time-to-live, but it stays in memory until newer entries push it out (oldest first, at 5,000) or the process restarts."},{"evidence":[{"contains":"const seen = new Map<string, number>();","file":"src/api/auth.ts"},{"contains":"This remembers recent ones in","file":"src/ohttp/replay.ts"}],"holds":"SHA-256 digests of a wallet address, timestamp and request hash, and of the first bytes of an encapsulated request. Not the request.","id":"replay-memory","name":"Replay guards in memory","purpose":"Two small in-memory sets stop replays: a used wallet signature (when Redis is not configured) and an Oblivious HTTP encapsulated request prefix.","request_text":"hashes","ttl":"Ten minutes for a wallet signature (old entries are swept once the set passes 50,000); until the key's acceptance window ends for an encapsulated request, with at most 100,000 kept."},{"evidence":[{"contains":"What it keeps: four families of counters for the current hour, and nothing else.","file":"src/lib/dpstats.ts"},{"contains":"The router still keeps its per-request rows for billing","file":"src/services/private-stats.ts","note":"The private lanes still leave the per-request rows described under Postgres; only the published aggregates are noisy."}],"holds":"Four families of counts for the current hour, released once with noise when the hour ends; the raw counts are then discarded.","id":"private-lane-counters","name":"Private-lane counters in memory","purpose":"Differentially private hourly counters for the attested and unlinkable lanes: how many requests, how many were refused and why, latency and token buckets. They contain no request, no address, no key and no timestamp finer than an hour.","request_text":"none","ttl":"Released hours are kept for 48 hours; the privacy-budget ledger for 30 days."},{"evidence":[{"contains":"if (!privateLane) ctx.telemetry.span(\"chat \" + r.model.id","file":"src/api/chat.ts"},{"contains":"p.c.req.header(\"traceparent\")?.split(\"-\")[1]","file":"src/api/chat.ts"},{"contains":"Spans never carry prompt or completion content.","file":"src/gateway/otel.ts"}],"holds":"The attributes listed, buffered in memory for up to five seconds before export.","id":"telemetry","name":"Trace export (OpenTelemetry), off unless an endpoint is set","purpose":"When OTEL_EXPORTER_OTLP_ENDPOINT is set, one span per chat or text-completion call is sent to that endpoint: model, provider, token counts, cost, generation id, mode, attempt count, whether it streamed, and the trace id from a traceparent header if the caller sent one. Calls on the attested and unlinkable lanes send no span. Spans carry no prompt or completion.","request_text":"none","ttl":"In memory for seconds; kept by whatever receives it, which the operator chooses."},{"evidence":[{"contains":"if (billing.key?.tracing && shouldExportTrace({ lane: p.disc.lane, privateLaneRequest: privateLane, privateRoute }))","file":"src/api/chat.ts"},{"contains":"export function shouldExportTrace(o: { lane: string; privateLaneRequest: boolean; privateRoute: boolean }) {","file":"src/services/tracing.ts"},{"contains":"if (!stored.include_content) {","file":"src/services/tracing.ts"}],"holds":"The listed fields of recent calls, in a bounded in-memory queue (2,000 calls at most across all keys; more are dropped and counted) until they are delivered or given up.","id":"customer-tracing","name":"Trace export to a key owner's own destination, off unless the owner sets one","purpose":"A key's owner can set a tracing destination on the key (their OpenTelemetry collector, Langfuse or Helicone). Each public-lane call made with that key is then sent there: model, provider, token counts, sampling settings, finish reason, latency, cost, receipt id and lane. Prompt and completion text is included only if the owner set include_content. Calls on the attested and unlinkable lanes are never sent.","request_text":"answer-text","ttl":"In memory for seconds, or until retries end; kept by the destination the key's owner chose."},{"evidence":[{"contains":"The private age identity never belongs on this host","file":"scripts/backup-offsite.ts"},{"contains":"pg_dump custom-format archive encrypted to public age recipients","file":"scripts/backup-offsite.ts"}],"holds":"The database as it was when the backup ran.","id":"backups","name":"Encrypted database backups","purpose":"A scheduled pg_dump (daily in the reference deployment) of the whole database, encrypted to public age recipients and uploaded to S3-compatible storage. Every table listed on this page is in it. The private key that opens it is never on the host that makes the backup.","request_text":"none","ttl":"The code writes each archive under a new key and never deletes one; how long archives last is set by the storage bucket's own rules, which are not in this repository."}],"redis":{"families":[{"evidence":[{"contains":"ctx.limiter.take(`anon:${from.id}`","file":"src/hardening/middleware.ts"},{"contains":"await this.redis.pexpire(k, windowMs + 1000)","file":"src/lib/ratelimit.ts"}],"holds":"address","key":"rl:anon:<caller address or onion>:<window start>","limiter_prefix":"anon:","purpose":"Anonymous public API reads and MCP messages share one per-client minute counter. Valid API keys retain their existing limits. Tor shares a separate onion counter with ONION_POOL_MULTIPLIER times the limit. Authenticated in-process dispatch and direct private-network traffic without forwarding headers are exempt.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`tools-call:${key.keyHash}`","file":"src/tools/call.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts"},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts"}],"holds":"key-hash","key":"rl:tools-call:<key hash>:<window start>","limiter_prefix":"tools-call:","purpose":"Paid tool calls per minute for one API key (60).","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`tools-list:${key.accountId}`","file":"src/tools/routes.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts"},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts"}],"holds":"account","key":"rl:tools-list:<account id>:<window start>","limiter_prefix":"tools-list:","purpose":"Tool listings per hour for one account (20); each listing asks the tool for its quote.","ttl":"3,601 seconds (the 3,600-second window plus one second)","window_seconds":3600},{"evidence":[{"contains":"await ctx.limiter.take(`agent-pay:${key.keyHash}`","file":"src/api/agent-pay.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts"},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts"}],"holds":"key-hash","key":"rl:agent-pay:<key hash>:<window start>","limiter_prefix":"agent-pay:","purpose":"Payment confirmations and reads per minute for one agent key (60); each can read the chain.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`agent-certificate:${key.accountId}`","file":"src/api/agent-certificates.ts"},{"contains":"await ctx.limiter.take(`agent-certificate:${key.accountId}`","file":"src/agents/profiles.ts"},{"contains":"await ctx.limiter.take(`agent-certificate:${key.accountId}`","file":"src/identity/track-record.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"account","key":"rl:agent-certificate:<account id>:<window start>","limiter_prefix":"agent-certificate:","purpose":"Record-certificate and track-record issuance attempts: five per minute per account, shared across standalone, profile and track-record issuance, its keys and router replicas. Contains only the account id and a counter; no certificate pseudonym, claims or stats.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`agent-replay:${caller.keyHash}`","file":"src/api/agents.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"key-hash","key":"rl:agent-replay:<caller key hash>:<window start>","limiter_prefix":"agent-replay:","purpose":"Rulebook replays (POST /api/v1/agents/:key_hash/replay), ten per minute per calling key. Contains only the caller's key hash and a counter; no draft, call or result.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`agent-feedback:${reviewer.accountId}`","file":"src/identity/routes.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts"},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts"}],"holds":"account","key":"rl:agent-feedback:<account id>:<window start>","limiter_prefix":"agent-feedback:","purpose":"Paid-feedback submissions, thirty per minute per reviewing account. Contains only the account id and a counter.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`proof-pack:${key.keyHash}`","file":"src/api/proof-pack.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts"},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts"}],"holds":"key-hash","key":"rl:proof-pack:<key hash>:<window start>","limiter_prefix":"proof-pack:","purpose":"Proof pack downloads, ten per minute per API key. Contains only the key hash and a counter.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`lane-report:${key.keyHash}`","file":"src/api/lane-report.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts"},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts"}],"holds":"key-hash","key":"rl:lane-report:<key hash>:<window start>","limiter_prefix":"lane-report:","purpose":"Lane reports, thirty per minute per API key. Contains only the key hash and a counter.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"ctx.limiter.take(`telegram-link:${action}:${actor}`","file":"src/telegram/linking.ts"}],"holds":"telegram-user","key":"rl:telegram-link:<action>:<account or Telegram user id>:<window start>","limiter_prefix":"telegram-link:","purpose":"Account link-code issuance (five per minute per account), code consumption (ten per minute per Telegram user) and approval callbacks (twenty per minute per Telegram user). Only identifiers and counters, no code or message text.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`facilitator:${from.id}`","file":"src/facilitator/routes.ts"}],"holds":"address","key":"rl:facilitator:<caller address or onion>:<window start>","limiter_prefix":"facilitator:","purpose":"Facilitator requests per caller address per minute (FACILITATOR_RPM, 120 by default), a bucket apart from the API's. The raw address is part of the key; over Tor the shared onion bucket is used.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`facilitator-payer:${payer.toLowerCase()}`","file":"src/facilitator/routes.ts"}],"holds":"wallet","key":"rl:facilitator-payer:<payer wallet>:<window start>","limiter_prefix":"facilitator-payer:","purpose":"Verify and settle calls per payer wallet per minute, so one payer cannot drain the relay with tiny payments. Links calls by the public payer wallet.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`facilitator-seller:${payTo.toLowerCase()}`","file":"src/facilitator/routes.ts"}],"holds":"wallet","key":"rl:facilitator-seller:<payTo wallet>:<window start>","limiter_prefix":"facilitator-seller:","purpose":"Verify and settle calls per seller payTo wallet per minute.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`facilitator-listing:${listing.payTo}`","file":"src/facilitator/routes.ts"}],"holds":"wallet","key":"rl:facilitator-listing:<payTo wallet>:<window start>","limiter_prefix":"facilitator-listing:","purpose":"Signed listing writes per payTo wallet per hour (FACILITATOR_LISTINGS_PER_HOUR).","ttl":"3,601 seconds (the 3,600-second window plus one second)","window_seconds":3600},{"evidence":[{"contains":"await ctx.limiter.take(`network-host-wallet:${auth.wallet}`","file":"src/api/network-hosts.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"wallet","key":"rl:network-host-wallet:<operator wallet>:<window start>","limiter_prefix":"network-host-wallet:","purpose":"Wallet-authenticated host signup and credential updates, three per minute per wallet. Links attempts by the public operator wallet.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`network-host-address:${from.id}`","file":"src/api/network-hosts.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"address","key":"rl:network-host-address:<caller address or onion>:<window start>","limiter_prefix":"network-host-address:","purpose":"Host signup and credential attempts, ten per minute per network address, with the existing scaled shared onion bucket. The raw address is temporarily part of the Redis key.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`network-waitlist:${bucket}`","file":"src/network/waitlist.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"digest","key":"rl:network-waitlist:<minute-keyed address digest or onion>:<window start>","limiter_prefix":"network-waitlist:","purpose":"Waitlist POST and DELETE requests, ten per minute per address; onion requests share the existing scaled onion bucket. A secret-keyed HMAC rotates every minute; no raw IP or user agent is stored. The digest still links requests within that minute.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await limitOrThrow(ctx, `ip:${from.id}`","file":"src/api/chat.ts"},{"contains":"await ctx.limiter.take(`ip:${from.id}`","file":"src/api/embeddings.ts"},{"contains":"await ctx.limiter.take(`ip:${from.id}`","file":"src/api/rerank.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"address","key":"rl:ip:<caller address>:<window start>","limiter_prefix":"ip:","purpose":"Requests per minute for a call that carries no API key. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await limitOrThrow(ctx, `blind-ip:${from.id}`","file":"src/api/chat.ts"},{"contains":"await ctx.limiter.take(`blind-ip:${from.id}`","file":"src/api/embeddings.ts"},{"contains":"await ctx.limiter.take(`blind-ip:${from.id}`","file":"src/api/rerank.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"address","key":"rl:blind-ip:<caller address>:<window start>","limiter_prefix":"blind-ip:","purpose":"Requests per minute for a call paid with a blind token. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`newkey:${from.id}`","file":"src/api/keys.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"address","key":"rl:newkey:<caller address>:<window start>","limiter_prefix":"newkey:","purpose":"New API keys per hour. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.","ttl":"3,601 seconds (the 3,600-second window plus one second)","window_seconds":3600},{"evidence":[{"contains":"await ctx.limiter.take(`wallet-login:${from.id}`","file":"src/api/keys.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"address","key":"rl:wallet-login:<caller address>:<window start>","limiter_prefix":"wallet-login:","purpose":"Wallet sign-in challenges per minute. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`team-auth:${from.id}`","file":"src/api/teams.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"address","key":"rl:team-auth:<caller address>:<window start>","limiter_prefix":"team-auth:","purpose":"Team join and sign-in attempts per minute (passkey or wallet), which need no API key. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`pm:${from.id}`","file":"src/api/paymaster.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"address","key":"rl:pm:<caller address>:<window start>","limiter_prefix":"pm:","purpose":"Paymaster requests per minute. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"`ohttp-gw:ip:${from.id}`","file":"src/ohttp/gateway.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"address","key":"rl:ohttp-gw:ip:<caller address>:<window start>","limiter_prefix":"ohttp-gw:ip:","purpose":"Oblivious HTTP gateway requests per minute from a client that did not come through an authenticated relay. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"`ohttp-gw:relay:${relay.keyId}`","file":"src/ohttp/gateway.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"nothing-personal","key":"rl:ohttp-gw:relay:<relay key id>:<window start>","limiter_prefix":"ohttp-gw:relay:","purpose":"Oblivious HTTP gateway requests per minute for one authenticated relay. It names the relay, not the clients behind it.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`tlog-cosign:${from.id}`","file":"src/tlog/routes.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"address","key":"rl:tlog-cosign:<caller address>:<window start>","limiter_prefix":"tlog-cosign:","purpose":"Transparency-log cosignature submissions per minute. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`claim-issue-ip:${from.id}`","file":"src/services/creators.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"address","key":"rl:claim-issue-ip:<caller address>:<window start>","limiter_prefix":"claim-issue-ip:","purpose":"Creator claim challenges per hour. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.","ttl":"3,601 seconds (the 3,600-second window plus one second)","window_seconds":3600},{"evidence":[{"contains":"await ctx.limiter.take(`claim-verify-ip:${from.id}`","file":"src/services/creators.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"address","key":"rl:claim-verify-ip:<caller address>:<window start>","limiter_prefix":"claim-verify-ip:","purpose":"Creator claim verifications per hour. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.","ttl":"3,601 seconds (the 3,600-second window plus one second)","window_seconds":3600},{"evidence":[{"contains":"await limitOrThrow(ctx, `k:${key.keyHash}`","file":"src/api/chat.ts"},{"contains":"await ctx.limiter.take(`k:${key.keyHash}`","file":"src/api/embeddings.ts"},{"contains":"await ctx.limiter.take(`k:${key.keyHash}`","file":"src/api/rerank.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"key-hash","key":"rl:k:<key hash>:<window start>","limiter_prefix":"k:","purpose":"Requests per minute for one API key. Keyed by the SHA-256 of the key; no address is read for a call that carries a key.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`kc:${key.keyHash}`","file":"src/api/anthropic.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"key-hash","key":"rl:kc:<key hash>:<window start>","limiter_prefix":"kc:","purpose":"Requests per minute for one API key on the Anthropic-compatible endpoint.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await limitOrThrow(ctx, `kt:${billing.key.keyHash}`","file":"src/api/chat.ts"},{"contains":"tk.limitOrThrow(ctx, `kt:${billing.key.keyHash}`","file":"src/api/council.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"key-hash","key":"rl:kt:<key hash>:<window start>","limiter_prefix":"kt:","purpose":"Tokens per minute for one API key: a running count of prompt tokens, not their text.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`skills-import:${key.keyHash}`","file":"src/api/skills.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"key-hash","key":"rl:skills-import:<key hash>:<window start>","limiter_prefix":"skills-import:","purpose":"Skill imports per hour for one API key (each import may fetch a repository and runs the scanner).","ttl":"3,601 seconds (the 3,600-second window plus one second)","window_seconds":3600},{"evidence":[{"contains":"await ctx.limiter.take(`blind:buy:${caller.keyHash}`","file":"src/blind/purchase.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"key-hash","key":"rl:blind:buy:<key hash>:<window start>","limiter_prefix":"blind:buy:","purpose":"Blind-token purchases per minute for one API key.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(\"provider-applications\"","file":"src/providers/application.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"nothing-personal","key":"rl:provider-applications:<window start>","limiter_prefix":"provider-applications","purpose":"Provider applications per minute, counted across all callers in one key. There is no per-caller part.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await ctx.limiter.take(`claim:${v.model}`","file":"src/api/public.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"model","key":"rl:claim:<model id>:<window start>","limiter_prefix":"claim:","purpose":"Creator claims per hour for one model.","ttl":"3,601 seconds (the 3,600-second window plus one second)","window_seconds":3600},{"evidence":[{"contains":"await ctx.limiter.take(`claim-issue:${modelId}`","file":"src/services/creators.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"model","key":"rl:claim-issue:<model id>:<window start>","limiter_prefix":"claim-issue:","purpose":"Claim challenges per hour for one model.","ttl":"3,601 seconds (the 3,600-second window plus one second)","window_seconds":3600},{"evidence":[{"contains":"await ctx.limiter.take(`claim-verify:${id}`","file":"src/services/creators.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"nothing-personal","key":"rl:claim-verify:<claim id>:<window start>","limiter_prefix":"claim-verify:","purpose":"Claim verifications per hour for one claim.","ttl":"3,601 seconds (the 3,600-second window plus one second)","window_seconds":3600},{"evidence":[{"contains":"await this.ctx.limiter.take(`telegram:${uid}`","file":"src/services/telegram.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"telegram-user","key":"rl:telegram:<Telegram user id>:<window start>","limiter_prefix":"telegram:","purpose":"Telegram bot messages per minute for one Telegram user. The user id is a number Telegram assigns; the message text is not part of the key.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"ctx.limiter.take(\"readiness\", 0, 1, 60_000)","file":"src/services/readiness.ts"},{"contains":"const k = `rl:${key}:${start}`;","file":"src/lib/ratelimit.ts","note":"The stored key is rl:<limiter key>:<window start in ms>."},{"contains":"await this.redis.pexpire(k, windowMs + 1000);","file":"src/lib/ratelimit.ts","note":"The key expires one second after its window ends."}],"holds":"nothing-personal","key":"rl:readiness:<window start>","limiter_prefix":"readiness","purpose":"The readiness probe checks the limiter works by taking zero from a fixed key.","ttl":"61 seconds (the 60-second window plus one second)","window_seconds":60},{"evidence":[{"contains":"await this.redis.set(`cache:${key}`, JSON.stringify({ payload, upstream: upstream.toString() }), \"PX\", ttlS * 1000);","file":"src/gateway/cache.ts"},{"contains":"const payload = this.seal(scope, response);","file":"src/gateway/cache.ts"},{"contains":"validateCacheTtl(body, ctx.cfg.gateway.cacheTtlS);","file":"src/api/chat.ts"},{"contains":"billing?.mode !== \"blind\"","file":"src/api/chat.ts","note":"Never used for a blind-token call, a call with a disclosure ceiling, a restricted model variant or a stream."}],"holds":"digest","key":"cache:<sha256>","purpose":"The opt-in response cache (a request that sends cache.mode or the X-Anyroute-Cache header). It holds the answer to a request, so for as long as it lives this is a place answer text is kept: sealed with AES-256-GCM under a key derived from the router's APP_SECRET and the caller's own scope, so only that caller's identical request can read it back. The Redis key is a SHA-256 of the scope and the request, not the request.","request_text":"answer-text","ttl":"It is kept for the time-to-live the request asked for in cache.ttl: at most CACHE_TTL_S, which is 3,600 seconds unless the operator changed it, and also the default when the request names none."},{"evidence":[{"contains":"`walletauth:${id}`, \"1\", \"PX\", 600_000, \"NX\"","file":"src/api/auth.ts"}],"holds":"wallet","key":"walletauth:<sha256>","purpose":"Replay protection for wallet-signed requests: a marker that a signature was already used. The key is a SHA-256 of the wallet address, the timestamp and the request's hash.","ttl":"600 seconds"},{"evidence":[{"contains":"saveInputs = (b: BatchRow, lines: LineInput[], ttlMs: number) => this.hset(`batch:${b.id}:in`","file":"src/services/batches.ts"},{"contains":"private seal = (b: Pick<BatchRow, \"id\" | \"keyHash\">, v: unknown) => encrypt(this.scope(b), JSON.stringify(v));","file":"src/services/batches.ts"},{"contains":"await this.del(`batch:${b.id}:in`);","file":"src/services/batches.ts"},{"contains":"await batchStore(ctx).purge(b);","file":"src/services/batches.ts"}],"holds":"nothing-personal","key":"batch:<batch id>:in and batch:<batch id>:out","purpose":"The Batch API (POST /api/v1/batches). A batch's requests (:in) and its answers (:out), one field per line, each sealed with AES-256-GCM under a key derived from the router's APP_SECRET, the batch id and the hash of the key that sent it, so only that key's batch can read them back. They are kept here, never in the database, so the worker can run the lines and the key can fetch the results.","request_text":"request-and-answer-text","ttl":"The sealed requests are deleted when the batch finishes; the sealed answers BATCH_RESULTS_TTL after that (86,400 seconds, 24 hours, unless the operator changed it). A batch that never finishes ends when its 24-hour completion window closes, so nothing outlives the window plus that time."},{"evidence":[{"contains":"removeOnComplete: 100, removeOnFail: 100","file":"src/services/jobs.ts"},{"contains":"upsertJobScheduler(j.name, { every: j.everyMs }, { name: j.name","file":"src/services/jobs.ts"}],"holds":"nothing-personal","key":"bull:anyroute-jobs-<group>:*","purpose":"The background job queue (BullMQ) that makes exactly one replica run each recurring job. The job data is empty ({}), so no request or user data is in it; a finished job's result or failure message is kept for the last 100 completed and 100 failed jobs.","ttl":"Recurring job schedules stay while the router runs; only the most recent 100 completed and 100 failed jobs are kept."},{"evidence":[{"contains":"if (this.redis) return (await this.redis.set(ref, sealed, \"PX\", RECOVERY_TTL_MS, \"NX\")) === \"OK\";","file":"src/pay/recovery.ts"},{"contains":"const sealed = encrypt(this.scope(scope), JSON.stringify(kept));","file":"src/pay/recovery.ts"},{"contains":"export const RECOVERY_TTL_MS = 24 * 3_600_000;","file":"src/pay/recovery.ts"},{"contains":"await paidResultStore(ctx).del(gone.map((r) => r.ref));","file":"src/pay/recovery.ts"}],"holds":"digest","key":"x402paid:<sha256>","purpose":"x402 payment recovery. The answer to a call paid with x402, kept so the payer can have it sent again, byte for byte, if it was lost on the way (PAYMENT-RECOVERY), instead of paying twice. It is sealed with AES-256-GCM under a key derived from the router's APP_SECRET, the payer, the authorization nonce and the request's hash, so only a recovery of that exact request by that payer can open it. The key is a SHA-256 of the payer and the nonce.","request_text":"answer-text","ttl":"86,400 seconds (24 hours) from the answer, set when it is written; the x402-recovery-expire job also deletes it with its row. Calls not paid with x402 leave nothing here."}],"memory_fallback":{"evidence":[{"contains":"const cutoff = Date.now() - 5 * 60_000;","file":"src/lib/ratelimit.ts"},{"contains":"Production requires authenticated Redis.","file":"src/config.ts"}],"purpose":"Without Redis (development) the same rate-limit counters live in the router process's memory and are removed once their window started more than five minutes ago (checked every minute). Nothing is written to disk.","ttl":"About five minutes after the window started."},"summary":"Redis holds rate-limit counters, the opt-in response cache, the sealed answers of x402 calls kept 24 hours for payment recovery, replay markers and the job queue. It is optional in development and required in production. Every key expires; the rate-limit keys below are the only place a caller's network address is used, and only for calls without an API key."}},"postgres":{"tables":[{"about_request":"yes","category":"request","columns":[{"about_request":"yes","name":"id","nullable":false,"purpose":"First 24 hex characters of SHA-256 of the referer and title, so the same app maps to one row.","type":"text"},{"about_request":"yes","flags":["name:network"],"name":"url","nullable":true,"purpose":"The HTTP-Referer header value, cut to 500 characters. It is whatever the calling application sent, usually its own site address.","review":{"covers":["name:network"],"verdict":"request-header","why":"A request header kept on purpose so apps can be ranked. It names an application's site, not the caller's network address, and callers can omit it."},"type":"text"},{"about_request":"yes","flags":["name:content"],"name":"title","nullable":true,"purpose":"The X-Title header value, cut to 200 characters: the application's display name.","review":{"covers":["name:content"],"verdict":"request-header","why":"A request header kept on purpose for app rankings. It is a short label the caller chooses, not a prompt."},"type":"text"},{"about_request":"yes","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"apps","purpose":"Where calls come from, for app rankings: the HTTP-Referer and X-Title headers a caller chose to send, kept as the caller wrote them (truncated). Not recorded for the unlinkable lane.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"yes","category":"request","columns":[{"about_request":"yes","name":"batch_id","nullable":false,"purpose":"The batch the line belongs to.","type":"text"},{"about_request":"yes","name":"idx","nullable":false,"purpose":"The line's position in the batch, from 0.","type":"integer"},{"about_request":"yes","name":"api","nullable":false,"purpose":"chat or embeddings.","type":"text"},{"about_request":"yes","name":"status","nullable":false,"purpose":"queued, running, succeeded, failed, cancelled or expired.","type":"text"},{"about_request":"yes","name":"attempts","nullable":false,"purpose":"How many times the worker started the line (a line whose providers were all unavailable is tried again, up to BATCH_LINE_MAX_ATTEMPTS).","type":"integer"},{"about_request":"yes","name":"status_code","nullable":true,"purpose":"The HTTP status the line's call returned.","type":"integer"},{"about_request":"yes","name":"generation_id","nullable":true,"purpose":"The generation the line produced, whose receipt it has.","type":"text"},{"about_request":"yes","name":"cost","nullable":false,"purpose":"What the line was charged, after the batch discount, in pico-USD.","type":"bigint"},{"about_request":"yes","name":"list_cost","nullable":false,"purpose":"What the line would have cost without the discount, in pico-USD.","type":"bigint"},{"about_request":"yes","name":"failure_code","nullable":true,"purpose":"For a line that did not succeed, the error type (for example insufficient_credits or batch_cancelled). A fixed code, never text from a request.","type":"text"},{"about_request":"yes","name":"not_before","nullable":false,"purpose":"The earliest the line runs (a rate-limited line waits), or, while it runs, when it counts as interrupted.","type":"timestamp with time zone"},{"about_request":"yes","name":"finished_at","nullable":true,"purpose":"When the line ended.","type":"timestamp with time zone"}],"name":"batch_lines","purpose":"One row per line of a batch: its status, the HTTP status its call returned, the generation (and so the signed receipt) it produced and what it was charged. No request or answer text: that is sealed outside the database.","retention":"Deleted with the batch's sealed answers when its results expire (BATCH_RESULTS_TTL after the batch finished, 24 hours unless the operator changed it)."},{"about_request":"aggregate","category":"request","columns":[{"about_request":"aggregate","name":"id","nullable":false,"purpose":"The batch id (batch_ and random hex).","type":"text"},{"about_request":"aggregate","name":"account_id","nullable":false,"purpose":"The account the batch's lines are billed to.","type":"text"},{"about_request":"aggregate","name":"key_hash","nullable":false,"purpose":"The hash of the API key that sent the batch; only that key can read or cancel it.","type":"text"},{"about_request":"aggregate","name":"api","nullable":false,"purpose":"Which API every line calls: chat or embeddings.","type":"text"},{"about_request":"aggregate","name":"status","nullable":false,"purpose":"validating, in_progress, cancelling, completed, failed, expired or cancelled.","type":"text"},{"about_request":"aggregate","name":"total","nullable":false,"purpose":"How many lines the batch has.","type":"integer"},{"about_request":"aggregate","name":"completed","nullable":false,"purpose":"How many lines succeeded.","type":"integer"},{"about_request":"aggregate","name":"failed","nullable":false,"purpose":"How many lines failed.","type":"integer"},{"about_request":"aggregate","name":"cost","nullable":false,"purpose":"What the batch's lines were charged, after the batch discount, in pico-USD.","type":"bigint"},{"about_request":"aggregate","name":"list_cost","nullable":false,"purpose":"What the same calls would have cost without the batch discount, in pico-USD.","type":"bigint"},{"about_request":"aggregate","name":"discount_bps","nullable":false,"purpose":"The batch discount in basis points (BATCH_DISCOUNT_BPS when the batch was sent; 5000 is half price).","type":"integer"},{"about_request":"aggregate","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"started_at","nullable":true,"purpose":"When the worker started the batch.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"cancelling_at","nullable":true,"purpose":"When the key asked to cancel the batch.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"finished_at","nullable":true,"purpose":"When the batch's last line ended.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"expires_at","nullable":false,"purpose":"The end of the 24-hour completion window: lines not run by then end unrun and unbilled.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"results_expire_at","nullable":true,"purpose":"When the batch's answers and line rows are deleted (finished_at plus BATCH_RESULTS_TTL).","type":"timestamp with time zone"},{"about_request":"aggregate","name":"purged_at","nullable":true,"purpose":"When they were deleted.","type":"timestamp with time zone"}],"name":"batches","purpose":"One row per batch sent to the Batch API (POST /api/v1/batches): the key that sent it, its status, how many lines it has and how many succeeded or failed, and what it cost. The requests and answers of its lines are never written to the database: they are kept sealed in Redis or the router's memory (see the Redis section) until the batch's results expire.","retention":"No automatic deletion of the row itself; when the batch's results expire (results_expire_at), its line rows and its sealed requests and answers are deleted and purged_at is set."},{"about_request":"yes","category":"request","columns":[{"about_request":"yes","name":"id","nullable":false,"purpose":"Generation id, random. It is also the id of the signed receipt (the X-Receipt-Id response header).","type":"text"},{"about_request":"yes","name":"ts","nullable":false,"purpose":"When the call was recorded.","type":"timestamp with time zone"},{"about_request":"yes","name":"key_hash","nullable":true,"purpose":"SHA-256 of the API key that made the call (the key itself is never stored). Empty for wallet-paid and blind-token calls.","type":"text"},{"about_request":"yes","name":"account_id","nullable":true,"purpose":"The account that was billed. For a blind-token call it is the shared token pool, not a person.","type":"text"},{"about_request":"yes","name":"model_id","nullable":false,"purpose":"The catalogue model id that answered, such as author/slug.","type":"text"},{"about_request":"yes","name":"provider_id","nullable":false,"purpose":"The provider that served the call.","type":"text"},{"about_request":"yes","name":"tokens_in","nullable":false,"purpose":"Prompt tokens billed, as a count.","type":"integer"},{"about_request":"yes","name":"tokens_out","nullable":false,"purpose":"Completion tokens billed, as a count.","type":"integer"},{"about_request":"yes","name":"reasoning_tokens","nullable":false,"purpose":"Reasoning tokens billed, as a count.","type":"integer"},{"about_request":"yes","name":"cached_tokens","nullable":false,"purpose":"Prompt tokens the provider served from its cache, as a count.","type":"integer"},{"about_request":"yes","name":"cache_write_tokens","nullable":false,"purpose":"Prompt tokens written to the provider's cache, as a count.","type":"integer"},{"about_request":"yes","name":"cost","nullable":false,"purpose":"Total charged to the caller, in pico-USD (1e-12 USD).","type":"bigint"},{"about_request":"yes","name":"upstream_cost","nullable":false,"purpose":"What the provider charged the router for the call, in pico-USD.","type":"bigint"},{"about_request":"yes","name":"royalty","nullable":false,"purpose":"The share of the cost owed to the model's creator, in pico-USD.","type":"bigint"},{"about_request":"yes","name":"margin","nullable":false,"purpose":"The router's fee on the call, in pico-USD.","type":"bigint"},{"about_request":"yes","name":"cache_discount","nullable":false,"purpose":"The discount given for cached prompt tokens, in pico-USD.","type":"bigint"},{"about_request":"yes","name":"mode","nullable":false,"purpose":"How the call was paid: prepaid, per_call, paywith, byok, cache or blind.","type":"text"},{"about_request":"yes","name":"latency_ms","nullable":true,"purpose":"Milliseconds until the provider's first response.","type":"integer"},{"about_request":"yes","name":"generation_time_ms","nullable":true,"purpose":"Milliseconds for the whole call.","type":"integer"},{"about_request":"yes","name":"finish_reason","nullable":true,"purpose":"Why the model stopped, such as stop or length.","type":"text"},{"about_request":"yes","name":"native_finish_reason","nullable":true,"purpose":"The stop reason as the provider reported it.","type":"text"},{"about_request":"yes","name":"streamed","nullable":false,"purpose":"Whether the answer was streamed.","type":"boolean"},{"about_request":"yes","name":"cancelled","nullable":false,"purpose":"Whether the caller cancelled before the answer finished.","type":"boolean"},{"about_request":"yes","name":"quant","nullable":true,"purpose":"Quantisation of the endpoint that answered (for example fp8), or unknown.","type":"text"},{"about_request":"yes","name":"data_region","nullable":true,"purpose":"The first datacenter region the provider lists, not the caller's location.","type":"text"},{"about_request":"yes","name":"is_byok","nullable":false,"purpose":"Whether the caller's own provider key paid for the call.","type":"boolean"},{"about_request":"yes","name":"private","nullable":false,"purpose":"Whether the caller asked for a private route (provider.private or a :private model).","type":"boolean"},{"about_request":"yes","name":"attestation_hash","nullable":true,"purpose":"Hash of the attestation report of the provider, when an attested provider served the call.","type":"text"},{"about_request":"yes","name":"receipt_id","nullable":true,"purpose":"The receipt's id (the same as id).","type":"text"},{"about_request":"yes","name":"receipt_sig","nullable":true,"purpose":"The router's Ed25519 signature over the receipt.","type":"text"},{"about_request":"yes","name":"receipt_key_id","nullable":true,"purpose":"Which receipt signing key signed it.","type":"text"},{"about_request":"yes","flags":["type:json"],"name":"receipt","nullable":true,"purpose":"The signed v1 receipt payload: model, provider, token counts, cost, timing, mode, lane, disclosure class, payer (a key hash or a wallet address), the two SHA-256 digests and a summary of the provider's attestation. Blind payment adds a single nullifier and issuer key id, or token_count, nullifiers and token_key_ids for a set; no buyer or credential bytes. The ciphertext chat adapter also signs end_to_end_encrypted and e2ee: version, suite, gateway_attested, complete, billing_basis, input_byte_bound, max_tokens, request_bytes, response_bytes and gateway_receipt with id, keyset digest, response-hash, request-hash and upstream verification state plus upstream session id and GPU claim. Request-hash verification remains false in the router. No public keys, replay nonces, credentials or content are retained. When ROUTE_EXPLAIN_ENABLED is true, route stores version, serving provider id, selection reason, eligible count, aggregate skip and fallback error-class counts, lane, required parameter names from a fixed allowlist and whether the provider is a network host. No other provider ids, weights, URLs, messages or content are added. With DECISION_TAGS_ENABLED, decision_tag stores the caller's X-Anyroute-Decision-Tag: a validated sha256 digest the caller computed, never what it was computed from. Fixed fields chosen by the router.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Every field is set by the router's receipt code from numbers, ids and hashes; it never copies request or answer text into the payload."},"type":"jsonb"},{"about_request":"yes","name":"receipt_leaf","nullable":true,"purpose":"This receipt's leaf hash in the anchoring tree.","type":"text"},{"about_request":"yes","name":"anchor_index","nullable":true,"purpose":"Which anchor (Merkle root) this receipt was included in, once anchored.","type":"integer"},{"about_request":"yes","name":"leaf_index","nullable":true,"purpose":"The receipt's position in that anchor tree.","type":"integer"},{"about_request":"yes","flags":["type:json"],"name":"receipt_v2","nullable":true,"purpose":"The v2 receipt claims as JSON: model, provider, lane, hashed request and response, power-of-two token-count buckets and cost units. The optional route claim carries the same versioned selection summary as v1, without other provider ids, raw errors or weights. The optional decision_tag claim is the same caller-computed sha256 digest as v1. Null for receipts made before v2.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Built by buildClaimsV2 from ids, hashes and buckets; the claims carry no payer, address, IP or content."},"type":"jsonb"},{"about_request":"yes","name":"receipt_cose","nullable":true,"purpose":"The v2 receipt as signed COSE_Sign1 bytes, base64.","type":"text"},{"about_request":"yes","name":"receipt_leaf_v2","nullable":true,"purpose":"The v2 receipt's leaf hash in the anchoring tree.","type":"text"},{"about_request":"yes","name":"leaf_index_v2","nullable":true,"purpose":"The v2 leaf's position in the anchor tree.","type":"integer"},{"about_request":"yes","flags":["type:json"],"name":"paid_with","nullable":true,"purpose":"For a pay-with call: the token symbol and address, raw units accrued, the fair price used and the swap transaction, when there is one.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Written by the pay-with code from token symbols, addresses and amounts."},"type":"jsonb"},{"about_request":"yes","name":"payment_tx","nullable":true,"purpose":"For a per-call payment: the transaction hash that paid.","type":"text"},{"about_request":"yes","name":"app_id","nullable":true,"purpose":"Links to the apps row when the caller sent HTTP-Referer or X-Title. Not recorded for the unlinkable lane.","type":"text"},{"about_request":"yes","flags":["type:json"],"name":"attempts","nullable":true,"purpose":"Every provider the router tried for the call: provider, model, whether it worked, error kind, HTTP status and latency. A failed attempt also keeps up to 200 characters of the provider's own error message, with URLs, keys, emails and long hex removed.","review":{"covers":["type:json"],"verdict":"may-hold-fragment","why":"The failure message is the provider's text, not ours. Providers normally send a generic reason, but a provider could quote part of a rejected request in it, so up to 200 characters of request text could end up here."},"type":"jsonb"},{"about_request":"yes","flags":["name:content"],"name":"request_sha256","nullable":true,"purpose":"Ordinary chat: SHA-256 of canonical request JSON (stream flags excluded). The E2EE adapter hashes the exact forwarded encrypted envelope bytes, including whitespace and stream flags. Someone who already has the exact request can check it against this; the text cannot be recovered from it.","review":{"covers":["name:content"],"verdict":"digest-only","why":"A hash of the request, kept so a receipt can be checked against a request the caller holds; it is 64 hex characters and holds no text."},"type":"text"},{"about_request":"yes","flags":["name:content"],"name":"response_sha256","nullable":true,"purpose":"Ordinary chat: SHA-256 of response text (all choices joined). The E2EE adapter hashes encrypted JSON or SSE wire bytes, including framing; an interrupted response hashes the observed prefix. The text cannot be recovered from it.","review":{"covers":["name:content"],"verdict":"digest-only","why":"A hash of the answer, kept for the receipt; it is 64 hex characters and holds no text."},"type":"text"},{"about_request":"yes","name":"settled_period","nullable":true,"purpose":"The UTC hour in which the call was settled to the provider, for example 2026-09-26T13.","type":"text"}],"name":"generations","purpose":"One row per call the router served: who was billed, which model and provider answered, token counts, cost, timing, how it was paid and the signed receipt. It holds hashes of the request and the response, never their text.","retention":"No automatic deletion: no job or route in the code removes rows from this table. Rows are read back for receipts, usage history, settlement and provider scoring."},{"about_request":"yes","category":"request","columns":[{"about_request":"yes","name":"model_id","nullable":false,"purpose":"The model that was tried.","type":"text"},{"about_request":"yes","name":"provider_id","nullable":false,"purpose":"The provider that was tried.","type":"text"},{"about_request":"yes","name":"ts","nullable":false,"purpose":"When the attempt finished.","type":"timestamp with time zone"},{"about_request":"yes","name":"ok","nullable":false,"purpose":"Whether the attempt produced a usable answer.","type":"boolean"},{"about_request":"yes","name":"latency_ms","nullable":true,"purpose":"Milliseconds until the first response.","type":"integer"},{"about_request":"yes","name":"tps","nullable":true,"purpose":"Output tokens per second, when it could be measured.","type":"real"},{"about_request":"yes","name":"empty200","nullable":false,"purpose":"Whether the provider answered 200 with an empty completion.","type":"boolean"},{"about_request":"yes","name":"status_code","nullable":true,"purpose":"The HTTP status the provider returned, when there was one.","type":"integer"},{"about_request":"yes","flags":["name:content"],"name":"error_kind","nullable":true,"purpose":"A fixed code for the failure from the router's ErrorKind list, such as http_5xx, rate_limited, provider_auth, rejected, empty200 or interrupted. Null when the attempt worked.","review":{"covers":["name:content"],"verdict":"no-request-content","why":"One of a short list of codes chosen by the router (ErrorKind); the provider's message is not stored here."},"type":"text"},{"about_request":"yes","name":"source","nullable":false,"purpose":"traffic for a real call, probe for the router's own health probe.","type":"text"},{"about_request":"yes","name":"caller","nullable":true,"purpose":"A 16-character truncation of the SHA-256 of the account id, set only on failed attempts, so one caller cannot single-handedly mark a provider as failing. It is not the account id.","type":"text"}],"name":"health","purpose":"One row per provider attempt (and per probe): did it work, how fast, which status. It feeds routing and provider scores. It has no request or answer text and no account id.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"billing","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"The account id. For a wallet account it is derived from the wallet address.","type":"text"},{"about_request":"no","name":"inference_keys_default","nullable":false,"purpose":"Whether newly provisioned child keys default to inference-only access. Management keys can explicitly select account scope.","type":"boolean"},{"about_request":"no","name":"kind","nullable":false,"purpose":"key for an API-key account, wallet for a wallet account.","type":"text"},{"about_request":"no","name":"wallet","nullable":true,"purpose":"The wallet address of a wallet account. Empty for a key account.","type":"text"},{"about_request":"aggregate","name":"balance","nullable":false,"purpose":"The spendable balance, including provisional deposit credits: the sum of the account's ledger lines, in pico-USD. A database trigger keeps it equal to that sum.","type":"bigint"},{"about_request":"aggregate","name":"held","nullable":false,"purpose":"The amount reserved by open holds for calls in flight, in pico-USD.","type":"bigint"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"accounts","purpose":"One row per billing account: an API-key account or a wallet account, with its settled balance and the amount held for calls in flight.","retention":"No automatic deletion. The ledger refers to accounts and is append-only, so an account row stays."},{"about_request":"yes","category":"billing","columns":[{"about_request":"yes","name":"id","nullable":false,"purpose":"Hold id; for a chat call it is the generation id.","type":"text"},{"about_request":"yes","name":"account_id","nullable":false,"purpose":"The account the amount is reserved on.","type":"text"},{"about_request":"yes","name":"key_hash","nullable":true,"purpose":"The key hash that made the call, when there is one.","type":"text"},{"about_request":"yes","name":"amount","nullable":false,"purpose":"The reserved amount in pico-USD; it cannot change after creation.","type":"bigint"},{"about_request":"yes","name":"status","nullable":false,"purpose":"held, settled or released.","type":"text"},{"about_request":"yes","name":"kind","nullable":false,"purpose":"What the hold was for; usage for a call, tool_call for a paid x402 tool, data_tool for a market-data tool call.","type":"text"},{"about_request":"yes","flags":["type:json"],"name":"result","nullable":true,"purpose":"How the hold ended: the amount charged and any uncovered amount, as strings in pico-USD, and expired: true when the hold timed out.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Written only by settle() and release() in ledger.ts as { charged, uncovered, expired } amounts."},"type":"jsonb"},{"about_request":"yes","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"yes","name":"expires_at","nullable":false,"purpose":"When an unsettled hold is released automatically (the holds-expire job).","type":"timestamp with time zone"}],"name":"holds","purpose":"A reservation of balance made before a call runs, settled to the real cost afterwards or released. One hold per call.","retention":"The database refuses to delete holds (trigger holds_apply_held), so they are kept permanently."},{"about_request":"yes","category":"billing","columns":[{"about_request":"yes","name":"id","nullable":false,"purpose":"Ledger line id.","type":"text"},{"about_request":"yes","name":"account_id","nullable":false,"purpose":"The account the line applies to.","type":"text"},{"about_request":"yes","name":"key_hash","nullable":true,"purpose":"The key hash the line came from, when there is one.","type":"text"},{"about_request":"yes","name":"amount","nullable":false,"purpose":"The signed amount in pico-USD: positive adds to the balance, negative takes from it.","type":"bigint"},{"about_request":"yes","name":"kind","nullable":false,"purpose":"What the line is: provisional (early escrow credit), deposit, credit, usage, refund, paywith, change, adjustment, withdrawal_lock, withdrawal, blind_purchase, tool_call (a paid x402 tool), data_tool (a market-data tool call) and similar.","type":"text"},{"about_request":"yes","name":"ref","nullable":false,"purpose":"A unique idempotency reference, such as usage:<generation id> or escrow:<transaction>:<log index>, so a line can never be posted twice.","type":"text"},{"about_request":"yes","name":"generation_id","nullable":true,"purpose":"For a usage line, the generation it paid for.","type":"text"},{"about_request":"yes","flags":["name:content"],"name":"description","nullable":false,"purpose":"A short line written by the router, such as \"<model> via <provider>\", \"USDG deposit <transaction hash>\" or \"Model usage\". Never text from a request.","review":{"covers":["name:content"],"verdict":"no-request-content","why":"Every description is built in code from model ids, provider ids, transaction hashes and fixed phrases (ledger.ts, escrow.ts, indexer.ts); no caller-supplied string is used."},"type":"text"},{"about_request":"yes","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"ledger","purpose":"The append-only money ledger: deposits, credits, usage charges, refunds, withdrawals and adjustments. A usage line names the generation it paid for; it does not say what the call was about.","retention":"The database refuses every update and delete on this table (trigger ledger_no_update), so lines are kept permanently."},{"about_request":"yes","category":"billing","columns":[{"about_request":"yes","name":"id","nullable":false,"purpose":"Refund id, also the id of its signed refund receipt (GET /api/v1/receipts/{id}).","type":"text"},{"about_request":"yes","name":"source_id","nullable":false,"purpose":"What is refunded: the generation id, or payment:<transaction hash> for a per-call payment no provider served. Unique.","type":"text"},{"about_request":"yes","name":"generation_id","nullable":true,"purpose":"The refunded generation, whose id is also its original receipt id. Null for an unserved paid call.","type":"text"},{"about_request":"yes","name":"account_id","nullable":false,"purpose":"Account credited (or whose per-call wallet is refunded on-chain).","type":"text"},{"about_request":"yes","name":"key_hash","nullable":true,"purpose":"Hash of the API key that made the call, copied from the generation; null for a per-call wallet payer.","type":"text"},{"about_request":"yes","name":"rule","nullable":false,"purpose":"Fixed rule name: upstream_failure, fallback_price, truncated_stream, structured_output or unattested_lane.","type":"text"},{"about_request":"yes","name":"status","nullable":false,"purpose":"pending until the settlement job decides it, then issued, or void when nothing charged is left to refund.","type":"text"},{"about_request":"yes","name":"amount","nullable":false,"purpose":"Refund in pico-USD: the rule's amount capped by what the ledger charged (or, for an unserved paid call, by the payment still unspent).","type":"bigint"},{"about_request":"yes","name":"charged","nullable":false,"purpose":"What the ledger charged for the call, or what the unserved per-call payment was, in pico-USD.","type":"bigint"},{"about_request":"yes","flags":["type:json"],"name":"evidence","nullable":false,"purpose":"Fixed facts behind the rule: error class counts, provider ids, token counts, costs, lane and disclosure class, a payment transaction hash or the first call id of a JSON repair.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Written only by the make-good hooks from numbers, fixed codes, provider ids, generation ids and transaction hashes; never request or answer text, headers or caller addresses."},"type":"jsonb"},{"about_request":"yes","name":"provider_id","nullable":true,"purpose":"Provider whose failure caused the refund, when one did; null when no provider is responsible (a JSON answer that does not parse).","type":"text"},{"about_request":"yes","name":"strike","nullable":false,"purpose":"Whether the refund is also a strike against that provider (an attested-lane call served without a fresh attestation).","type":"boolean"},{"about_request":"yes","name":"payer","nullable":true,"purpose":"Wallet address that paid the call on-chain per call, refunded on-chain; null for credits to a prepaid balance.","type":"text"},{"about_request":"yes","name":"onchain_usdg","nullable":true,"purpose":"USDG base units owed on-chain for this refund (whole units; any remainder below one unit stays as balance).","type":"bigint"},{"about_request":"yes","name":"payout_status","nullable":false,"purpose":"none, owed, batched (in a signed transfer) or paid.","type":"text"},{"about_request":"yes","name":"payout_id","nullable":true,"purpose":"The makegood_payouts transfer that pays this refund.","type":"text"},{"about_request":"yes","flags":["type:json"],"name":"receipt","nullable":true,"purpose":"The signed refund receipt payload (kind refund): ids, rule, amounts, settlement, provider and the evidence above.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Canonical JSON built by issueRefund from the fields of this row and the original generation id; it carries amounts, fixed codes and hashes, no request or answer text."},"type":"jsonb"},{"about_request":"yes","name":"receipt_sig","nullable":true,"purpose":"Ed25519 signature over the canonical refund receipt, by the router's receipt key.","type":"text"},{"about_request":"yes","name":"receipt_key_id","nullable":true,"purpose":"Id of the receipt key that signed it.","type":"text"},{"about_request":"yes","name":"receipt_leaf","nullable":true,"purpose":"Hash of the signed receipt in the form receipt anchoring uses; refund receipts are not yet anchored.","type":"text"},{"about_request":"yes","name":"detected_at","nullable":false,"purpose":"When the rule was met (the call settled or failed).","type":"timestamp with time zone"},{"about_request":"yes","name":"issued_at","nullable":true,"purpose":"When the settlement job issued or voided the refund.","type":"timestamp with time zone"}],"name":"makegood_refunds","purpose":"One row per call (or per unserved per-call payment) that met a make-good refund rule: the rule, the capped refund, the signed refund receipt and, for calls paid on-chain per call, the on-chain refund still owed or paid. Disabled unless MAKEGOOD_ENABLED.","retention":"No automatic deletion: no job or route in the code removes rows from this table. At most one row per source: the source id is unique, so a call is never refunded twice."},{"about_request":"aggregate","category":"billing","columns":[{"about_request":"aggregate","name":"id","nullable":false,"purpose":"Provider and accrual-hour identifier; also the input to the on-chain operation digest.","type":"text"},{"about_request":"aggregate","name":"provider_id","nullable":false,"purpose":"The host owed a net payout.","type":"text"},{"about_request":"aggregate","name":"period","nullable":false,"purpose":"UTC hour when anchored receipts accrue, which may follow the served hour.","type":"text"},{"about_request":"aggregate","name":"gross_pico","nullable":false,"purpose":"Sum of upstream_cost for eligible linked generations, before the network fee.","type":"numeric(78, 0)"},{"about_request":"aggregate","name":"fee_pico","nullable":false,"purpose":"Floor of gross times configured basis points divided by 10000.","type":"numeric(78, 0)"},{"about_request":"aggregate","name":"status","nullable":false,"purpose":"accrued, swapped or burned, reconciled with on-chain operation state.","type":"text"},{"about_request":"aggregate","name":"swap_tx","nullable":true,"purpose":"Confirmed swap transaction hash, not request content.","type":"text"},{"about_request":"aggregate","name":"burn_tx","nullable":true,"purpose":"Confirmed dead-address transfer transaction hash.","type":"text"},{"about_request":"aggregate","name":"anyr_amount","nullable":true,"purpose":"ANYR base units measured by the executor's balance delta.","type":"numeric(78, 0)"},{"about_request":"aggregate","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"network_fee_ledger","notes":["The planned executor reads its public token, adapter, oracle and keeper addresses, daily cap, operation state and transaction events from the chain in memory to check configured settings and reconcile swaps. Quotes use a pinned block and may add an independent pool TWAP. No request text, caller address, new log field or Redis key is read or stored by these checks. Payouts and fee burns are not switched on yet.","Sub-USDG-unit fee dust remains unswapped and is reported separately. Burns transfer to the dead address; AnyrToken totalSupply is unchanged. Public totals aggregate across hosts; recent entries expose transactions, status and token amounts, without host invoice amounts. Transactions themselves are public on chain and can be correlated with hosts. Amounts above the configured per-run or remaining daily cap wait for a later run or operator reconciliation."],"purpose":"Network host fees from confirmed per-host receipt roots, grouped in the UTC hour when they accrue. Gross and fee are pico-USD; net is invoiced through settlements. Closed-hour fees are swapped through the guarded buyback oracle path and transferred to the token dead address. Swap and burn transactions are public through the network burns API.","retention":"No automatic deletion, and rows are never changed after they are written."},{"about_request":"no","category":"billing","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Payout id.","type":"text"},{"about_request":"no","name":"provider_id","nullable":false,"purpose":"The provider paid.","type":"text"},{"about_request":"no","name":"usdg","nullable":false,"purpose":"Amount in USDG base units.","type":"bigint"},{"about_request":"no","name":"to","nullable":true,"purpose":"The destination address for the payout.","type":"text"},{"about_request":"no","name":"status","nullable":false,"purpose":"pending, submitted, paid or invoice.","type":"text"},{"about_request":"no","name":"tx","nullable":true,"purpose":"The payment transaction.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"payouts","purpose":"A payout to a provider: the amount in USDG, where it went and its status.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"yes","category":"billing","columns":[{"about_request":"yes","name":"nonce","nullable":false,"purpose":"The quote id (32 bytes hex). For an x402 payment claim it is x402:<payer wallet>:<authorization nonce>.","type":"text"},{"about_request":"yes","name":"price_usdg","nullable":false,"purpose":"The quoted price in USDG base units (1e-6).","type":"bigint"},{"about_request":"yes","name":"price_pico","nullable":false,"purpose":"The same price in pico-USD.","type":"bigint"},{"about_request":"yes","flags":["name:content"],"name":"request_sha256","nullable":false,"purpose":"SHA-256 of the request the quote is for. It binds the quote to that one request; the request cannot be recovered from it.","review":{"covers":["name:content"],"verdict":"digest-only","why":"A hash of the request body, used to check that a payment belongs to the request it quoted."},"type":"text"},{"about_request":"yes","name":"model_id","nullable":false,"purpose":"The model the quote is for.","type":"text"},{"about_request":"yes","name":"expires_at","nullable":false,"purpose":"When the quote stops being payable.","type":"timestamp with time zone"},{"about_request":"yes","name":"status","nullable":false,"purpose":"open, paid, used, expired or failed.","type":"text"},{"about_request":"yes","name":"payer","nullable":true,"purpose":"The wallet address that paid, once a payment is seen.","type":"text"},{"about_request":"yes","name":"tx_hash","nullable":true,"purpose":"The payment transaction.","type":"text"},{"about_request":"yes","name":"account_id","nullable":true,"purpose":"The account the payment was credited to.","type":"text"},{"about_request":"yes","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"quotes","purpose":"A price quoted for one pay-per-call request (HTTP 402 and x402), so a payment can be matched to exactly the request it was for.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"aggregate","category":"billing","columns":[{"about_request":"aggregate","name":"model_id","nullable":false,"purpose":"The model.","type":"text"},{"about_request":"aggregate","name":"period","nullable":false,"purpose":"The settlement period.","type":"text"},{"about_request":"aggregate","name":"amount","nullable":false,"purpose":"Royalty in pico-USD.","type":"bigint"},{"about_request":"aggregate","name":"usdg","nullable":false,"purpose":"Royalty in USDG base units.","type":"bigint"},{"about_request":"aggregate","name":"creator","nullable":true,"purpose":"The creator's payout address, when one is known.","type":"text"},{"about_request":"aggregate","name":"stream_tx","nullable":true,"purpose":"The transaction that streamed the royalty.","type":"text"},{"about_request":"aggregate","name":"claimed","nullable":false,"purpose":"Whether the creator claimed it.","type":"boolean"}],"name":"royalties","purpose":"The royalty a model's creator earned in one period, and whether it was claimed.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"aggregate","category":"billing","columns":[{"about_request":"aggregate","name":"seller_id","nullable":false,"purpose":"The listing the float belongs to.","type":"text"},{"about_request":"aggregate","name":"balance","nullable":false,"purpose":"USDG base units left.","type":"numeric(78, 0)"},{"about_request":"aggregate","name":"funded","nullable":false,"purpose":"USDG base units paid in, in total.","type":"numeric(78, 0)"},{"about_request":"aggregate","name":"debited","nullable":false,"purpose":"USDG base units taken for gas, in total.","type":"numeric(78, 0)"},{"about_request":"aggregate","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"seller_gas_floats","purpose":"USDG a seller prepaid to the treasury so the facilitator settles its payments below the minimum; each such settle is debited at its measured gas times a buffer.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"aggregate","category":"billing","columns":[{"about_request":"aggregate","name":"provider_id","nullable":false,"purpose":"The provider owed.","type":"text"},{"about_request":"aggregate","name":"period","nullable":false,"purpose":"The UTC hour, such as 2026-09-26T13.","type":"text"},{"about_request":"aggregate","name":"tokens","nullable":false,"purpose":"Total tokens invoiced in the hour; network hosts include only newly eligible anchored work.","type":"bigint"},{"about_request":"aggregate","name":"requests","nullable":false,"purpose":"Number of calls invoiced in the hour; network hosts include only newly eligible anchored work.","type":"integer"},{"about_request":"aggregate","name":"upstream","nullable":false,"purpose":"Upstream cost for the hour, in pico-USD.","type":"bigint"},{"about_request":"aggregate","name":"fee","nullable":false,"purpose":"The router's fee for the hour, in pico-USD.","type":"bigint"},{"about_request":"aggregate","name":"usdg_owed","nullable":false,"purpose":"USDG base units owed to the provider for the hour.","type":"bigint"},{"about_request":"aggregate","name":"payout_id","nullable":true,"purpose":"The payout that included the hour, once paid.","type":"text"},{"about_request":"aggregate","name":"paid_tx","nullable":true,"purpose":"The transaction that paid it.","type":"text"},{"about_request":"aggregate","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"settlements","purpose":"What one provider is owed for one UTC hour: token totals, request count, upstream cost, the router's fee and the USDG owed. Network hosts use only confirmed per-host receipts and the configured network fee; their period is the accrual hour.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"billing","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Install id (si_...).","type":"text"},{"about_request":"no","name":"skill_id","nullable":false,"purpose":"The skill installed.","type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"The installing account.","type":"text"},{"about_request":"no","name":"key_hash","nullable":true,"purpose":"The key that installed it.","type":"text"},{"about_request":"no","name":"price_usdg","nullable":false,"purpose":"The price paid in USDG base units; 0 for a free skill or the author's own.","type":"bigint"},{"about_request":"no","name":"author_share","nullable":false,"purpose":"Pico-USD credited to the author's account (the price less SKILLS_FEE_BPS).","type":"bigint"},{"about_request":"no","name":"fee","nullable":false,"purpose":"Pico-USD credited to the network fee account.","type":"bigint"},{"about_request":"no","flags":["type:json"],"name":"receipt","nullable":false,"purpose":"The install receipt: skill id, content hash, level, installer and author accounts, amounts and time, with an Ed25519 signature from the receipt key.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Ids, hashes, amounts and a timestamp chosen by our code, plus the signature over them."},"type":"jsonb"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"skill_installs","purpose":"One row per (skill, installing account): the price paid, the author's share, the network fee and the signed install receipt. The ledger rows of a paid install use refs derived from the same pair, which makes an install idempotent.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"yes","category":"billing","columns":[{"about_request":"yes","name":"id","nullable":false,"purpose":"Call id (tc_...), also the id of its hold.","type":"text"},{"about_request":"yes","name":"key_hash","nullable":false,"purpose":"The key that paid.","type":"text"},{"about_request":"yes","name":"account_id","nullable":false,"purpose":"The account charged.","type":"text"},{"about_request":"yes","name":"seller_id","nullable":true,"purpose":"The tool listing id when the address is listed, else null.","type":"text"},{"about_request":"yes","name":"pay_to","nullable":false,"purpose":"The seller's payTo wallet (public on chain).","type":"text"},{"about_request":"yes","name":"resource","nullable":false,"purpose":"The tool's https origin and path that was paid, without the query string.","type":"text"},{"about_request":"yes","name":"method","nullable":false,"purpose":"GET or POST.","type":"text"},{"about_request":"yes","name":"network","nullable":false,"purpose":"The x402 network of the paid offer.","type":"text"},{"about_request":"yes","name":"x402_version","nullable":false,"purpose":"1 or 2: which x402 wire format the seller spoke.","type":"integer"},{"about_request":"yes","name":"price_units","nullable":false,"purpose":"The seller's price in USDG base units.","type":"bigint"},{"about_request":"yes","name":"price","nullable":false,"purpose":"The seller's price in pico-USD.","type":"bigint"},{"about_request":"yes","name":"take","nullable":false,"purpose":"The router's take in pico-USD (TOOLS_TAKE_BPS).","type":"bigint"},{"about_request":"yes","name":"hold_id","nullable":false,"purpose":"The hold on the key's balance.","type":"text"},{"about_request":"yes","name":"payer","nullable":false,"purpose":"The router's own buyer wallet that signed the authorization.","type":"text"},{"about_request":"yes","name":"nonce","nullable":false,"purpose":"The EIP-3009 nonce of that authorization; the reconcile job asks the chain whether it was used.","type":"text"},{"about_request":"yes","name":"valid_before","nullable":false,"purpose":"When that authorization expires.","type":"timestamp with time zone"},{"about_request":"yes","name":"settle_tx","nullable":true,"purpose":"The settlement transaction hash the seller reported, if any.","type":"text"},{"about_request":"yes","flags":["name:content"],"name":"response_sha256","nullable":true,"purpose":"SHA-256 of the tool's answer bytes, as in the receipt. The answer cannot be recovered from it.","review":{"covers":["name:content"],"verdict":"digest-only","why":"A hash of the tool answer kept for the signed receipt; 64 hex characters, no text."},"type":"text"},{"about_request":"yes","name":"seller_status","nullable":true,"purpose":"The tool's HTTP status code.","type":"integer"},{"about_request":"yes","name":"status","nullable":false,"purpose":"paying, ok, failed, released or charged_after_failure.","type":"text"},{"about_request":"yes","name":"failure","nullable":true,"purpose":"A fixed failure code, such as seller_status_500 or response_too_large.","type":"text"},{"about_request":"yes","flags":["type:json"],"name":"receipt","nullable":true,"purpose":"The tool.call receipt: COSE_Sign1 bytes (base64), key id, leaf and the signed claims (hashes, amounts, seller, address, settlement).","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Ids, hashes, amounts, the public tool address and wallet, and the signature over them; no arguments or answer text."},"type":"jsonb"},{"about_request":"yes","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"yes","name":"closed_at","nullable":true,"purpose":"When the hold was charged or released.","type":"timestamp with time zone"}],"name":"tool_calls","purpose":"One row per paid x402 tool call made with a key's balance: the seller, the tool address, the price and take, the hold, the signed authorization's nonce and the settlement transaction, the answer's hash and the signed tool.call receipt. Never the tool arguments, the query string or the answer.","retention":"No automatic deletion: these are billing records, like generations and the ledger."},{"about_request":"yes","category":"billing","columns":[{"about_request":"yes","name":"payer","nullable":false,"purpose":"The wallet that signed the payment authorization (lowercase hex), as on the public settlement.","type":"text"},{"about_request":"yes","name":"nonce","nullable":false,"purpose":"The authorization's EIP-3009 nonce (32 bytes hex), public on-chain once settled.","type":"text"},{"about_request":"yes","flags":["name:content"],"name":"request_sha256","nullable":false,"purpose":"SHA-256 of the request the payment paid for (the receipt's request_sha256). A recovery must send the identical request.","review":{"covers":["name:content"],"verdict":"digest-only","why":"A hash of the request body, compared with the hash of a recovery request so an answer is sent again only for the request it answered."},"type":"text"},{"about_request":"yes","flags":["name:content"],"name":"response_sha256","nullable":false,"purpose":"SHA-256 of the answer's bytes as they were sent, checked before the sealed answer is sent again.","review":{"covers":["name:content"],"verdict":"digest-only","why":"A hash of the answer bytes, so the answer sent again is checked to be byte-identical to the one first sent; the answer cannot be recovered from it."},"type":"text"},{"about_request":"yes","flags":["name:content"],"name":"body_ref","nullable":false,"purpose":"The name of the Redis key that holds the sealed answer: x402paid: and a SHA-256 of the payer and the nonce.","review":{"covers":["name:content"],"verdict":"no-request-content","why":"A fixed prefix and a hash of the payer and the nonce naming where the sealed answer lives; the answer bytes are never written to this column."},"type":"text"},{"about_request":"yes","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"x402_paid_results","purpose":"One row per x402 payment whose call was answered, so a payer who lost the answer can have it sent again instead of paying twice. It names the paying wallet and the authorization nonce and holds hashes; the answer itself is sealed outside the database.","retention":"24 hours. Recovery refuses an older row, and the x402-recovery-expire job (and, at most hourly, each router replica that keeps answers) deletes it together with any sealed answer still held for it."},{"about_request":"aggregate","category":"receipts","columns":[{"about_request":"aggregate","name":"id","nullable":false,"purpose":"Random public certificate id.","type":"text"},{"about_request":"aggregate","name":"key_hash","nullable":false,"purpose":"The certified key; never published.","type":"text"},{"about_request":"aggregate","flags":["type:json"],"name":"certificate","nullable":false,"purpose":"The signed certificate: random pseudonym, aggregate stats, Merkle root and anchor counts, the public profile slug and ERC-8004 agent id when registered.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Aggregates and hashes written by the router: no counterparty, no amount per counterparty, no request or answer text and no key hash."},"type":"jsonb"},{"about_request":"aggregate","name":"published","nullable":false,"purpose":"Whether the owner chose to show it on the public card.","type":"boolean"},{"about_request":"aggregate","name":"created_at","nullable":false,"purpose":"When it was issued.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"expires_at","nullable":false,"purpose":"Seven days after issuance.","type":"timestamp with time zone"}],"name":"agent_track_records","purpose":"Portable track-record certificates: a router-signed count, total spend, refund and dispute rates of one key's anchored receipts, with a Merkle root over those receipts' anchor leaves.","retention":"Until the key is deleted (cascade). Certificates expire after seven days but stay stored; published ones show on the card until they expire."},{"about_request":"aggregate","category":"receipts","columns":[{"about_request":"aggregate","name":"index","nullable":false,"purpose":"Anchor number, counting up from zero.","type":"integer"},{"about_request":"aggregate","name":"root","nullable":false,"purpose":"The Merkle root of the interval's receipt leaves (32 bytes, hex).","type":"text"},{"about_request":"aggregate","name":"from_ts","nullable":false,"purpose":"Start of the interval covered.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"to_ts","nullable":false,"purpose":"End of the interval covered.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"count","nullable":false,"purpose":"How many receipts the root covers.","type":"integer"},{"about_request":"aggregate","name":"tx_hash","nullable":true,"purpose":"The chain transaction that recorded the root.","type":"text"},{"about_request":"aggregate","name":"status","nullable":false,"purpose":"pending, submitted, confirmed or local.","type":"text"},{"about_request":"aggregate","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"anchors","purpose":"A Merkle root over the receipts signed in one interval, and the chain transaction that recorded it. Lets anyone check that a receipt existed at that time.","retention":"No automatic deletion, and rows are never changed after they are written."},{"about_request":"yes","category":"receipts","columns":[{"about_request":"yes","name":"provider_id","nullable":false,"purpose":"The attested host that produced the receipt.","type":"text"},{"about_request":"yes","name":"leaf","nullable":false,"purpose":"The receipt's leaf hash.","type":"text"},{"about_request":"yes","name":"anchor_id","nullable":false,"purpose":"The host_anchors row that includes it.","type":"integer"},{"about_request":"yes","name":"leaf_index","nullable":false,"purpose":"Its position in that root's tree.","type":"integer"},{"about_request":"yes","name":"receipt_id","nullable":false,"purpose":"The receipt's id.","type":"text"},{"about_request":"yes","name":"receipt_ts","nullable":false,"purpose":"The time the receipt itself states.","type":"timestamp with time zone"},{"about_request":"yes","name":"collected_at","nullable":false,"purpose":"When the router collected the leaf.","type":"timestamp with time zone"}],"name":"host_anchor_leaves","purpose":"The receipt leaves collected from attested hosts. A row holds a leaf hash, the receipt id and the time; not the receipt's own hashes or usage.","retention":"No automatic deletion, and rows are never changed after they are written."},{"about_request":"aggregate","category":"receipts","columns":[{"about_request":"aggregate","name":"id","nullable":false,"purpose":"Row number, counting up from 1.","type":"serial"},{"about_request":"aggregate","name":"provider_id","nullable":false,"purpose":"The attested host.","type":"text"},{"about_request":"aggregate","name":"attestation_ref","nullable":false,"purpose":"SHA-256 of the boot quote the router verified for that host.","type":"text"},{"about_request":"aggregate","name":"receipt_key_id","nullable":false,"purpose":"The host's receipt key id.","type":"text"},{"about_request":"aggregate","name":"receipt_public_key","nullable":false,"purpose":"The host's raw Ed25519 receipt public key, hex, as its verified quote bound it.","type":"text"},{"about_request":"aggregate","name":"root","nullable":false,"purpose":"The Merkle root of the collected leaves.","type":"text"},{"about_request":"aggregate","name":"from_ts","nullable":false,"purpose":"Start of the interval the leaves were collected in.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"to_ts","nullable":false,"purpose":"End of that interval.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"count","nullable":false,"purpose":"How many leaves the root covers.","type":"integer"},{"about_request":"aggregate","name":"status","nullable":false,"purpose":"pending, confirmed or local.","type":"text"},{"about_request":"aggregate","name":"tx_hash","nullable":true,"purpose":"The chain transaction that recorded the root.","type":"text"},{"about_request":"aggregate","name":"block_number","nullable":true,"purpose":"The block of that transaction.","type":"bigint"},{"about_request":"aggregate","name":"chain_index","nullable":true,"purpose":"The anchor's index in the on-chain receipt anchor contract once posted.","type":"integer"},{"about_request":"aggregate","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"host_anchors","purpose":"A Merkle root over the receipts one attested host signed in an interval, tied to the attestation its receipt key was bound in.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"yes","category":"receipts","columns":[{"about_request":"yes","name":"generation_id","nullable":false,"purpose":"Router generation ID; no prompt or response bytes.","type":"text"},{"about_request":"yes","name":"provider_id","nullable":false,"purpose":"Provider that served the call.","type":"text"},{"about_request":"yes","name":"receipt_id","nullable":false,"purpose":"Strict rcpt_ identifier from the upstream response header, not caller-provided text.","type":"text"},{"about_request":"yes","name":"accrued_period","nullable":true,"purpose":"Null until included in a network invoice; then the UTC accrual hour preventing repeated accrual.","type":"text"}],"name":"network_receipt_links","purpose":"Links a router generation to a sidecar receipt ID from the response header, so only work included in that host's confirmed root can be invoiced. The collected leaf's signature is checked by host-anchor. Each sidecar receipt may be linked once per provider.","retention":"No automatic deletion, and rows are never changed after they are written."},{"about_request":"no","category":"receipts","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Key id: 16 hex characters, the first bytes of the public key's digest.","type":"text"},{"about_request":"no","name":"public_key","nullable":false,"purpose":"The raw 32-byte public key, hex. Published at /api/v1/receipts/keys.","type":"text"},{"about_request":"no","name":"private_key_enc","nullable":true,"purpose":"The private key, AES-256-GCM encrypted with the router's APP_SECRET. Null for a key that can no longer sign; the router then makes a new one.","type":"text"},{"about_request":"no","name":"valid_from","nullable":false,"purpose":"When the key started signing.","type":"timestamp with time zone"},{"about_request":"no","name":"retired_at","nullable":true,"purpose":"When it stopped signing, once rotated out.","type":"timestamp with time zone"},{"about_request":"no","name":"onchain_tx","nullable":true,"purpose":"The transaction that published the public key on chain.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"receipt_keys","purpose":"The Ed25519 keys that sign receipts, with the dates each was valid. Public halves are published; the private half is encrypted at rest.","retention":"Keys are rotated (RECEIPT_KEY_ROTATION_DAYS) and retired, never deleted, so old receipts stay verifiable."},{"about_request":"no","category":"receipts","columns":[{"about_request":"no","name":"size","nullable":false,"purpose":"The tree size the checkpoint is for.","type":"bigint"},{"about_request":"no","name":"root_hash","nullable":false,"purpose":"The tree's root hash, hex.","type":"text"},{"about_request":"no","name":"checkpoint","nullable":false,"purpose":"The checkpoint text: origin, size and base64 root hash.","type":"text"},{"about_request":"no","name":"signature","nullable":false,"purpose":"The log's signature line over that text.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"tlog_checkpoints","purpose":"Signed checkpoints of the transparency log: its size and root, signed by the log's key.","retention":"No automatic deletion, and rows are never changed after they are written."},{"about_request":"no","category":"receipts","columns":[{"about_request":"no","name":"size","nullable":false,"purpose":"The checkpoint size the witness signed.","type":"bigint"},{"about_request":"no","name":"witness","nullable":false,"purpose":"The witness's key name.","type":"text"},{"about_request":"no","name":"key_id","nullable":false,"purpose":"Hex of the 4-byte signed-note key id.","type":"text"},{"about_request":"no","name":"timestamp","nullable":false,"purpose":"The cosignature's own time, in seconds.","type":"bigint"},{"about_request":"no","name":"line","nullable":false,"purpose":"The signature line as the witness sent it.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When a newer cosignature from the same witness replaced the row.","type":"timestamp with time zone"}],"name":"tlog_cosignatures","purpose":"Witness cosignatures on checkpoints: independent parties confirming the log showed them the same tree.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"receipts","columns":[{"about_request":"no","name":"idx","nullable":false,"purpose":"The entry's leaf index in the log.","type":"bigint"},{"about_request":"no","name":"kind","nullable":false,"purpose":"receipt_key, ohttp_key_config, blind_issuer_key, measurement_bundle, attestation_binding or data_inventory.","type":"text"},{"about_request":"no","name":"sha256","nullable":false,"purpose":"Hex digest of the key or configuration the entry names.","type":"text"},{"about_request":"no","name":"subject","nullable":false,"purpose":"The key id, epoch, provider or inventory the entry is about.","type":"text"},{"about_request":"no","name":"entry","nullable":false,"purpose":"The exact canonical JSON that was hashed into the log: public keys, digests and configuration, never request data. Sidecar bindings v2 include the source archive hash, engine name and image digest, and model ID and digest.","type":"text"},{"about_request":"no","name":"leaf_hash","nullable":false,"purpose":"The entry's RFC 6962 leaf hash.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"tlog_entries","purpose":"The entries of the public transparency log: receipt keys, Oblivious HTTP key configurations, blind-token issuer keys, measurement bundles, attestation bindings and data inventories (this page's own hash).","retention":"Append-only by design: entries are never updated or deleted, because the log's tree hashes them."},{"about_request":"no","category":"receipts","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Row number, counting up from 1.","type":"serial"},{"about_request":"no","name":"size","nullable":false,"purpose":"The checkpoint's tree size.","type":"bigint"},{"about_request":"no","name":"root_hash","nullable":false,"purpose":"The checkpoint's root hash, hex.","type":"text"},{"about_request":"no","flags":["name:content"],"name":"note","nullable":false,"purpose":"The signed checkpoint note that was anchored: checkpoint text, a blank line and the log's signature line.","review":{"covers":["name:content"],"verdict":"no-request-content","why":"The note is the transparency-log checkpoint text (origin, size, root hash) plus a signature line; nothing else is ever placed in it."},"type":"text"},{"about_request":"no","name":"artifact_sha256","nullable":false,"purpose":"The SHA-256 the Rekor entry holds.","type":"text"},{"about_request":"no","name":"key_id","nullable":false,"purpose":"SHA-256 of the anchoring key's public key info, hex.","type":"text"},{"about_request":"no","flags":["name:network"],"name":"rekor_url","nullable":false,"purpose":"The address of the Rekor log the entry was submitted to.","review":{"covers":["name:network"],"verdict":"public-reference","why":"The address of a public transparency log server, set by the operator; it is not a caller's address."},"type":"text"},{"about_request":"no","name":"uuid","nullable":false,"purpose":"The Rekor entry id.","type":"text"},{"about_request":"no","name":"status","nullable":false,"purpose":"pending or verified. Only verified rows are served.","type":"text"},{"about_request":"no","name":"log_index","nullable":true,"purpose":"The entry's index in Rekor.","type":"bigint"},{"about_request":"no","name":"integrated_time","nullable":true,"purpose":"When Rekor integrated the entry, in seconds.","type":"bigint"},{"about_request":"no","name":"log_id","nullable":true,"purpose":"Rekor's log id.","type":"text"},{"about_request":"no","name":"entry_base64","nullable":true,"purpose":"The entry body as Rekor returned it, base64.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"inclusion_proof","nullable":true,"purpose":"The inclusion proof: log index, tree size, root hash, hashes and Rekor's checkpoint.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Copied from Rekor's inclusion-proof response and typed as { logIndex, treeSize, rootHash, hashes, checkpoint }."},"type":"jsonb"},{"about_request":"no","name":"signed_entry_timestamp","nullable":true,"purpose":"Rekor's signed entry timestamp, base64.","type":"text"},{"about_request":"no","name":"checkpoint_verified","nullable":false,"purpose":"Whether Rekor's checkpoint signature verified against the pinned key.","type":"boolean"},{"about_request":"no","name":"set_verified","nullable":false,"purpose":"Whether the signed entry timestamp verified against the pinned key.","type":"boolean"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"verified_at","nullable":true,"purpose":"When the inclusion proof verified.","type":"timestamp with time zone"}],"name":"tlog_rekor_anchors","purpose":"Records of checkpoints the router anchored in a public Rekor log, with the proof that the entry is included.","retention":"A pending row that turns out not to be an entry for its checkpoint is dropped and the checkpoint is submitted again; verified rows are kept."},{"about_request":"yes","category":"keys","columns":[{"about_request":"yes","name":"id","nullable":false,"purpose":"Random URL-safe decision identifier, not an authentication credential.","type":"text"},{"about_request":"yes","name":"key_hash","nullable":false,"purpose":"Hash of the deciding API key; only that key can report an outcome.","type":"text"},{"about_request":"yes","name":"event_id","nullable":false,"purpose":"Identifier of the aggregate action decision on the existing agent event hash chain; events have their own retention.","type":"bigint"},{"about_request":"yes","name":"action","nullable":false,"purpose":"Caller-chosen bounded action name such as trade.order or transfer.send.","type":"text"},{"about_request":"yes","name":"target","nullable":true,"purpose":"Optional caller-chosen symbol, recipient wallet address or host label, stored verbatim; this is not the caller's network address.","type":"text"},{"about_request":"yes","name":"amount_pico","nullable":false,"purpose":"Requested action amount in integer pico-USD; an unreported allow holds this amount against the daily action limit.","type":"numeric(78, 0)"},{"about_request":"yes","name":"details_sha256","nullable":true,"purpose":"Optional SHA-256 digest of canonical order JSON; order details themselves are not stored.","type":"text"},{"about_request":"yes","name":"decision","nullable":false,"purpose":"allow, deny or approval_required from the rulebooks checked at decision time.","type":"text"},{"about_request":"yes","name":"created_at","nullable":false,"purpose":"When the decision was recorded.","type":"timestamp with time zone"},{"about_request":"yes","name":"outcome_status","nullable":true,"purpose":"Null before reporting; executed, skipped or failed afterward, accepted once only for an allowed action.","type":"text"},{"about_request":"yes","name":"outcome_amount_pico","nullable":true,"purpose":"Optional agent-reported actual pico-USD amount, required for executed; it may exceed the allowed amount and is not verified against a brokerage or chain.","type":"numeric(78, 0)"},{"about_request":"yes","name":"outcome_at","nullable":true,"purpose":"When the deciding key reported its outcome, or null before reporting.","type":"timestamp with time zone"}],"name":"agent_action_decisions","notes":["Action and target labels remain readable, including symbols, recipient wallet addresses or hosts supplied by the agent. Do not send secrets or request text in these labels. Only a SHA-256 digest of order details is accepted; full orders are not accepted here.","Unreported allowed actions count their requested amount. Executed outcomes count the agent-reported amount; skipped and failed outcomes release the daily amount. All allowed checks still count toward the hourly count. These records do not prove execution or control brokerage or wallet keys."],"purpose":"Action checks, reported outcomes and rolling action limits for the deciding agent key, separate from model spend.","retention":"Rows remain until operator deletion. Rolling day and hour limits read only the preceding 24 hours and hour; those windows do not delete records."},{"about_request":"yes","category":"keys","columns":[{"about_request":"yes","name":"id","nullable":false,"purpose":"Random URL-safe approval identifier, not an authentication credential.","type":"text"},{"about_request":"yes","name":"key_hash","nullable":false,"purpose":"The API or session key requesting this approval; approval cannot transfer to another key.","type":"text"},{"about_request":"yes","flags":["type:json"],"name":"intent","nullable":false,"purpose":"Explicit projection of model, lane, declared tool names, output token limit and estimated pico-USD cost, or action name, target, order digest and pico-USD amount; a multi-model request stores an intents array.","review":{"covers":["type:json"],"verdict":"config","why":"Only routing or action metadata is copied; action targets can be symbols, recipient wallets or hosts. messages, answers, tool arguments and descriptions are excluded. Declared model and tool identifiers are caller-chosen labels whose meaning cannot be inferred by shape checks."},"type":"jsonb"},{"about_request":"yes","name":"intent_hash","nullable":false,"purpose":"SHA-256 of canonical projected intents including the estimated cost, used to reuse an identical pending approval.","type":"text"},{"about_request":"yes","name":"max_cost_pico","nullable":false,"purpose":"The original estimated pico-USD cost ceiling; retries may cost less but cannot exceed this amount.","type":"numeric(78, 0)"},{"about_request":"yes","name":"status","nullable":false,"purpose":"pending, approved, denied, expired or used. Only approved, unexpired approvals can be consumed.","type":"text"},{"about_request":"yes","name":"requested_at","nullable":false,"purpose":"When the approval was created.","type":"timestamp with time zone"},{"about_request":"yes","name":"decided_at","nullable":true,"purpose":"When the principal approved or denied the request, or null.","type":"timestamp with time zone"},{"about_request":"yes","name":"decided_by","nullable":true,"purpose":"The deciding principal's API key hash, or null before a decision.","type":"text"},{"about_request":"yes","name":"expires_at","nullable":false,"purpose":"The fixed validity deadline from request time; approval does not extend it.","type":"timestamp with time zone"},{"about_request":"yes","name":"used_at","nullable":true,"purpose":"When the router consumed the approval after a successful spend reservation, on an allowed cache hit, or on an allowed action check.","type":"timestamp with time zone"}],"name":"agent_approvals","notes":["No prompt or answer fields are stored. Model and declared tool names remain readable; callers choose these identifiers. The router still reads request text in memory on every lane. Action approvals store the action name, optional readable target (including wallet or host labels), optional order digest and amount, never full order details. Council and dual requests store the entire set of model intents with a shared total cost ceiling."],"purpose":"Principal approval of an agent's estimated inference spend or reported action amount, consumed once by the requesting key.","retention":"Approval validity defaults to 15 minutes (AGENT_APPROVAL_TTL_S). Pending and approved rows become expired on access or another approval evaluation. Rows remain until operator deletion; validity expiry does not delete records."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Random public feedback id.","type":"text"},{"about_request":"no","name":"subject_key_hash","nullable":false,"purpose":"The reviewed agent's key; never published.","type":"text"},{"about_request":"no","name":"reviewer_account_id","nullable":false,"purpose":"The paying account, kept to enforce one entry per receipt and the reviewer's right to withdraw; never published.","type":"text"},{"about_request":"no","name":"receipt_kind","nullable":false,"purpose":"Fixed receipt kind such as model.call or agreement.release.","type":"text"},{"about_request":"no","name":"receipt_id","nullable":false,"purpose":"The router's own receipt or agreement milestone id that backs the entry; never published.","type":"text"},{"about_request":"no","name":"score","nullable":false,"purpose":"Score from 0 to 100.","type":"integer"},{"about_request":"no","name":"tag1","nullable":true,"purpose":"Optional short tag (letters, digits, spaces and . _ : - only, up to 32 characters).","type":"text"},{"about_request":"no","name":"tag2","nullable":true,"purpose":"Optional second short tag, same limits.","type":"text"},{"about_request":"no","name":"paid_pico","nullable":false,"purpose":"What the reviewer paid on the receipt, net of recorded refunds, in pico-USD; used for weighting and shown only as a band.","type":"bigint"},{"about_request":"no","name":"paid_at","nullable":false,"purpose":"When the payment happened; weights halve every PAID_FEEDBACK_HALF_LIFE_DAYS after it.","type":"timestamp with time zone"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the entry was written.","type":"timestamp with time zone"},{"about_request":"no","name":"revoked_at","nullable":true,"purpose":"When the reviewer withdrew it; null while it counts.","type":"timestamp with time zone"}],"name":"agent_feedback","notes":["Public: the score, tags, receipt kind, a coarse payment band and the payment day, linked to the agent's public profile slug. Never public: the reviewer's account, the receipt id and the exact amount. One entry per receipt."],"purpose":"Paid feedback: a 0 to 100 score and up to two short tags per receipt, accepted only from the receipt's payer about its payee or the agent it served.","retention":"Until the subject key is deleted (cascade). A reviewer can withdraw an entry, which stops counting it; the row is kept with its withdrawal time. No automatic deletion."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"key_hash","nullable":false,"purpose":"The agent key these choices belong to; never published.","type":"text"},{"about_request":"no","name":"id","nullable":false,"purpose":"Random 144-bit public id used in the registration file URL; independent of the key hash and the profile slug.","type":"text"},{"about_request":"no","name":"identity_opt_out","nullable":true,"purpose":"Owner's choice; null means the default (opted out only when the key's rulebook allows only the unlinkable lane).","type":"boolean"},{"about_request":"no","name":"reputation_opt_in","nullable":false,"purpose":"Owner's choice to accept paid feedback; false by default.","type":"boolean"},{"about_request":"no","name":"status","nullable":false,"purpose":"Fixed registration state: none, awaiting_owner, queued, submitted, registered or failed.","type":"text"},{"about_request":"no","name":"mode","nullable":true,"purpose":"owner (the owner's wallet sends the transaction) or registrar (the isolated worker sends it).","type":"text"},{"about_request":"no","name":"registry","nullable":true,"purpose":"Public registry identifier eip155:<chain id>:<contract address>.","type":"text"},{"about_request":"no","name":"agent_id","nullable":true,"purpose":"The public ERC-8004 agent id read from the registration transaction.","type":"text"},{"about_request":"no","flags":["name:network"],"name":"owner_address","nullable":true,"purpose":"The wallet that holds the identity token, read from the public registration event.","review":{"covers":["name:network"],"verdict":"wallet-address","why":"A blockchain wallet address from a public on-chain event, not a network address; it is shown to the owner only."},"type":"text"},{"about_request":"no","name":"tx_hash","nullable":true,"purpose":"The public registration transaction hash.","type":"text"},{"about_request":"no","flags":["name:content"],"name":"error","nullable":true,"purpose":"Fixed failure code of the last registration attempt.","review":{"covers":["name:content"],"verdict":"no-request-content","why":"Only fixed codes written by the router (reverted, no_registration, uri_mismatch, send_failed); never library text, a request or an answer."},"type":"text"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row last changed.","type":"timestamp with time zone"}],"name":"agent_identities","notes":["The ERC-8004 identity registry is a public contract the router does not operate. The registration file it points to is served only while the key has not opted out and contains owner-written profile fields and router links, never the key hash or account. Keys whose rulebook allows only the unlinkable lane are opted out unless the owner opts in."],"purpose":"Per agent key: the owner's identity opt-out and reputation opt-in, and the progress of an ERC-8004 identity registration the owner asked for.","retention":"Until the key is deleted (cascade). Opting out keeps the row so the choice persists. A registration sent to the chain is public and permanent there; deleting this row does not remove it."},{"about_request":"yes","category":"keys","columns":[{"about_request":"yes","name":"id","nullable":false,"purpose":"Allocated correlation identifier.","type":"bigserial"},{"about_request":"yes","flags":["name:content"],"name":"request_id","nullable":false,"purpose":"Router-generated request scope identifier; groups multiple models and inherited policy evaluations in one request.","review":{"covers":["name:content"],"verdict":"no-request-content","why":"A random UUID is generated inside the router for correlation. It never includes a URL, body, prompt, answer, or any caller-supplied string."},"type":"text"},{"about_request":"yes","name":"key_hash","nullable":false,"purpose":"The actual requesting API key or session key, rather than the parent policy key.","type":"text"},{"about_request":"yes","name":"ts","nullable":false,"purpose":"When the correlation was recorded, in UTC.","type":"timestamp with time zone"},{"about_request":"yes","name":"event_id","nullable":true,"purpose":"The exact policy decision or approval-use event; null for generation links. Removed with its event.","type":"bigint"},{"about_request":"yes","name":"generation_id","nullable":true,"purpose":"The exact generation or reservation identifier; null for event links. A failed reservation or provider call need not produce a generation.","type":"text"},{"about_request":"yes","name":"approval_id","nullable":true,"purpose":"The approval identifier on a recorded approval-use event; otherwise null.","type":"text"}],"name":"agent_ledger_links","notes":["Only router-generated identifiers, timestamps and key hashes are stored. No prompt or answer text is added. A reservation link can precede a generation or remain without one after a provider failure. Existing records without correlation remain separate and are marked unlinked in the API. Parent policy events are attributed to the session key that made the request. The ledger describes policy evaluations and recorded generations through AnyRoute; errors before policy evaluation or generation creation have no ledger row."],"purpose":"Explicit correlation of rulebook decision events, requesting keys and generation identifiers for the agent activity ledger.","retention":"90 days; the agent-ledger-retention worker removes older links hourly when AGENT_POLICY_ENABLED is on. Deleting a linked event also removes that event's link. Generations retain their existing lifetime. With the flag off or worker absent, deletion waits."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"key_hash","nullable":false,"purpose":"The listed agent key; never published.","type":"text"},{"about_request":"no","flags":["name:network"],"name":"endpoint_sha256","nullable":false,"purpose":"SHA-256 of the probed endpoint URL, so a changed endpoint invalidates the old result.","review":{"covers":["name:network"],"verdict":"digest-only","why":"A digest of the owner-declared public endpoint URL; never a caller's network address."},"type":"text"},{"about_request":"no","name":"live","nullable":false,"purpose":"Whether the endpoint answered with a status below 500, other than 404 and 410, within the timeout.","type":"boolean"},{"about_request":"no","name":"http_status","nullable":true,"purpose":"The status code the endpoint answered with; null when it did not answer.","type":"integer"},{"about_request":"no","name":"latency_ms","nullable":true,"purpose":"Time to the response headers in milliseconds.","type":"integer"},{"about_request":"no","flags":["name:content"],"name":"error","nullable":true,"purpose":"Fixed failure code: timeout, network, blocked or http.","review":{"covers":["name:content"],"verdict":"no-request-content","why":"Only fixed codes chosen by the router; no response body, header or library message is stored."},"type":"text"},{"about_request":"no","name":"probed_at","nullable":false,"purpose":"When the probe ran.","type":"timestamp with time zone"},{"about_request":"no","flags":["type:json"],"name":"receipt","nullable":false,"purpose":"The probe receipt the router signed with its receipt key: the public profile slug, endpoint digest, time, result, status and latency.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Fixed fields written by the router, signed with the published receipt key; no response body, headers or key hash."},"type":"jsonb"}],"name":"agent_liveness","purpose":"The latest signed liveness probe of each listed agent's declared endpoint (daily agent-liveness job).","retention":"Replaced by each probe; deleted with the key (cascade). A result for an endpoint the owner has since changed is not shown."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"key_hash","nullable":false,"purpose":"The API key this rulebook governs.","type":"text"},{"about_request":"no","name":"version","nullable":false,"purpose":"Rulebook schema version, currently 1.","type":"integer"},{"about_request":"no","flags":["type:json"],"name":"spec","nullable":false,"purpose":"Optional agreements.max_escrow_usd and counterparties_allow restrict preparation through the router; they do not enforce transactions sent elsewhere. Strict bounded rulebook: model and tool allow/deny names, lanes, an optional default privacy route (route_default) for requests that name no lane, cost and output caps, UTC windows, approval threshold, optional spend/request/denial/distinct-model circuit breakers and breach action, plus optional action and target allow/deny lists, separate action amount and count caps and an action approval threshold. Optional autonomy stores bounded rung requirements, spending multipliers and selected reset event kinds; it contains no prompt fields.","review":{"covers":["type:json"],"verdict":"config","why":"A strict schema excludes prompt and answer fields. Model and tool labels are owner-written identifiers of at most 160 characters; their contents are whatever the owner chooses to write."},"type":"jsonb"},{"about_request":"no","name":"sha256","nullable":false,"purpose":"SHA-256 of the canonical rulebook JSON.","type":"text"},{"about_request":"no","name":"killed","nullable":false,"purpose":"Whether the router refuses the next request under this rulebook.","type":"boolean"},{"about_request":"no","name":"killed_at","nullable":true,"purpose":"When the rulebook was killed, if it is killed.","type":"timestamp with time zone"},{"about_request":"no","name":"killed_reason","nullable":true,"purpose":"A principal-supplied reason of at most 160 characters, or fixed policy reason codes for an automatic kill, including breaker:<field> for circuit breakers.","type":"text"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the policy or kill state last changed.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_by","nullable":false,"purpose":"The principal key hash or the agent key hash for an automatic kill.","type":"text"},{"about_request":"no","name":"playbook_id","nullable":true,"purpose":"The playbook this key follows, or null. While set, spec and sha256 hold a copy of that playbook's current rules, rewritten in the same transaction as every playbook change; stopping following keeps the copy as the key's own rulebook.","type":"text"}],"name":"agent_policies","notes":["Model and tool identifiers and a kill reason are user-supplied text. Shape and size checks cannot judge the meaning a principal assigns to these labels. Action rules retain owner-chosen action names and target allow/deny labels, including recipient wallets or hosts; amount limits are separate from model caps. No prompt or answer fields are accepted."],"purpose":"The principal's current agent rulebook and kill state, enforced by the router for requests through AnyRoute.","retention":"Until the principal removes the rulebook. Updating a rulebook replaces its current specification and preserves kill state."},{"about_request":"yes","category":"keys","columns":[{"about_request":"yes","name":"id","nullable":false,"purpose":"Monotonically allocated event identifier for pagination.","type":"bigserial"},{"about_request":"yes","name":"key_hash","nullable":false,"purpose":"The key whose rulebook was evaluated or changed; parent decisions are recorded under the parent key.","type":"text"},{"about_request":"yes","name":"ts","nullable":false,"purpose":"When the event was recorded, at millisecond precision.","type":"timestamp with time zone"},{"about_request":"yes","name":"kind","nullable":false,"purpose":"action_decision and action_outcome (readable action/target identifiers, order digest and reported amounts), decision, breaker_request (one observation per policy admission batch with breakers), policy_set, killed, resumed, approval_requested, approval_approved, approval_denied or approval_used. Approval events are recorded under the requesting key. Removing a rulebook records policy_set with a null intent. Autonomy also records autonomy_clean once per allowed reservation or cache/tool authorization, autonomy_state for derived progress, and breaker for an agent breaker event.","type":"text"},{"about_request":"yes","name":"decision","nullable":true,"purpose":"allow, deny or approval_required for a decision; null for changes; breaker_request stores the batch decision.","type":"text"},{"about_request":"yes","flags":["type:json"],"name":"reasons","nullable":false,"purpose":"Fixed reason codes and router-written messages; policy change events carry an empty list.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Only evaluator-defined codes and constant messages are stored. No request text or principal-written kill reason is copied into this field."},"type":"jsonb"},{"about_request":"yes","flags":["type:json"],"name":"intent","nullable":true,"purpose":"Inference model, lane, estimated pico-USD cost, maximum output tokens and declared tool names; or an MCP tool name; action intents include a readable action and optional target (including recipient wallets or hosts), an amount and optional order digest, never full order details. Outcome events include the decision id, reported status and amount and whether it exceeded the requested amount. Approval and breaker_request events may contain an intents array for the full model set. Breaker counters read these routing identifiers and decisions; legacy decision events without a batch marker count individually. Resume resets breaker observations, leaving cap spend unchanged. Null for policy changes. An autonomy_state checkpoint stores only rung number, rung since timestamp, clean request count and last clean timestamp. Autonomy clean and breaker events have null intent; none stores prompt text.","review":{"covers":["type:json"],"verdict":"config","why":"Explicit metadata projection excludes messages, tool arguments, descriptions and answers. Model and tool identifiers are readable labels from the request or catalogue; a caller can choose what a declared tool name means."},"type":"jsonb"},{"about_request":"yes","name":"policy_sha256","nullable":false,"purpose":"Digest of the evaluated or changed rulebook.","type":"text"},{"about_request":"yes","name":"prev_hash","nullable":false,"purpose":"The previous retained chain head, or 64 zeros when no preceding event remains.","type":"text"},{"about_request":"yes","name":"hash","nullable":false,"purpose":"SHA-256 of prior hash bytes and canonical event fields excluding id, prev_hash and hash.","type":"text"}],"name":"agent_policy_events","purpose":"A per-key hash chain of rulebook decisions and policy, kill and resume changes. Decisions contain routing metadata, never prompts or answers.","retention":"90 days; the agent-policy-retention worker removes older events hourly when AGENT_POLICY_ENABLED is on and the worker runs this job. With the flag off or the worker absent, deletion waits. A retained suffix starts with its prior hash as a checkpoint. For active autonomy rulebooks, the latest autonomy_state checkpoint and following suffix remain until superseded or the rulebook is removed, even beyond 90 days, to preserve earned progress."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"slug","nullable":false,"purpose":"Random 144-bit public identifier independent of the key hash; regenerated after unpublish and republish.","type":"text"},{"about_request":"no","name":"key_hash","nullable":false,"purpose":"Internal unique key association for ownership checks and current opted-in policy categories; never returned in public cards.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"settings","nullable":false,"purpose":"Validated public display name, short description, optional HTTP(S) homepage, optional HTTPS agent endpoint (probed daily for liveness when AGENT_IDENTITY_ENABLED is on), optional payout wallet that other agents pay directly in USDG, capability tags and selected rulebook categories.","review":{"covers":["type:json"],"verdict":"config","why":"Owner-supplied publication settings deliberately become public. They contain bounded text and chosen category names, never a copied private rulebook or automatic key identifiers."},"type":"jsonb"},{"about_request":"no","flags":["type:json"],"name":"certificates","nullable":false,"purpose":"Latest router-issued certificate for the selected key and chosen claims; replaced or cleared on each publication update.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Strict signed claim identifiers, fresh pseudonym, issuance and expiry times, signing key identifier and signature. Valid certificates are public; expired or invalid certificates stay stored until update or deletion but are not returned publicly."},"type":"jsonb"}],"name":"agent_profiles","notes":["Public: random slug, owner-written name, description, optional homepage, optional payout wallet, capability tags, only selected boolean rulebook categories, and selected router-issued certificates while signatures and expiry are valid. Publishing intentionally links certificate pseudonyms to this profile. The private key-hash mapping is never returned publicly; the router still knows it. Disabled or expired keys are hidden. No certificate or rulebook proves host sealing or hardware attestation, which is reported unavailable. User-written text can identify its owner. No inference prompt or answer is collected here."],"purpose":"Opt-in public agent cards and an internal mapping to the owned key for updates, removal and selected live rulebook summaries.","retention":"Until unpublish or deletion of the key. Profile updates replace settings and certificates. Database backups and copies made by public readers can outlive deletion."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Session id.","type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"The account the session belongs to.","type":"text"},{"about_request":"no","name":"parent_key_hash","nullable":false,"purpose":"The key that created the session.","type":"text"},{"about_request":"no","name":"key_hash","nullable":false,"purpose":"The session's own key hash (a row in keys).","type":"text"},{"about_request":"no","name":"name","nullable":false,"purpose":"A label the creator gave the session.","type":"text"},{"about_request":"no","name":"budget","nullable":true,"purpose":"The session's spend cap in pico-USD; empty means only the parent key's limits apply.","type":"bigint"},{"about_request":"no","name":"expires_at","nullable":false,"purpose":"When the session ends by itself.","type":"timestamp with time zone"},{"about_request":"no","name":"ended_at","nullable":true,"purpose":"When it ended.","type":"timestamp with time zone"},{"about_request":"no","name":"end_reason","nullable":true,"purpose":"ended, expired or budget.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"metadata","nullable":true,"purpose":"Labels the creator attached to the session: up to 32 short string, number or boolean values, 2 KB in all.","review":{"covers":["type:json"],"verdict":"config","why":"checkMetadata refuses key names that look like prompt or completion text (such as prompt or messages), at most 32 keys, string values of at most 256 characters and 2,048 bytes in all. It cannot judge what a creator types into a value, so the text is whatever the creator wrote."},"type":"jsonb"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"agent_sessions","purpose":"A short-lived sub-key for one agent run, with its own budget and expiry, so an agent's spending can be capped and ended.","retention":"Ended sessions keep their row; a session ends at its expiry, when its budget is spent or when its owner ends it."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"key_id","nullable":false,"purpose":"The token key id: hex SHA-256 of the RFC 9578 public key info.","type":"text"},{"about_request":"no","name":"epoch","nullable":false,"purpose":"The epoch the key issues in.","type":"integer"},{"about_request":"no","name":"denomination","nullable":false,"purpose":"Token units a token from this key is worth.","type":"integer"},{"about_request":"no","name":"unit_price","nullable":false,"purpose":"Pico-USD per token unit, fixed when the key is made.","type":"bigint"},{"about_request":"no","name":"spki","nullable":false,"purpose":"The public key, base64url.","type":"text"},{"about_request":"no","name":"private_enc","nullable":true,"purpose":"The private key, AES-GCM encrypted with APP_SECRET. Null once the key no longer issues.","type":"text"},{"about_request":"no","name":"valid_from","nullable":false,"purpose":"When the key started.","type":"timestamp with time zone"},{"about_request":"no","name":"issue_until","nullable":false,"purpose":"When it stops signing new tokens.","type":"timestamp with time zone"},{"about_request":"no","name":"redeem_until","nullable":false,"purpose":"When tokens from it stop being accepted.","type":"timestamp with time zone"},{"about_request":"no","name":"revoked_at","nullable":true,"purpose":"When it was revoked, if it was.","type":"timestamp with time zone"},{"about_request":"no","name":"issued","nullable":false,"purpose":"How many tokens were signed: a count and nothing else.","type":"bigint"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"blind_keys","purpose":"Issuer keys for blind tokens (Privacy Pass): one per epoch and denomination. Nothing here links a buyer to a token.","retention":"The private half is wiped when the epoch stops issuing; the public half stays so old tokens remain verifiable."},{"about_request":"yes","category":"keys","columns":[{"about_request":"yes","name":"nullifier","nullable":false,"purpose":"SHA-256 of the token.","type":"text"},{"about_request":"yes","name":"key_id","nullable":false,"purpose":"The issuer key that signed it.","type":"text"},{"about_request":"yes","name":"status","nullable":false,"purpose":"reserved while a request runs, spent once served.","type":"text"},{"about_request":"yes","name":"reserved_at","nullable":false,"purpose":"When the token was reserved.","type":"timestamp with time zone"},{"about_request":"yes","name":"spent_at","nullable":true,"purpose":"When the request it paid for was served.","type":"timestamp with time zone"},{"about_request":"yes","name":"generation_id","nullable":true,"purpose":"The generation the token paid for; all members of a set share it, linking those redeemed tokens to the same request but never to a purchase.","type":"text"}],"name":"blind_nullifiers","purpose":"Spent blind tokens, one row per token including each member of a request set reserved atomically. A row holds the SHA-256 of a token so it cannot be spent twice; the issuer cannot connect that hash to the blinded request it signed.","retention":"A reservation is deleted if the request fails before anything is served; spent rows are kept so a token cannot be replayed."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Row number, counting up from 1.","type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"The account that brought the key.","type":"text"},{"about_request":"no","name":"provider_id","nullable":false,"purpose":"The provider the key is for.","type":"text"},{"about_request":"no","name":"key_enc","nullable":false,"purpose":"The provider key, AES-256-GCM encrypted with the router's APP_SECRET.","type":"text"},{"about_request":"no","name":"label","nullable":false,"purpose":"A masked label so the owner can tell keys apart.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"byok_keys","purpose":"A provider API key an account brought so calls to that provider use its own account there. Stored encrypted; only the router can decrypt it, to make calls for that account.","retention":"Kept until the owner deletes it (DELETE /api/v1/byok/:provider removes the row)."},{"about_request":"aggregate","category":"keys","columns":[{"about_request":"aggregate","name":"id","nullable":false,"purpose":"Random record id.","type":"text"},{"about_request":"aggregate","name":"ref","nullable":false,"purpose":"What triggered it: settle:<hold id> after a debit, reserve:<request id> when the key's limit would refuse a request, or skip:<key hash>:<reason>:<limit>:<week> for a skipped top-up. Unique, so each is recorded once.","type":"text"},{"about_request":"aggregate","name":"key_hash","nullable":false,"purpose":"The key whose limit was raised.","type":"text"},{"about_request":"aggregate","name":"account_id","nullable":false,"purpose":"The account the key belongs to.","type":"text"},{"about_request":"aggregate","name":"outcome","nullable":false,"purpose":"added, skipped_balance (the account's available credits did not cover the key's allowance after it), skipped_weekly (the rule's weekly maximum) or skipped_org_budget (the team's org budget).","type":"text"},{"about_request":"aggregate","name":"amount_pico","nullable":false,"purpose":"The rule's top-up amount in pico-USD.","type":"bigint"},{"about_request":"aggregate","name":"limit_before_pico","nullable":false,"purpose":"The key's limit before, in pico-USD.","type":"bigint"},{"about_request":"aggregate","name":"limit_after_pico","nullable":false,"purpose":"The key's limit after; the same as before when skipped.","type":"bigint"},{"about_request":"aggregate","name":"spent_pico","nullable":false,"purpose":"The key's spend counted against its limit when checked, in pico-USD.","type":"bigint"},{"about_request":"aggregate","name":"available_pico","nullable":false,"purpose":"The account's balance minus open holds when checked, in pico-USD.","type":"bigint"},{"about_request":"aggregate","name":"week_start","nullable":false,"purpose":"UTC Monday 00:00 of the week the top-up counts in.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"week_total_pico","nullable":false,"purpose":"Top-ups added to the key that week, including this one when added, in pico-USD.","type":"bigint"},{"about_request":"aggregate","name":"max_per_week_pico","nullable":false,"purpose":"The rule's weekly maximum, in pico-USD.","type":"bigint"},{"about_request":"aggregate","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"key_topups","purpose":"One row per auto top-up of a key's limit, and one per top-up the router skipped and why (once per key, reason, limit and week). No money moves: the limit is an allowance on the account's own balance. Activity and the inbox show these rows.","retention":"No automatic deletion, and rows are never changed after they are written."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"key_hash","nullable":false,"purpose":"SHA-256 of the key's secret. The secret itself is never stored.","type":"text"},{"about_request":"no","name":"chain_key_hash","nullable":false,"purpose":"keccak256 of the address derived from the secret, the id the on-chain contracts use for the key.","type":"text"},{"about_request":"no","flags":["name:network"],"name":"key_address","nullable":false,"purpose":"The blockchain address derived from the key's secret. It is public on chain when the key is funded.","review":{"covers":["name:network"],"verdict":"wallet-address","why":"A blockchain address derived from the key, not a network address of a caller."},"type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"The account the key belongs to.","type":"text"},{"about_request":"no","name":"parent_hash","nullable":true,"purpose":"For a key made from another key (an agent session), the parent's key hash.","type":"text"},{"about_request":"no","name":"name","nullable":false,"purpose":"The label the owner gave the key.","type":"text"},{"about_request":"no","name":"label","nullable":false,"purpose":"A masked display form of the key, such as sk-ar-v1-abcd...wxyz: the first and last few characters only.","type":"text"},{"about_request":"no","name":"budget","nullable":true,"purpose":"The key's spend limit in pico-USD. Empty means unlimited.","type":"bigint"},{"about_request":"no","name":"budget_reset","nullable":true,"purpose":"How often the budget resets: daily, weekly or monthly, or never.","type":"text"},{"about_request":"no","name":"period_start","nullable":true,"purpose":"When the current budget period began.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"spent","nullable":false,"purpose":"Spend in the current budget period, in pico-USD.","type":"bigint"},{"about_request":"aggregate","name":"spent_total","nullable":false,"purpose":"All-time spend of the key, in pico-USD.","type":"bigint"},{"about_request":"no","name":"rpm","nullable":true,"purpose":"Requests-per-minute limit for the key.","type":"integer"},{"about_request":"no","name":"tpm","nullable":true,"purpose":"Tokens-per-minute limit for the key.","type":"integer"},{"about_request":"no","name":"team_id","nullable":true,"purpose":"The team the key belongs to, when it has one.","type":"text"},{"about_request":"no","name":"allowed_models","nullable":true,"purpose":"If set, the only models the key may call.","type":"text[]"},{"about_request":"no","name":"pay_with_default","nullable":true,"purpose":"The Stock Token symbol the key pays with by default.","type":"text"},{"about_request":"no","name":"scope","nullable":true,"purpose":"Null keeps account access; inference permits model calls and this key’s own generation and receipt reads only.","type":"text"},{"about_request":"no","name":"include_byok_in_limit","nullable":false,"purpose":"Stored compatibility selection. Provider-side BYOK expenditure is not tracked; usage counts router-billed charges once.","type":"boolean"},{"about_request":"no","name":"management","nullable":false,"purpose":"Whether the key may manage other keys.","type":"boolean"},{"about_request":"no","flags":["type:json"],"name":"routing","nullable":true,"purpose":"Imported routing presets: model aliases and default provider preferences the owner set for this key.","review":{"covers":["type:json"],"verdict":"config","why":"Routing settings written by the key's owner and validated as aliases and provider preferences; there is no field for message text."},"type":"jsonb"},{"about_request":"no","flags":["type:json"],"name":"guardrails","nullable":true,"purpose":"The key's input guardrails: PII mode, phrases to block, a maximum input length and whether to redact output.","review":{"covers":["type:json"],"verdict":"config","why":"The owner's filter settings. Deny phrases are words the owner wants blocked (up to 50 of 200 characters); they are rules, not requests."},"type":"jsonb"},{"about_request":"no","flags":["type:json"],"name":"tracing","nullable":true,"purpose":"Where the key's owner asked for traces of this key's public-lane calls to go (their own OpenTelemetry collector, Langfuse or Helicone), and whether to include prompt and completion text. The destination URL and credentials are AES-256-GCM encrypted with APP_SECRET and never returned by the API.","review":{"covers":["type:json"],"verdict":"config","why":"Destination settings written by the key's owner: a type, flags, a masked host, header names and one sealed string. The schema has no field for message text; content is only ever sent to the owner's destination, never stored here."},"type":"jsonb"},{"about_request":"no","flags":["type:json"],"name":"topup","nullable":true,"purpose":"The key's auto top-up rule, or empty: below_usd, add_usd and max_per_week_usd. When the key has less than below_usd of its limit left, the router raises the limit by add_usd from the account's own credits, at most max_per_week_usd per UTC week.","review":{"covers":["type:json"],"verdict":"config","why":"Three numbers written by the key's owner and checked against a strict schema; there is no field for text."},"type":"jsonb"},{"about_request":"no","name":"disabled","nullable":false,"purpose":"Whether the key is turned off.","type":"boolean"},{"about_request":"no","name":"expires_at","nullable":true,"purpose":"When the key stops working, if it expires.","type":"timestamp with time zone"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"yes","name":"last_used","nullable":true,"purpose":"When the key last made a call.","type":"timestamp with time zone"}],"name":"keys","purpose":"One row per API key. The secret is never stored: the row holds its SHA-256 and a masked label. It also holds the key's limits, budget and spend.","retention":"Deleting a key only disables it (DELETE /api/v1/keys/:hash sets disabled); the row stays because generations and balances refer to it."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"epoch","nullable":false,"purpose":"The key's epoch.","type":"integer"},{"about_request":"no","name":"key_id","nullable":false,"purpose":"The 8-bit key identifier of the key configuration (epoch mod 256).","type":"integer"},{"about_request":"no","name":"kem_id","nullable":false,"purpose":"The HPKE KEM identifier.","type":"integer"},{"about_request":"no","name":"public_key","nullable":false,"purpose":"The public key, base64url.","type":"text"},{"about_request":"no","name":"config","nullable":false,"purpose":"The encoded key configuration (RFC 9458), base64url.","type":"text"},{"about_request":"no","name":"config_sha256","nullable":false,"purpose":"SHA-256 of that configuration.","type":"text"},{"about_request":"no","name":"private_enc","nullable":true,"purpose":"The private key, AES-GCM encrypted with APP_SECRET. Null once destroyed.","type":"text"},{"about_request":"no","name":"valid_from","nullable":false,"purpose":"When the key starts to be used.","type":"timestamp with time zone"},{"about_request":"no","name":"accept_until","nullable":false,"purpose":"Requests to this key are opened until here.","type":"timestamp with time zone"},{"about_request":"no","name":"revoked_at","nullable":true,"purpose":"When it was revoked, if it was.","type":"timestamp with time zone"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"ohttp_keys","purpose":"Oblivious HTTP gateway keys, one per epoch. Their public halves are published; each private half is destroyed when its epoch's window ends.","retention":"The private half is destroyed when the epoch's acceptance window ends, after which recorded traffic for that epoch can no longer be opened. The public half stays."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Monotonically allocated change identifier.","type":"bigserial"},{"about_request":"no","name":"playbook_id","nullable":false,"purpose":"The playbook changed; kept after the playbook is deleted.","type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"The owning account.","type":"text"},{"about_request":"no","name":"team_id","nullable":true,"purpose":"The owning team, or null for an account-wide playbook.","type":"text"},{"about_request":"no","name":"name","nullable":false,"purpose":"The playbook's name after this change.","type":"text"},{"about_request":"no","name":"action","nullable":false,"purpose":"create, update (new rules and version), rename or delete.","type":"text"},{"about_request":"no","name":"version","nullable":false,"purpose":"The playbook's version after this change.","type":"integer"},{"about_request":"no","name":"sha256","nullable":false,"purpose":"SHA-256 of the canonical rules after this change.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"spec","nullable":false,"purpose":"The rules as of this change, so each recorded digest can be checked.","review":{"covers":["type:json"],"verdict":"config","why":"A copy of a playbook's strict rulebook: owner-written configuration validated against a schema that excludes prompt and answer fields."},"type":"jsonb"},{"about_request":"no","name":"followers","nullable":false,"purpose":"How many keys followed the playbook when it changed.","type":"integer"},{"about_request":"no","name":"actor","nullable":false,"purpose":"Hash of the principal key that made the change.","type":"text"},{"about_request":"no","name":"notify","nullable":false,"purpose":"Whether the change belongs to a team (a team playbook, or an account-wide one in an account with teams); updates marked so appear in the inbox of the team's owners and admins.","type":"boolean"},{"about_request":"no","name":"at","nullable":false,"purpose":"When the change was recorded, at millisecond precision.","type":"timestamp with time zone"}],"name":"playbook_changes","purpose":"A record of every playbook change (create, update, rename, delete) with its version, digest, rules and the number of keys following it; changes to a team's playbooks also appear in the team inbox.","retention":"Rows remain until operator deletion, including after the playbook is deleted."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Random playbook identifier.","type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"The account that owns the playbook.","type":"text"},{"about_request":"no","name":"team_id","nullable":true,"purpose":"The team whose owners and admins may change it, or null for an account-wide playbook that only management keys change.","type":"text"},{"about_request":"no","name":"name","nullable":false,"purpose":"Owner-chosen name, unique within the account regardless of case.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"spec","nullable":false,"purpose":"The playbook's current rulebook, validated by the same strict schema as a key's own rulebook.","review":{"covers":["type:json"],"verdict":"config","why":"The strict rulebook schema excludes prompt and answer fields. Model, tool and action labels are owner-written identifiers of at most 160 characters; their contents are whatever the owner chooses to write."},"type":"jsonb"},{"about_request":"no","name":"sha256","nullable":false,"purpose":"SHA-256 of the canonical rulebook JSON, the same digest each following key's rulebook carries.","type":"text"},{"about_request":"no","name":"version","nullable":false,"purpose":"Counts rule changes: 1 at creation, plus one for each change of rules. A rename keeps it.","type":"integer"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the playbook was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When its name or rules last changed.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_by","nullable":false,"purpose":"Hash of the principal key that made the last change.","type":"text"}],"name":"playbooks","notes":["The rules are the same strict rulebook as agent_policies.spec and carry the same owner-written labels. The name is owner-written text of at most 100 characters. No prompt or answer fields are accepted."],"purpose":"Shared rulebooks (playbooks): one named rulebook that many keys of an account or team follow, so one change applies to all of them.","retention":"Until a principal deletes the playbook. Deleting is refused while keys follow it unless they each keep its rules as their own."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"team_id","nullable":false,"purpose":"The team.","type":"text"},{"about_request":"no","name":"seq","nullable":false,"purpose":"The entry's position in the team's chain: 1, 2, 3, ...","type":"integer"},{"about_request":"no","name":"at","nullable":false,"purpose":"When the change was made.","type":"timestamp with time zone"},{"about_request":"no","name":"actor","nullable":false,"purpose":"Who made it: key:<first 16 hex digits of the key hash>, passkey:<member id> or wallet:<address>.","type":"text"},{"about_request":"no","name":"action","nullable":false,"purpose":"What changed, such as member.join, key.create, budget.set, preset.save or route.update.","type":"text"},{"about_request":"no","name":"target","nullable":false,"purpose":"What it changed: a key hash, member id, invite hash prefix, preset or route name.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"detail","nullable":false,"purpose":"A few fixed fields about the change: a role, a limit, a lane, a version and hash, the names of the fields that changed.","review":{"covers":["type:json"],"verdict":"config","why":"Fields chosen by the router for each action (src/teams/audit.ts, src/api/teams.ts): no free text from a call, and for presets only the version, hash and lane, never the system prompt."},"type":"jsonb"},{"about_request":"no","name":"prev_hash","nullable":false,"purpose":"The previous entry's hash (64 zeros for the first entry).","type":"text"},{"about_request":"no","name":"hash","nullable":false,"purpose":"sha256(prev_hash bytes || canonical JSON of the entry).","type":"text"}],"name":"team_audit","purpose":"A team's audit log: who changed members, keys, budgets, presets, routes and lane settings, and when. Each entry is hash-chained to the one before it, so an export can be checked offline (scripts/verify-audit.mjs). It records settings changes only, never what anyone asked a model.","retention":"No automatic deletion, and rows are never changed after they are written. A database trigger rejects UPDATE and DELETE."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"team_id","nullable":false,"purpose":"The team.","type":"text"},{"about_request":"no","name":"key_hash","nullable":false,"purpose":"The member key's hash.","type":"text"},{"about_request":"no","name":"role","nullable":false,"purpose":"owner, admin, dev, viewer or agent (member is the older default).","type":"text"},{"about_request":"no","name":"principal_id","nullable":true,"purpose":"For a key issued when a member signed in with a passkey or wallet, that member (team_principals.id).","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"team_members","purpose":"Which keys are in which team and their role.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Member id (tp_...).","type":"text"},{"about_request":"no","name":"team_id","nullable":false,"purpose":"The team.","type":"text"},{"about_request":"no","name":"kind","nullable":false,"purpose":"passkey or wallet.","type":"text"},{"about_request":"no","name":"subject","nullable":false,"purpose":"For a passkey, its credential id (random bytes the authenticator chose, base64url); for a wallet, its address.","type":"text"},{"about_request":"no","name":"public_key","nullable":true,"purpose":"The passkey's public key (COSE, base64url). It can check signatures, not make them.","type":"text"},{"about_request":"no","name":"alg","nullable":true,"purpose":"The passkey's signature algorithm: -7 ES256, -8 EdDSA or -257 RS256.","type":"integer"},{"about_request":"no","name":"sign_count","nullable":false,"purpose":"The passkey's signature counter, so a cloned authenticator is noticed.","type":"bigint"},{"about_request":"no","name":"role","nullable":false,"purpose":"The member's role: owner (the bound owner wallet), admin, dev or viewer.","type":"text"},{"about_request":"no","name":"disabled","nullable":false,"purpose":"Whether the member was revoked.","type":"boolean"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"last_used","nullable":true,"purpose":"When the member last signed in.","type":"timestamp with time zone"}],"name":"team_principals","purpose":"Members of a team who sign in without an API key: a passkey (WebAuthn) or a wallet. There is no email, name or device information: a passkey row holds only its credential id and public key (attestation is not requested), a wallet row only its address.","retention":"Kept while the team exists; revoking a member disables the row and the keys issued to it."},{"about_request":"no","category":"keys","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Team id.","type":"text"},{"about_request":"no","name":"name","nullable":false,"purpose":"The team's name, chosen by its owner.","type":"text"},{"about_request":"no","name":"owner_account","nullable":false,"purpose":"The account that owns the team.","type":"text"},{"about_request":"no","flags":["name:network"],"name":"owner_address","nullable":true,"purpose":"The wallet or Safe that owns the team, once it signed a one-time message (checked by recovery for a wallet, by EIP-1271 isValidSignature for a contract wallet). Empty until one is bound.","review":{"covers":["name:network"],"verdict":"wallet-address","why":"A blockchain address the owner chose to bind, not a network address of a caller."},"type":"text"},{"about_request":"no","name":"owner_kind","nullable":false,"purpose":"account (no wallet bound), eoa (a wallet) or contract (a Safe or another smart wallet).","type":"text"},{"about_request":"no","name":"owner_verified_at","nullable":true,"purpose":"When the owner's wallet signature was checked.","type":"timestamp with time zone"},{"about_request":"no","name":"budget","nullable":true,"purpose":"The org budget in pico-USD: a cap on the sum of the limits of the team's keys. Empty means no cap.","type":"bigint"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"teams","purpose":"A team, also called an organisation: a named group of keys under one owning account, optionally bound to a wallet or a Safe, with an optional org budget.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Row number, counting up from 1.","type":"serial"},{"about_request":"no","name":"provider_id","nullable":false,"purpose":"The provider.","type":"text"},{"about_request":"no","name":"kind","nullable":false,"purpose":"attestation, canary or probe.","type":"text"},{"about_request":"no","name":"ts","nullable":false,"purpose":"When it happened.","type":"timestamp with time zone"},{"about_request":"no","name":"ok","nullable":false,"purpose":"Whether it passed.","type":"boolean"},{"about_request":"no","name":"reason","nullable":true,"purpose":"A failure code from a fixed list, empty when it passed.","type":"text"},{"about_request":"no","name":"simulated","nullable":false,"purpose":"Whether the evidence came from development mode; never counts as a fresh attestation.","type":"boolean"},{"about_request":"no","name":"tee_kind","nullable":true,"purpose":"The hardware type.","type":"text"},{"about_request":"no","name":"attestation_hash","nullable":true,"purpose":"The report hash of a passing run.","type":"text"},{"about_request":"no","name":"tls_spki_sha256","nullable":true,"purpose":"SHA-256 of the certificate key the connection was pinned to, when pinned.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"measurements","nullable":true,"purpose":"Digests and hardware registers of a passing run.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Only digests (image, compose, model) and register values; the table's comment states nothing raw from the provider is stored."},"type":"jsonb"},{"about_request":"no","name":"measurement_changed","nullable":false,"purpose":"Whether the measurement differs from the previous passing run.","type":"boolean"},{"about_request":"no","flags":["type:json"],"name":"verifiers","nullable":true,"purpose":"The names of the verifiers that accepted the quote.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"A list of verifier names configured by the operator."},"type":"jsonb"},{"about_request":"no","flags":["type:json"],"name":"detail","nullable":true,"purpose":"Further check results as codes and numbers.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Written by the attestation-events code from fixed fields; the table's comment states nothing raw from the provider is stored."},"type":"jsonb"}],"name":"attestation_events","purpose":"The public proof-time record: one row per attestor run, canary run or change of the health probe's outcome.","retention":"Rows older than ATTESTATION_HISTORY_DAYS (default 30) are pruned by the attestor job (pruneAttestationEvents); 0 turns recording off."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Row number, counting up from 1.","type":"serial"},{"about_request":"no","name":"provider_id","nullable":false,"purpose":"The provider.","type":"text"},{"about_request":"no","name":"ts","nullable":false,"purpose":"When the run happened.","type":"timestamp with time zone"},{"about_request":"no","name":"ok","nullable":false,"purpose":"Whether it passed.","type":"boolean"},{"about_request":"no","name":"tee_kind","nullable":true,"purpose":"The hardware type.","type":"text"},{"about_request":"no","name":"report_hash","nullable":true,"purpose":"Hash of the report.","type":"text"},{"about_request":"no","name":"nonce","nullable":true,"purpose":"The fresh nonce the router sent to prove the report was made for this run.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"measurements","nullable":true,"purpose":"The image, compose and model digests and hardware registers the report committed to.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Digests and register values taken from a verified report."},"type":"jsonb"},{"about_request":"no","flags":["type:json"],"name":"detail","nullable":true,"purpose":"Why a run failed, or which verifiers accepted it, with the signing address and classifier flag, as short strings and flags written by the attestor.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Written by attestProvider about a report the router fetched with a fresh nonce. An attestation run starts from the router's schedule, so no caller's request can reach this column."},"type":"jsonb"}],"name":"attestations","purpose":"The result of each attestation run against a provider: whether it passed, the report hash and the measurements it committed to.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"model_id","nullable":false,"purpose":"The model checked.","type":"text"},{"about_request":"no","name":"provider_id","nullable":false,"purpose":"The provider checked.","type":"text"},{"about_request":"no","name":"ts","nullable":false,"purpose":"When the check ran.","type":"timestamp with time zone"},{"about_request":"no","name":"quant_match","nullable":true,"purpose":"Whether the result matched the declared precision.","type":"boolean"},{"about_request":"no","name":"quant_guess","nullable":true,"purpose":"The precision the result looks like.","type":"text"},{"about_request":"no","name":"distance","nullable":true,"purpose":"How far the result was from the reference.","type":"real"},{"about_request":"no","name":"quality","nullable":true,"purpose":"A quality score for the result.","type":"real"},{"about_request":"no","flags":["type:json"],"name":"detail","nullable":true,"purpose":"The check's accuracy, how many prompts were answered, the declared precision and the fingerprint length.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Numbers and the declared precision written by runCanaries (accuracy, answered, declared, logprobs, fingerprint_tokens); the canary prompts are the router's own."},"type":"jsonb"}],"name":"canaries","purpose":"Results of quantisation checks: known prompts sent to a provider to see whether it serves the precision it declares. Made from fixed prompts the router wrote itself, not from any customer request.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"model_id","nullable":false,"purpose":"The model.","type":"text"},{"about_request":"no","name":"quant","nullable":false,"purpose":"The precision the fingerprint is for: bf16, fp8, int4 and so on.","type":"text"},{"about_request":"no","flags":["name:network","type:json"],"name":"fingerprint","nullable":false,"purpose":"The model's output fingerprint at that precision for the router's own canary prompts.","review":{"covers":["name:network","type:json"],"verdict":"no-request-content","why":"A model-behaviour fingerprint (token probabilities on the router's own fixed prompts), not a device or network fingerprint and not a customer request."},"type":"jsonb"},{"about_request":"no","name":"source","nullable":false,"purpose":"Where the reference came from.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"canary_references","purpose":"The reference fingerprint of a model at each precision, which canary results are compared to.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Row number, counting up from 1.","type":"serial"},{"about_request":"no","name":"hf_repo","nullable":false,"purpose":"The repository.","type":"text"},{"about_request":"no","name":"base_model","nullable":false,"purpose":"The base model.","type":"text"},{"about_request":"no","name":"revision","nullable":true,"purpose":"The revision seen at discovery.","type":"text"},{"about_request":"no","name":"license","nullable":true,"purpose":"The licence.","type":"text"},{"about_request":"no","name":"variant","nullable":false,"purpose":"The variant.","type":"text"},{"about_request":"no","name":"creator_handle","nullable":false,"purpose":"The uploader's handle.","type":"text"},{"about_request":"no","name":"status","nullable":false,"purpose":"discovered, rejected, evaluated, failed, approved or servable.","type":"text"},{"about_request":"no","name":"reason","nullable":true,"purpose":"Why a candidate was rejected.","type":"text"},{"about_request":"no","name":"model_id","nullable":true,"purpose":"The catalogue model id it is served under.","type":"text"},{"about_request":"no","flags":["name:network"],"name":"endpoint_provider","nullable":true,"purpose":"The provider whose offer for the model is evaluated.","review":{"covers":["name:network"],"verdict":"public-reference","why":"A provider slug (a short name such as deepinfra), not a network address."},"type":"text"},{"about_request":"no","name":"source_created_at","nullable":true,"purpose":"When the repository was created.","type":"timestamp with time zone"},{"about_request":"no","name":"approved_by","nullable":true,"purpose":"Who approved it.","type":"text"},{"about_request":"no","name":"approved_at","nullable":true,"purpose":"When it was approved.","type":"timestamp with time zone"},{"about_request":"no","flags":["name:content"],"name":"approval_note","nullable":true,"purpose":"A note written by the approving operator.","review":{"covers":["name:content"],"verdict":"config","why":"Free text written by an operator when approving a candidate; not derived from any request."},"type":"text"},{"about_request":"no","name":"servable_at","nullable":true,"purpose":"When it became servable.","type":"timestamp with time zone"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"lane_candidates","purpose":"New open-weights uploads found on Hugging Face that derive from an approved base model, with their evaluation status.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Claim id.","type":"text"},{"about_request":"no","name":"model_id","nullable":false,"purpose":"The model.","type":"text"},{"about_request":"no","name":"hf_repo","nullable":false,"purpose":"The repository.","type":"text"},{"about_request":"no","name":"handle","nullable":false,"purpose":"The uploader's Hugging Face handle.","type":"text"},{"about_request":"no","flags":["name:network"],"name":"address","nullable":false,"purpose":"The wallet address royalties are to be sent to.","review":{"covers":["name:network"],"verdict":"wallet-address","why":"A blockchain wallet address supplied by the creator, not a network address."},"type":"text"},{"about_request":"no","name":"challenge","nullable":false,"purpose":"The challenge text the uploader must publish.","type":"text"},{"about_request":"no","name":"status","nullable":false,"purpose":"pending or verified.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"expires_at","nullable":false,"purpose":"When the challenge expires.","type":"timestamp with time zone"},{"about_request":"no","name":"verified_at","nullable":true,"purpose":"When it was verified.","type":"timestamp with time zone"},{"about_request":"no","name":"onchain_tx","nullable":true,"purpose":"The transaction that recorded the claim.","type":"text"}],"name":"lane_claims","purpose":"Creator royalty claims: the router issues a challenge, the uploader publishes it in their Hugging Face repository, and the router checks it.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Row number, counting up from 1.","type":"serial"},{"about_request":"no","name":"candidate_id","nullable":false,"purpose":"The candidate evaluated.","type":"integer"},{"about_request":"no","name":"ts","nullable":false,"purpose":"When it ran.","type":"timestamp with time zone"},{"about_request":"no","name":"provider_id","nullable":false,"purpose":"The provider evaluated.","type":"text"},{"about_request":"no","name":"model_id","nullable":false,"purpose":"The model evaluated.","type":"text"},{"about_request":"no","name":"refusal_rate","nullable":true,"purpose":"Share of the benign probe prompts that were refused.","type":"real"},{"about_request":"no","name":"capability_score","nullable":true,"purpose":"Share of the exact-check prompts answered correctly.","type":"real"},{"about_request":"no","name":"canary_accuracy","nullable":true,"purpose":"The canary exact-match score.","type":"real"},{"about_request":"no","name":"canary_quant_match","nullable":true,"purpose":"Whether the canary matched the declared precision.","type":"boolean"},{"about_request":"no","name":"passed","nullable":false,"purpose":"Whether the candidate passed.","type":"boolean"},{"about_request":"no","flags":["type:json"],"name":"detail","nullable":true,"purpose":"Scores and counts for the run.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Numbers written by the evaluation code; the prompts used are the router's own fixed sets."},"type":"jsonb"}],"name":"lane_evals","purpose":"One row per evaluation run of a candidate endpoint: refusal rate, capability score and canary accuracy. Made from fixed prompts the router wrote itself, not from any customer request.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Row number, counting up from 1.","type":"serial"},{"about_request":"no","name":"provider_id","nullable":false,"purpose":"The provider.","type":"text"},{"about_request":"no","name":"compose_hash","nullable":false,"purpose":"The deployment hash the bundle describes.","type":"text"},{"about_request":"no","name":"bundle_digest","nullable":false,"purpose":"SHA-256 of the canonical bundle bytes.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"bundle","nullable":false,"purpose":"The bundle itself: the components a measurement is made of.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"A signed, canonical bundle of digests and component names that an operator hands over and the router verifies."},"type":"jsonb"},{"about_request":"no","name":"signature","nullable":false,"purpose":"The bundle's signature, base64.","type":"text"},{"about_request":"no","name":"signer_key_id","nullable":false,"purpose":"SHA-256 of the signer's public key info.","type":"text"},{"about_request":"no","name":"status","nullable":false,"purpose":"pending, verified or rejected.","type":"text"},{"about_request":"no","name":"rekor_uuid","nullable":true,"purpose":"The public-log entry id.","type":"text"},{"about_request":"no","name":"rekor_entry","nullable":true,"purpose":"The entry hash inside that id.","type":"text"},{"about_request":"no","name":"rekor_log_index","nullable":true,"purpose":"The entry's index in the public log.","type":"bigint"},{"about_request":"no","name":"rekor_integrated_at","nullable":true,"purpose":"When the public log integrated it.","type":"timestamp with time zone"},{"about_request":"no","flags":["type:json"],"name":"rekor_entry_json","nullable":true,"purpose":"The public-log entry as the log returned it.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"The response of a public transparency log for the bundle's entry (body, proof, signed timestamp)."},"type":"jsonb"},{"about_request":"no","name":"rekor_inclusion_verified","nullable":false,"purpose":"Whether the inclusion proof verified.","type":"boolean"},{"about_request":"no","name":"rekor_checkpoint_verified","nullable":false,"purpose":"Whether the log's checkpoint signature verified.","type":"boolean"},{"about_request":"no","name":"rekor_set_verified","nullable":false,"purpose":"Whether the signed entry timestamp verified.","type":"boolean"},{"about_request":"no","name":"checked_at","nullable":true,"purpose":"When the log was last checked.","type":"timestamp with time zone"},{"about_request":"no","name":"verified_at","nullable":true,"purpose":"When the bundle verified.","type":"timestamp with time zone"},{"about_request":"no","flags":["name:content"],"name":"error","nullable":true,"purpose":"Why the bundle was rejected or could not be checked.","review":{"covers":["name:content"],"verdict":"no-request-content","why":"An error string produced while verifying a bundle and its public-log entry; nothing in that check involves a caller's request."},"type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"measurement_bundles","purpose":"Signed measurement bundles: what a provider's measurement is made of, signed with the measurement key, recorded in a public log and verified by the router.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Row number, counting up from 1.","type":"serial"},{"about_request":"no","name":"provider_id","nullable":false,"purpose":"The provider.","type":"text"},{"about_request":"no","name":"image_digest","nullable":false,"purpose":"The container image digest.","type":"text"},{"about_request":"no","name":"compose_hash","nullable":false,"purpose":"The hash of the deployment definition.","type":"text"},{"about_request":"no","name":"model_digest","nullable":false,"purpose":"The digest of the model weights.","type":"text"},{"about_request":"no","name":"status","nullable":false,"purpose":"observed, ready, registered or revoked.","type":"text"},{"about_request":"no","name":"verifier","nullable":false,"purpose":"Which verifiers accepted the quote, comma separated.","type":"text"},{"about_request":"no","name":"tee_kind","nullable":true,"purpose":"The hardware type.","type":"text"},{"about_request":"no","name":"quote","nullable":false,"purpose":"The verified hardware quote, hex.","type":"text"},{"about_request":"no","name":"quote_proof_hash","nullable":false,"purpose":"keccak256 of the quote bytes.","type":"text"},{"about_request":"no","name":"report_hash","nullable":true,"purpose":"The attestation report hash that produced the row.","type":"text"},{"about_request":"no","name":"attested_at","nullable":false,"purpose":"When it was attested.","type":"timestamp with time zone"},{"about_request":"no","name":"last_seen_at","nullable":false,"purpose":"When it was last seen.","type":"timestamp with time zone"},{"about_request":"no","name":"rekor_uuid","nullable":true,"purpose":"The public-log entry id, when found.","type":"text"},{"about_request":"no","name":"rekor_entry","nullable":true,"purpose":"The entry hash inside that id.","type":"text"},{"about_request":"no","name":"rekor_log_index","nullable":true,"purpose":"The entry's index in the public log.","type":"bigint"},{"about_request":"no","name":"rekor_kind","nullable":true,"purpose":"The entry type.","type":"text"},{"about_request":"no","name":"rekor_integrated_at","nullable":true,"purpose":"When the public log integrated it.","type":"timestamp with time zone"},{"about_request":"no","name":"rekor_inclusion_verified","nullable":false,"purpose":"Whether the inclusion proof verified.","type":"boolean"},{"about_request":"no","name":"rekor_checkpoint_verified","nullable":false,"purpose":"Whether the log's checkpoint signature verified.","type":"boolean"},{"about_request":"no","name":"rekor_checked_at","nullable":true,"purpose":"When the public log was last checked.","type":"timestamp with time zone"},{"about_request":"no","flags":["name:content"],"name":"rekor_error","nullable":true,"purpose":"The last error from checking the public log, as a short code or message.","review":{"covers":["name:content"],"verdict":"no-request-content","why":"An error string produced while looking up a public log entry; nothing in this lookup involves a caller's request."},"type":"text"},{"about_request":"no","name":"calldata","nullable":true,"purpose":"Prepared registry call data, when built.","type":"text"},{"about_request":"no","name":"calldata_target","nullable":true,"purpose":"The registry contract it is for.","type":"text"},{"about_request":"no","name":"calldata_built_at","nullable":true,"purpose":"When it was built.","type":"timestamp with time zone"},{"about_request":"no","name":"tx_hash","nullable":true,"purpose":"The registering transaction.","type":"text"},{"about_request":"no","name":"registered_at","nullable":true,"purpose":"When it was registered.","type":"timestamp with time zone"},{"about_request":"no","name":"revoked_at","nullable":true,"purpose":"When it was revoked.","type":"timestamp with time zone"},{"about_request":"no","name":"superseded_at","nullable":true,"purpose":"When a later verified quote committed to other digests.","type":"timestamp with time zone"},{"about_request":"no","name":"superseded_by","nullable":true,"purpose":"The row that replaced this one.","type":"integer"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"measurements","purpose":"The image, compose and model digests a provider's confidential endpoint has been seen running, each bound into a hardware quote a verifier accepted, with whether the digest was found in a public log.","retention":"History is kept: a superseded measurement gets superseded_at and stays."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Model id, author/slug.","type":"text"},{"about_request":"no","name":"author","nullable":false,"purpose":"The author part of the id.","type":"text"},{"about_request":"no","name":"name","nullable":false,"purpose":"Display name.","type":"text"},{"about_request":"no","flags":["name:content"],"name":"description","nullable":false,"purpose":"A short description of the model, from the provider listing or an operator.","review":{"covers":["name:content"],"verdict":"config","why":"Descriptive text about a model from provider listings; it is catalogue data, not a request."},"type":"text"},{"about_request":"no","name":"ctx","nullable":false,"purpose":"Context length in tokens.","type":"integer"},{"about_request":"no","name":"max_out","nullable":true,"purpose":"Maximum output tokens.","type":"integer"},{"about_request":"no","flags":["type:json"],"name":"arch","nullable":false,"purpose":"Modality, input and output modalities, tokenizer and instruction type.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Fixed catalogue fields about the model: modality, input_modalities, output_modalities, tokenizer, instruct_type."},"type":"jsonb"},{"about_request":"no","name":"hf_repo","nullable":true,"purpose":"The Hugging Face repository the weights come from, when known.","type":"text"},{"about_request":"no","name":"creator","nullable":true,"purpose":"The creator's payout address, when known.","type":"text"},{"about_request":"no","name":"royalty_bps","nullable":false,"purpose":"The creator's royalty in basis points.","type":"integer"},{"about_request":"no","name":"created_unix","nullable":false,"purpose":"When the model was created, in Unix seconds.","type":"integer"},{"about_request":"no","name":"hidden","nullable":false,"purpose":"Whether the model is hidden from listings.","type":"boolean"}],"name":"models","purpose":"The model catalogue: id, name, context length, modalities and creator.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"model_id","nullable":false,"purpose":"The model.","type":"text"},{"about_request":"no","name":"variant","nullable":false,"purpose":"mainstream, native_low_refusal or abliterated.","type":"text"},{"about_request":"no","name":"status","nullable":false,"purpose":"servable or candidate (not approved for serving).","type":"text"},{"about_request":"no","name":"base_model","nullable":true,"purpose":"The model it derives from.","type":"text"},{"about_request":"no","name":"license","nullable":true,"purpose":"The licence identifier from the weights' model card.","type":"text"},{"about_request":"no","name":"weights_source","nullable":true,"purpose":"Where the weights come from.","type":"text"},{"about_request":"no","name":"weights_revision","nullable":true,"purpose":"The commit the weights were taken from.","type":"text"},{"about_request":"no","name":"weights_digest","nullable":true,"purpose":"SHA-256 of the weights manifest, when there is one.","type":"text"},{"about_request":"no","name":"creator_handle","nullable":true,"purpose":"The uploader's Hugging Face handle.","type":"text"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"models_lane","purpose":"Per-model metadata for open-weights variants: which lane a model can be served on, its base model, licence and weights source.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"model_id","nullable":false,"purpose":"The model.","type":"text"},{"about_request":"no","name":"provider_id","nullable":false,"purpose":"The provider.","type":"text"},{"about_request":"no","name":"provider_model_id","nullable":false,"purpose":"The id the provider uses for the model.","type":"text"},{"about_request":"no","name":"price_prompt","nullable":false,"purpose":"Pico-USD per prompt token.","type":"bigint"},{"about_request":"no","name":"price_completion","nullable":false,"purpose":"Pico-USD per completion token.","type":"bigint"},{"about_request":"no","name":"price_request","nullable":false,"purpose":"Pico-USD per request.","type":"bigint"},{"about_request":"no","name":"price_image","nullable":false,"purpose":"Pico-USD per image.","type":"bigint"},{"about_request":"no","name":"price_web_search","nullable":false,"purpose":"Pico-USD per web search.","type":"bigint"},{"about_request":"no","name":"price_reasoning","nullable":false,"purpose":"Pico-USD per reasoning token.","type":"bigint"},{"about_request":"no","name":"price_cache_read","nullable":true,"purpose":"Pico-USD per cached prompt token.","type":"bigint"},{"about_request":"no","name":"price_cache_write","nullable":true,"purpose":"Pico-USD per token written to cache.","type":"bigint"},{"about_request":"no","name":"quant","nullable":false,"purpose":"Quantisation, such as fp8, or unknown.","type":"text"},{"about_request":"no","name":"ctx","nullable":true,"purpose":"Context length at this provider.","type":"integer"},{"about_request":"no","name":"max_out","nullable":true,"purpose":"Maximum output tokens at this provider.","type":"integer"},{"about_request":"no","name":"supported_parameters","nullable":false,"purpose":"Request parameters the provider supports.","type":"text[]"},{"about_request":"no","flags":["type:json"],"name":"features","nullable":false,"purpose":"Feature flags such as tools or json mode.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Feature flags and limits read from the provider's model listing; about the offer, not any request."},"type":"jsonb"},{"about_request":"no","name":"is_moderated","nullable":false,"purpose":"Whether the provider moderates content.","type":"boolean"},{"about_request":"no","name":"status","nullable":false,"purpose":"live, shadow or disabled.","type":"text"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"offers","purpose":"What one provider charges to serve one model, and the model's features at that provider.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","name":"provider_id","nullable":false,"purpose":"The provider.","type":"text"},{"about_request":"no","name":"retention","nullable":false,"purpose":"attested, policy or logs (the most conservative when there is no row).","type":"text"},{"about_request":"no","name":"jurisdiction","nullable":false,"purpose":"The provider's jurisdiction, or unknown.","type":"text"},{"about_request":"no","name":"legal_hold","nullable":true,"purpose":"Whether a legal hold is declared; empty means not declared.","type":"boolean"},{"about_request":"no","flags":["name:content"],"name":"legal_hold_note","nullable":true,"purpose":"A note on the legal hold, written by an operator.","review":{"covers":["name:content"],"verdict":"config","why":"Free text written by an operator about a provider's declared legal hold; it is not derived from any request."},"type":"text"},{"about_request":"no","name":"training_use","nullable":false,"purpose":"none, opt_in, yes or unknown.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"claims","nullable":false,"purpose":"For each stated value, the document it comes from and its date.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"A map of claim name to { source, as_of } written by an operator. Network admission and scheduled renewal record only retention with the checked host policy version and current time; the host dashboard reads this version and time to describe current build approval without storing another record; jurisdiction, legal hold and training use remain undeclared."},"type":"jsonb"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"provider_disclosure","purpose":"What a provider says, and can prove, about how it handles a prompt: retention, jurisdiction, legal hold and training use, each with a source and a date. Curated by an operator, or retention alone set after network sidecar attestation and signed host policy verification; nothing here comes from traffic.","retention":"Kept and replaced in place when an operator updates a provider's profile or a network host passes admission or scheduled policy renewal; removed on network rejection."},{"about_request":"no","category":"providers","columns":[{"about_request":"no","flags":["name:network"],"name":"network_host","nullable":false,"purpose":"Whether this provider was created by wallet-authenticated self-serve network signup; false for existing providers.","review":{"covers":["name:network"],"verdict":"config","why":"A boolean indicating the admission path, despite its network-related name. It cannot contain an address or any text."},"type":"boolean"},{"about_request":"no","name":"network_models","nullable":false,"purpose":"One to eight distinct requested model IDs supplied by the wallet operator, retained for network admission and re-application; separate from priced catalogue entries.","type":"text[]"},{"about_request":"no","flags":["type:json"],"name":"network_reasons","nullable":false,"purpose":"Current admission or scheduled renewal refusal reasons, returned publicly by the network status and host dashboard APIs.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Admission and scheduled renewal write policy and screening explanations and attestor failure messages about operator-supplied endpoints and model IDs. No inference body, key or contact is included; endpoint failure messages may name the host server."},"type":"jsonb"},{"about_request":"no","name":"id","nullable":false,"purpose":"Provider slug, such as deepinfra.","type":"text"},{"about_request":"no","name":"name","nullable":false,"purpose":"Display name.","type":"text"},{"about_request":"no","flags":["name:network"],"name":"base_url","nullable":false,"purpose":"The provider's API address that the router calls.","review":{"covers":["name:network"],"verdict":"public-reference","why":"The address of a provider's server, set by the operator. It is not a caller's address."},"type":"text"},{"about_request":"no","name":"api_key_enc","nullable":true,"purpose":"The router's own key at that provider, AES-256-GCM encrypted with APP_SECRET.","type":"text"},{"about_request":"no","name":"kind","nullable":false,"purpose":"openai for a standard API, tee for an attested endpoint, sidecar for a network host.","type":"text"},{"about_request":"no","flags":["name:network","type:json"],"name":"headers","nullable":true,"purpose":"Extra HTTP headers the router sends to that provider on every call, usually credentials. Stored only as one AES-GCM ciphertext under the router's APP_SECRET.","review":{"covers":["name:network","type:json"],"verdict":"config","why":"Fixed headers the provider's operator supplied in its application, stored encrypted (encrypted_v1). Nothing from a caller's request is ever written to it."},"type":"jsonb"},{"about_request":"no","flags":["type:json"],"name":"data_policy","nullable":false,"purpose":"What the provider says about training on prompts, retaining them, retention days and zero-data-retention, as entered by the operator or the provider.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Fixed fields (training, retains_prompts, retention_days, zdr, moderated) validated on entry; about the provider's policy, not about any request."},"type":"jsonb"},{"about_request":"no","name":"datacenter","nullable":true,"purpose":"Regions the provider lists.","type":"text[]"},{"about_request":"no","name":"attested","nullable":false,"purpose":"Whether the provider's last verified attestation passed.","type":"boolean"},{"about_request":"no","flags":["name:network"],"name":"attestation_url","nullable":true,"purpose":"Where the provider publishes its attestation report.","review":{"covers":["name:network"],"verdict":"public-reference","why":"The address of a report on a provider's server, set by the operator."},"type":"text"},{"about_request":"no","name":"attestation_hash","nullable":true,"purpose":"Hash of the last attestation report the router verified.","type":"text"},{"about_request":"no","name":"attested_at","nullable":true,"purpose":"When it was verified.","type":"timestamp with time zone"},{"about_request":"no","name":"tee_kind","nullable":true,"purpose":"The hardware type: tdx, snp, nvidia-cc, tinfoil or dev.","type":"text"},{"about_request":"no","name":"classifier_enabled","nullable":false,"purpose":"Whether the last verified attestation reported the in-enclave hard-block classifier as enabled.","type":"boolean"},{"about_request":"no","name":"bond_usdg","nullable":false,"purpose":"The provider's bond in USDG base units.","type":"bigint"},{"about_request":"no","name":"anyr_stake","nullable":false,"purpose":"The provider's $ANYR stake in base units.","type":"bigint"},{"about_request":"no","name":"operator","nullable":true,"purpose":"The operator's name.","type":"text"},{"about_request":"no","name":"payout_mode","nullable":false,"purpose":"invoice or usdg.","type":"text"},{"about_request":"no","flags":["name:network"],"name":"payout_address","nullable":true,"purpose":"The wallet address payouts go to, when the provider is paid in USDG.","review":{"covers":["name:network"],"verdict":"wallet-address","why":"A blockchain wallet address for payouts, not a network address of a caller."},"type":"text"},{"about_request":"no","name":"status","nullable":false,"purpose":"applied, shadow, live, suspended or delisted; network signup uses pending, probation or rejected.","type":"text"},{"about_request":"no","name":"shadow_until","nullable":true,"purpose":"When a shadow provider is due to be considered for live, or the end of a network host probation period.","type":"timestamp with time zone"},{"about_request":"no","name":"timeout_ms","nullable":true,"purpose":"Request timeout for this provider.","type":"integer"},{"about_request":"no","flags":["type:json"],"name":"static_models","nullable":true,"purpose":"A model list with prices for providers whose own listing lacks pricing, or network probation offers copied from the signed policy for requested quote-bound model IDs. Rejection clears this list and disables retained offers.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"A list of model IDs, catalogue slugs, names, optional Hugging Face IDs and quantization, prices, token limits and text modalities entered by an operator and checked before it is applied. Network admission copies these terms only after published-policy signature and hardware quote binding verification."},"type":"jsonb"},{"about_request":"no","flags":["name:network"],"name":"contact","nullable":true,"purpose":"A contact for the provider's operator, as given in the provider application.","review":{"covers":["name:network"],"verdict":"config","why":"A contact detail for the provider's operator, given by the operator in a provider application. It is not about callers."},"type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"providers","purpose":"The provider registry: each upstream that serves models, how to reach it, its status, whether its software is attested, and its bond and payout details.","retention":"Kept while the provider is listed; a provider that leaves is delisted (status), not deleted."},{"about_request":"yes","category":"chain","columns":[{"about_request":"yes","name":"decision_id","nullable":false,"purpose":"The Agent Guard decision (agent_action_decisions.id) this payment belongs to; random, not a credential.","type":"text"},{"about_request":"yes","name":"key_hash","nullable":false,"purpose":"Hash of the paying agent key; only that key confirms the payment.","type":"text"},{"about_request":"yes","name":"account_id","nullable":false,"purpose":"Account of the paying key, whose linked wallets may send the transfer.","type":"text"},{"about_request":"yes","name":"policy_sha256","nullable":false,"purpose":"Digest of the rulebook (or sorted rulebook digests) the decision was made under.","type":"text"},{"about_request":"yes","name":"recipient_profile","nullable":true,"purpose":"Public profile id that was paid, or that publishes the paid wallet; null for a wallet with no single profile.","type":"text"},{"about_request":"yes","name":"recipient_key_hash","nullable":true,"purpose":"Key hash behind that profile, used only to show the payment in its owner's inbox; never returned publicly.","type":"text"},{"about_request":"yes","name":"recipient_wallet","nullable":false,"purpose":"Lowercase 0x wallet that receives the USDG.","type":"text"},{"about_request":"yes","name":"amount_units","nullable":false,"purpose":"Allowed amount in USDG base units (6 decimals).","type":"numeric(78, 0)"},{"about_request":"yes","name":"memo_sha256","nullable":true,"purpose":"Optional SHA-256 digest of the payer's memo; the memo is not stored.","type":"text"},{"about_request":"yes","name":"status","nullable":false,"purpose":"awaiting_transfer, seen (waiting for finality), final or reversed.","type":"text"},{"about_request":"yes","name":"status_at","nullable":false,"purpose":"When the status last changed.","type":"timestamp with time zone"},{"about_request":"yes","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"yes","name":"tx_hash","nullable":true,"purpose":"The confirming Robinhood Chain transaction (public); unique with its log index.","type":"text"},{"about_request":"yes","name":"log_index","nullable":true,"purpose":"Log index of the USDG Transfer that pays the decision.","type":"integer"},{"about_request":"yes","name":"block_number","nullable":true,"purpose":"Block of that transfer.","type":"bigint"},{"about_request":"yes","name":"block_hash","nullable":true,"purpose":"Canonical hash of that block when last checked.","type":"text"},{"about_request":"yes","name":"payer_wallet","nullable":true,"purpose":"Linked wallet the USDG was sent from.","type":"text"},{"about_request":"yes","name":"paid_units","nullable":true,"purpose":"USDG base units actually transferred; counted against the daily action limit.","type":"numeric(78, 0)"},{"about_request":"yes","name":"verified_at","nullable":true,"purpose":"When the router first verified the transfer.","type":"timestamp with time zone"},{"about_request":"yes","name":"checked_at","nullable":true,"purpose":"When it was last re-verified.","type":"timestamp with time zone"},{"about_request":"yes","name":"reason","nullable":true,"purpose":"Fixed reason text when a payment is reversed.","type":"text"},{"about_request":"yes","flags":["type:json"],"name":"receipt","nullable":true,"purpose":"The signed payment receipt payload (anyroute.agent.payment.v1): decision, rulebook digest, payer, recipient, amounts, chain, transaction, block and status.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Canonical JSON built by src/agents/pay.ts from the fields of this row; wallets, hashes, amounts and fixed codes only, no request or answer text."},"type":"jsonb"},{"about_request":"yes","name":"receipt_sig","nullable":true,"purpose":"Ed25519 signature over the canonical receipt, by the router's receipt key; re-signed on each status change.","type":"text"},{"about_request":"yes","name":"receipt_key_id","nullable":true,"purpose":"Id of the receipt key that signed it.","type":"text"}],"name":"agent_payments","notes":["Recipient and payer wallets and the transaction are public on chain and can be correlated with the agent key that asked. Paying a public profile id also stores that profile and its key hash, so the recipient's owner sees the payment in their inbox. An optional memo is accepted only as a SHA-256 digest; the memo itself is never sent to the router."],"purpose":"One row per allowed pay.agent decision: who asked, the recipient wallet and amount Agent Guard allowed, and, once confirmed, the USDG transfer found on Robinhood Chain and the signed payment receipt. Anyroute never holds or moves this money; no balance changes. Disabled unless AGENT_PAY_ENABLED.","retention":"No automatic deletion: no job or route in the code removes rows from this table. The status changes from seen to final at the chain's finality point, or to reversed if the transfer leaves the canonical chain within ESCROW_REORG_HORIZON_BLOCKS."},{"about_request":"no","category":"chain","columns":[{"about_request":"no","name":"scope","nullable":false,"purpose":"Chain id, configured escrow and oracle addresses; isolates deployments.","type":"text"},{"about_request":"no","name":"block","nullable":false,"purpose":"Last canonical scanned block number.","type":"bigint"},{"about_request":"no","name":"block_hash","nullable":true,"purpose":"Hash at the canonical scan endpoint.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"checkpoints","nullable":false,"purpose":"Up to 128 scan endpoint block/hash pairs used to find a canonical reorg rewind point.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Only decoded public agreement event values and canonical block metadata are stored: wallets, USDG amounts, hashes, identifiers, bps and timestamps. No inference or evidence content is accepted into the chain journal or projection."},"type":"jsonb"},{"about_request":"no","name":"checked_at","nullable":false,"purpose":"Caught-up scan time, zero during backfill. Jury, posting and deletion require freshness within 120 seconds.","type":"timestamp with time zone"}],"name":"agreement_cursor","purpose":"Finality-aware resumable agreement event cursor and cross-worker serialization lock.","retention":"Public chain journal and projections remain until the operator removes the agreement index. Orphaned events and projections are removed and replayed on reorganization."},{"about_request":"no","category":"chain","columns":[{"about_request":"no","name":"scope","nullable":false,"purpose":"Chain id, configured escrow and oracle addresses; isolates deployments.","type":"text"},{"about_request":"no","name":"tx_hash","nullable":false,"purpose":"Public transaction hash, unique with deployment scope and log position.","type":"text"},{"about_request":"no","name":"log_index","nullable":false,"purpose":"Canonical log position in a block.","type":"integer"},{"about_request":"no","name":"block","nullable":false,"purpose":"Canonical event block number.","type":"bigint"},{"about_request":"no","name":"block_hash","nullable":false,"purpose":"Event block hash checked against the RPC.","type":"text"},{"about_request":"no","name":"event","nullable":false,"purpose":"AgreementEscrow milestone lifecycle events and DisputeOracle TallyRecorded, PanelRequired and RulingPosted ABI event names.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"args","nullable":false,"purpose":"Public event arguments: agreement id, payer/payee wallets, USDG base-unit amount, terms/deliverable/evidence hashes, milestone index, deadline, oracle address, review deadline, payout amounts, ruling path and verdict encoding, evidence root, jury version, participation and consensus bitmaps and tally hash. indexedEscrow and indexedOracle identify configured contracts. indexedAt is the canonical block timestamp.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Only decoded public agreement event values and canonical block metadata are stored: wallets, USDG amounts, hashes, identifiers, bps and timestamps. No inference or evidence content is accepted into the chain journal or projection."},"type":"jsonb"}],"name":"agreement_events","purpose":"Reversible public AgreementEscrow event journal, bounded by confirmation and finality checks.","retention":"Public chain journal and projections remain until the operator removes the agreement index. Orphaned events and projections are removed and replayed on reorganization."},{"about_request":"yes","category":"chain","columns":[{"about_request":"yes","name":"scope","nullable":false,"purpose":"Chain id, configured escrow and oracle addresses; isolates deployments.","type":"text"},{"about_request":"yes","name":"agreement_id","nullable":false,"purpose":"Composite decimal agreement.milestone identifier from the configured escrow contract.","type":"text"},{"about_request":"yes","name":"dispute","nullable":false,"purpose":"Canonical dispute transaction hash and log index, or before-dispute plus the creation transaction/log identity for earlier evidence; prevents reuse of a reorged id from exposing old content.","type":"text"},{"about_request":"yes","name":"party","nullable":false,"purpose":"Authenticated account wallet matched to the indexed payer or payee, never a caller IP.","type":"text"},{"about_request":"yes","name":"sha256","nullable":false,"purpose":"SHA-256 of canonical JSON content before encryption; public to both parties.","type":"text"},{"about_request":"yes","flags":["name:content"],"name":"content","nullable":false,"purpose":"AES-GCM encrypted canonical JSON evidence; may contain arbitrary text including prompts, deliverables and personal information. The router decrypts it for party detail and jury calls. Default cap 16 KiB per item and 32 entries per party. Evidence is not end-to-end encrypted through the router.","review":{"covers":["name:content"],"verdict":"holds-request-text","why":"The feature explicitly persists party-uploaded evidence content. Encryption at rest does not prevent the router or an operator with APP_SECRET from reading it. Only wallet-linked parties can retrieve it through these routes, and configured attested models receive it for adjudication."},"type":"text"},{"about_request":"yes","name":"created_at","nullable":false,"purpose":"Time this record was first saved by the router.","type":"timestamp with time zone"}],"name":"agreement_evidence","purpose":"Party-uploaded text or JSON evidence, encrypted with APP_SECRET and hash-committed. Only the parties have REST access; the router and jury providers read the decrypted bundle.","retention":"Evidence and signed jury statements are deleted after canonical resolution plus AGREEMENT_RETENTION_DAYS (30 by default), while agreement-retention runs with a fresh index. Parties may delete their own evidence after that interval. Backups follow the operator backup policy; deletion is not erasure from backups or chain."},{"about_request":"aggregate","category":"chain","columns":[{"about_request":"aggregate","name":"scope","nullable":false,"purpose":"Chain id, configured escrow and oracle addresses; isolates deployments.","type":"text"},{"about_request":"aggregate","name":"agreement_id","nullable":false,"purpose":"Composite decimal agreement.milestone identifier from the configured escrow contract.","type":"text"},{"about_request":"aggregate","name":"dispute","nullable":false,"purpose":"Canonical dispute transaction hash and log index, or before-dispute plus the creation transaction/log identity for earlier evidence; prevents reuse of a reorged id from exposing old content.","type":"text"},{"about_request":"aggregate","name":"root","nullable":false,"purpose":"RFC 6962 SHA-256 Merkle root of canonical header and ordered party-evidence leaves.","type":"text"},{"about_request":"aggregate","name":"status","nullable":false,"purpose":"dry_run, panel, submitted, posting_failed or posted. A dry_run does not send a transaction. Posted denotes a successful transaction receipt, with escrow state reconciled separately by the index.","type":"text"},{"about_request":"aggregate","flags":["type:json"],"name":"statement","nullable":false,"purpose":"Signed jury scope, dispute, root, leaf digests, fixed rubric digest, model list, majority threshold, per-model verdict/reason or fixed failure code, receipt id/link/policy hash, internal router-signed operational receipt with request/response hashes, provider attestation reference including report hash/time/TEE/TLS pin, checked gateway receipt reference and upstream claims, provider-list-price operator cost estimate and token usage (not an invoice; failed calls may incur unmeasured cost), consensus bps, agreeing-model bitmap (separate from on-chain signer-order bitmaps), issuance time and trust notice. Model reasons may quote evidence text.","review":{"covers":["type:json"],"verdict":"holds-request-text","why":"Structured model verdict reasons are answer text and can repeat uploaded evidence. This statement therefore stores answer content openly in the inventory, behind party-only API access and resolution-based retention. The public key log contains public signing material. Chain calldata contains evidence root and per-key basis-point votes with EIP-712 signatures; the oracle records signer-order bitmaps and tally hash. The worker holds one operator-configured private key per model; models do not hold these keys."},"type":"jsonb"},{"about_request":"aggregate","name":"key_id","nullable":false,"purpose":"Existing router Ed25519 receipt signing key id, published in the transparency key log when enabled and always before posting; dry-run can omit the key log.","type":"text"},{"about_request":"aggregate","name":"signature","nullable":false,"purpose":"Base64 Ed25519 signature over canonical statement JSON.","type":"text"},{"about_request":"aggregate","name":"posting_tx","nullable":true,"purpose":"Hash of the persisted oracle transaction, public once broadcast.","type":"text"},{"about_request":"aggregate","name":"posting_raw","nullable":true,"purpose":"APP_SECRET-encrypted signed oracle transaction, saved before broadcast for identical nonce/byte retries. No private signer key is saved here.","type":"text"},{"about_request":"aggregate","name":"created_at","nullable":false,"purpose":"Time this record was first saved by the router.","type":"timestamp with time zone"}],"name":"agreement_jury","purpose":"Router-signed model jury statement and durable ruling intent for the canonical dispute. Complete hung tallies may enter the panel path; failed or abstaining votes remain unresolved until a valid tally or expiry. Default consensus status is dry_run.","retention":"Evidence and signed jury statements are deleted after canonical resolution plus AGREEMENT_RETENTION_DAYS (30 by default), while agreement-retention runs with a fresh index. Parties may delete their own evidence after that interval. Backups follow the operator backup policy; deletion is not erasure from backups or chain."},{"about_request":"no","category":"chain","columns":[{"about_request":"no","name":"scope","nullable":false,"purpose":"Chain id, configured escrow and oracle addresses; isolates deployments.","type":"text"},{"about_request":"no","name":"kind","nullable":false,"purpose":"Fixed agreement projection kind; each row is an individual milestone.","type":"text"},{"about_request":"no","name":"id","nullable":false,"purpose":"Composite decimal agreement.milestone identifier from the configured escrow contract.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"data","nullable":false,"purpose":"Agreement id and creation transaction/log identity, public payer/payee wallets, amount, terms hash, ordered deliverable hashes, agreement deadline, milestone index, oracle address, review deadline and exact payout amounts, dispute identity/evidence hash/time, resolution time and public on-chain ruling. No uploaded evidence or model reasons.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Only decoded public agreement event values and canonical block metadata are stored: wallets, USDG amounts, hashes, identifiers, bps and timestamps. No inference or evidence content is accepted into the chain journal or projection."},"type":"jsonb"}],"name":"agreement_projection","purpose":"Canonical agreement state rebuilt from the journal; both parties' wallet-linked accounts have API access.","retention":"Public chain journal and projections remain until the operator removes the agreement index. Orphaned events and projections are removed and replayed on reorganization."},{"about_request":"no","category":"chain","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"The cursor's name.","type":"text"},{"about_request":"no","name":"block","nullable":false,"purpose":"The last block read.","type":"bigint"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"chain_cursor","purpose":"How far the router has read each chain.","retention":"One row per cursor, overwritten as the chain advances."},{"about_request":"no","category":"chain","columns":[{"about_request":"no","name":"tx_hash","nullable":false,"purpose":"The transaction.","type":"text"},{"about_request":"no","name":"log_index","nullable":false,"purpose":"The log's position in the transaction.","type":"integer"},{"about_request":"no","name":"contract","nullable":false,"purpose":"The contract that emitted it.","type":"text"},{"about_request":"no","name":"event","nullable":false,"purpose":"The event name.","type":"text"},{"about_request":"no","name":"block_number","nullable":false,"purpose":"The block.","type":"bigint"},{"about_request":"no","flags":["type:json"],"name":"args","nullable":false,"purpose":"The event's decoded arguments: addresses, amounts and hashes.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Decoded on-chain event arguments; public blockchain data."},"type":"jsonb"},{"about_request":"no","name":"processed","nullable":false,"purpose":"Whether the router has acted on it.","type":"boolean"},{"about_request":"no","name":"processed_at","nullable":true,"purpose":"When it did.","type":"timestamp with time zone"},{"about_request":"no","flags":["name:content"],"name":"error","nullable":true,"purpose":"Why processing the event failed, when it did.","review":{"covers":["name:content"],"verdict":"no-request-content","why":"An error string from the chain indexer while handling a public on-chain event; the indexer never sees a request."},"type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"chain_events","purpose":"Contract events the router has read from the chain, each processed once.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"chain","columns":[{"about_request":"no","name":"tx_hash","nullable":false,"purpose":"The public transaction hash.","type":"text"},{"about_request":"no","name":"log_index","nullable":false,"purpose":"The log's position in the transaction.","type":"integer"},{"about_request":"no","name":"block_number","nullable":false,"purpose":"The block.","type":"bigint"},{"about_request":"no","name":"block_time","nullable":false,"purpose":"The block's time.","type":"timestamp with time zone"},{"about_request":"no","flags":["name:network"],"name":"from_address","nullable":false,"purpose":"The wallet the USDG left.","review":{"covers":["name:network"],"verdict":"wallet-address","why":"A lowercase blockchain wallet or contract address copied from a public USDG Transfer log; not a caller's network address."},"type":"text"},{"about_request":"no","flags":["name:network"],"name":"to_address","nullable":false,"purpose":"The wallet the USDG went to.","review":{"covers":["name:network"],"verdict":"wallet-address","why":"A lowercase blockchain wallet or contract address copied from a public USDG Transfer log; not a caller's network address."},"type":"text"},{"about_request":"no","name":"value_usdg","nullable":false,"purpose":"The amount in USDG base units, capped at the bigint maximum.","type":"bigint"},{"about_request":"no","name":"authorized","nullable":false,"purpose":"Whether an EIP-3009 authorization of the sender moved it (an AuthorizationUsed log by the sender in the same transaction).","type":"boolean"},{"about_request":"no","name":"tx_from","nullable":true,"purpose":"For an authorized transfer, the public address that sent the transaction (the relayer); null otherwise.","type":"text"}],"name":"commerce_transfers","purpose":"When COMMERCE_STATS_ENABLED and COMMERCE_FUNDING_FROM_BLOCK are set, every USDG Transfer on the configured chain from that block on, so the commerce ledger can tell which wallets funded which. Public chain data only; no account, key, receipt or request is linked to a row.","retention":"No automatic deletion: the funding filter reads the whole copy from the start block. Removed only when the operator drops the table or clears the copy."},{"about_request":"no","category":"chain","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"<transaction>:<log index>.","type":"text"},{"about_request":"no","name":"tx_hash","nullable":false,"purpose":"The transaction.","type":"text"},{"about_request":"no","name":"log_index","nullable":false,"purpose":"The log's position in the transaction.","type":"integer"},{"about_request":"no","name":"block_number","nullable":false,"purpose":"The block.","type":"bigint"},{"about_request":"no","name":"token","nullable":false,"purpose":"The token contract.","type":"text"},{"about_request":"no","name":"symbol","nullable":false,"purpose":"The token symbol.","type":"text"},{"about_request":"no","flags":["name:network"],"name":"from_address","nullable":false,"purpose":"The wallet that sent the tokens, as recorded on chain.","review":{"covers":["name:network"],"verdict":"wallet-address","why":"A blockchain wallet address that is public in the transfer itself; not a network address."},"type":"text"},{"about_request":"no","name":"raw_amount","nullable":false,"purpose":"The amount in token base units.","type":"numeric(78, 0)"},{"about_request":"no","name":"status","nullable":false,"purpose":"pending_finality, pending, provisional (credited while settling), credited, orphaned or reversed.","type":"text"},{"about_request":"no","name":"block_hash","nullable":true,"purpose":"The block hash when recorded; the credit is checked against it.","type":"text"},{"about_request":"no","name":"account_id","nullable":true,"purpose":"The account it was credited to.","type":"text"},{"about_request":"no","name":"price18","nullable":true,"purpose":"USD per whole token at 18 decimals, as read from the price feed (USDG: exactly 1, credited at par).","type":"text"},{"about_request":"no","name":"price_updated_at","nullable":true,"purpose":"When the feed last updated.","type":"timestamp with time zone"},{"about_request":"no","name":"credited","nullable":true,"purpose":"The pico-USD credited after the haircut.","type":"bigint"},{"about_request":"no","flags":["name:content"],"name":"error","nullable":true,"purpose":"Why crediting failed, when it did.","review":{"covers":["name:content"],"verdict":"no-request-content","why":"An error string from the escrow indexer about an on-chain transfer; no request is involved."},"type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"credited_at","nullable":true,"purpose":"When it was credited.","type":"timestamp with time zone"},{"about_request":"no","name":"checked_at","nullable":true,"purpose":"When the credit was last re-verified against the canonical chain.","type":"timestamp with time zone"},{"about_request":"no","name":"reversed_at","nullable":true,"purpose":"When a credit was reversed.","type":"timestamp with time zone"},{"about_request":"no","name":"review_reason","nullable":true,"purpose":"Set when an operator has to look: a reversal, or an orphan after finality.","type":"text"},{"about_request":"no","name":"reviewed_at","nullable":true,"purpose":"Set once an operator has reconciled it.","type":"timestamp with time zone"}],"name":"escrow_deposits","purpose":"Stock Token, $ANYR and USDG transfers into the escrow wallet: one row per transfer, its price, its status and whether it was credited.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"yes","category":"chain","columns":[{"about_request":"yes","name":"id","nullable":false,"purpose":"Random settlement identifier (fst_ followed by 24 hex characters); also the receipt id.","type":"text"},{"about_request":"yes","name":"kind","nullable":false,"purpose":"payment, or gas_float for a seller's gas float top-up.","type":"text"},{"about_request":"yes","name":"payer","nullable":false,"purpose":"Lowercase wallet address that signed the authorization.","type":"text"},{"about_request":"yes","name":"pay_to","nullable":false,"purpose":"Lowercase wallet address the USDG went to.","type":"text"},{"about_request":"yes","name":"value","nullable":false,"purpose":"Authorized USDG base units.","type":"numeric(78, 0)"},{"about_request":"yes","name":"nonce","nullable":false,"purpose":"The authorization's EIP-3009 nonce.","type":"text"},{"about_request":"yes","name":"tx_hash","nullable":true,"purpose":"Relay transaction hash, once settled.","type":"text"},{"about_request":"yes","name":"status","nullable":false,"purpose":"verified (claimed, relay in flight), settled or failed.","type":"text"},{"about_request":"yes","flags":["name:content"],"name":"error","nullable":true,"purpose":"A fixed code for a failed relay (relay_failed).","review":{"covers":["name:content"],"verdict":"no-request-content","why":"A fixed code written by the facilitator code, never chain error text, a request body or an answer."},"type":"text"},{"about_request":"yes","name":"seller_id","nullable":true,"purpose":"Listing the payment belongs to, when the payTo has one.","type":"text"},{"about_request":"yes","name":"x402_version","nullable":false,"purpose":"x402 protocol version of the payment, 1 or 2.","type":"smallint"},{"about_request":"yes","name":"fee_value","nullable":true,"purpose":"USDG base units of the facilitator fee authorization, when a fee is charged.","type":"numeric(78, 0)"},{"about_request":"yes","name":"fee_tx_hash","nullable":true,"purpose":"Transaction hash of the relayed fee authorization.","type":"text"},{"about_request":"yes","name":"gas_debit","nullable":true,"purpose":"USDG base units taken from the seller's gas float for this settle.","type":"numeric(78, 0)"},{"about_request":"yes","name":"settled_at","nullable":true,"purpose":"When the relay landed and the receipt was signed.","type":"timestamp with time zone"},{"about_request":"yes","name":"receipt_cose","nullable":true,"purpose":"The signed receipt (base64 COSE_Sign1): network, asset, transaction, amount, payTo and fee. It names no payer.","type":"text"},{"about_request":"yes","name":"receipt_leaf","nullable":true,"purpose":"The receipt's leaf hash in the hourly anchoring tree.","type":"text"},{"about_request":"yes","name":"receipt_key_id","nullable":true,"purpose":"Receipt signing key id.","type":"text"},{"about_request":"yes","name":"anchor_index","nullable":true,"purpose":"Anchor (Merkle root) this receipt was included in, once rooted.","type":"integer"},{"about_request":"yes","name":"leaf_index","nullable":true,"purpose":"Position of the receipt's leaf in that anchor's tree.","type":"integer"},{"about_request":"yes","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"facilitator_settlements","notes":["Payer, payTo, amount, nonce and transaction hash are the same facts the public chain shows for the transfer. Payers are not screened: the facilitator never holds the funds it relays."],"purpose":"One row per facilitator settle that passed verification: the payer's signed USDG authorization relayed straight to the seller's payTo (or to the treasury for a gas float top-up). (payer, nonce) is unique, so an authorization settles at most once here. Settled rows carry a signed receipt of kind facilitator.settle that joins the hourly anchor.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"chain","columns":[{"about_request":"no","name":"scope","nullable":false,"purpose":"Chain id and HostBond contract address; public chain identifiers.","type":"text"},{"about_request":"no","name":"block","nullable":false,"purpose":"Last scanned canonical block, or the deployment block minus one before scanning.","type":"bigint"},{"about_request":"no","name":"block_hash","nullable":true,"purpose":"Canonical block hash at the scan cursor.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"checkpoints","nullable":false,"purpose":"Up to 128 scan endpoints as block number/hash pairs. Reorgs rewind to the newest matching checkpoint, or the deployment block when none remain canonical.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Contains only public HostBond event values or projections: wallet and contract identifiers, amounts, reason codes, hashes, flags and block times. No inference content or caller connection address is read."},"type":"jsonb"},{"about_request":"no","name":"checked_at","nullable":false,"purpose":"Last caught-up scan time. Zero during backfill; routing boosts and slashing stop after 120 seconds without a caught-up pass.","type":"timestamp with time zone"}],"name":"host_bond_cursor","purpose":"Resumable HostBond event scan cursor, isolated by chain and contract. Serializes scans and slash intents across workers.","retention":"Kept until the operator removes the bond index. Orphaned journal events and projections are removed on a chain reorganization; slash intent and evidence commitments are retained for idempotency."},{"about_request":"no","category":"chain","columns":[{"about_request":"no","name":"scope","nullable":false,"purpose":"Chain id and HostBond contract address.","type":"text"},{"about_request":"no","name":"tx_hash","nullable":false,"purpose":"Public transaction hash, unique with scope and log index.","type":"text"},{"about_request":"no","name":"log_index","nullable":false,"purpose":"Log position within the canonical block.","type":"integer"},{"about_request":"no","name":"block","nullable":false,"purpose":"Canonical event block number.","type":"bigint"},{"about_request":"no","name":"block_hash","nullable":false,"purpose":"Block hash checked against the RPC's canonical chain.","type":"text"},{"about_request":"no","name":"event","nullable":false,"purpose":"ABI event name, including Bonded, UnbondRequested/Cancelled/Unbonded, slash lifecycle, role, ownership and minimum changes.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"args","nullable":false,"purpose":"Decoded public ABI arguments: bytes32 host id/evidence root/dispute hash, slash id, operator/recipient/role wallets, amount, total, reason, cooldown/dispute deadline and delisting flag. Numbers are decimal strings; no arbitrary transaction calldata is stored.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Contains only public HostBond event values or projections: wallet and contract identifiers, amounts, reason codes, hashes, flags and block times. No inference content or caller connection address is read."},"type":"jsonb"}],"name":"host_bond_events","purpose":"Every decoded event from the configured HostBond deployment, including ownership and parameter changes. Reversible journal; no inference records are changed.","retention":"Kept until the operator removes the bond index. Orphaned journal events and projections are removed on a chain reorganization; slash intent and evidence commitments are retained for idempotency."},{"about_request":"no","category":"chain","columns":[{"about_request":"no","name":"scope","nullable":false,"purpose":"Chain id and HostBond contract address.","type":"text"},{"about_request":"no","name":"kind","nullable":false,"purpose":"Projection kind: host, slash or parameters.","type":"text"},{"about_request":"no","name":"id","nullable":false,"purpose":"Bytes32 host id, decimal slash id, or the fixed current parameter key.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"data","nullable":false,"purpose":"Host projections contain operator wallet, total and queued bond, unbond deadline and delisting flag. Slash projections contain host id, amount, contract reason, evidence root, dispute deadline/hash, status, approval generation and transaction history. Parameter projection contains minimum bond, approval generation, owner/pending owner, slasher and refund pool wallets. All values are public on-chain data.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Contains only public HostBond event values or projections: wallet and contract identifiers, amounts, reason codes, hashes, flags and block times. No inference content or caller connection address is read."},"type":"jsonb"}],"name":"host_bond_projection","purpose":"Reversible HostBond state reduced from the journal, with one row per host, slash or parameter set. The provider's existing bond_usdg field is left unchanged.","retention":"Kept until the operator removes the bond index. Orphaned journal events and projections are removed on a chain reorganization; slash intent and evidence commitments are retained for idempotency."},{"about_request":"aggregate","category":"chain","columns":[{"about_request":"aggregate","name":"scope","nullable":false,"purpose":"Chain id and HostBond contract address.","type":"text"},{"about_request":"aggregate","name":"root","nullable":false,"purpose":"0x-prefixed SHA-256 commitment of the exact canonical evidence bundle; primary key with scope prevents repeated proposal intents.","type":"text"},{"about_request":"aggregate","name":"provider_id","nullable":false,"purpose":"Network provider id from the registry.","type":"text"},{"about_request":"aggregate","flags":["name:network"],"name":"host_id","nullable":false,"purpose":"keccak256 of the provider id, matched to the HostBond operator before proposal.","review":{"covers":["name:network"],"verdict":"no-request-content","why":"A bytes32 contract host identifier, derived from the provider id with keccak256. It is not a caller connection address or a host's network endpoint."},"type":"text"},{"about_request":"aggregate","name":"canonical","nullable":false,"purpose":"Exact canonical structured bundle: format, provider/host ids, fault kind, contract reason or null, policy version/hash where applicable, observed binding or receipt digest, attestation reference, receipt public key when applicable, and rejection digest. Contains hashes and identifiers only. Raw quotes, bindings, receipt envelopes, signature bytes, prompt and answer text are not retained here. A commitment does not by itself prove fault; review requires the source evidence.","type":"text"},{"about_request":"aggregate","name":"reason","nullable":false,"purpose":"Contract MeasurementDrift code 0 for verified policy rejection; -1 means invalid receipt evidence awaiting policy review, never automatically proposed.","type":"integer"},{"about_request":"aggregate","name":"amount","nullable":false,"purpose":"Proposal amount in USDG base units: current whole bond at preparation, or would-be amount in dry run. Owner independently approves the exact proposal.","type":"text"},{"about_request":"aggregate","name":"status","nullable":false,"purpose":"ready, review, dry_run, submitted, executing, cancelled or executed; always reconciled against the canonical journal before action.","type":"text"},{"about_request":"aggregate","name":"proposal_tx","nullable":true,"purpose":"Hash of the single persisted proposal transaction.","type":"text"},{"about_request":"aggregate","name":"proposal_raw","nullable":true,"purpose":"APP_SECRET-encrypted signed proposal transaction. Saved before broadcasting; retries reuse identical bytes and nonce. The signed transaction becomes public on broadcast; no slasher key is persisted.","type":"text"},{"about_request":"aggregate","name":"execution_tx","nullable":true,"purpose":"Hash of the single persisted execution transaction.","type":"text"},{"about_request":"aggregate","name":"execution_raw","nullable":true,"purpose":"APP_SECRET-encrypted signed execution transaction, saved before broadcast and reused on retry. Independent owner approval and the undisputed window are checked before preparation.","type":"text"},{"about_request":"aggregate","name":"created_at","nullable":false,"purpose":"Time this exact evidence commitment was first stored.","type":"timestamp with time zone"}],"name":"host_slash_evidence","purpose":"Hash-committed evidence of quote-bound host policy rejection and invalid receipts from the pinned host feed, plus durable proposal/execution intents. Disabled unless NETWORK_BONDS_ENABLED.","retention":"Kept until the operator removes the bond index. Orphaned journal events and projections are removed on a chain reorganization; slash intent and evidence commitments are retained for idempotency."},{"about_request":"aggregate","category":"chain","columns":[{"about_request":"aggregate","name":"id","nullable":false,"purpose":"Transfer id.","type":"text"},{"about_request":"aggregate","name":"payer","nullable":false,"purpose":"Wallet address the refund is sent to.","type":"text"},{"about_request":"aggregate","name":"usdg","nullable":false,"purpose":"Amount in USDG base units: the sum of that payer's owed refunds in the batch.","type":"bigint"},{"about_request":"aggregate","name":"status","nullable":false,"purpose":"signed (stored, possibly broadcast), paid (mined successfully) or failed (reverted; its refunds are owed again).","type":"text"},{"about_request":"aggregate","name":"tx_hash","nullable":false,"purpose":"Hash of the signed transfer transaction.","type":"text"},{"about_request":"aggregate","name":"signed_tx_enc","nullable":false,"purpose":"The signed transaction bytes encrypted under APP_SECRET, kept to rebroadcast the identical transfer; never the treasury key.","type":"text"},{"about_request":"aggregate","name":"created_at","nullable":false,"purpose":"When the transfer was signed.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"settled_at","nullable":true,"purpose":"When it was seen mined or reverted.","type":"timestamp with time zone"}],"name":"makegood_payouts","purpose":"On-chain make-good refund transfers: one USDG transfer from the refund treasury per payer per batch, signed and stored before it is broadcast so a retry resends the same transfer and never pays twice.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"chain","columns":[{"about_request":"no","name":"payout_id","nullable":false,"purpose":"The payout whose claimed invoices this transfer settles.","type":"text"},{"about_request":"no","name":"signed_tx_enc","nullable":false,"purpose":"Encrypted serialized signed blockchain transfer: chain, nonce, USDG contract, destination, amount and fees; no inference text or signing key.","type":"text"},{"about_request":"no","name":"tx_hash","nullable":false,"purpose":"Hash of the signed transfer, fixed before first broadcast.","type":"text"}],"name":"network_payout_dispatch","notes":["The signed transaction can authorize only its encoded transfer, but replaying it before inclusion broadcasts that transfer. It is encrypted with APP_SECRET and never exposed by public APIs. No private signing key is stored here. Reverted, destination-changed or nonce-conflicted transfers require operator reconciliation."],"purpose":"Durable signed USDG transfer for a network payout. Written before broadcasting so recovery sends identical bytes and cannot pay again using another nonce.","retention":"No automatic deletion, and rows are never changed after they are written."},{"about_request":"yes","category":"chain","columns":[{"about_request":"yes","name":"id","nullable":false,"purpose":"Debt id.","type":"text"},{"about_request":"yes","name":"chain_key_hash","nullable":false,"purpose":"The key's chain hash.","type":"text"},{"about_request":"yes","name":"account_id","nullable":false,"purpose":"The account.","type":"text"},{"about_request":"yes","name":"generation_id","nullable":false,"purpose":"The generation that created the debt.","type":"text"},{"about_request":"yes","name":"token","nullable":false,"purpose":"The token contract.","type":"text"},{"about_request":"yes","name":"amount","nullable":false,"purpose":"Pico-USD owed.","type":"bigint"},{"about_request":"yes","name":"raw_estimate","nullable":true,"purpose":"Estimated token units.","type":"bigint"},{"about_request":"yes","name":"fair_price18","nullable":true,"purpose":"The fair price used, 18 decimals.","type":"text"},{"about_request":"yes","name":"swap_id","nullable":true,"purpose":"The swap that settled it.","type":"text"},{"about_request":"yes","name":"raw_allocated","nullable":true,"purpose":"Token units allocated to it by the swap.","type":"bigint"},{"about_request":"yes","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"paywith_debts","purpose":"What a pay-with call owes in tokens, until a swap settles it.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"chain","columns":[{"about_request":"no","name":"key_hash","nullable":false,"purpose":"The key's chain hash.","type":"text"},{"about_request":"no","name":"wallet","nullable":false,"purpose":"The wallet that opened the session.","type":"text"},{"about_request":"no","name":"token","nullable":false,"purpose":"The token contract.","type":"text"},{"about_request":"no","name":"symbol","nullable":false,"purpose":"The token symbol.","type":"text"},{"about_request":"no","name":"cap_raw_day","nullable":false,"purpose":"The daily cap in token base units.","type":"bigint"},{"about_request":"aggregate","name":"spent_raw_today","nullable":false,"purpose":"Spent today in token base units.","type":"bigint"},{"about_request":"no","name":"day_start","nullable":true,"purpose":"When today's window began.","type":"timestamp with time zone"},{"about_request":"no","name":"active","nullable":false,"purpose":"Whether the session is active.","type":"boolean"},{"about_request":"no","name":"opened_tx","nullable":true,"purpose":"The transaction that opened it.","type":"text"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"paywith_sessions","purpose":"Pay-with sessions: a wallet's daily cap for paying with a Stock Token through a key.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"aggregate","category":"chain","columns":[{"about_request":"aggregate","name":"id","nullable":false,"purpose":"Swap id.","type":"text"},{"about_request":"aggregate","name":"key_hash","nullable":false,"purpose":"The key's chain hash.","type":"text"},{"about_request":"aggregate","name":"token","nullable":false,"purpose":"The token contract.","type":"text"},{"about_request":"aggregate","name":"raw_spent","nullable":true,"purpose":"Token units spent.","type":"bigint"},{"about_request":"aggregate","name":"fair_price","nullable":true,"purpose":"The fair price used.","type":"text"},{"about_request":"aggregate","name":"usdg_out","nullable":false,"purpose":"USDG base units received.","type":"bigint"},{"about_request":"aggregate","name":"tx","nullable":true,"purpose":"The swap transaction.","type":"text"},{"about_request":"aggregate","name":"status","nullable":false,"purpose":"pending, submitted, confirmed or failed.","type":"text"},{"about_request":"aggregate","flags":["name:content"],"name":"error","nullable":true,"purpose":"Why the swap failed, when it did.","review":{"covers":["name:content"],"verdict":"no-request-content","why":"An error string from a swap transaction; no request is involved."},"type":"text"},{"about_request":"aggregate","name":"ts","nullable":false,"purpose":"When the swap was created.","type":"timestamp with time zone"},{"about_request":"aggregate","flags":["type:json"],"name":"allocations","nullable":true,"purpose":"Which debts the swap settled and how much of it each got.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Debt ids and token amounts written by the pay-with aggregator."},"type":"jsonb"}],"name":"paywith_swaps","purpose":"Swaps that turn pay-with tokens into USDG to settle debts.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"aggregate","category":"chain","columns":[{"about_request":"aggregate","name":"id","nullable":false,"purpose":"Slash id.","type":"text"},{"about_request":"aggregate","name":"provider_id","nullable":false,"purpose":"The provider.","type":"text"},{"about_request":"aggregate","name":"model_id","nullable":true,"purpose":"The model, when the penalty is per model.","type":"text"},{"about_request":"aggregate","name":"kind","nullable":false,"purpose":"empty200, quant_fraud, uptime or param_drop.","type":"text"},{"about_request":"aggregate","name":"amount_usdg","nullable":false,"purpose":"The amount in USDG base units.","type":"bigint"},{"about_request":"aggregate","name":"delist","nullable":false,"purpose":"Whether the provider is delisted with it.","type":"boolean"},{"about_request":"aggregate","name":"evidence_root","nullable":false,"purpose":"A Merkle root over the evidence.","type":"text"},{"about_request":"aggregate","flags":["type:json"],"name":"evidence","nullable":false,"purpose":"The evidence: counts of requests and empty answers, canary results or uptime figures, and the window they cover.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Assembled by gatherEvidence in slasher.ts from counts, canary results and time windows; no request or answer text is read."},"type":"jsonb"},{"about_request":"aggregate","name":"status","nullable":false,"purpose":"proposed, disputed, cancelled, executed or auto_refunded.","type":"text"},{"about_request":"aggregate","name":"proposed_at","nullable":false,"purpose":"When it was proposed.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"executable_at","nullable":false,"purpose":"When it may be executed.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"executed_at","nullable":true,"purpose":"When it was.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"dispute_hash","nullable":true,"purpose":"The hash of the provider's dispute.","type":"text"},{"about_request":"aggregate","name":"disputed_at","nullable":true,"purpose":"When it disputed.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"onchain_id","nullable":true,"purpose":"The id on chain.","type":"text"},{"about_request":"aggregate","name":"tx_hash","nullable":true,"purpose":"The transaction.","type":"text"},{"about_request":"aggregate","name":"refunded","nullable":false,"purpose":"Pico-USD refunded to callers affected.","type":"bigint"}],"name":"slashes","purpose":"Penalties proposed against a provider for empty answers, precision fraud, poor uptime or dropped parameters, with the evidence and where it stands.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"aggregate","category":"chain","columns":[{"about_request":"aggregate","name":"epoch","nullable":false,"purpose":"The epoch.","type":"integer"},{"about_request":"aggregate","name":"root","nullable":false,"purpose":"The Merkle root.","type":"text"},{"about_request":"aggregate","name":"as_of","nullable":false,"purpose":"The time the spend is counted to.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"total_spent_usdg","nullable":false,"purpose":"Total spend in USDG base units.","type":"bigint"},{"about_request":"aggregate","flags":["type:json"],"name":"leaves","nullable":false,"purpose":"Pairs of a key's chain hash and its cumulative spend in USDG base units, in tree order.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"[chainKeyHash, cumulativeSpentUsdg] pairs built from ledger totals."},"type":"jsonb"},{"about_request":"aggregate","name":"tx_hash","nullable":true,"purpose":"The transaction that posted the root.","type":"text"},{"about_request":"aggregate","name":"status","nullable":false,"purpose":"pending, submitted or confirmed.","type":"text"},{"about_request":"aggregate","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"spent_roots","purpose":"A Merkle root over every key's cumulative spend, posted on chain so balances can be settled.","retention":"No automatic deletion: no job or route in the code removes rows from this table."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Memory id.","type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"The account that owns it.","type":"text"},{"about_request":"no","name":"scope","nullable":false,"purpose":"An HMAC of the character id under the client's key: it groups one character's memories without naming the character.","type":"text"},{"about_request":"no","name":"kind","nullable":false,"purpose":"summary, fact, lorebook or state, as the client labels it.","type":"text"},{"about_request":"no","name":"sealed","nullable":false,"purpose":"The ciphertext the client sealed (arm1.<iv>.<ciphertext>); the API refuses anything that is not in this sealed form.","type":"text"},{"about_request":"no","name":"key_id","nullable":false,"purpose":"A 16-hex fingerprint derived from the client's key, so the client can tell which key sealed it. The key cannot be recovered from it.","type":"text"},{"about_request":"no","name":"bytes","nullable":false,"purpose":"Size of the ciphertext in characters.","type":"integer"},{"about_request":"no","name":"embedding","nullable":true,"purpose":"Only when the client opts in (embedding_opt_in): a vector the client computed from the memory, for similarity search. It cannot be turned back into the text, but it can reveal what the memory is about, so it is off by default. Empty otherwise.","type":"real[]"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"character_memory","purpose":"Character memory an account keeps: rolling summaries, facts and lorebook notes sealed on the account's own device (AES-256-GCM) under a viewing key the router never receives. The router stores ciphertext, never the memory's text, and cannot tell which character a memory belongs to.","retention":"Kept until the account deletes it (DELETE /api/v1/memory/:id, or ?scope= / ?all=1 for many)."},{"about_request":"aggregate","category":"operations","columns":[{"about_request":"aggregate","name":"character_id","nullable":false,"purpose":"The public character.","type":"text"},{"about_request":"aggregate","name":"period","nullable":false,"purpose":"The UTC day, YYYY-MM-DD.","type":"text"},{"about_request":"aggregate","name":"calls","nullable":false,"purpose":"Calls that used the character that day (never counted on the unlinkable lane).","type":"integer"},{"about_request":"aggregate","name":"cost","nullable":false,"purpose":"What those calls cost in total, in pico-USD.","type":"bigint"}],"name":"character_usage","purpose":"Creator attribution for public characters: how many calls used each one and what they cost, summed per UTC day. It records no request, answer, key or caller.","retention":"No automatic deletion: no job or route in the code removes rows from this table. Rows are deleted with their character."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Character id, used as @character/<id>.","type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"The account that owns it.","type":"text"},{"about_request":"no","name":"visibility","nullable":false,"purpose":"public (listed in discovery), unlisted (readable by anyone with the id) or private (sealed, owner only).","type":"text"},{"about_request":"no","name":"name","nullable":true,"purpose":"The card's name; empty for a private card.","type":"text"},{"about_request":"no","name":"tags","nullable":false,"purpose":"The card's tags, lowercased, for discovery; empty for a private card.","type":"text[]"},{"about_request":"no","name":"creator","nullable":true,"purpose":"The card's creator field as the card states it; empty for a private card.","type":"text"},{"about_request":"no","name":"spec","nullable":true,"purpose":"chara_card_v2 or chara_card_v3; empty for a private card.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"card","nullable":true,"purpose":"The normalized card of a public or unlisted character: name, description, personality, scenario, greetings, example dialogue, system prompt, post-history instructions, tags, creator notes and lorebook. Empty for a private card.","review":{"covers":["type:json"],"verdict":"config","why":"Written by the card's owner through POST or PUT /api/v1/characters and normalized to the Tavern card fields, at most 512 KB. It is text a creator publishes for others to use, not text taken from a call: chats with the character are not stored here or anywhere else, and a private card is never stored in this column."},"type":"jsonb"},{"about_request":"no","name":"sealed_card","nullable":true,"purpose":"A private card as the owner's device sealed it: AES-256-GCM ciphertext under a key the router never receives. Empty for a public or unlisted card.","type":"text"},{"about_request":"no","name":"card_hash","nullable":false,"purpose":"SHA-256 of the card's canonical JSON. For a private card the router checks a card sent with a chat against it before using it.","type":"text"},{"about_request":"no","name":"default_model","nullable":true,"purpose":"The model @character/<id> uses when a request names none.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"characters","purpose":"Character cards an account registers (Tavern Card v2 or v3). A public or unlisted card is text its creator publishes for others to use, kept as written. A private card is kept only as the ciphertext the owner's own device sealed, with the SHA-256 of the card; the router never receives its key or its text at rest.","retention":"Kept until the owner deletes the character (DELETE /api/v1/characters/:id), which also deletes its attribution counters."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Random listing identifier (fsl_ followed by 24 hex characters).","type":"text"},{"about_request":"no","name":"pay_to","nullable":false,"purpose":"Lowercase wallet address the seller is paid at, which signed the listing. Public in every 402 response the seller sends.","type":"text"},{"about_request":"no","name":"resource","nullable":false,"purpose":"The seller's paid https URL as signed. The first payTo to list a URL owns that entry.","type":"text"},{"about_request":"no","name":"price_hint","nullable":true,"purpose":"Price the seller states, in USDG base units; the seller's own 402 response stays authoritative.","type":"numeric(78, 0)"},{"about_request":"no","flags":["type:json"],"name":"result_schema","nullable":true,"purpose":"JSON schema the seller published for its endpoint's result (x402 outputSchema), as signed.","review":{"covers":["type:json"],"verdict":"config","why":"Seller-written description of a public paid endpoint's result shape, signed by its payTo key and shown in discovery; never a caller's request or answer."},"type":"jsonb"},{"about_request":"no","name":"tags","nullable":false,"purpose":"Up to ten lowercase words the seller chose for search.","type":"text[]"},{"about_request":"no","name":"listed","nullable":false,"purpose":"Whether the listing shows in discovery.","type":"boolean"},{"about_request":"no","name":"signature","nullable":false,"purpose":"The payTo key's EIP-712 signature over the listing.","type":"text"},{"about_request":"no","name":"signed_at","nullable":false,"purpose":"issuedAt of the stored signature; only a later signature replaces the listing.","type":"timestamp with time zone"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"facilitator_sellers","purpose":"Sellers who opted in to the facilitator's discovery index: the paid URL, a price hint, an output schema and tags, each listing signed by the seller's payTo key. Shown publicly at /facilitator/discovery/resources while listed.","retention":"Kept until the seller replaces it with a later signed listing; listed false hides it from discovery. No job removes rows."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"version","nullable":false,"purpose":"Consecutive policy version, beginning at 1.","type":"integer"},{"about_request":"no","name":"issued_at","nullable":false,"purpose":"The policy's issue time supplied by the operator.","type":"timestamp with time zone"},{"about_request":"no","name":"canonical","nullable":false,"purpose":"Canonical JSON of the operator's policy: version, issue time, TEE kinds, approved sidecar image and source hashes, engine names and image digests, model IDs and digests, GPU CC requirements and optional model offer terms: catalogue slug, display name, Hugging Face ID, context and completion limits, quantization and positive USD-per-token prompt/completion prices. Offer terms are public operator-provided metadata, not inference content. A strict bounded schema accepts no prompt fields; names are operator-written identifiers with a restricted alphabet, so the router cannot know what meaning the operator assigns them. Public through the policy API.","type":"text"},{"about_request":"no","name":"sha256","nullable":false,"purpose":"SHA-256 of the exact canonical policy bytes.","type":"text"},{"about_request":"no","name":"signature","nullable":false,"purpose":"Base64 Ed25519 signature over the canonical policy bytes.","type":"text"},{"about_request":"no","name":"verifier_key","nullable":false,"purpose":"The public signed-note verifier key identifying the log key that signed this version.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"host_policies","purpose":"Public versions of the network host admission policy, signed with the transparency log's Ed25519 key. Publication alone does not admit providers; wallet-authenticated network admission verifies this policy before probation.","retention":"No automatic deletion, and rows are never changed after they are written."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"key","nullable":false,"purpose":"The key, a family name plus an identifier (see the families above).","type":"text"},{"about_request":"no","flags":["type:json"],"name":"value","nullable":false,"purpose":"The value, as JSON. Its shape depends on the key family.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Each family is written by one piece of code from ids, hashes, timestamps, amounts and settings; the families are listed under the table. None takes a value from the body of a chat, embeddings or other inference request."},"type":"jsonb"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"kv","notes":["deposit-watch:<chain id>:<account id>:<transaction hash>: account-scoped submitted-deposit status. Keeps account id, lane (escrow or USDG), transaction hash and submission time, up to 20 submitted hashes per account. Removed after indexed credit, otherwise retained until operator deletion. No typed amount or sender is accepted; display amounts and senders come from public chain logs. The deposit list also caches decoded unindexed USDG logs in process memory for five seconds, containing public key hashes, sending wallets, amounts, transaction hashes and block numbers; it does not credit funds.","fast-credit:lock: an empty singleton row locked during escrow crediting to serialize account and global outstanding-credit caps. Kept until operator deletion.","fast-credit:deposit:<chain id>:<lane>:<transaction>:<log index>: durable provisional deposit bookkeeping. Stores chain and lane identity, account id, sending wallet, transaction and log index, block and canonical hash, fixed capped pico-USD total, provisional pico-USD amount, provisional/final/reversed status, ledger and reversal references and kinds, and escrow price with its timestamp and per-deposit cap marker. Final settlement changes state and credits only the remainder; reversals debit the provisional amount. Kept indefinitely for idempotency. No inference text or caller network address.","telegram-link-code:<account id>: SHA-256 of a random single-use code, account id, principal key hash and expiry. One code per account, replaced on issuance, deleted on consumption/cancellation. Valid for five minutes; expired rows are purged on enabled polling or issuance. The code itself is returned once and stays in page memory until linking, cancellation or navigation; it is never saved in browser storage.","telegram-link:<Telegram user id>: account id, owner/admin principal key hash, Telegram user id, random generation and linked timestamp. One account per Telegram identity and one identity per principal key. Kept until /unlink or DELETE /api/v1/telegram/link; disabling or expiring the key or removing its role prevents use. No API key or message text. Existing chat keys under telegram:user are separate.","telegram-approval:<approval id>:<Telegram user id>:<link generation>: approval id, Telegram user id, generation, expiry, Telegram message id and fixed decision status. Delivery markers stop repeat polling sends and bind buttons to the originating message and current link. Deleted on unlink; expired markers are purged on enabled polling or issuance. Worker interruptions can repeat a notification; decisions use the dashboard's atomic logic. Telegram receives readable intent metadata and alerts, not inference messages or tool arguments. Message text is never stored here.","upstream-balance:<provider id>: latest USD balance (including zero and negative readings), check time and unknown/unsupported check state, with the last successful reading and its time retained across failed checks; upstream-credit-hold:<provider id>: expiry of a five-minute provider-wide routing hold after explicit insufficient credits. Balance readings at or below UPSTREAM_BALANCE_EXHAUSTED_USD (default 0) block routing until a later reading exceeds that threshold, including across restarts and failed polls. Enabled only by UPSTREAM_MONITOR_ENABLED. Overwritten in place; expired hold rows remain until operator deletion. No response text, API keys or caller identifiers are copied. Alerts use the existing alerts:state and alerts:lease rows and configured operations webhook. Balance state changes alert immediately with hashed provider check names; exhausted reminders are no more frequent than six hours. The alerts:state checks also retain the last delivered time for balance notices.","agent-alerts:<account id>: newest 100 metadata-only owner alerts per account, visible for up to 90 days; expired feed, denial and dedupe metadata is purged on the next alert write or enabled worker cleanup, while inactive account rows remain until operator deletion; threshold cooldowns, denial counts with up to 10,000 recent timestamps and random transaction batch markers per key (10-minute rolling retention on writes/cleanup), timestamps, key hashes, selected channels, delivery attempts, destination rule ids or Telegram ids and per-account delivery rate/lease state. No prompt, answer, intent, kill reason, webhook URL or API key is copied. Existing Spend Watch destinations are decrypted for guarded egress; existing Telegram principal links are decrypted and permission-checked before delivery. Email has no account destination. Delivery is at-least-once; a crash after sending can repeat an attempt.","telegram:offset, telegram:user:<Telegram user id>: the update cursor, and per user the API key sealed under APP_SECRET, the chosen model and the private-mode switch (services/telegram.ts). Message text is not stored.","wallet-login:<nonce>: a sign-in challenge (wallet address, the router's own origin, chain id, expiry and the message to sign). Deleted when used; older ones are pruned.","team-invite:<sha256 of the invite>: a single-use team invite (team, role, how to join, expiry and the inviting key's hash). The invite itself is never stored. Deleted when used; expired ones are deleted when the next invite is made.","team-challenge:<id>: a team join, sign-in or owner challenge (team, method, the WebAuthn challenge or the message to sign, and the wallet address when there is one). Deleted when used; older than 10 minutes are pruned.","job-health:<job>, alerts:state, alerts:lease, backup:last: when each background job last ran, a fixed failure marker (operator job snapshots and queue failures redact configured private chain RPC URLs), alert state, an alert lease and the time and checksum of the last database backup.","agreement-jury:heartbeat: written by the isolated agreement-jury worker each pass after its signer keys matched the DisputeOracle's jury on chain: the escrow and oracle addresses, threshold, the jury signers' public addresses and the time. GET /api/v1/status reads it to report whether automatic rulings are on. Overwritten in place; no evidence, verdict or key material.","tls-pin:<provider>, aci-gateway:<provider>, aci-gpu:<model>, attest-policy:<provider>, attest-allow:<provider>, static-models-pending:<provider>, apply-token:<application id>: facts about providers (pinned certificate keys, verified gateway keysets, operator allow-lists, a pending model list, and the SHA-256 of an application token).","paywith-allowance:<chain key hash>, paywith-intent:<chain key hash>, paywith-commitment:<commitment>: a signed pay-with allowance (wallet address and signature), the wallet and token a key holder registered for pay-with, and the swap a usage commitment belongs to.","escrow:checkpoints, spent_settled:<epoch>, margin_unsent, holder-credits-run:<period>:<time>, ipx-oracle:*: chain cursors and settlement bookkeeping. margin_unsent retains accumulated protocol margin and provider-side fees in pico-USD; settlement reports the rounded USDG amount without transferring or clearing it.","sealed-agent:<key hash>: owner-selected HTTPS /attest URL, expected image digest and measured compose hash, random registration revision, last check timestamp, fixed success/failure code, verifier names and verified TLS SPKI hash. Overwritten on registration and each check; deleted by the principal's DELETE endpoint. No quote, certificate, API credential or inference content is stored. Owner-selected hostnames are settings and may carry meanings chosen by that owner. Records remain while disabled until explicitly removed; badge success expires after 30 minutes."],"purpose":"The router's small key-value store: job status, cursors, cached facts about providers, pending sign-in challenges and Telegram bot state. No request or answer text is written here.","retention":"Per key family: a wallet sign-in or team challenge is deleted when used and any older than 10 minutes is deleted when the next challenge is made; a team invite is deleted when used and expired ones when the next invite is made; a Telegram user's row is deleted by /forget; other families are overwritten in place."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Random UUID identifying this sign-up, not an account or machine identity.","type":"text"},{"about_request":"no","name":"role","nullable":false,"purpose":"Selected role: host_gpu, host_cpu, relay, witness or developer.","type":"text"},{"about_request":"no","name":"hardware","nullable":false,"purpose":"Hardware description typed by the participant, at most 200 characters; unverified free text, not a prompt sent to a model.","type":"text"},{"about_request":"no","name":"readiness","nullable":false,"purpose":"Optional pasted readiness hints, at most 300 characters; unverified free text, not attestation or a prompt sent to a model.","type":"text"},{"about_request":"no","name":"region","nullable":false,"purpose":"Selected continent only; not inferred from a network address.","type":"text"},{"about_request":"no","flags":["name:network"],"name":"contact","nullable":true,"purpose":"Optional contact typed by the participant, at most 120 characters; may identify them. Null when omitted or blank.","review":{"covers":["name:network"],"verdict":"config","why":"Voluntarily supplied contact for the owner to respond to interest, not a connection address read from the request. May contain an email, handle or any contact the participant chooses; kept privately until deletion."},"type":"text"},{"about_request":"no","name":"paid_in","nullable":false,"purpose":"Payout preference only: usdg, anyr or any. Payouts are planned, not available.","type":"text"},{"about_request":"no","name":"delete_code_hash","nullable":false,"purpose":"SHA-256 of a random 32-byte deletion code. The raw code is returned once to its holder.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"Server timestamp when the sign-up was saved.","type":"timestamp with time zone"}],"name":"network_waitlist","notes":["Hardware, readiness and contact are user-supplied text. Do not paste prompts or other sensitive information. The owner can read these fields through the ADMIN_TOKEN-protected read-only export. No network address or user agent is stored in this table. The delete code itself is returned once and never stored."],"purpose":"Network interest sign-ups, not host admission or attestation. Stores exactly the submitted role, hardware, readiness, continent, optional contact and payout preference, plus an id, deletion digest and time. Free text is private to the owner export; public statistics contain only counts.","retention":"Until the participant deletes it with their code, or the owner deletes the list when the program launches or is cancelled. Program-wide removal is an owner operation; no automatic launch or cancellation signal exists."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Version id.","type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"The account that owns it.","type":"text"},{"about_request":"no","name":"name","nullable":false,"purpose":"The name used in @preset/<name>.","type":"text"},{"about_request":"no","name":"version","nullable":false,"purpose":"The version number: 1, 2, 3, ... per preset.","type":"integer"},{"about_request":"no","name":"hash","nullable":false,"purpose":"SHA-256 of the version's canonical JSON, so two versions with the same content have the same hash.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"config","nullable":false,"purpose":"The preset: models, provider preferences, sampling controls and, when the owner sets them, a description (up to 280 characters), a system prompt (up to 16,000 characters), a response_format and up to 32 tool definitions.","review":{"covers":["type:json"],"verdict":"config","why":"Written by the account owner through PUT /api/v1/presets/:name and validated by a strict schema (presetDocSchema) with size caps. The system prompt is text the owner saves as a setting, not text taken from a call: requests that use the preset are not stored here or anywhere else."},"type":"jsonb"},{"about_request":"no","name":"source","nullable":false,"purpose":"put for a saved change, rollback for a version restored from an earlier one.","type":"text"},{"about_request":"no","name":"restored_from","nullable":true,"purpose":"The version a rollback copied; empty otherwise.","type":"integer"},{"about_request":"no","name":"created_by","nullable":true,"purpose":"The key that saved the version.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"preset_versions","purpose":"The versions of a preset an account calls as @preset/<name>[@<version>]: one row per saved version, never changed after it is written. A preset is a saved route plus the defaults a route cannot hold: a system prompt, a response_format and tool definitions the account owner writes.","retention":"Kept until the account deletes the preset (DELETE /api/v1/presets/:name), which deletes every version."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","flags":["name:network"],"name":"address","nullable":false,"purpose":"Lowercase 0x-prefixed 20-byte wallet address listed by OFAC.","review":{"covers":["name:network"],"verdict":"wallet-address","why":"A public digital currency wallet identifier from the SDN list, never a caller's IP or connection address."},"type":"text"},{"about_request":"no","name":"list_date","nullable":false,"purpose":"Publication date from the SDN XML, at midnight UTC.","type":"timestamp with time zone"},{"about_request":"no","name":"source_hash","nullable":false,"purpose":"SHA-256 of the exact downloaded XML bytes; no XML or identity text is retained.","type":"text"}],"name":"sanctions_addresses","purpose":"EVM-compatible digital currency addresses extracted from the public OFAC SDN XML for provider admission and USDG payout screening. No names or identity records are stored.","retention":"Replaced atomically on a successful refresh; a failed refresh keeps the last good list."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Singleton identifier, always 1.","type":"integer"},{"about_request":"no","name":"list_date","nullable":false,"purpose":"Publication date from the SDN XML, at midnight UTC; this date determines freshness.","type":"timestamp with time zone"},{"about_request":"no","name":"source_hash","nullable":false,"purpose":"SHA-256 of the downloaded XML bytes.","type":"text"},{"about_request":"no","name":"entry_count","nullable":false,"purpose":"Number of distinct EVM-compatible wallet addresses stored.","type":"integer"},{"about_request":"no","name":"ignored_count","nullable":false,"purpose":"Number of digital currency entries whose identifier is not an EVM-compatible 0x address.","type":"integer"},{"about_request":"no","name":"refreshed_at","nullable":false,"purpose":"When the successful download was stored, in UTC; does not reset the publication date's age.","type":"timestamp with time zone"}],"name":"sanctions_meta","purpose":"Singleton metadata for the current sanctions list, exposed by GET /api/v1/network/sanctions.","retention":"Replaced with the address list on a successful refresh; retained on failure."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Route id.","type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"The account that owns it.","type":"text"},{"about_request":"no","name":"slug","nullable":false,"purpose":"The name used in @route/<slug>.","type":"text"},{"about_request":"no","name":"name","nullable":false,"purpose":"The route's display name, up to 80 characters.","type":"text"},{"about_request":"no","flags":["name:content"],"name":"description","nullable":false,"purpose":"A description written by the account, up to 280 characters.","review":{"covers":["name:content"],"verdict":"config","why":"A label the owner types about the route (limited to 280 characters). It is a setting, not a request; the API cannot tell what an owner chooses to write."},"type":"text"},{"about_request":"no","flags":["type:json"],"name":"config","nullable":false,"purpose":"The route: models, provider preferences and a closed list of sampling controls (temperature, top_p, max_tokens, seed, stop sequences and similar).","review":{"covers":["type:json"],"verdict":"config","why":"Validated by a strict schema (routeConfigSchema) that lists the allowed fields. There is no field for messages or system prompts; the only free text is up to four stop sequences of 32 characters."},"type":"jsonb"},{"about_request":"no","name":"created_by","nullable":true,"purpose":"The key that created it.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"saved_routes","purpose":"A saved routing policy an account calls as @route/<slug>: ordered fallback models, provider preferences and default sampling settings. It cannot hold prompt or system-prompt text.","retention":"Kept until the account deletes the route (DELETE /api/v1/routes/:slug)."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Skill id: sk_ followed by the first 24 hex characters of content_hash.","type":"text"},{"about_request":"no","name":"name","nullable":false,"purpose":"The skill's name from SKILL.md, up to 64 characters.","type":"text"},{"about_request":"no","name":"slug","nullable":false,"purpose":"The name in lowercase letters, digits and hyphens.","type":"text"},{"about_request":"no","name":"version","nullable":false,"purpose":"The version from SKILL.md, up to 32 characters.","type":"text"},{"about_request":"no","flags":["name:content"],"name":"description","nullable":false,"purpose":"The description from SKILL.md, up to 1,024 characters.","review":{"covers":["name:content"],"verdict":"config","why":"Written by the skill's author in the SKILL.md frontmatter of a skill they publish; shown in the public registry. It is not a request to a model."},"type":"text"},{"about_request":"no","name":"author","nullable":false,"purpose":"The author named in SKILL.md, up to 80 characters.","type":"text"},{"about_request":"no","name":"account_id","nullable":true,"purpose":"The publishing account, credited the author share of paid installs; empty for a mirrored skill.","type":"text"},{"about_request":"no","name":"created_by","nullable":true,"purpose":"The key hash that imported the skill; empty for the mirror job.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"source","nullable":false,"purpose":"Where the skill came from: upload, git (repository URL, ref, commit, folder) or mirror (the registry index).","review":{"covers":["type:json"],"verdict":"public-reference","why":"The public repository URL, ref, commit and folder the importer named, or the registry index the operator configured in SKILLS_SOURCES. It identifies public code, not a caller."},"type":"jsonb"},{"about_request":"no","flags":["type:json"],"name":"files","nullable":false,"purpose":"The skill's files: path, type, mode, size and SHA-256 of each, in canonical order.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Paths, sizes, modes and hashes computed from the published archive."},"type":"jsonb"},{"about_request":"no","name":"tar_sha256","nullable":false,"purpose":"The content hash: SHA-256 of the canonical tar of the files, which a client checks after download and the key on chain (SkillRegistry).","type":"text"},{"about_request":"no","name":"archive","nullable":false,"purpose":"The files as a gzipped canonical tar (base64), capped at SKILLS_MAX_BYTES unpacked. It is the published skill, served by the download route.","type":"text"},{"about_request":"no","name":"size","nullable":false,"purpose":"Unpacked bytes.","type":"integer"},{"about_request":"no","name":"file_count","nullable":false,"purpose":"Number of files.","type":"integer"},{"about_request":"no","name":"level","nullable":false,"purpose":"The scan level: trusted, caution or dangerous.","type":"text"},{"about_request":"no","name":"score","nullable":false,"purpose":"The scan score, 0 to 100.","type":"integer"},{"about_request":"no","flags":["type:json"],"name":"report","nullable":false,"purpose":"The scan report: scanner version, score, level, counts per severity and each finding (rule, file, line, a 160-character excerpt of the skill's own file, severity).","review":{"covers":["type:json"],"verdict":"public-reference","why":"Computed by the scanner from the published skill's files; the excerpts are lines of those files. Nothing from any request is written here."},"type":"jsonb"},{"about_request":"no","name":"price_usdg","nullable":false,"purpose":"Install price in USDG base units (6 decimals); 0 for a free skill.","type":"bigint"},{"about_request":"no","name":"revoked_at","nullable":true,"purpose":"When the operator revoked the skill.","type":"timestamp with time zone"},{"about_request":"no","name":"revoked_reason","nullable":true,"purpose":"The operator's reason for revoking it, up to 280 characters.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"skills","purpose":"Agent skills published to the Skills Hub: the manifest from SKILL.md, the files as one canonical tar, its SHA-256, where it came from and the static scan report. A skill is public content its author chose to publish; it is not a request.","retention":"Kept while the hub lists the skill. A revoked skill stays, marked revoked, so its report and hash remain checkable."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Rule id.","type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"The account.","type":"text"},{"about_request":"no","name":"key_hash","nullable":true,"purpose":"The key the rule watches; empty means the whole account.","type":"text"},{"about_request":"no","name":"kind","nullable":false,"purpose":"threshold, budget_pct or anomaly.","type":"text"},{"about_request":"no","name":"window","nullable":false,"purpose":"day, week or month.","type":"text"},{"about_request":"no","name":"threshold","nullable":true,"purpose":"The spend threshold in pico-USD, for a threshold rule.","type":"bigint"},{"about_request":"no","name":"pct","nullable":true,"purpose":"The budget percentage, for a budget_pct rule.","type":"integer"},{"about_request":"no","flags":["name:network"],"name":"webhook_url_enc","nullable":true,"purpose":"The address alerts are posted to, if the owner set one. Stored encrypted with the router's APP_SECRET.","review":{"covers":["name:network"],"verdict":"config","why":"A destination the account owner chose for alerts, stored only as ciphertext. It is not a caller's address."},"type":"text"},{"about_request":"no","name":"enabled","nullable":false,"purpose":"Whether the rule is on.","type":"boolean"},{"about_request":"no","name":"last_fired_at","nullable":true,"purpose":"When it last fired.","type":"timestamp with time zone"},{"about_request":"no","name":"last_period","nullable":true,"purpose":"The period it last fired for, so it fires at most once per period.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"state","nullable":true,"purpose":"The rule's firing history and delivery status.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Firings and their delivery status written by the spend-watch job (period, amount, status, lease); it holds spend figures, never request content."},"type":"jsonb"},{"about_request":"no","name":"created_by","nullable":true,"purpose":"The key that created it.","type":"text"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"}],"name":"spend_alerts","purpose":"Alert rules on spend (threshold, share of a budget, anomaly), evaluated by the spend-watch job. They read spending totals, not requests.","retention":"Kept until the account deletes the rule (DELETE /api/v1/spend/alerts/:id)."},{"about_request":"aggregate","category":"operations","columns":[{"about_request":"aggregate","name":"instance","nullable":false,"purpose":"A random id of the router process that released the hour (a new one each start), so the releases of several processes can be summed.","type":"text"},{"about_request":"aggregate","name":"hour","nullable":false,"purpose":"The UTC hour the release covers.","type":"timestamp with time zone"},{"about_request":"aggregate","name":"epsilon","nullable":false,"purpose":"The privacy budget the release spent (the sum over its families).","type":"real"},{"about_request":"aggregate","flags":["type:json"],"name":"counts","nullable":false,"purpose":"The released noisy counts: requests per lane, refusals per fixed reason and requests per fixed latency bucket.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Three objects of noisy integers keyed by the fixed, public label lists of lib/dpstats.ts and services/private-stats.ts, copied from a release that was already public. No request, key or time finer than the hour."},"type":"jsonb"}],"name":"status_dp_hours","purpose":"The differentially private hourly releases of the private-lane counters (the same releases GET /api/v1/stats publishes), copied as released so the status page can show 90 days for the attested and unlinkable lanes. Copying and summing released values is post-processing: it spends no privacy budget and adds nothing about any request.","retention":"Deleted after 91 days by the status loop (services/slo.ts pruneStatus)."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Incident id (inc_... for an operator's incident, sug_... for an automatic suggestion).","type":"text"},{"about_request":"no","flags":["name:content"],"name":"title","nullable":false,"purpose":"The incident's headline, up to 140 characters.","review":{"covers":["name:content"],"verdict":"config","why":"Written by the operator through POST /api/v1/status/incidents (or a fixed sentence for a suggestion). It is a status notice, not a request."},"type":"text"},{"about_request":"no","name":"status","nullable":false,"purpose":"suggested, investigating, identified, monitoring, resolved or dismissed.","type":"text"},{"about_request":"no","name":"impact","nullable":false,"purpose":"none, minor, major or critical.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"lanes","nullable":false,"purpose":"The privacy lanes affected.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"An array of lane names from the fixed list public, attested, unlinkable."},"type":"jsonb"},{"about_request":"no","flags":["type:json"],"name":"surfaces","nullable":false,"purpose":"The API surfaces affected; empty for all.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"An array of surface names from the fixed list in services/slo.ts."},"type":"jsonb"},{"about_request":"no","name":"source","nullable":false,"purpose":"operator or auto.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"updates","nullable":false,"purpose":"The status updates, oldest first: time, status and the operator's text (up to 2,000 characters each).","review":{"covers":["type:json"],"verdict":"config","why":"Each update is a time, a status from a fixed list and text the operator writes through POST /api/v1/status/incidents/:id/updates; a suggestion's first update is a fixed sentence with numbers. No request text is ever written here."},"type":"jsonb"},{"about_request":"no","flags":["type:json"],"name":"evidence","nullable":true,"purpose":"For an automatic suggestion: the lanes, surfaces, window, measured availability, target, request count and whether the figure was DP-noised.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Numbers and names from fixed lists, computed from status_windows or status_dp_hours, which are themselves sums."},"type":"jsonb"},{"about_request":"no","name":"started_at","nullable":false,"purpose":"When the incident began.","type":"timestamp with time zone"},{"about_request":"no","name":"resolved_at","nullable":true,"purpose":"When it was resolved.","type":"timestamp with time zone"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"status_incidents","purpose":"Incidents on the public status page: written by the operator through the incident API, or recorded as a suggestion when a lane's availability falls below its target (a suggestion is not shown until the operator confirms it).","retention":"No automatic deletion: the incident history is part of the public record."},{"about_request":"aggregate","category":"operations","columns":[{"about_request":"aggregate","name":"surface","nullable":false,"purpose":"The API surface: chat, embeddings, batch, messages, ollama or rerank.","type":"text"},{"about_request":"aggregate","name":"bucket","nullable":false,"purpose":"Start of the five-minute bucket (UTC).","type":"timestamp with time zone"},{"about_request":"aggregate","name":"ok","nullable":false,"purpose":"Public-lane requests answered with a 2xx or 3xx.","type":"integer"},{"about_request":"aggregate","name":"failed","nullable":false,"purpose":"Public-lane requests answered with a 5xx: these count against availability.","type":"integer"},{"about_request":"aggregate","name":"rejected","nullable":false,"purpose":"Public-lane requests refused with a 4xx other than 429: the caller's error, not counted against availability.","type":"integer"},{"about_request":"aggregate","name":"rate_limited","nullable":false,"purpose":"Public-lane requests refused with a 429.","type":"integer"},{"about_request":"aggregate","name":"latency","nullable":false,"purpose":"Served public-lane requests per fixed latency bucket (the edges in lib/dpstats.ts), in edge order: time to first token for streams, time to the full response otherwise.","type":"integer[]"}],"name":"status_windows","purpose":"The public status page's record of the public lane (GET /api/v1/status/slo): per API surface and five-minute bucket, how many public-lane requests succeeded, failed with a 5xx, were refused with a 4xx or were rate limited, and how many served requests fell in each fixed latency bucket. Requests on the attested and unlinkable lanes are never counted here.","retention":"Deleted after 91 days by the status loop (services/slo.ts pruneStatus)."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Run id, a sequence number.","type":"bigserial"},{"about_request":"no","name":"seller_id","nullable":false,"purpose":"The tool listing probed.","type":"text"},{"about_request":"no","name":"ok","nullable":false,"purpose":"Whether the answer matched the listing's known answer.","type":"boolean"},{"about_request":"no","name":"latency_ms","nullable":true,"purpose":"Time for the probe.","type":"integer"},{"about_request":"no","name":"failure","nullable":true,"purpose":"A fixed failure code, or null.","type":"text"},{"about_request":"no","name":"price_units","nullable":true,"purpose":"What the probe paid, in USDG base units, if it paid.","type":"bigint"},{"about_request":"no","name":"settle_tx","nullable":true,"purpose":"The settlement transaction hash the seller reported, if any.","type":"text"},{"about_request":"no","name":"at","nullable":false,"purpose":"When it ran.","type":"timestamp with time zone"}],"name":"tool_canary_runs","purpose":"Results of the daily paid canary probe of each listed tool: whether the known answer came back, latency, a failure code, what the probe paid and the settlement transaction.","retention":"Deleted after 90 days by the canary job; deleted with the listing."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Listing id (tl_...), also the seller id on tool calls and canary runs.","type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"The account that listed the tool.","type":"text"},{"about_request":"no","name":"created_by","nullable":false,"purpose":"Key hash that listed it; never a raw API key.","type":"text"},{"about_request":"no","name":"skill_id","nullable":true,"purpose":"The Skills Hub skill whose paid invocation this is, or null.","type":"text"},{"about_request":"no","name":"name","nullable":false,"purpose":"Seller-written tool name, up to 80 characters.","type":"text"},{"about_request":"no","name":"summary","nullable":false,"purpose":"Seller-written one-line summary, up to 280 characters.","type":"text"},{"about_request":"no","name":"resource","nullable":false,"purpose":"The tool's public https origin and path, without a query string.","type":"text"},{"about_request":"no","name":"method","nullable":false,"purpose":"GET or POST.","type":"text"},{"about_request":"no","name":"price_units","nullable":false,"purpose":"The price the tool quoted in its 402 when listed, in USDG base units.","type":"bigint"},{"about_request":"no","name":"pay_to","nullable":false,"purpose":"The seller's payTo wallet from that quote; calls are refused if the live quote names another wallet.","type":"text"},{"about_request":"no","name":"network","nullable":false,"purpose":"The x402 network name of that quote.","type":"text"},{"about_request":"no","flags":["type:json"],"name":"canary","nullable":false,"purpose":"The seller-written probe: method, optional query arguments and JSON body, and the expected substring or SHA-256 of a correct answer.","review":{"covers":["type:json"],"verdict":"config","why":"Written by the listing account and validated against a strict schema; it describes a public probe, never a caller's request or answer."},"type":"jsonb"},{"about_request":"no","name":"status","nullable":false,"purpose":"listed, delisted (three failed probes in a row) or removed.","type":"text"},{"about_request":"no","name":"failures","nullable":false,"purpose":"Consecutive failed canary probes.","type":"integer"},{"about_request":"no","name":"delisted_at","nullable":true,"purpose":"When the canary rule delisted it.","type":"timestamp with time zone"},{"about_request":"no","name":"checked_at","nullable":true,"purpose":"When it was last probed.","type":"timestamp with time zone"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"When the row was created.","type":"timestamp with time zone"},{"about_request":"no","name":"updated_at","nullable":false,"purpose":"When the row was last changed.","type":"timestamp with time zone"}],"name":"tool_listings","purpose":"x402 tools a seller account listed for the paid tool catalog (/tools), each with a known-answer canary probe and its current probe state. A Skills Hub skill's paid invocation is a listing that names the skill.","retention":"Until the listing account removes it (the row stays with status removed so the address cannot silently change hands); delisted rows stay to show why."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Random internal delivery identifier.","type":"text"},{"about_request":"no","name":"destination_id","nullable":false,"purpose":"Owned destination association.","type":"text"},{"about_request":"no","name":"event_id","nullable":false,"purpose":"Stable identifier sent in the event header, shared across retries for duplicate suppression.","type":"text"},{"about_request":"no","name":"event","nullable":false,"purpose":"Fixed event type name; endpoint.check is an owner-requested connectivity notice.","type":"text"},{"about_request":"no","name":"reference","nullable":false,"purpose":"Source identifier only, such as a ledger, policy event, agreement or host id. No source body is copied.","type":"text"},{"about_request":"no","name":"event_at","nullable":false,"purpose":"Source event time used for retention and ordering.","type":"timestamp with time zone"},{"about_request":"no","name":"event_status","nullable":true,"purpose":"Fixed source status at discovery, not arbitrary source text.","type":"text"},{"about_request":"no","name":"attempts","nullable":false,"purpose":"Claimed delivery attempt count, capped at three.","type":"integer"},{"about_request":"no","name":"status","nullable":false,"purpose":"Fixed delivery state: pending, delivered, blocked, failed or cancelled.","type":"text"},{"about_request":"no","name":"http_status","nullable":true,"purpose":"Receiver HTTP status code, never its response body.","type":"integer"},{"about_request":"no","name":"latency_ms","nullable":true,"purpose":"Elapsed time for the attempted send in milliseconds.","type":"integer"},{"about_request":"no","name":"attempted_at","nullable":true,"purpose":"When the most recent result was recorded.","type":"timestamp with time zone"},{"about_request":"no","name":"next_attempt","nullable":false,"purpose":"Retry lease and due time; ordinary retries wait five minutes.","type":"timestamp with time zone"},{"about_request":"no","flags":["type:json"],"name":"history","nullable":false,"purpose":"Up to three attempt timestamps, delivery state, HTTP status, latency and retry count.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Fixed result codes and numeric timing/count metadata only; excludes webhook bodies, receiver bodies, URL, signature headers, signing secret and exception text."},"type":"jsonb"}],"name":"webhook_deliveries","purpose":"Durable event references, duplicate suppression and delivery attempt metadata without webhook bodies.","retention":"Terminal records are deleted after 90 days by the enabled worker; pending records remain until attempted or cancelled. Destination removal cascades deletion. Each event has at most three recorded attempts, and the API returns the last 100 attempts."},{"about_request":"no","category":"operations","columns":[{"about_request":"no","name":"id","nullable":false,"purpose":"Random destination identifier, scoped to one account.","type":"text"},{"about_request":"no","name":"account_id","nullable":false,"purpose":"Account whose owner manages this destination.","type":"text"},{"about_request":"no","name":"created_by","nullable":false,"purpose":"API key hash used for visibility and authorization; never a raw API key.","type":"text"},{"about_request":"no","name":"key_hash","nullable":true,"purpose":"Optional key scope inherited from a Spend Watch rule; null is account-wide.","type":"text"},{"about_request":"no","name":"rule_id","nullable":true,"purpose":"Optional linked Spend Watch rule identifier, removed with that rule.","type":"text"},{"about_request":"no","flags":["name:network"],"name":"url_enc","nullable":false,"purpose":"HTTPS URL encrypted under APP_SECRET; path and query can hold receiver credentials. API responses show scheme and host only.","review":{"covers":["name:network"],"verdict":"config","why":"Owner-supplied delivery endpoint sealed using APP_SECRET, never the caller network address. URLs can identify the receiver and carry credentials, so only scheme and host are returned."},"type":"text"},{"about_request":"no","name":"secret_enc","nullable":true,"purpose":"Server-generated random signing secret encrypted under APP_SECRET, null for an unsigned legacy or revoked destination. Plaintext is revealed only on creation or rotation, never in subsequent reads or delivery logs.","type":"text"},{"about_request":"no","name":"revoked","nullable":false,"purpose":"Whether delivery has been stopped and its signing credential removed.","type":"boolean"},{"about_request":"no","flags":["type:json"],"name":"events","nullable":false,"purpose":"Selected fixed event type identifiers.","review":{"covers":["type:json"],"verdict":"config","why":"Strict event names chosen by the owner, excluding arbitrary text, addresses, prompts or answers."},"type":"jsonb"},{"about_request":"no","flags":["type:json"],"name":"scan","nullable":false,"purpose":"Bounded reader progress: time window, activity cursor and sweep time.","review":{"covers":["type:json"],"verdict":"no-request-content","why":"Only timestamps, pagination filter digest and event identifiers; no activity bodies, intent text, endpoint URL or credentials."},"type":"jsonb"},{"about_request":"no","name":"created_at","nullable":false,"purpose":"Creation time and lower bound for event discovery.","type":"timestamp with time zone"}],"name":"webhook_destinations","purpose":"Owner-controlled HTTPS destinations, encrypted signing credentials and subscriptions for account event notices.","retention":"Until destination removal or linked Spend Watch rule deletion. Revocation erases the encrypted signing key and stops deliveries; database backups can outlive removal."}]},"summary":{"caveats":[{"text":"A request that turns the response cache on has its answer kept, sealed with AES-256-GCM, in Redis and in the router's memory. It is kept for the time-to-live the request asked for in cache.ttl: at most CACHE_TTL_S, which is 3,600 seconds unless the operator changed it, and also the default when the request names none. Requests that do not ask for caching leave nothing here, and a call paid with a blind token, a call on the attested lane or with any disclosure ceiling, a restricted model variant and a streamed answer are never cached. A semantic cache also keeps a 1,024-number hashed word vector of the prompt in memory.","title":"The response cache keeps answers when you ask it to"},{"text":"Where x402 is switched on, the answer to a call paid with x402 is kept, sealed with AES-256-GCM, in Redis (or the router's memory without Redis), never in the database, so the payer can have it sent again with PAYMENT-RECOVERY if it was lost on the way. 86,400 seconds (24 hours) from the answer, set when it is written; the x402-recovery-expire job also deletes it with its row. Calls not paid with x402 leave nothing here. For that time the database keeps only the payer, the authorization nonce, two hashes and the name of the Redis key.","title":"A call paid with x402 keeps its answer for 24 hours, so a lost answer is never paid for twice"},{"text":"A batch sent to POST /api/v1/batches has its requests and answers kept, sealed with AES-256-GCM, in Redis (or the router's memory without Redis), never in the database. The sealed requests are deleted when the batch finishes; the sealed answers BATCH_RESULTS_TTL after that (86,400 seconds, 24 hours, unless the operator changed it). A batch that never finishes ends when its 24-hour completion window closes, so nothing outlives the window plus that time. Calls that are not part of a batch leave nothing here.","title":"The Batch API keeps a batch's requests and answers until its results expire"},{"text":"generations.attempts: up to 200 characters of the message a provider sent back when an attempt failed, with URLs, keys, emails and long hex removed. The text is the provider's, not ours; a provider could quote part of a rejected request in it.","title":"A failed provider attempt can keep a short piece of the provider's own error message"},{"text":"apps.url and apps.title: the HTTP-Referer and X-Title headers of a chat call, cut to 500 and 200 characters, so apps can be ranked. Leave the headers out and nothing is kept. They are not recorded on the unlinkable lane.","title":"Two request headers are kept as you wrote them"},{"text":"agent_approvals.intent, agent_policies.spec, agent_policy_events.intent, agent_profiles.settings, agent_sessions.metadata, keys.routing, keys.guardrails, keys.tracing, keys.topup, playbook_changes.spec, playbooks.spec, team_audit.detail, characters.card, facilitator_sellers.result_schema, preset_versions.config, saved_routes.description, saved_routes.config, skills.description, status_incidents.title, status_incidents.updates, tool_listings.canary, and webhook_destinations.events hold configuration you write: descriptions, routing and guardrail settings, the system prompts and tool definitions of your presets, the character cards you publish, session labels. The API checks their shape and size, but it cannot know what you choose to write in a description or a label.","title":"Settings you type are stored as you typed them"},{"text":"Memories you keep for a character are sealed on your device under a key the router never receives; the database holds the ciphertext. If you opt in to memory search, it also holds a vector your client computed from each memory, which cannot be turned back into the text but can reveal what it is about.","title":"Character memory is kept only as ciphertext, with a vector if you opt in"}],"counts":{"columns":1163,"hash_columns":7,"reviewed_columns":121,"tables":106},"facts":["Every one of the 106 tables and 1,163 columns in the database schema is described on this page, and the build fails if a table or column is added without one.","No table has a column for a network address, and no line the code writes to its log records one. Calls without an API key are rate-limited by the caller's address, which appears only inside a Redis key that expires between 61 seconds and 3,601 seconds after the counting window begins. Over Tor no address is used at all."],"headline":"Some tables hold request or answer text: agreement_evidence.content and agreement_jury.statement.","reads":"This page is about what is kept. It is not a claim that nobody can read a request while it is in flight: on ordinary chat routes on every lane the router reads the text of a request in memory, and the provider reads it too under its own policy. The dedicated, off-by-default E2EE adapter forwards encrypted content without decryption; the gateway enclave restores it. Clear routing and billing metadata remains visible."}}