ibexharness
DocsBlogReleasesRoadmap
GitHub
ibexharness

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)
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%