Skip to main content
Pages

Architecture

Standalone memory service for AI tools, with durable memory, evidence, team isolation, and MCP access.

Architecture

Dense-Mem is a standalone memory service. The host LLM decides when memory is useful; Dense-Mem owns evidence intake, Entity resolution, Relationship lifecycle, durable provenance, retrieval, trace, and audit.

This page is the v2 architecture overview. Detailed rules live in the linked canonical pages.

System Map

%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart TB
  Client["LLM host / MCP client"] --> Access["Authenticated access layer"]
  Browser["User and operator portals"] --> Access
  Access --> Services["Team-scoped application services"]

  Services --> Remember["Remember"]
  Services --> Recall["Recall"]
  Services --> Trace["Trace and correction"]
  Services --> Control["Control plane"]
  Services --> Dream["Dreaming"]

  Remember --> Providers["Reviewer, verifier,<br/>and embedding providers"]
  Recall --> Providers
  Dream --> Providers

  Remember --> PG[("PostgreSQL + pgvector<br/>single source of truth")]
  Recall --> PG
  Trace --> PG
  Control --> PG
  Dream --> PG

  Services -. "optional coordination" .-> Redis[("Redis or one-process memory")]

PostgreSQL is the only required database. It stores durable knowledge and control state and serves graph-shaped, full-text, and vector reads. pgvector is an extension inside PostgreSQL. Redis is optional coordination and never contains memory truth. Neo4j is not part of normal target runtime; the temporary 2.1.x bridge reads it only in boot-gated migration mode.

Responsibility Boundaries

BoundaryResponsibility
Accesslistener separation, authentication, authorization, tenant/profile scope, request limits, deterministic injection scanning, and safe errors
Applicationremember, recall, trace, correction, dreaming, and control orchestration
DomainEntity identity, predicate vocabulary, Relationship identity/lifecycle, evidence acceptance, and Hypothesis rules
PostgreSQLdurable ledger, current state, queues, review, audit, SemanticEdge queries, full-text, and pgvector
Model providersstructured extraction, one-call verification, embeddings, and optional dream generation; no write authority
Coordinationrate limits, leases/signals, and SSE concurrency; Redis when distributed, process memory when safely single-instance

Store ownership and recovery belong in Data Model And Storage. Listener and authorization boundaries belong in Request Lifecycle And Security.

Request Paths

%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart LR
  Request["Authenticated request"] --> Kind{"Operation"}
  Kind -- remember --> Write["Stage evidence and queue placement"]
  Kind -- recall --> Read["Search and bounded adjacency"]
  Kind -- trace --> Trace["Read provenance and current graph"]
  Kind -- review/correct --> Correct["Append decision and recompute"]
  Kind -- control --> Admin["Manage scoped control state"]

  Write --> PG["PostgreSQL transaction"]
  Read --> PG
  Trace --> PG
  Correct --> PG
  Admin --> PG

The authenticated principal fixes team, profile, role, and scopes before any application service runs. A request never chooses its tenant.

Target Runtime Composition

Dependency direction is inward: transports call application services; application services apply domain policy through ports; adapters implement storage, provider, and coordination ports.

cmd/server/
  composition root
​
internal/
  domain/
    evidence/
    entity/
    relationship/
    verification/
    hypothesis/
  service/
    remember/
    recall/
    trace/
    correction/
    dreaming/
  repository/
    knowledge/
    search/
    control/
  storage/
    postgres/
      ledger/
      current/
      search/
      queue/
    redis/
      coordination/
  provider/
    embedding/
    reviewer/
    verifier/
    dream/
  transport/
    mcp/
    http/
    portal/
%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart LR
  Transport["MCP and first-party portals"] --> Application["Application services"]
  Application --> Domain["Domain contracts and policy"]
  Application --> Ports["Repository, provider,<br/>and coordination ports"]
  PG["PostgreSQL adapter"] --> Ports
  Redis["Optional Redis adapter"] --> Ports
  AI["AI provider adapters"] --> Ports

This tree is a responsibility map, not a command to preserve or invent package names. Before implementation, map current packages and move code only where a boundary is otherwise unenforceable.

Startup And Shutdown

