feat(server): add server foundation for S12 OCI local (MR 1/5)

Why

Foundation slice of the S12 OCI-local stack. Anchors the contract surface every subsequent OCI handler MR depends on. This MR replaces the previous version of !124 after Pawel asked the stack to be split with file-level boilerplate factored out into !141 (MR-0) so reviewers could land mechanical changes first and focus the rest of the stack on Go code.

Issue: #19 (closed) Spec: S12 (already merged via !48 (merged))

Stack and merge order

# MR Branch Targets Blocks
0 !141 (merged) 19-oci-boilerplate main !124 (closed)
1 !124 (closed) ← you are here 19-oci-foundation 19-oci-boilerplate !125 (closed)
2 !125 (closed) 19-oci-database 19-oci-foundation !126 (closed)
3 !126 (closed) 19-oci-cas 19-oci-database !127 (closed)
4 !127 (closed) 19-oci-format 19-oci-cas !128 (closed)
5 !128 (closed) 19-oci-wiring 19-oci-format n/a

What's in MR-1

25 files, ~4,800 insertions, all Go code. One squash commit on top of MR-0.

  • internal/auth/: anticipatory contract for S08. Validator, Identity, HasGrant, the Middleware, and the BootstrapValidator with constant-time-compare. The auth-decision label constants live in internal/observability and internal/auth consumes them so the two packages cannot drift. Future S08 swap preserves the Identity shape, the middleware position, and the /v2/auth/token URL.
  • internal/middleware/: the package's middlewares (Chain, BodySize with exempt-prefix OriginalBody stash, HeaderHardening, Recovery, RequestID, RoutePattern). Tight AllocsPerRun budgets (1 and 0 respectively) pin the two hot-path optimizations (exempt-only OriginalBody stash and RoutePattern context-rewrap fast-path) so a regression fails CI deterministically.
  • internal/observability/: foundation slice of S03's metric set. The metrics are http_requests_total, http_request_duration_seconds (with OTel-trace-id exemplars on sampled spans), panics_total, auth_decisions_total, and db_connection_pool_size. The package exposes cardinality allowlists as Allowed* slice helpers, and cardinality-audit tests assert the materialized series count matches the allowlist sizes. Off-allowlist prefixes and methods collapse to _other_. Off-allowlist decisions and outcomes drop the call entirely so a typo fails the audit rather than landing a synthetic bucket.
  • internal/gc/: Lock interface plus an InMemoryLock placeholder. ErrLockTimeout covers both context.Canceled and context.DeadlineExceeded by design so handlers map every "lock not obtained" outcome to a single 503 UNAVAILABLE response.
  • internal/testutil/: DSN parsing helper and test-DB plumbing.
  • go.mod: promotes prometheus/client_{golang,model} and otel/trace from indirect to direct since the new packages consume them.

The proto schema and generated code, .gitlab-ci.yml validate-stage hardening, and the dev-tooling configs all live in MR-0 (!141 (merged)).

Test plan

  • CI green on this MR (build, vet, lint, test, bench-regression, fuzz seed corpus). Both test:bench-regression and test:fuzz activate on this MR (it adds internal/{auth,middleware,observability}/**/*.go).
  • benchstat MR comment appears in this MR after CI runs (verifies BENCHSTAT_NOTE_TOKEN plumbing). The comment should show the foundation benchmarks with no target-side baseline (first MR introducing them). The job tolerates that gracefully.
  • Allocation budgets pass deterministically: auth happy path ≤ 8, observability HTTP middleware ≤ 6, BodySize non-exempt = 1, RoutePattern holder-seeded = 0.
  • Cardinality-audit tests pin the (method × route × status_code) and (prefix × decision × outcome) series counts.
  • go mod tidy is a no-op locally.
  • !125 (closed) builds cleanly on top of this branch.

Reviewer-feedback rounds

This branch absorbed three review passes before being rebuilt on MR-0. The most recent round (post-second-pass review) addressed:

  • W1: chain-position references in routepattern.go now match the S01 spec and the metrics-middleware doc.
  • W2: this MR description documents the plan-file waiver.
Edited by Hayley Swimelar

Merge request reports

Loading
Loading