AgentExperience.Storage.Postgres
0.1.0-preview.4
See the version list below for details.
dotnet add package AgentExperience.Storage.Postgres --version 0.1.0-preview.4
NuGet\Install-Package AgentExperience.Storage.Postgres -Version 0.1.0-preview.4
<PackageReference Include="AgentExperience.Storage.Postgres" Version="0.1.0-preview.4" />
<PackageVersion Include="AgentExperience.Storage.Postgres" Version="0.1.0-preview.4" />
<PackageReference Include="AgentExperience.Storage.Postgres" />
paket add AgentExperience.Storage.Postgres --version 0.1.0-preview.4
#r "nuget: AgentExperience.Storage.Postgres, 0.1.0-preview.4"
#:package AgentExperience.Storage.Postgres@0.1.0-preview.4
#addin nuget:?package=AgentExperience.Storage.Postgres&version=0.1.0-preview.4&prerelease
#tool nuget:?package=AgentExperience.Storage.Postgres&version=0.1.0-preview.4&prerelease
AgentExperience.Storage.Postgres
Preview — not production ready. This is a
0.1.0-previewpackage, and it claims no production readiness. Public APIs may change between previews. Read Known limits and documented boundaries before you rely on it.
The PostgreSQL storage for AgentExperience.NET, over plain Npgsql.
It implements every storage port: the Experience Record store with its audited lifecycle (IExperienceRecordStore),
text search (IExperienceCandidateSource), sharing grants and their access log (IExperienceGrantStore,
IExperienceGrantAccessLog), and the reuse-feedback ledger (IExperienceReuseFeedbackStore). It also ships the
journaled schema migrator, deletion and retention, and opt-in crypto-shredding.
Requires Npgsql 10.0.3, dbup-postgresql 7.0.1, dbup-core 6.1.1, and
Microsoft.Extensions.DependencyInjection.Abstractions 10.0.12, or any later release in the same major. Targets
net10.0. Tested against
PostgreSQL 15, 16, 17 and 18; PostgreSQL 14 is not supported, because 0005_create_experience_grants uses
PostgreSQL 15 syntax. No EF Core, Dapper, Pgvector, or pgvector extension: vectors are the separate
AgentExperience.Storage.Postgres.Vectors package.
Setting it up
Two database roles: an owner that applies the schema, and an application role the stores connect as. The application role owns nothing, which is what makes the append-only guards and the erasure path bind it.
using AgentExperience.Core.DependencyInjection;
using AgentExperience.Storage.Postgres;
using AgentExperience.Storage.Postgres.DependencyInjection;
using Npgsql;
// On every deploy, as the owner role, before the stores are used. Nothing migrates on its own.
await using (var owner = NpgsqlDataSource.Create(ownerConnectionString))
{
await ExperienceSchemaMigrator.MigrateAsync(owner, cancellationToken);
await ExperienceSchemaMigrator.ApplyApplicationRolePrivilegesAsync(
owner,
new ExperienceApplicationRoleOptions("agent_experience_app") { AllowErasure = true },
cancellationToken);
}
// The stores, as the application role.
services.AddSingleton(NpgsqlDataSource.Create(applicationConnectionString));
services.AddAgentExperiencePostgresStore(); // IExperienceRecordStore
services.AddAgentExperiencePostgresCandidateSource(); // IExperienceCandidateSource (text search)
services.AddAgentExperiencePostgresGrantStore(); // optional: only if you share records across scopes
services.AddAgentExperiencePostgresReuseFeedbackStore(); // optional: only if you record reuse feedback
services.AddAgentExperiencePostgresGrantAccessLog( // optional: a trail of who READ shared records
onNotRecorded: failure => logger.LogError(failure.Failure, "grant access row not written"));
services.AddAgentExperiencePostgresEncryption(keyStore); // optional: crypto-shredding for every component above
// Core's extensions then supply capture, lifecycle, finalization and retrieval over them.
services.AddAgentExperienceCore(sanitizationOptions, captureLimits);
services.AddAgentExperienceRetrieval();
Every registration uses TryAdd, so your own implementation of a port wins. The store, search, grant, feedback and
access-log registrations also have an overload taking an explicit NpgsqlDataSource (useful to give the access log
its own pool). The stores never dispose the data source; the host owns it.
MigrateAsync applies 0001–0003 and 0005–0018 (there is no 0014; 0004 belongs to the vectors package).
It is journaled, runs one transaction per script, and serializes concurrent hosts with an advisory lock. The owner
needs one superuser grant, once: GRANT SET ON PARAMETER agent_experience.purge_authorized, agent_experience.access_purge_authorized TO <owner>.
What to know
- The host is the authority. Every call takes an
AuthorizationContextthe host built from its own identity checks, never from model output. A scope outside it isDeniedbefore any connection opens. Scope matching is exact in SQL; a null scope field is never a wildcard, and another scope's record reads asNotFound. - Expected refusals are results, not exceptions.
NotFound,Denied,Invalid,Conflict,StaleRevision,StatusMismatch,Deletedand so on. Database failures throwExperienceStoreException; the store never logs. - Lifecycle changes are atomic and append-only. The event and the record's new status commit in one transaction, checked against the record's revision and idempotent by event ID. Database triggers refuse edits to any ledger. They do not bind the table owner or a superuser, which is inherent in PostgreSQL.
- Sharing is an explicit, expiring grant, enforced in SQL, capped at 90 days by default
(
PostgresExperienceGrantPolicy), read-only, and audited. A grant's disclosure level decides whether a borrowed lesson's tool names reach a model. - Deletion leaves a tombstone and removes everything else that named the record, in one transaction. There is no
default retention and no timer:
SweepExpiredAsyncruns when you call it, one scope exactly unless you passScopeMatch.Subtree. In the default plaintext mode, backups, replicas, WAL and the dead row version still hold the erased text (the KL-2 boundary); crypto-shredding makes erasure reach every copy except the derived search data. - Erasure is the only part that emits telemetry, as the
delete,retention.sweep,grant.purge,grant.access.purgeandrecord.sealoperations on theAgentExperience.Storage.Postgressource and meter.
Guides
| Topic | Guide |
|---|---|
| Wiring, the two roles, the privilege manifest, the trust boundary, results and failures | Deployment |
| Lifecycle commits, supersession, history, append-only guards | Lifecycle |
| Confidence evidence and the independence key | Confidence and independence |
| The reuse-feedback ledger | Reuse feedback |
| Text search | Retrieval |
| Sharing grants, disclosure levels, the access log | Sharing and grants |
| Deletion, tombstones, retention sweeps, what erasure does not reach | Deletion and retention |
| Crypto-shredding, key custody, upgrading a plaintext deployment | Crypto-shredding |
| Every migration, the migrator's behaviour, data semantics | PostgreSQL schema |
More
- Documentation: guide and glossary
- Supported versions: compatibility evidence
- Changes between previews: changelog
- License: Apache-2.0
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AgentExperience.Abstractions (>= 0.1.0-preview.4)
- dbup-core (>= 6.1.1)
- dbup-postgresql (>= 7.0.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.12)
- Npgsql (>= 10.0.3)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on AgentExperience.Storage.Postgres:
| Package | Downloads |
|---|---|
|
AgentExperience.Storage.Postgres.Vectors
Preview, not production ready. pgvector adapter for AgentExperience.NET: stores one derived embedding per Experience Record through the IExperienceEmbeddingIndex port, with conditional revision-and-existence-checked writes, scoped idempotent re-indexing, and a scoped nearest-neighbour search that applies the same eligibility filters as the text channel. Split out of AgentExperience.Storage.Postgres because that package's dependency boundary forbids Pgvector and the model-provider abstractions. Requires Npgsql 10.0.3, Pgvector 0.3.2, and Microsoft.Extensions.AI.Abstractions 10.10.0 or later within the same major (the same minor for Pgvector). |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-preview.10 | 62 | 10/10/2026 |
| 0.1.0-preview.9 | 137 | 10/10/2026 |
| 0.1.0-preview.8 | 157 | 10/9/2026 |
| 0.1.0-preview.7 | 163 | 10/5/2026 |
| 0.1.0-preview.6 | 48 | 10/1/2026 |
| 0.1.0-preview.5 | 58 | 10/1/2026 |
| 0.1.0-preview.4 | 50 | 9/29/2026 |
| 0.1.0-preview.3 | 52 | 9/29/2026 |
| 0.1.0-preview.2 | 761 | 9/26/2026 |
| 0.1.0-preview.1 | 754 | 9/24/2026 |
Preview release. Not production ready, and it claims no production readiness: the Known limits table lists every unresolved item, and any unresolved item blocks a production-readiness claim. The Documented boundaries table beside it states exactly what no code change can remove. Public APIs may change between previews. See https://github.com/fabbrik/AgentExperience.NET/blob/main/docs/known-limits.md