fix(realtime): remove NXDOMAIN server override on the 4 /realtime/* operations (GA-CONTRACT-001)

YA
1mo ago
+21-20

User description

Problem

Part of GA gate item CONTRACT-001. The 4 /realtime/* operations (realtimeConnect,
realtimePublish, realtimePresence, realtimeHistory) each carry a per-operation servers
override to the bare host https://realtime.wave.online. That host does not resolve: dig realtime.wave.online @1.1.1.1 and dig realtime.wave.online @8.8.8.8 both return NXDOMAIN
(confirmed 2026-09-28). Any client that honors OpenAPI's per-operation servers field (as it is
required to) will construct an unreachable URL for these four operations.

Root cause

The override was correct when it was written, for a design that was never built: a standalone
realtime edge host, separate from the gateway. What actually shipped (wave-gateway
src/realtime-channel.ts) serves these four operations THROUGH the gateway itself, at
https://api.wave.online/v1/realtime/connect, /v1/realtime/channels/{channel}/publish, etc.
The gateway authenticates the caller, meters the call, and only then forwards internally — with
an injected shared secret — to the real edge worker at https://rt.wave.online (a different
host than the one this spec named, and one a public caller can never reach directly: the edge
worker validates the internal secret and would refuse a direct hit).

Live-probed against the deployed gateway (commit b7b0dd062, 2026-09-28):
https://api.wave.online/v1/realtime/connect etc. answer correctly (402/401 depending on auth
state — never NXDOMAIN); https://realtime.wave.online/... cannot be reached at all.

Each operation's description also named the internal, post-rewrite edge path ("the real path
is /v1/connect?channel=<id>") — accurate about what the gateway forwards to internally,
misleading as guidance to a caller of this contract, who should call the documented
/v1/realtime/* path exactly as declared and never needs to know the internal forward target
exists.

Fix

  • Removed the servers: [{ url: https://realtime.wave.online }] override from all four
    operations (/realtime/connect GET, /realtime/channels/{channel}/publish POST,
    /realtime/channels/{channel}/presence GET, /realtime/channels/{channel}/history GET).
    With no per-operation override, each now resolves against the document's default server
    (https://api.wave.online/v1) like every other /v1 route — matching what is actually
    deployed.
  • Removed the "the real path is /v1/connect..." / /v1/channels/{channel}/... sentences from
    each operation's description — that internal detail is not this contract's concern and was
    actively misleading (a caller who followed it would hit the WRONG path, since the gateway's
    own route table expects /v1/realtime/channels/{channel}/publish, not /v1/channels/{channel} /publish).
  • Updated the Realtime tag's top-level description (previously "Served at realtime.wave.online
    (not the api host)") to state the real, current shape: served through the gateway at
    /v1/realtime/*.
  • Added an inline comment at the top of the four operations naming the NXDOMAIN finding and the
    date, so a future reader does not have to re-derive why the override is absent.

No schema, parameter, response, or operationId changed on any of the four operations — this is
strictly a servers/description correction. 232 paths, unchanged path count.

Test plan (local — CI is billing-blocked org-wide, ignored per operator instruction)

$ npx redocly lint openapi.yaml
openapi.yaml: validated in 238ms
Woohoo! Your API description is valid.
You have 58 warnings.

$ node --test "scripts/ga/**/*.test.mjs"
# tests 35
# pass 35
# fail 0

Zero new lint warnings. Diffed against a clean origin/main (3bed828) baseline copy of
openapi.yaml, linted standalone: identical 58 warnings, byte-identical warning list (all
pre-existing no-unused-components notices unrelated to this change). The 35/35 GA test suite
result is unchanged before and after this diff (these tests exercise the contract-drift /
compat-check machinery, not the realtime paths specifically, but a clean pass with the edited
spec confirms nothing downstream broke on the schema).

Manual verification the fix matches reality:

$ dig realtime.wave.online @1.1.1.1 +short   # (before and after this diff — unrelated to the fix)
# (empty — NXDOMAIN)
$ dig rt.wave.online @1.1.1.1 +short
172.66.40.86
$ curl -s -o /dev/null -w '%{http_code}\n' https://api.wave.online/v1/realtime/connect?channel=x
402   # or 401, depending on live auth state — never a connection failure

Companion PR (different repo)

wave-av/wave-gateway#1912 (branch fix/ga-contract-001) — the primary CONTRACT-001 fix
(8 dead-advertised-family routes no longer generate MCP tools/route-table entries; 5
gateway-native routes answer 401 instead of a stray 404 to a keyless caller). This api-spec fix
is independent and additive: wave-gateway vendors api-spec at a pinned SHA
(vendor/api-spec/pin.json, currently 963712a), so this change does not take effect at the
live gateway until a future npm run spec:sync bumps that pin — tracked separately, not part of
either PR's diff.

Deploy / rollback / live-proof (for the later authorized ship step — NOT run by this worker)

This repo publishes a document, not a running service — "deploy" here means merging to main
so downstream consumers (wave-gateway's spec:sync, SDK codegen, doc sites) can pick up the new
pin on their own schedule. No live traffic changes the moment this merges.

# "deploy" = merge to main (operator-authorized only)
gh pr merge <this-pr-number> --repo wave-av/api-spec --squash

# rollback = revert the merge commit
git revert -m 1 <merge-sha>

# live proof after a downstream consumer (e.g. wave-gateway) re-pins and deploys:
curl -s https://api.wave.online/openapi.json \
  | jq -r '.paths["/realtime/connect"].get.servers // "none (uses default server — correct)"'
# expect: "none (uses default server — correct)", not "https://realtime.wave.online"

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com


[!NOTE]
Cursor Bugbot is generating a summary for commit f2aadf14886222396e6496b7826fafeb91af3b1e. Configure here.


CodeAnt-AI Description

Route realtime API clients through the reachable gateway endpoints

What Changed

  • Realtime WebSocket, publish, presence, and history operations now use the document’s default gateway server instead of the unreachable realtime.wave.online host
  • Realtime documentation now directs callers to /v1/realtime/* gateway routes and removes internal forwarding paths that could lead clients to incorrect URLs

Impact

✅ Reachable realtime API requests
✅ Fewer failed realtime connections
✅ Clearer client integration guidance

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.