Skip to content

Why Affiant

An LLM agent proposes a database write. Six months later, an auditor — or an angry customer, or a compliance officer — asks: where did this value come from? Did the user type it? Did the model infer it from something adjacent in the conversation? Was it looked up from a system of record, or invented?

Most agent frameworks cannot answer that question, because they never asked it in the first place. A tool call is logged as a function name and a blob of arguments. The blob might contain the right value, but it carries no record of why that value is what it is, no distinction between a fact the user stated and a guess the model made, and no trail from “proposed” to “approved” to “committed.”

Whole-call approval — a human or a policy engine approving or rejecting an entire tool call before it executes — is now a commodity capability across agent frameworks. It answers “should this call happen at all?” It does not answer “is this specific field trustworthy?” Approving an opaque call is testimony without evidence: the reviewer sees a function name and an arguments blob, not which field came from the user, which came from a lookup, and which the model quietly filled in.

If you would rather see it than read about it: Meridian and HR Portal are public host applications built on Affiant. Any email works; ask either agent to change something and watch the card arrive.

Affiant is a deterministic evidence layer for .NET agents. It sits between your agent host — Semantic Kernel, Microsoft Agent Framework, or Microsoft.Extensions.AI, see Interception Backends — and the database that host writes to, and it changes what a “write” means: instead of a tool mutating a row, a write-intent tool produces a WriteProposal — a sworn, field-level record of the mutation it wants to make, called an Affidavit — and the actual database write happens only after a human has reviewed and approved it.

The name is the whole idea. An affiant is a person who swears to the truth of a statement under oath. Affiant borrows the vocabulary of a sworn deposition because that vocabulary already has the right shape: a statement made under oath (the Affidavit), a record of where each fact in it came from (provenance), and a process for someone in authority to examine that statement before it has effect (review). See Affidavits & Provenance for the full type shapes.

Concretely, an Affidavit is not one opaque value — it is a set of fields, and every field carries its own provenance tag, independent of the others. A RequestLeave call might produce an Affidavit with a StartDate field tagged UserStated (the user typed the date), an EmployeeId field tagged External (resolved from a directory lookup), and a RemainingDaysAfter field tagged Computed (derived by your own business logic). Three fields, three different evidentiary bases, each visible on its own.

This is deliberately not a security product and not a prompt-engineering technique. Framework code observes the conversation and the tool results passing through it — via whichever backend’s own tool-invocation seam is in play (Semantic Kernel’s function-invocation filter pipeline, Microsoft Agent Framework’s function-calling middleware, or Microsoft.Extensions.AI’s FunctionInvokingChatClient seam) — rather than asking the model to narrate where its own values came from. Determinism comes from that interception layer, not from trusting the model to be honest about itself. See The Seven Normative Rules for the rules this rests on, in particular the rule that context extraction and review gating live in filters, never in prompt text.

Affidavits. Every proposed create or update is packaged as an Affidavit: an operation type, an entity type, an optional entity ID (null means create), and a list of fields. Each field carries its current value, its previous value (so an update shows exactly what is changing), a full provenance chain — not just the current source, but the ordered history of how the field arrived at that value — and a flag for whether the field is mandatory. The Affidavit as a whole carries an aggregate confidence score, any warnings the framework attached during inference, and whether it requires reviewer confirmation before it can proceed.

The provenance hierarchy. Every field’s source is one of seven states, ordered from most to least deterministic: UserStated, External, Computed, Conversation, Inferred, Default, Empty. The ordering is load-bearing — when two provenance tags carry equal confidence, ties break toward the more deterministic source. Empty is not a missing badge; it is an explicit tag applied when provenance is genuinely unknown, so “nobody tracked this” is never silently indistinguishable from “the user said it.” Full details are in Affidavits & Provenance.

Evidence Cards and the Docket. An Affidavit doesn’t get approved in the abstract — it is filed onto the Docket, a durable review queue, and rendered to a human reviewer as an Evidence Card: the exhibit showing every field, its value, and its provenance, side by side. Approved and rejected Affidavits both persist, so the review history is itself an audit trail. See Docket & Evidence Cards.

A structural guarantee, not a convention. Write-intent tools are marked with [AffiantWriteTool] and return a WriteProposal — they do not call SaveChanges or its equivalent themselves. The only place a database write actually happens is inside the host’s IWriteExecutor, invoked after the ReviewGate resolves the Affidavit as approved. See Review Gate & Write Executors.

Affiant is for .NET teams building LLM agents — chat copilots, task assistants, autonomous workflow agents — that sit in front of a real database and a real system of record: HR platforms, operations and maintenance tools, financial or logistics systems, anything where a wrong or unexplainable write has a cost. If your agent’s tool calls are read-only, or if a wrong write is cheap to notice and undo, the review overhead Affiant introduces may not be worth it. If your agent’s tool calls create or mutate rows that someone downstream will act on — approve a request, schedule a shipment, adjust a balance — provenance and a review gate earn their keep.

The framework runs on three interception backends — Semantic Kernel, Microsoft Agent Framework, and Microsoft.Extensions.AI — sitting on one shared, backend-neutral pipeline; pick whichever one your host already uses. See Interception Backends for how they differ, EF Core with PostgreSQL or SQLite for persistence, Installation for the package set, and Quickstart for a working example (built against Semantic Kernel; the same Affidavit, Docket, and Evidence Card flow applies unchanged on the other two).

You do not need to rebuild your agent’s tool-calling layer to adopt this. A write tool you already have becomes an Affiant write tool by changing what it returns — a WriteProposal carrying an Affidavit, instead of a direct database write — and by declaring the field schema the framework should extract and merge on your behalf. Read tools change even less: they keep returning results for the model to reason over, formatted so both the model and a UI can render them. See Tool Envelopes for the shared contract every tool returns.

Affiant does not compete with agent-identity or agent-governance products — it answers a different question. A framework that governs which agent took an action, authenticated and authorized at the agent level, is solving agent identity. Affiant solves data identity: where each written value came from, field by field. The two compose; neither replaces the other.

Affiant is also not an approval gate on whole tool calls — that capability exists elsewhere and is complementary. And it is not omniscient about every tool a model can invoke: it intercepts locally-invoked tool calls, including locally-invoked MCP tools, because those flow through the same client-side function-invocation pipeline it hooks into. Tools that execute on a remote, hosted runtime — rather than being invoked locally by your process — are outside that interception seam, and Affiant does not claim coverage there. This boundary is deliberate and documented, not a gap we’re hiding: see The Honest Boundary for exactly what is and isn’t covered, and why.