Skip to content

FDR Vector Memory Versioning

The Volidator Flight Data Recorder (FDR) performs Input-Side Forensic Reconstruction by caching agent tool inputs and outputs. However, if your agent’s long-term memory (vector database) changes between runs (due to document updates, memory retrieval, or deletions), replaying the agent requires reconstructing the exact memory state at that millisecond.

To solve this without massive Write-Ahead Log (WAL) databases, Volidator implements a bi-temporal metadata model. Instead of mutating or deleting vectors, we stamp them with _vld_from (valid from) and _vld_to (valid to) timestamps, creating a queryable historical version chain.


When replaying an agent run from 6 months ago, you cannot simply query your current vector database. Over those 6 months:

  • Old documents were deleted.
  • Existing memory vectors were updated or overwritten.
  • New facts were learned by the agent.

If your replay CLI queries the active vector index, the agent will receive different context than it did at the time of the original execution, leading to a mismatched simulation. This is the Memory Shift Problem.

To perform a successful forensic replay, you must be able to query the vector database exactly as it stood at millisecond T.


Bi-temporal versioning tracks data state along two distinct timelines:

  1. Valid Time: The period during which a fact is true in the real world.
  2. System Time: The period during which the database recognized that fact as active.

In Volidator’s FDR Vector Memory:

  • _vld_from (Valid From): The system epoch millisecond when the vector was inserted or updated.
  • _vld_to (Valid To): The epoch millisecond when the vector was replaced or soft-deleted (remains null for active records).

When your agent queries the vector store, the Volidator middleware automatically re-writes the request to only match records where valid_from <= asOf AND (valid_to > asOf OR valid_to IS NULL).

Depending on your architecture, Volidator supports two tiers of compliance assurance.


Feature Tier 1: Engine-Enforced Tier 2: Middleware-Enforced
Target Database Self-hosted relational (e.g., PostgreSQL + pgvector) Hosted SaaS APIs (Pinecone, Qdrant Cloud, Weaviate Cloud)
Enforcement Layer Database Triggers (BEFORE DELETE / UPDATE) SDK Client Wrapper Interception
Auditor Rating High Assurance (Tamper-proof by database engine) Standard Assurance (SDK boundary limit)
Dashboard Bypass ❌ Blocked by database engine ⚠️ Possible if admin performs direct deletions

For self-hosted pgvector databases, you enforce bi-temporal compliance directly inside the database engine. If any client tries to execute a raw SQL DELETE or UPDATE statement, the database triggers abort the transaction, guaranteeing immutability.

Run this migration to add temporal fields to your pgvector table and set up the triggers:

-- 1. Add valid_from and valid_to columns to your vector table
ALTER TABLE agent_memory_vectors
ADD COLUMN valid_from_ts BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000),
ADD COLUMN valid_to_ts BIGINT NULL;
-- 2. Prevent hard deletes. Intercept and convert to soft-deletes or abort
CREATE OR REPLACE FUNCTION abort_hard_deletes()
RETURNS TRIGGER AS $$
BEGIN
RAISE EXCEPTION 'Volidator FDR Tier 1 Block: Hard deletions are forbidden on table %. Update valid_to_ts to perform a soft-delete.', TG_TABLE_NAME;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER enforce_soft_delete_only
BEFORE DELETE ON agent_memory_vectors
FOR EACH ROW EXECUTE FUNCTION abort_hard_deletes();
-- 3. Prevent inline updates of text content or embeddings
CREATE OR REPLACE FUNCTION abort_inline_updates()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.embedding IS DISTINCT FROM OLD.embedding OR NEW.text_content IS DISTINCT FROM OLD.text_content THEN
RAISE EXCEPTION 'Volidator FDR Tier 1 Block: Inline updates of vector embeddings/content are forbidden. Insert a new record with valid_from_ts instead.';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER enforce_append_only_updates
BEFORE UPDATE ON agent_memory_vectors
FOR EACH ROW EXECUTE FUNCTION abort_inline_updates();

Wrap your database queries to automatically inject the temporal constraints:

import { wrapVectorStore } from '@volidator/node/fdr-vector';
// Wrap your client
const db = wrapVectorStore(pgClient, {
mode: 'pgvector',
namespace: 'financial_agent_memory',
validFromField: 'valid_from_ts',
validToField: 'valid_to_ts'
});
// Queries automatically filter: WHERE valid_from_ts <= NOW AND (valid_to_ts > NOW OR valid_to_ts IS NULL)
const results = await db.query({
query_embedding: queryVector,
limit: 5
});
// To query historic state (e.g. during an audit replay at time T)
const historicalResults = await db.query({
query_embedding: queryVector,
limit: 5
}, 1718224800000); // Pass past timestamp in milliseconds

Tier 2 — Middleware-Enforced (Hosted SaaS)

Section titled “Tier 2 — Middleware-Enforced (Hosted SaaS)”

For cloud vector databases like Pinecone, Weaviate Cloud, or Qdrant Cloud, database triggers are not available because the underlying storage engines are closed-source SaaS APIs.

In this tier, Volidator intercepts mutations at the SDK Client Wrapper layer.

import { Pinecone } from '@pinecone-database/pinecone';
import { wrapVectorStore } from '@volidator/node/fdr-vector';
const pinecone = new Pinecone({ apiKey: process.env.PINECONE_API_KEY });
const index = pinecone.index('agent-memory');
// Wrap the Pinecone client
const wrappedIndex = wrapVectorStore(index as any, {
mode: 'hosted',
namespace: 'agent-memory'
});
// Intercepts delete and performs a soft metadata write instead
await wrappedIndex.delete(['doc_uuid_999'], 'User session expired');

[!WARNING] Hosted Tier 2 Assurance Boundary: Because hosted SaaS databases do not support raw SQL trigger enforcement, the bi-temporal rule is enforced strictly at the SDK layer. A user or administrator who connects directly to the Pinecone console or calls the raw Pinecone REST API can still perform hard deletions that bypass Volidator’s logging mechanism.

Auditors must review account access policies and RBAC controls on cloud vector providers to verify that developers do not have direct console credentials that bypass the wrapped SDK.