%%{init: {"sequence": {"rightAngles": true}}}%%
sequenceDiagram
  autonumber
  participant S as Server
  participant P as PostgreSQL
  participant R as Redis or process memory
  participant A as Model providers
  participant W as Workers
  participant H as HTTP
  actor O as Operator

  S->>S: Load and validate configuration
  S->>P: Connect and inspect release/migration state
  S->>H: Start health and control surfaces
  alt Migration required in 2.1.x
    S->>H: Enter maintenance and log migration_required
    O->>H: Start or resume after preflight
    S->>A: Validate migration provider contracts
    S->>P: Run official-pipeline migration and hard gates
    P-->>S: Commit automatic cutover marker
    S->>S: Close legacy migration adapter
  else Compatible completed marker
    S->>P: Continue normal release startup
  end
  S->>P: Apply compatible schema migrations
  S->>P: Validate pgvector, embedding contract, and search-index profile
  S->>R: Build required coordination backend
  S->>A: Validate configured provider contracts
  S->>W: Start placement, embedding, cleanup, and optional schedulers
  S->>H: Enable main v2 data plane
  H-->>S: Serve until termination
  S->>H: Stop accepting traffic
  S->>W: Drain or release work safely
  S->>S: Close providers and adapters

PostgreSQL and a compatible completed migration marker are always readiness gates. Redis is a gate only when distributed coordination is required or explicitly configured as mandatory. A multi-instance deployment cannot silently fall back to process-local limits or leases.

Provider readiness distinguishes required operations: an unavailable verifier may make write placement not-ready while authorized trace reads can still operate. Exact health and incident procedure belongs in Operations Runbook.

Semantic Model Boundary

%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart LR
  Evidence["Evidence fragments"] --> Observation["Relationship observations"]
  Observation --> Verification["Verification events"]
  Verification --> Current["Profile-owned Relationship current state"]
  Current --> Cross["Cross-profile reference ledger"]
  Current --> Edge["SemanticEdge read<br/>active validated/fact only"]
  Current --> Trace["Trace with support and history"]
  Current --> Dream["Optional isolated Hypotheses"]
  • Entity and typed Value are the only semantic-node kinds.
  • A SemanticEdge is a graph-shaped read of one eligible Relationship row.
  • Relationship lifecycle is profile-owned and same-team readable; corrections of another profile create caller-owned knowledge plus immutable references.
  • Names and aliases are Entity metadata.
  • Evidence, observations, verification, transitions, reviews, and Hypotheses are ledger records, not semantic nodes.
  • Candidate Relationships have no active edge and do not enter default recall.
  • A Hypothesis can connect only existing endpoints and cannot change knowledge.

Canonical ownership:

ConcernCanonical page
Entity reuse, create, ambiguity, merge, and splitEntity Identity And Resolution
Predicate, Relationship identity, evidence, verification, tier, status, and forgetRelationship Model And Lifecycle
PostgreSQL, Redis, transactions, durable storage, jobs, and recoveryData Model And Storage
PostgreSQL tenant keys, table placement, RLS/query locality, and future team shardingPostgreSQL Cluster-Safe Schema
pgvector exact/ANN execution, HNSW/halfvec, index load, and search topologyANN, HNSW, And Halfvec
remember stage order and strict one-call verifierMemory Write Pipeline
recall eligibility, PostgreSQL branches, and trace escalationRecall Ranking
cosine distance, RRF, reranking, and conflict preferenceVector Search And Ranking
Hypothesis generation boundaryDreaming
MCP discovery/execution and first-party portal boundaryRequest Lifecycle And Security

Write Boundary

Remember first validates and deterministically scans the bounded request, then atomically commits exact evidence, the scan event, and queued, guarded, or quarantined processing intent. A worker handling queued evidence extracts structure, retrieves immutable Entity/predicate candidates, makes one strict verifier request containing bounded security_signals, entity_results, and relationship_results, validates the whole response, applies deterministic policy, and commits all material outcomes in PostgreSQL.

%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart LR
  Request["Authenticated bounded request"] --> Scan{"Pass, guarded,<br/>or quarantine?"}
  Scan -- quarantine --> StageQ["Commit quarantined intake"]
  StageQ --> Quarantine["Restricted audit only"]
  Scan -- pass or guarded --> Intake["Commit evidence and queue intent"]
  Intake --> Extract["Structure extraction"]
  Extract --> ExtractSignal{"Reviewer security signal?"}
  ExtractSignal -- Yes --> Quarantine
  ExtractSignal -- No --> Context["Server Entity/predicate context"]
  Context --> Verify["One verifier response"]
  Verify --> Validate["Closed-schema, security-signal,<br/>and allowlist validation"]
  Validate --> Signal{"Model security signal?"}
  Signal -- Yes --> Quarantine
  Signal -- No --> Policy["Deterministic lifecycle"]
  Policy --> Commit["One PostgreSQL transaction"]
  Commit --> Immediate["Current rows, SemanticEdges,<br/>and full-text available"]
  Commit --> Async["Versioned embedding job"]

Invalid verifier output is regenerated as a complete response. The application does not coerce it or commit a valid subset. Full details belong in Memory Write Pipeline.

Read Boundary

