IBEX Harness
DocsBenchmarksBlogChangelogRoadmap
GitHub
IBEX Harness

Documentation

Architecture Decision RecordsADR-0002: Repository foundation bootstrapADR-0003: Branch protection and merge policyADR-0004: Protobuf and code generation policyADR-0005: Postgres migration strategyADR-0006: Auth protobuf contract (`ibex.auth.v1`)ADR-0007: Auth token validation implementationADR-0008: Security scanning and CI quality gatesADR-0009: Permission bitmap layoutADR-0010: Cryptography policyADR-0011: Proxy auth gRPC client and middlewareADR-0012: Proxy request normalization (OpenAI chat)ADR-0013: Proxy input validation and stable error envelopeADR-0014: Core domain migration sequencingADR-0015: Proxy rate limit skeleton (Phase 1)ADR-0016: Proxy agent identity verification (Phase 1)ADR-0017: Request ID and trace context strategy (Phase 1)ADR-0018: Graceful shutdown contract (Phase 1)ADR-0019: OpenTelemetry provider configuration (Phase 1)ADR-0020: Shared package boundaries — `packages/config` and `packages/apierror`ADR-0021: Prometheus Metric Catalog (Phase 1)ADR-0022: Health check contract (Phase 1)ADR-0023: Docs site architecture (Phase 1.5)ADR-0024: Benchmark data publishing modelADR-0025: LLM provider abstractionADR-0026: OpenAI client designADR-0027: Streaming dual-write strategyADR-0028: Auth cache designADR-0029: Token revocation propagation via Redis pub/subADR-0030: Directive versioning strategyADR-0031: System prompt injection strategyADR-0032: Session data model and retentionADR-0033: ClickHouse llm_traces schema and retentionADR-0034: Proxy overhead performance measurement methodologyADR-0035: Chat Idempotency-Key Redis dedupeADR-0038: Context assembly service design and gRPC contractADR-0039: Proxy Postgres ownership for session and directive storesADR-0040: Anthropic provider adapterADR-0041: Model capability registryADR-0042: Self-hosted OpenAI-compatible LLM adapterADR-0043: Tokenizer registry architectureADR-0044: Non-streaming response pipelineADR-0045: Streaming response transformationADR-0046: Embedder interface and profile registryADR-0047: Memory temporal validity foundationADR-0048: Memory multi-label categoriesADR-0049: Memory relationship graph readinessADR-0050: MCP server skeleton (transport, auth, audit)ADR-0051: Local LGTM observability stack (Phase 2.5 exit pull-forward)ADR-0052: Memory schema v2 expand (HNSW, quality columns)ADR-0053: Vector store abstraction and composite scoring v2
ADRs›ADR-0049: Memory relationship graph readiness
ADRs

ADR-0049: Memory relationship graph readiness

Architecture decision record 0049 — ibex_core.memory_relationships org-safe CREATE, bidirectional traversal indexes, supersession view, and depth-capped tip helper for Phase 2.5 Track E.

ADR-0049: Memory relationship graph readiness

  • Status: Accepted
  • Date: 2026-08-25
  • Authors: IBEX Harness team
  • Milestone: 2.5.G5.M3 Relationship graph readiness

Context

Phase 3 conflict / extraction writers will emit typed edges (supersedes, contradicts, …). Phase 5 recursive CTEs will walk supersession chains to resolve “current” memories. Track E (2.5.G5) must land graph-ready schema before those writers.

The milestone sketch assumed memory_relationships already existed and only needed a source-type index plus a helper view. Applied migrations through 000015 have no memory_relationships table. The DATABASE_SCHEMA draft used single-column FKs and non-FORCE RLS — insufficient for multi-tenant isolation (ADR-0047).

Edge semantics: supersedes means source replaces target. Resolving to the current tip from an older memory walks incoming supersedes (target → source), so a source-only index is incomplete.

Decision

1) Greenfield CREATE (not index-only ALTER)

Ship ibex_core.memory_relationships in 000016_create_memory_relationships. Phase 3.1.1 must not CREATE TABLE memory_relationships again (expand-only if columns are added later).

2) Tenancy-first DDL

  • org_id NOT NULL → organizations ON DELETE RESTRICT
  • Composite FKs (source_memory_id, org_id) and (target_memory_id, org_id) → memories(id, org_id) ON DELETE CASCADE (same-org edges enforced structurally)
  • Taxonomy CHECK for the six relationship types (unchanged)
  • confidence NUMERIC(3,2) NOT NULL DEFAULT 0.90 CHECK (0..1)
  • CHECK (source_memory_id <> target_memory_id) (no self-loops)
  • UNIQUE (source_memory_id, target_memory_id, relationship_type)
  • FORCE ROW LEVEL SECURITY + ibex_core.rls_org_visible(org_id)

3) Bidirectional graph-traversal indexes

  • (org_id, source_memory_id, relationship_type) — forward walks / “what did this replace?”
  • (org_id, target_memory_id, relationship_type) — reverse walks / “resolve to current tip”

Org-leading keys serve service-account queries that filter by org_id explicitly (RLS bypass).

4) Helper view + tip function (schema readiness)

  • View ibex_core.memory_supersession_edges — relationship_type = 'supersedes' projection with security_invoker = true (PG16) so caller RLS applies
  • Function ibex_core.resolve_supersession_tip(org_id, memory_id, max_depth DEFAULT 5) — SECURITY INVOKER, search_path pinned, base case seeds from memories where id and org_id match (returns NULL when invisible/mismatched), org_id predicate at every recursion level, hard depth cap 1..5 (out-of-range returns start id), cycle break via path array; valid seed with no outgoing supersedes returns the start id

No application Go/Python writers in this milestone.

5) Non-goals

  • No new edge types / taxonomy renames
  • No Apache AGE or external graph database
  • No backfill (empty table until Phase 3 writers)

Consequences

Positive

  • Phase 3 can insert edges without inventing tenancy shape
  • Phase 5 CTEs have indexes and a reference tip helper matching 5.B.1 constraints
  • Cross-org edges fail closed at the FK layer

Negative

  • Sketch “table already exists / index-only” diverges (documented on the milestone)
  • Branching supersession graphs make tip selection depth-primary then deterministic by id; writers should prefer chains

Rollout

  • Migration: infra/migrations/postgres/000016_create_memory_relationships.{up,down}.sql
  • Down is dev/test only; production forward-only per ADR-0005

References

  • ADR-0005
  • ADR-0047
  • ADR-0048
  • Milestone 2.5.G5.M3
  • Milestones 3.1.1, 3.C.3, 5.B.1

Was this page helpful?

Edit on GitHub

Last updated on

PreviousADR-0048: Memory multi-label categoriesNextADR-0050: MCP server skeleton (transport, auth, audit)

On this page

  • Context
  • Decision
  • 1) Greenfield CREATE (not index-only ALTER)
  • 2) Tenancy-first DDL
  • 3) Bidirectional graph-traversal indexes
  • 4) Helper view + tip function (schema readiness)
  • 5) Non-goals
  • Consequences
  • Positive
  • Negative
  • Rollout
  • References
0%