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-0020: Shared package boundaries — `packages/config` and `packages/apierror`
ADRs

ADR-0020: Shared package boundaries — `packages/config` and `packages/apierror`

Architecture decision record 0020.

ADR-0020: Shared package boundaries — packages/config and packages/apierror

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

Context

M1.4.2 requires typed environment loading and a canonical error code registry before Phase 2 adds Python services and LLM provider forwarding. Prior milestones deferred both concerns:

  • ADR-0015: proxy rate-limit config in services/proxy/internal/config until M1.4.2
  • ADR-0013: stable HTTP error envelope in services/proxy/internal/errors until M1.4.2

Both services/auth and services/proxy used scattered os.Getenv calls with per-field validation.

Decision

1) packages/config

  • All Go service environment loading uses config.Load[T]() / config.MustLoad[T]() with struct env:"VAR" tags
  • Underlying parser: github.com/caarlos0/env/v11
  • config.Secret and secret:"true" tags redact values in config.LogDebug
  • Service-specific validation (ports, DSN format, rate-limit overrides) remains in services/*/internal/config after env parse
  • packages/telemetry keeps internal ConfigFromEnv for OTEL_* variables; services compose telemetry config after IBEX env load

2) packages/apierror

  • Single registry for HTTP JSON error codes and gRPC status mappings
  • Error code strings are stable per ADR-0013 — this ADR relocates the registry; it does not rename shipped codes (MISSING_TOKEN, not UNAUTHENTICATED)
  • Full envelope preserved: field_errors, detail, docs_url, timestamp (ADR-0013)
  • Handlers use apierror.Write / apierror.WriteStatus; no raw error code string literals outside this package

3) Boundaries

PackageMay importMust not
packages/configstdlib, caarlos0/envservice packages, packages/logger (bootstrap ordering)
packages/apierrorstdlib, google.golang.org/grpc/codesservice handlers, DB, Redis

Consequences

  • New error codes are added only in packages/apierror
  • New required env vars are documented via struct tags + .env.example + ENVIRONMENT_VARIABLES.md
  • Phase 2 Python services document pydantic-settings pattern separately (AGENTS.md)

References

  • M1.4.2 milestone
  • ADR-0013
  • AGENTS.md
  • ARCHITECTURE_LAYERING.md — consumer-owned ports vs intentional shared package interfaces (session / idempotency / directive)

Was this page helpful?

Edit on GitHub

Last updated on

PreviousADR-0019: OpenTelemetry provider configuration (Phase 1)NextADR-0021: Prometheus Metric Catalog (Phase 1)

On this page

  • Context
  • Decision
  • 1) packages/config
  • 2) packages/apierror
  • 3) Boundaries
  • Consequences
  • References
0%