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-0024: Benchmark data publishing model
ADRs

ADR-0024: Benchmark data publishing model

Architecture decision record 0024.

ADR-0024: Benchmark data publishing model

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

Context

The benchmark workflow collects proxy load and Go microbenchmark results, validates them, and produces benchmark-data.json for the docs dashboard. An earlier design pushed benchmark JSON commits onto contributor PR branches using GITHUB_TOKEN. That caused:

  1. CI cascade noise — every bot push emitted pull_request synchronize and re-ran CI, CodeQL, Semgrep, and semantic PR checks.
  2. Integrity bypass risk — trusting git author email to skip comparison allowed spoofing via local commit metadata.
  3. Token exposure — persist-credentials: true on PR head checkouts left credentials available to later script steps.
  4. Rerun loops — cumulative PR path filters and merge-ref diffs re-triggered full benchmark collection after data-only commits.

The docs site embeds benchmark JSON at build time (docs/app/src/lib/benchmarks/published-data.ts). Preview on PRs must show fresh benchmark results without mutating the PR branch.

Decision

1) No in-PR branch writes from ibex-harness workflows

  • Remove publish-benchmark-data (PR branch commits) from .github/workflows/benchmark.yml.
  • PR benchmark results live in the benchmark-data workflow artifact and PR comments only.
  • docs-build in .github/workflows/ci.yml overlays the latest successful artifact for the PR head SHA before building docs.

2) Integrity checks without spoofable trust

  • verify_pr_benchmark_integrity.sh fetches the base ref with an explicit one-shot token header; checkout uses persist-credentials: false.
  • If benchmark-data.json is unchanged from base, verification passes (artifact is the PR preview source).
  • If the branch claims the current PR in committed JSON (pr_number match), committed data must equal the workflow artifact (compare_pr_benchmark_json.py).
  • Do not trust git author email for bypass decisions.

3) Latest-commit benchmark gate

  • detect-benchmark-trigger in .github/workflows/benchmark.yml checks out pull_request.head.sha with fetch-depth: 2 and diffs HEAD~1..HEAD so data-only commits do not re-run collection.

4) Post-merge publishing via external GitHub App

  • Publishing to main is handled by ibexharness-benchmark-bot via repository_dispatch after weekly (Sunday) or manual main benchmark runs.
  • Harness notify-benchmark-bot / notify-hnsw-benchmark-bot jobs send repository_dispatch when BENCHMARK_BOT_ENABLED=true on schedule, workflow_dispatch, or path-triggered push to main (so published history is not Sunday-only).
  • Interim open-benchmark-data-pr removed; bot opens data PRs with App identity.
  • Every PR still runs collection and posts a benchmark comment; that path never publishes JSON to main.

5) run_number semantics

  • run_number stores GITHUB_RUN_NUMBER, not the workflow run ID.
  • validate_published_data.py rejects rows where run_number equals the numeric ID embedded in run_url.

Consequences

  • PR branches stay free of automated benchmark commits; CI runs once per human code push.
  • Docs preview on PRs depends on a successful Benchmarks workflow artifact (falls back to committed JSON if none yet).
  • Fork PRs continue to use artifact download only; no branch writes.
  • Post-merge benchmark data PRs are opened by ibexharness-benchmark-bot (configure per bot repo APP_SETUP.md).

Alternatives considered

AlternativeWhy rejected
In-PR publish with author-email bypassSpoofable; caused rerun loops
[skip ci] in bot commit messagesDoes not stop all workflows; weak merge-gate story
ALLOW_PUBLISH_RECONCILE on mismatchMasks stale bot JSON; removed with in-PR publish
Keep publishing with github.actor skip onlyStill mutates PR branch; github.actor is forgeable (Sonar S8232)

References

  • PR #177 benchmark pre-PR pipeline work
  • ibexharness-benchmark-bot — external app specification and implementation

Was this page helpful?

Edit on GitHub

Last updated on

PreviousADR-0023: Docs site architecture (Phase 1.5)NextADR-0025: LLM provider abstraction

On this page

  • Context
  • Decision
  • 1) No in-PR branch writes from ibex-harness workflows
  • 2) Integrity checks without spoofable trust
  • 3) Latest-commit benchmark gate
  • 4) Post-merge publishing via external GitHub App
  • 5) run_number semantics
  • Consequences
  • Alternatives considered
  • References
0%