Normal recall queries same-team active validated_claim and fact profile-owned Relationships through PostgreSQL full-text, pgvector, and bounded adjacency branches. It returns a compact authored Relationship, conflict/support handles, and relationship_id, not all evidence or verifier history.

Trace fetches normalized provenance when the caller needs to understand, correct, or forget knowledge. Graph visualization uses the same semantic-node and SemanticEdge query shape; it is not another database or authority.

Consistency Boundary

Core semantic state and its append-only history commit atomically in one PostgreSQL transaction.

%%{init: {"sequence": {"rightAngles": true}}}%%
sequenceDiagram
  participant W as Placement worker
  participant P as PostgreSQL
  participant E as Embedding worker

  W->>P: Begin semantic transaction
  W->>P: Append evidence decisions and transitions
  W->>P: Update current Entity / Relationship rows
  W->>P: Upsert search document and embedding job
  W->>P: Commit
  P-->>W: Authoritative state and SemanticEdge visibility
  E->>P: Claim embedding job
  E->>P: Write vector only for matching source version

Only embeddings are intentionally asynchronous because they are derived. search_state exposes their freshness. There is no cross-database graph projection, outbox, or graph-reconciliation loop in the target.

Host And Service Responsibilities

AreaDense-Mem ownsHost LLM owns
Rememberevidence persistence, extraction review, strict verification, identity resolution, lifecycle, and traceabilitysubmitting evidence and the smallest supported hint
Embeddingsevidence, Entity, Relationship, and query embeddings through configured providersno normal-use vectors
Recallbounded retrieval, ranking, graph frontier, freshness, and trace handlesdeciding which returned context to use, cite, or question
Ambiguityexact candidates, impact, review state, and safe decision applicationpresenting the ambiguity and collecting the user's evidence-backed choice
Operationsisolation, profiles, roles, keys, portals, telemetry, backup, and recoveryclient configuration and safe use of returned context

Dense-Mem is not an autonomous truth oracle. Models propose structured judgments; deterministic server rules control durable state.

Refactor Boundary

The target should be implemented as reviewable vertical slices:

%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart LR
  Contract["1. Versioned domain contracts"] --> Schema["2. PostgreSQL schema<br/>and repositories"]
  Schema --> Remember["3. Remember + strict verifier"]
  Remember --> Recall["4. Recall + trace"]
  Recall --> Dream["5. Candidate-safe dreaming"]
  Dream --> Migration["6. 2.1.x official-pipeline<br/>legacy migration"]
  Migration --> Cutover["7. Automatic cutover"]
  Cutover --> Remove["8. Remove Neo4j bridge<br/>in 2.2.0"]

Each slice needs contract, tenant-isolation, idempotency, and failure tests before another slice relies on it. Legacy Neo4j data is migration input, not a second target model.

Risks And Mitigations

RiskConcrete failure modeMitigation
Target mistaken for shipped behavioran operator uses v2 PostgreSQL-only recovery on the current runtimelabel target status, expose contract/runtime versions, and gate cutover on release checks
PostgreSQL graph query is unboundeda hub Entity causes a recursive query to exhaust memorypartial adjacency indexes and strict seed/fan-out/depth/edge/time budgets
ANN tenant filter loses recallshared approximate search omits relevant team rows before hydrationenforce the team-shaped execution/topology gates in ANN, HNSW, And Halfvec
Provider controls truthverifier returns tier=fact or an arbitrary ID and it reaches storageclosed schema excludes writes; allowlist validation and deterministic lifecycle
Big-bang refactor stallsevery package changes before one end-to-end slice worksvertical slices, legacy adapters at boundaries, and passing acceptance invariants per slice
Redis becomes a hidden databasereplicas lose identity or review state after Redis restartcoordination-only ports and restart tests proving PostgreSQL is complete

Architecture Invariants

  1. Authentication fixes the team; request data cannot override it.
  2. PostgreSQL is the only durable source of knowledge and control state.
  3. pgvector is part of PostgreSQL, not a separate authority.
  4. Redis and process memory contain no canonical memory.
  5. Entity and typed Value are the only semantic nodes.
  6. One active profile-owned validated_claim or fact Relationship produces at most one SemanticEdge.
  7. Candidates and Hypotheses never enter default recall or active graph reads.
  8. Stored knowledge and search context can inform comparison but never count as submitted evidence.
  9. Only deterministic policy after a valid complete verifier response changes tier/status.
  10. Required recall failures are visible; optional degradation is reported.
  11. Embedding and search-index versions form explicit linked deployment contracts with separate rebuild lifecycles.
  12. Normal target runtime has no Neo4j dependency; only the temporary 2.1.x migration gate may connect, and 2.2.0 removes that code.
  13. Same-team visibility never permits one profile to mutate another profile's knowledge.