Why Affiant
The question nobody can answer
Section titled “The question nobody can answer”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.
What Affiant is
Section titled “What Affiant is”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.
What you get
Section titled “What you get”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.
Who this is for
Section titled “Who this is for”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.
What this is not
Section titled “What this is not”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.