AgentExperience.Storage.Postgres 0.1.0-preview.4

This is a prerelease version of AgentExperience.Storage.Postgres.
There is a newer prerelease version of this package available.
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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AgentExperience.Storage.Postgres" Version="0.1.0-preview.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AgentExperience.Storage.Postgres" Version="0.1.0-preview.4" />
                    
Directory.Packages.props
<PackageReference Include="AgentExperience.Storage.Postgres" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AgentExperience.Storage.Postgres --version 0.1.0-preview.4
                    
#r "nuget: AgentExperience.Storage.Postgres, 0.1.0-preview.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AgentExperience.Storage.Postgres@0.1.0-preview.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AgentExperience.Storage.Postgres&version=0.1.0-preview.4&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=AgentExperience.Storage.Postgres&version=0.1.0-preview.4&prerelease
                    
Install as a Cake Tool

AgentExperience.Storage.Postgres

Preview — not production ready. This is a 0.1.0-preview package, 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 AuthorizationContext the host built from its own identity checks, never from model output. A scope outside it is Denied before any connection opens. Scope matching is exact in SQL; a null scope field is never a wildcard, and another scope's record reads as NotFound.
  • Expected refusals are results, not exceptions. NotFound, Denied, Invalid, Conflict, StaleRevision, StatusMismatch, Deleted and so on. Database failures throw ExperienceStoreException; 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: SweepExpiredAsync runs when you call it, one scope exactly unless you pass ScopeMatch.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.purge and record.seal operations on the AgentExperience.Storage.Postgres source 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

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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