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 v2ADR-0054: In-process Presidio PII detection in memoryADR-0055: Memory write-path exact and near-duplicate dedupADR-0056: Temporal-interval-aware conflict detectionADR-0057: Memory write-path persistence and orchestrationADR-0058: Semantic search FTS fallback triggerADR-0059: Hot cache read pathADR-0060: Memory service tenant isolation architectureADR-0061: Retrieval-quality benchmark methodologyADR-0062: Worker task observability and dead-letter handlingADR-0063: Extraction output schema v2ADR-0064: Extraction provider registry and batch executionADR-0065: Extraction batch idempotency and turn pointer orderingADR-0066: Extraction quality evaluation harnessADR-0067: Context capability catalog generate-and-diff for token budgetsADR-0068: Composite scoring-time relevance gateADR-0069: Context packer bounded DP knapsackADR-0070: Context formatting locked ordering and session nonceADR-0071: Context assembly gRPC degradation ladder and retrieval deadlineADR-0072: Extraction enqueue via worker HTTP (not Celery Redis wire format)ADR-0073: Organization Lifecycle and Cascading SuspensionADR-0074 Provider Credential StorageADR-0075 Per-Org Model Routing PolicyADR-0076: Circuit Breaker per ProviderADR-0077: Provider Fallback RoutingADR-0078: Operator runtime topology & environment contract (4.P.0)ADR-0079: Operator session RS256 dual-verify and TOTP step-upIBEX Console service rename and boundaryADR-0081: Fail-closed Proxy runtime controlsD2 metadata-only trace read contractD2 publication, identity, query, and lifecycle contract
ADRs›ADR-0066: Extraction quality evaluation harness
ADRs

ADR-0066: Extraction quality evaluation harness

Architecture decision record 0066 — gold-set extraction eval, cassette CI, manual vLLM side-by-side, and 3pp absolute regression gate.

ADR-0066: Extraction quality evaluation harness

  • Status: Accepted
  • Date: 2026-09-03
  • Authors: IBEX Harness team
  • Milestone: 3.5.B.4 Extraction quality evaluation harness
  • Depends on: ADR-0064, ADR-0065, ADR-0061

Context

Parseability checks (“valid JSON > 99%”) do not measure extraction correctness. Phase 3 already gates retrieval quality (ADR-0061). Track B needs the extraction counterpart: per-category precision/recall, exact category-set accuracy, and temporal-field accuracy.

Milestone wording asks for OpenAI and vLLM evaluated side-by-side, but 3.5.B.2 established there is no GPU CI runner. Live LLM calls on every PR would also be costly and flaky.

Decision

1) Layout

Harness lives under services/worker/eval/ with versioned gold data in gold_set/v1/ (subdirectory versioning; ranking-quality used gold_set_v1.json filenames — B.4 follows the milestone v1/ layout).

2) vLLM conflict → path (a)

  • CI-enforced: OpenAI cassette (and optional live on weekly full / workflow_dispatch only).
  • Manual: vLLM numbers committed in baseline_results.json with enforcement: manual and last_refreshed.
  • Side-by-side requirement is satisfied by publishing both blocks; summaries always label enforcement so manual/stale vLLM is never mistaken for CI.

3) Cassette hybrid (cost / flakiness)

ProfileBehavior
smoke (PR) / fast (main)Cassette replay — $0, deterministic
full (Sunday / dispatch)Live OpenAI if secret present; else cassette + explicit skip note

Manifest contract hashes (fail-closed on cassette profiles):

  • prompt_sha256 tracks EXTRACTION_SYSTEM_PROMPT_BATCH
  • schema_sha256 tracks canonical BatchExtractionResult.model_json_schema() (structural contract, not raw schema.py bytes)

cassette_kind distinguishes oracle_aligned_expected_json (deterministic scoring/gate baseline) from live_openai_recorded (written by EXTRACTION_EVAL_MODE=record). This is a documented process + fail-closed hash/kind gate, not cryptographic proof that cassette bytes were produced by a particular model call.

CI additionally fails PRs that change prompt_v2.py / schema.py while cassette_kind remains oracle-aligned, unless the PR body contains EXTRACTION_EVAL_ORACLE_OK=1 (explicit reviewer-visible exception). EXTRACTION_EVAL_ALLOW_PROMPT_DRIFT must not appear in the extraction-eval workflow.

4) Metrics and gate

  • Per-category precision/recall for all five VALID_LABELS.
  • Category-assignment accuracy = exact label-set equality (over- and under-label fail).
  • Temporal-field accuracy scored separately (supersession ⇒ valid_until set; indefinite ⇒ None).
  • Gate uses absolute max_regression_pp: 3.0 (unlike ranking-quality’s relative 5%). Exit code 1 on fail — proven by unit test, not status-field-only.
  • End-to-end cassette regression detection is covered by a corrupted-cassette fixture test (not only isolated metrics.py units).

5) Benchmark bot / publish

Published history: web/public/benchmarks/extraction-quality-benchmark-data.json. Bot suite + extraction_benchmark_main_complete dispatch mirror memory ranking/write publishing (see ibexharness-benchmark-bot).

Consequences

  • Contributors do not spend OpenAI budget on routine PRs.
  • Prompt/schema drift without cassette refresh fails via contract hashes; oracle + contract-file PR diffs fail unless live-recorded or explicitly overridden in the PR body.
  • Operators must refresh vLLM baselines manually when comparing providers.
  • Pin BENCHMARK_BOT_SHA must include post-extraction-pr-comment before PR comments render for this suite.

Was this page helpful?

Edit on GitHub

Last updated on

PreviousADR-0065: Extraction batch idempotency and turn pointer orderingNextADR-0067: Context capability catalog generate-and-diff for token budgets

On this page

  • Context
  • Decision
  • 1) Layout
  • 2) vLLM conflict → path (a)
  • 3) Cassette hybrid (cost / flakiness)
  • 4) Metrics and gate
  • 5) Benchmark bot / publish
  • Consequences
0%