Packages
Affiant ships as ten co-versioned NuGet packages, all targeting net10.0. “Co-versioned”
means every release publishes all ten together under one version number — there is no
cross-package version skew to reason about, and no package moves ahead of the others.
Affiant.AgentFramework (the Microsoft Agent Framework bridge) joined the set on 2026-07-05;
Affiant.Extensions.AI (the Microsoft.Extensions.AI bridge) joined on 2026-08-20.
The dependency graph is a strict DAG (directed acyclic graph — dependencies only point one way,
never in a cycle) rooted at Affiant.Abstractions. This mirrors the
Microsoft.Extensions.*.Abstractions / Microsoft.Extensions.* convention many .NET developers
already know: reference Affiant.Abstractions alone if you only need to implement a contract —
say, a custom IWriteExecutor for your domain —
without pulling in any concrete service.
The ten packages
Section titled “The ten packages”| Package | Role | Key types |
|---|---|---|
Affiant.Abstractions |
Domain-agnostic primitives and every framework interface. Zero dependencies on other Affiant packages. | Affidavit, ProvenanceTag, ProvenanceChain, ToolEnvelope, DocketEntry, AffiantToolDescriptor, Operation, IWriteExecutor, IFieldMapper<T>, IDocketStore, IStreamingTransport, ITaskInferenceStrategy, IApprovalPolicy |
Affiant.Core |
Concrete services: the Context Fabric, the Review Gate, inference orchestration, and telemetry. Where the framework’s actual logic lives. | ContextFabric, ReviewGate, DeterministicShortCircuit, TaskInferenceStep, TaskInferenceRunner, SchemaDrivenAffidavitProjection, AffiantToolRegistry, AffiantTelemetry |
Affiant.SemanticKernel |
The Semantic Kernel (SK) interception bridge — wires Affiant’s filters into SK’s function-invocation pipeline, adds per-provider connector-capability probing, and runs hard-failure startup validation. See the honest boundary for exactly what this can and cannot see. | AffiantFilterPipeline, InferenceTriggerFilter, ReviewGateFilter, ToolArgumentCaptureFilter, SemanticKernelInferenceCompletionPort, AffiantStartupValidator |
Affiant.AgentFramework |
The Microsoft Agent Framework (MAF) interception bridge — translates MAF’s function-calling middleware into the same neutral pipeline. See Interception Backends. | AffiantToolCatalog, AffiantFunctionInvocationMiddleware, AgentFrameworkInferenceCompletionPort, HostedToolAudit |
Affiant.Extensions.AI |
The Microsoft.Extensions.AI (M.E.AI) interception bridge — the lower-level abstraction both SK and MAF sit on top of. Wraps each AIFunction in a DelegatingAIFunction that runs the neutral pipeline at M.E.AI’s own function-calling seam. Provider-neutral: references Microsoft.Extensions.AI only, never a concrete provider client. See Interception Backends. |
AffiantToolCatalog, AffiantDelegatingAIFunction, ExtensionsAIInferenceCompletionPort, HostedToolAudit |
Affiant.Docket |
The review queue’s backend-neutral half: the in-memory IDocketStore implementation, plus the background service that expires stale entries — always required, regardless of which persistence backend you choose. SQL-backed Docket storage now lives in Affiant.EntityFramework (below), not here. |
InMemoryDocketStore, DocketExpiryService, DocketOptions |
Affiant.EntityFramework |
The EF Core persistence adapter — the shared DbContext, migrations, row-per-message chat session schema, and the SQLite/PostgreSQL IDocketStore implementations. Installing Affiant.Docket alone no longer pulls in EF Core, SQLite, or Npgsql; only installing this package does. |
AffiantDbContext, AffiantMigrator, PostgresChatSessionStore, SqliteChatSessionStore, PostgresDocketStore, SqliteDocketStore, ChatSessionEntity, DocketEntryEntity |
Affiant.Policies |
The approval-policy graph: auto-approval rules (Standing Orders), escalation rules (Referrals), and risk scoring, evaluated against every Affidavit before it reaches a human. |
StandingOrderBase, ReferralRuleBase, DefaultRiskScoreCalculator, RiskLevel |
Affiant.Transport.SignalR |
The reference real-time transport — a subclassable SignalR hub plus an IStreamingTransport implementation for delivering Evidence Cards and streaming agent output. |
AffiantHub, SignalRStreamingTransport<THub>, SignalROptions |
Affiant.Testing.ComplianceHarness |
A test helper, not a runtime dependency: verifies every registered write strategy has a paired fixture, and that the Affidavits it produces carry substantive provenance, not just well-shaped provenance. See the Compliance Harness guide. | ComplianceHarness, ComplianceVerificationResult, ITaskInferenceComplianceFixture, InferenceFixtureCase |
The dependency graph
Section titled “The dependency graph”Layer 0 Affiant.Abstractions (no Affiant dependencies)
Layer 1 Affiant.Core (→ Abstractions)
Layer 2 Affiant.SemanticKernel (→ Core) Affiant.AgentFramework (→ Core) Affiant.Extensions.AI (→ Core) Affiant.Policies (→ Core) Affiant.Transport.SignalR (→ Core) Affiant.EntityFramework (→ Core) Affiant.Docket (→ Core) Affiant.Testing.ComplianceHarness (→ Core)Every package below Affiant.Core sits at the same layer and never references any other
package at that layer — Affiant.SemanticKernel, Affiant.AgentFramework, and
Affiant.Extensions.AI are peers, none of them reference one another; Affiant.Docket and
Affiant.EntityFramework are peers too. This is a change from an earlier design: Affiant.Docket
used to depend directly on Affiant.EntityFramework for its SQLite- and PostgreSQL-backed
stores, which forced an adapter-to-adapter dependency the framework’s own layering rule forbids.
As of 1.0.0-beta.1, Affiant.Docket implements only the in-memory store and the expiry sweep;
the SQL-backed IDocketStore implementations moved to Affiant.EntityFramework, next to the
DbContext and entity configuration they were already built on. Installing Affiant.Docket
alone therefore no longer drags in EF Core, SQLite, or Npgsql — see
Docket & Evidence Cards for the
registration mechanics this split implies.
A practical read of the graph: if you’re implementing a custom IFieldMapper<T> or
IWriteExecutor for your domain, you need only Affiant.Abstractions. If you’re wiring up a
host application end to end, you’ll typically pull in Affiant.Core, one interception bridge
(Affiant.SemanticKernel, Affiant.AgentFramework, or Affiant.Extensions.AI — see
Interception Backends for which one fits your host),
Affiant.Docket (always, for the expiry sweep) plus Affiant.EntityFramework if you want a
durable Docket, Affiant.Policies if you want Standing Orders and Referrals, and
Affiant.Transport.SignalR unless you’re supplying your own IStreamingTransport — see the
FAQ on using Affiant without SignalR.
Referencing a single package
Section titled “Referencing a single package”A library that only implements a contract — for example, a NuGet package providing an
IFieldMapper<T> for a specific domain, published independently of any host application — needs
nothing but the bottom of the graph:
dotnet add package Affiant.Abstractions --prereleaseThat reference pulls in the interfaces and record types and nothing else: no Semantic Kernel
runtime, no EF Core, no SignalR. This is deliberate — Affiant.Abstractions is the seam a host
application never has to touch its dependencies to satisfy.
Installing
Section titled “Installing”Affiant is in beta — install with the --prerelease flag rather than pinning an exact version
suffix, so you always land on the current pre-1.0 release:
dotnet add package Affiant.Core --prereleasedotnet add package Affiant.SemanticKernel --prereleaseSwap Affiant.SemanticKernel for Affiant.AgentFramework or Affiant.Extensions.AI if your
host runs on a different backend — see Interception Backends
to pick the right one. Add the other packages the same way as your host application needs them.
See Installation for the full setup and Quickstart
for wiring a first write tool end to end.
Why one version number
Section titled “Why one version number”Co-versioning trades a small amount of install-size flexibility — you can’t take a bugfix in
Affiant.Core without also being offered updated Affiant.Docket, Affiant.Policies, and so on
— for a guarantee that matters more in a compliance-adjacent framework: any two Affiant packages
taken from the same version number are contract-compatible with each other, full stop. You never
have to consult a compatibility matrix to find out whether one package’s version works with
another’s — mismatched version numbers across Affiant packages are simply never offered.
Trust the invariant — every Affidavit field carries provenance
(Rule 7) — and expect the rest of the API surface, including
these package boundaries, to keep evolving until 1.0 GA.