Phase 3 core memory substrate

Mirror Phase 1's TestSecurity_SEC* pattern for the memory substrate: 10+ ISO-* cases proving tenant isolation end-to-end with real Postgres+pgvector+Redis, CI-gated via memory-security-integration job.

Milestone 3.E.1 — Memory Security Integration Test Suite

Status: Planned
Goal: Track E — Exit Gate
Phase: 3 — Core Memory Substrate
Estimated effort: 3 days


Why This Milestone Exists

Mirrors Phase 1's 1.5.1 pattern: prove the composed system (real Postgres with RLS, real pgvector HNSW index, real Redis hot cache) enforces tenant isolation end-to-end — not just that each service's unit tests pass in isolation. Individual milestone acceptance criteria only verify their own narrow slice; this gate catches emergent security failures when the pieces are composed together.


Test Matrix

Test IDScenarioExpected
ISO-1.1Org A writes memory, Org B searches with identical query textEmpty result set, not an error
ISO-1.2Org A agent ID used with Org B's PAT/org_id context403, mirrors proxy's AGENT_NOT_AUTHORIZED semantics
ISO-1.3Direct SQL query bypassing service layer, SET LOCAL app.current_org_id to Org AOrg B rows invisible even with malformed WHERE clause (RLS floor)
ISO-1.4memory_relationships edge referencing a memory from a different orgInsert rejected
ISO-1.5HNSW ANN search across a mixed corpus (Org A + Org B rows in same index)Zero cross-org leakage in top-K at every ef_search value
ISO-1.6Redis hot cache key collision test: two orgs' agents with colliding hash suffixesNo cross-tenant cache read possible
ISO-2.1GDPR delete cascade: delete orgAll memories, memory_relationships, memory_versions removed; MinIO archive objects also removed
ISO-2.2GDPR delete cascade partial failure (MinIO delete fails, Postgres succeeds)Orphan detection job flags mismatch
ISO-3.1PII redaction stage bypassed via direct DB writeRead-path redaction re-check as defense-in-depth
ISO-3.2Quarantined memory (status='quarantined')Never returned by search, regardless of similarity score

Test Infrastructure

Reuses the securityTestEnv-equivalent pattern, ported to Python:

Python
# Illustrative — exact path may differ
@pytest.fixture
async def isolation_env() -> IsolationTestEnv:
 pg = await start_postgres_testcontainer()
 redis = await start_redis_testcontainer()
 org_a, org_b = await seed_two_orgs(pg)
 yield IsolationTestEnv(pg=pg, redis=redis, org_a=org_a, org_b=org_b)
 await teardown(pg, redis)

CI Wiring

New job in .github/workflows/ci.yml, modeled on the existing security-integration job. Must use a pgvector-enabled Postgres image (pgvector/pgvector:pg16), not plain postgres:16.


Orientation (indicative)

Named paths, package layouts, libraries, schemas, env vars, and commands anywhere on this page are rough sketches for orientation — inspiration and a baseline, not a required change list.

During implementation, expect to:

  • open the live tree and follow existing patterns before inventing new ones
  • research current constraints (latency, tenancy, deploy shape, libraries) more deeply than this page can
  • advance the design beyond the sketch where measurement or code reality says so
  • land work in different filenames, merged packages, deferred docs, or new surfaces when the situation calls for it

Prefer outcomes over matching any particular file tree or command sequence.

Areas that may be involved (situational — not a checklist):

  • Evaluation / benchmarks
  • Memory service / repositories

Success signals

Outcome-oriented signals that the milestone is in good shape. Exact filenames, package layouts, and commands may differ from any sketches above.

  • All 10+ ISO-* cases pass with real Postgres+pgvector+Redis containers
  • memory-security-integration added to required branch-protection checks
  • Suite runs in <90s in CI
  • Repo guards / CI checks still pass

Prerequisites

  • Milestones 3.D.1–3.D.3 (read/ranking pipeline complete)
  • Phase 3 Track C milestones (write pipeline)
Edit on GitHub

Last updated on

On this page

0%