Check whether the citations in a draft actually verify
emem_guard_verdictVerify citations in any text before sending and get an allow/deny verdict with an actionable fix code, so broken references, signature mismatches, or ungrounded claims are caught while you can still repair them.
Instructions
Run emem-guard's policy pipeline over text you are about to send, against this responder's corpus. Finds every emem: citation, resolves each one, and returns allow or deny with a machine-readable reason: EMEM-GUARD DENY <CODE> token=<token|-> fix=<fix> leaf=<leaf|->. Codes are PROV_SIG (signature did not verify), PROV_BYTES (resolved to different content than claimed), PROV_DRIFT (reading has moved past its band threshold), CLAIM_UNGROUNDED (a measurable claim with no citation, opt-in via claim_gating). fix is the actionable half: refresh_token, remove_reference, contact_admin, cite_observation. ADVISORY: nothing is blocked, and a citation this responder does not hold is never a denial, because it is indistinguishable from one minted elsewhere. Memory algebra: the verify operation (https://emem.dev/docs/model.html).
When to use: Call it on your own draft before you assert something, or on a tool result before you reason on it, to catch a citation that does not resolve while you can still fix it. Set claim_gating:true to also be told which measurable claims carry no citation at all and which emem band would answer them. Checking a payload some other framework produced (a CloudEvent, an OPA input, an OpenAI moderations body, another server's tool call)? Send it as-is and name its shape, because the default reader only sees texts/messages and a check that read nothing still answers allow. To ENFORCE this rather than consult it, run your own node: emem_guard_selfhost returns the procedure, and it works across Anthropic Inference hooks, Claude Code hooks, MCP tool calls, OpenAI-shaped clients, CloudEvents and OPA-style policy clients.
Example arguments: {"texts":["Elevation there is 918 m per emem:fact:defi.zb493.xuqA.zcb5f:yqbolgeoycqkvj3zkxukb4bjw4odhpwvfzqo3fbgwf4spk45zala"]}
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| agent | No | Optional free-text label for who is asking. Advisory only, never a trust boundary. | |
| shape | No | Which envelope YOUR payload is in, so you never have to reshape it to ask the question: send the body your own framework produced and name its shape. native reads `texts`/`messages`; `mcp` reads a JSON-RPC tools/call or tool result; `openai` reads a moderations (`input`) or chat-completions body; `cloudevent` reads a CloudEvents 1.0 structured event; `policy` reads {input}. It matters: a CloudEvent whose citation sits at data.text is invisible to the native reader, and a check that read nothing answers `allow`, so confirm `citations_found` matches what you sent. Unrecognised values fall back to native rather than erroring. This selects how the body is READ only — the verdict always comes back in this tool's declared output shape, because a tool that declares an outputSchema owes conforming structuredContent. To get the ANSWER translated into the same envelope too (an OPA `result:{allow,deny}`, an MCP CallToolResult to substitute on a deny), call POST /v1/guard/verdict?shape=… directly. | native |
| texts | No | Free text to check. Any number of pieces, in any order: a draft answer, a tool result, a whole turn. | |
| messages | No | A chat-completions-shaped transcript, read for its text. Accepted so the same body works against a self-hosted emem-guard node and against any OpenAI-shaped client. Each item is {role, content} where content is a string or an array of blocks. | |
| claim_gating | No | Also flag measurable physical-world claims that carry NO citation (deny code CLAIM_UNGROUNDED, fix cite_observation). Off by default: it reports on the absence of a citation rather than on a failed check. The verdict names the sentence, the magnitude, and the emem band that would answer it. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| fix | No | The actionable half: what to change and retry. | |
| code | No | Present only on a deny. | |
| claim | No | On CLAIM_UNGROUNDED: the sentence, magnitude, quantity, anchor, and source_band. source_band is a recallable band key, or null when this responder observes no band in that quantity. | |
| action | Yes | NOT a clearance. `allow` means no rule fired, which on a transcript that cited nothing is silence rather than approval. Branch on citations_found and receipt.fact_cids. | |
| checked | Yes | How many were actually resolved, bounded by the verdict budget. | |
| receipt | Yes | ed25519 receipt. `fact_cids` lists what actually resolved and is the field that separates a real citation from an invented one. | |
| advisory | Yes | True on the hosted route, where nothing is blocked. Run your own node to enforce. | |
| citations_found | Yes | How many emem: tokens were found in the text. Compare with receipt.fact_cids: a well-formed token that resolved to nothing counts here and not there. |