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-0012: Proxy request normalization (OpenAI chat)
ADRs

ADR-0012: Proxy request normalization (OpenAI chat)

Architecture decision record 0012.

ADR-0012: Proxy request normalization (OpenAI chat)

  • Status: Accepted
  • Date: 2026-06-04
  • Authors: IBEX Harness team

Context

Milestone 1.2.1 added auth middleware and a 501 stub on POST /v1/chat/completions without reading the body. Goal 1.2 requires OpenAI-shaped JSON to parse into an internal type before provider forwarding (Phase 2). Milestone 1.2.3 owns semantic validation, body size limits, and full error envelope extensions.

Decision

1) Route and path

  • Service route: POST /v1/chat/completions (implemented in proxy router)
  • API documentation: /proxy/v1/chat/completions is the external/gateway prefix alias (same handler behind ingress)

2) Package layout

  • services/proxy/internal/llm/ — request DTOs and JSON parse only
  • services/proxy/internal/upstream/ — reserved for Phase 2 provider HTTP client (FILE_STRUCTURE.md)

3) Parse scope (1.2.2)

  • Decode JSON object; ignore unknown top-level fields (OpenAI compatibility)
  • Require messages (when present) to be a JSON array of objects with role and content strings
  • Extract model, messages, stream, optional temperature, max_tokens
  • Do not reject empty model or empty messages (1.2.3 validator)
  • Do not enforce Content-Type, body size, or IBEX headers (1.2.3)

4) Errors

ConditionHTTPcode
Malformed JSON / wrong JSON shape400INVALID_JSON
Valid parse, no provider501PROVIDER_NOT_CONFIGURED

Uses existing services/proxy/internal/errors/ envelope (ADR-0011).

5) Logging

Per SECURITY.md §10.1: after successful parse, log metadata only — org_id, request_id, model, message_count, stream. Never log message content.

6) Middleware order

metrics → logging → auth → handler in 1.2.2 only. 1.2.3+ (ADR-0013): metrics → requestContext → responseHeaders → logging → [bodyLimit → contentType → auth] → handler

7) Deferred to 1.2.3

  • MaxRequestBodyBytes, 413/415
  • VALIDATION_ERROR with field_errors
  • Required model, role enum, message bounds
  • X-IBEX-Agent-ID UUID validation
  • Response headers X-Request-ID, X-Trace-ID, X-Response-Time on all responses

Consequences

Positive

  • Goal 1.2 parse criterion met without provider HTTP
  • Clear boundary with validation milestone
  • Parsed request on context for 1.2.3 and Phase 2 upstream

Negative

  • Unbounded body read until 1.2.3 (documented risk)
  • Empty model still returns 501 until semantic validation lands

References

  • Milestone 1.2.2
  • Milestone 1.2.3
  • API_DOCUMENTATION.md — LLM Proxy API

Was this page helpful?

Edit on GitHub

Last updated on

PreviousADR-0011: Proxy auth gRPC client and middlewareNextADR-0013: Proxy input validation and stable error envelope

On this page

  • Context
  • Decision
  • 1) Route and path
  • 2) Package layout
  • 3) Parse scope (1.2.2)
  • 4) Errors
  • 5) Logging
  • 6) Middleware order
  • 7) Deferred to 1.2.3
  • Consequences
  • Positive
  • Negative
  • References
0%