PR: #364: feat(otel): delete homegrown correlation_id (cid) from app source [Story-1457] by @ankitmaheshwari-com
View PR →
Story 1457 · EPIC-1400 Observability trace graph migration (Phase-2) · R7e

APP-RIP: delete the homegrown correlation_id (cid) from pramaan-app

Founder decision (2026-06-19, EPIC-1400): retire the homegrown correlation_id and standardize request identity on the W3C / OTel trace_id / traceparent, with the Atlas run_id preserved as the business key on a separate axis. Story-1454 (R7b, merged) repointed the browser + server consumers to trace_id and deleted the cid components — but it left the core cid module (src/lib/correlation.ts) and its AsyncLocalStorage companion (correlation-context.ts) in place because several server paths still imported them. This Story finishes the rip-out: strip the residual cid stamping/logging from those consumers, relocate the one non-cid export they shared, and delete the two cid modules and their tests.

1 — What was still alive after Story-1454

A grep for correlation across src/ showed cid was not dead — it was still load-bearing:

The one subtlety: correlation.ts also exported REQUEST_ROUTE_HEADER (x-pramaan-route) — a sanitized-path request header that is not a cid concept and is still needed by proxy.ts, the workspace layout, and outbound-headers.ts. Deleting correlation.ts required giving that constant a clean new home first.

2 — Changes

FileChange
src/lib/request-route.tsnew Houses REQUEST_ROUTE_HEADER — the non-cid route-label header, with a doc note that it is not a tracing/identity primitive.
src/lib/correlation.tsdeleted The cid core (header const, UUIDv4 validate/mint/resolve).
src/lib/correlation-context.tsdeleted Dead AsyncLocalStorage cid context (no writer).
src/lib/outbound-headers.tsRemoved cid resolution + x-pramaan-correlation-id stamping and the correlationId field on OutboundRequestContext. The Bug-1471 active-span traceparent path is untouched.
src/lib/gateway.tsDropped correlationId from the destructure, the two log helpers, and all five call sites.
src/lib/server-auth.tsRemoved the cid resolution block from the currentUser failure path (and the now-unused next/headers import).
src/app/api/health/route.tsNow a bare { ok: true } liveness response — no cid echo.
src/lib/proxy-observability.tsRemoved the optional correlationId log field from ProxyLogInput and both log lines.
src/gen/_assert.tsRemoved correlation_id from ContractContext and the violation log (hand-authored helper, not a generated DTO).
proxy.ts, layout.tsxRe-import REQUEST_ROUTE_HEADER from @/lib/request-route.
bridge.ts, public-bridge.ts, trace.ts, kubb-client.ts, logger-browser.ts, pramaan-diagnostics.ts, trace-reference.tsxComment-only: fixed now-stale notes that claimed cid is still minted/stamped, and dropped the literal correlation from accurate historical notes (repo hygiene).
testsDeleted correlation.test.ts + gateway-correlation.test.ts (pure-cid behavior). Stripped cid from outbound-headers, trace-propagation-paths, gateway, proxy-observability, bridge, public-bridge, proxy-trace tests; kept the traceparent assertions and the proxy.test.ts "cid no longer stamped" regression.

3 — What was deliberately NOT touched

The Bug-1471 connected-graph path

outbound-headers.ts still injects the active @vercel/otel span via the installed W3C propagator (injectActiveTraceContext) so the forwarded traceparent (id A) is the same span exported to X-Ray — the join that makes pramaan-app-api land on the SAME trace. The kill-switch (PRAMAAN_OTEL_DISABLED) strip and the tracestate carry are unchanged. trace_id / span_id and run_id are untouched.

The generated backend contract mirror

src/gen/{zod,types,schemas} still carry HealthResponse.correlation_id. That field mirrors the backend contract (openapi/app-api.json still defines it) and is regenerated by codegen — per HR-22 + openapi/AGENTS.md it must not be hand-edited. Its removal is the separate pramaan-functions cid rip-out child (EPIC-1400 Phase-2), after which a mirror-sync + pnpm codegen drops it from the app. It is the only remaining correlation hit in src/, and it is backend-owned by design.

4 — Verification

# grep-zero cid in app source (only the generated backend mirror remains)
grep -rniE 'correlation' src/ | grep -v 'src/gen/'   # -> ZERO
grep -rniE 'correlationId|x-pramaan-correlation-id' src/   # -> ZERO

pnpm typecheck   # tsc --noEmit, exit 0
pnpm lint        # 0 errors (1 pre-existing img warning, unrelated)
pnpm test        # 93 files / 522 tests passed
pnpm build       # exit 0
git diff --check  # clean

Acceptance criterion "grep-zero cid in app" is met for all hand-authored app source; the lone residual is the generated backend mirror, owned by the functions cid rip-out + codegen sync.

Files changed

32 file(s), +77 / -740 lines

Path Role + -
openapi/app-api.jsonConfig+0-12
src/app/[locale]/(workspace)/clients/clients-client.test.tsxApp route+0-2
src/app/[locale]/(workspace)/layout.tsxApp route+1-1
src/app/api/health/route.tsApp route+2-14
src/components/trace-reference.tsxComponent+2-2
src/gen/_assert.tsGenerated contract+0-2
src/gen/schemas/healthResponse.jsonGenerated contract+0-5
src/gen/types/HealthResponse.tsGenerated contract+0-4
src/gen/zod/healthResponseSchema.tsGenerated contract+0-7
src/lib/bridge.tsLibrary+2-2
src/lib/correlation-context.tsLibrary+0-36
src/lib/correlation.tsLibrary+0-69
src/lib/gateway.tsLibrary+7-15
src/lib/kubb-client.tsLibrary+2-2
src/lib/logger-browser.tsLibrary+2-1
src/lib/outbound-headers.tsLibrary+13-35
src/lib/pramaan-diagnostics.tsLibrary+2-2
src/lib/proxy-observability.tsLibrary+0-13
src/lib/public-bridge.tsLibrary+2-2
src/lib/request-route.tsLibrary+12-0
src/lib/server-auth.tsLibrary+0-11
src/lib/trace.tsLibrary+1-3
src/proxy.tsSource+3-3
tests/unit/bridge.test.tsTest+0-39
tests/unit/lib/correlation.test.tsTest+0-137
tests/unit/lib/gateway-correlation.test.tsTest+0-132
tests/unit/lib/gateway.test.tsTest+4-36
tests/unit/lib/outbound-headers.test.tsTest+2-68
tests/unit/lib/proxy-observability.test.tsTest+0-8
tests/unit/lib/trace-propagation-paths.test.tsTest+15-40
tests/unit/proxy-trace.test.tsTest+4-5
tests/unit/public-bridge.test.tsTest+1-32