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-0033: ClickHouse llm_traces schema and retention
ADRs

ADR-0033: ClickHouse llm_traces schema and retention

Accepted — Phase 2 append-only llm_traces MergeTree; ORDER BY org/agent/time; 90-day TTL; no content; app-level org filter.

ADR-0033: ClickHouse llm_traces schema and retention

  • Status: Accepted (schema in 2.5.1; client in 2.5.2; emitter in 2.5.3)
  • Date: 2026-07-25
  • Authors: IBEX Harness team
  • Milestone: 2.5.1 ClickHouse schema

Context

Proxy chat already authenticates, injects directives, and records sessions/checkpoints. Phase 2 still needs an append-only analytics sink for per-request operational traces (tokens, latency breakdown, outcome) without blocking the LLM hot path. ClickHouse is already present in local compose (clickhouse/clickhouse-server:24.8.x).

DATABASE_SCHEMA.md historically sketched a richer inference_traces table (memory IDs, billing MVs). Phase 2 needs a minimal, privacy-safe table the async emitter can write immediately.

Decision

  1. Table: ibex.llm_traces — Phase-2 canonical analytics table. Richer inference_traces / billing MVs remain future / Phase 3+.
  2. Engine: MergeTree(), PARTITION BY toYYYYMM(event_date), ORDER BY (org_id, agent_id, requested_at), index_granularity = 8192. Primary sort key matches the dominant query: “traces for this org’s agent in a time range.”
  3. Types: LowCardinality(String) for model, provider, error_code. Latency fields are integer milliseconds. event_date is Date MATERIALIZED toDate(requested_at) for partition/TTL.
  4. No content: Never store prompt text, completion text, or message bodies. Hashes/metadata belong on Postgres checkpoints; traces stay operational.
  5. Retention: TTL event_date + INTERVAL 90 DAY default. Deployments may alter TTL via follow-on migration; enterprise longer retention is an ops decision, not a Phase-2 schema fork.
  6. Tenancy: ClickHouse has no Postgres-style RLS. Writers/readers must scope by org_id (enforced in 2.5.2/2.5.3 and CLICKHOUSE_ORG_FILTER_ENFORCEMENT).
  7. Migrations: golang-migrate ClickHouse driver under infra/migrations/clickhouse/, native TCP DSN (compose host port 9002; HTTP 8123 is for application clients). Multi-statement enabled; migrations table engine MergeTree.
  8. Dev topology: ClickHouse runs in compose-dev (resolved). External CH is supported via CLICKHOUSE_MIGRATE_DSN / CLICKHOUSE_DSN.

Consequences

  • Migration 000001_create_llm_traces creates the table; make clickhouse-migrate applies it.
  • 2.5.2 can implement a batched Writer against this schema without churn.
  • Phase 3 embedding / other ADRs must not reuse ADR-0033; pick the next free number.

Alternatives considered

  1. Use Postgres for traces — simpler ops; fails write volume and aggregation latency targets. Rejected.
  2. Ship full inference_traces now — unused memory/billing columns increase privacy surface. Deferred.
  3. ReplacingMergeTree / updates — traces are immutable; reject updates. MergeTree append-only wins.

Was this page helpful?

Edit on GitHub

Last updated on

PreviousADR-0032: Session data model and retentionNextADR-0034: Proxy overhead performance measurement methodology

On this page

  • Context
  • Decision
  • Consequences
  • Alternatives considered
0%