Skip to content

feat(obs): middleware mints X-Request-Id + runtime trust-gate spec#183

Merged
operatoruplift merged 1 commit intomasterfrom
request-id-runtime-test
Apr 27, 2026
Merged

feat(obs): middleware mints X-Request-Id + runtime trust-gate spec#183
operatoruplift merged 1 commit intomasterfrom
request-id-runtime-test

Conversation

@operatoruplift
Copy link
Copy Markdown
Owner

Closes the last trust-gate gap

The source-level trust-gate (#167-#174) confirmed every route file imports withRequestMeta. But there was a hidden gap: the middleware at middleware.ts intercepts every /api/* request first, and its 401 "Authentication required" response went out without an X-Request-Id header.

A user calling any auth-gated route without a token got a 401 with no request ID, breaking the support-debug contract.

Two changes

middleware.ts

  • Mints req_<uuid> if the incoming request doesn't already carry an X-Request-Id, otherwise propagates.
  • Attaches the ID to:
    • the 401 unauthorized response (header + body envelope)
    • every pass-through (forwarded as a request header so the downstream route's withRequestMeta reads the same value — IDs are now stable end-to-end)
  • The 401 body carries requestId + timestamp matching the canonical envelope shape.

tests/e2e/request-id-runtime.spec.ts (new — 16 probes)

Probes representative endpoints anonymously and asserts each response carries X-Request-Id matching ^req_[0-9a-f-]+.

Covers all four response shapes:

  • 200 success: capabilities, providers, sns.resolve, health.adapters, health.llm
  • 401 middleware-block: whoami, dashboard.stats, receipts.public-key, subscription POST, x402, tools.web, tools.notes, access.check, risk
  • 400 validation: waitlist, auth.login
  • 410 gone: subscription fall-through, x402 charge

.github/workflows/ci.yml

request-id-runtime.spec.ts joins the hermetic spec list. Future middleware regressions that drop the header now fail CI before merge.

Trust-gate at both layers

  • Source (pnpm check::trust-gate): 44/44 routes import @/lib/apiHelpers
  • Runtime (this spec): 16/16 representative endpoints emit X-Request-Id

Verified

pnpm exec tsc --noEmit
# exit 0

pnpm check
# 3 passed, 0 failed
# trust-gate: clean. 44/44 route files import @/lib/apiHelpers...

pnpm exec playwright test tests/e2e/request-id-runtime.spec.ts --reporter=list
# 16 passed (25.9s)

Net diff

3 files changed, 136 insertions(+), 7 deletions(-)

Rollback

Single git revert. Note: rolling back re-introduces the middleware 401 gap; investigate before reverting.

The middleware was a hidden gap in the trust-gate contract. Source
trust-gate (#167-#174) confirmed every route file imports
withRequestMeta. But the middleware in middleware.ts intercepts every
/api/* request first, and its 401 "Authentication required" response
went out without an X-Request-Id header.

Two changes:

## middleware.ts
- Mints `req_<uuid>` if the incoming request doesn't already carry an
  X-Request-Id, otherwise propagates.
- Attaches the ID to:
  - the 401 unauthorized response (status, body envelope, header)
  - every pass-through (forwarded as a request header so the route
    handler's `withRequestMeta` reads the same value)
- The 401 body now also carries `requestId` and `timestamp` to match
  the canonical envelope shape.

## tests/e2e/request-id-runtime.spec.ts (new)
- 16 probes against representative endpoints, all four response
  shapes (200 success, 401 middleware-block, 400/410/403 handler
  envelopes).
- Each asserts `X-Request-Id` is present and matches `^req_[0-9a-f-]+`.
- Picked endpoints to cover: public (capabilities, providers,
  sns.resolve, health.adapters, health.llm, waitlist, auth.login),
  auth-gated (whoami, dashboard.stats, receipts.public-key,
  subscription, x402, tools.web, tools.notes, access.check, risk).

## .github/workflows/ci.yml
- request-id-runtime.spec.ts joins the hermetic spec list, so a
  middleware regression that drops the header fails CI before merge.

Trust-gate is now enforced at BOTH layers: source (every route file
imports the helper) and runtime (every response carries the header).

## Verified

- pnpm exec tsc --noEmit: clean
- pnpm check: 3 passed, 0 failed
- pnpm exec playwright test request-id-runtime.spec.ts: 16/16 pass

## Rollback

Single git revert. Three files.
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website Ready Ready Preview, Comment Apr 27, 2026 4:50pm

@operatoruplift operatoruplift merged commit d7569f5 into master Apr 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant