- Resolve RPC call origins via a new WRNEXUS_INTERNAL_ORIGINS map (loopback
origins the gateway hands each child before spawning it), falling back to
the public appOrigin only when it is absent. Calls previously always went
to the public gateway origin, which the gateway unconditionally 404s on
the RPC prefix by design — every real cross-app call failed.
- Stop loadServices() from running ahead of routing and stop memoizing a
rejected load: one bad file under app/services/ no longer permanently
breaks every route in the app. A failed load logs loudly, is retried on
the next RPC request, and the RPC path gets a structured RPC_UNKNOWN
instead of an unhandled throw.
- Reject a service whose contract.name does not match the filename it is
mounted under, naming both, instead of silently mounting under the
filename while the typed client calls by contract name.
- Let ServiceError accept an explicit retryable and have the client pass the
wire value through, instead of recomputing (and silently flipping) it from
the error code alone.
- Document the gateway/X-Forwarded-* deployment requirement in the RPC
README.
Each of the three code blockers has a new/extended test that was verified to
fail when its fix was reverted (rpc/test/integration.test.ts,
dev-server/test/rpc-services-loading.test.ts).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds examples/auth-showcase/app/services/greeter-client.ts so the showcase
demonstrates both halves - the review noted the example was callee-only, so a
developer had no working reference for making a call.
Raises integration coverage to the planned 3 tests and adds the missing
rpc-endpoint cases. Also wires the prod build path for services.
304 tests pass across rpc/router/dev-server/cli; typecheck, lint, format and
check:public-api all clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Critical:
- router: fail loudly (WRN-SERVICE-COLLISION) when two app/services files
scan to the same service name, instead of silently letting directory-walk
order pick a winner.
Important:
- server.ts: wrap a throwing input schema so its raw message cannot escape
invoke(); returns RPC_INVALID and logs server-side instead.
- client.ts: race timeoutMs against transport.call so a stalled transport
cannot hang the caller; rejects with a ServiceError(RPC_TRANSPORT).
- client.ts: the proxy returns undefined for undeclared properties (incl.
then/catch/finally) instead of a function that throws, closing the
await-client thenable trap.
- gateway.ts / rpc-dispatch.ts: import RPC_PATH_PREFIX / RPC_INTERNAL_HEADER
from @wrnexus/rpc instead of hardcoding local copies.
- gateway.test.ts: cover the RPC-prefix edge block and internal-header
stripping across casing variants.
- http.test.ts / client.test.ts: cover anonymous-call header omission, the
internal marker, the retryable-status sweep, network/malformed/HTML
failures, AbortSignal propagation, the timeout path, and timer cleanup.
Minor:
- transport.ts: Object.hasOwn for handler lookup; note the entry-only abort
check.
- client.ts: wrap a missing/invalid WRNEXUS_RPC_SECRET as a ServiceError
(RPC_IDENTITY) instead of a bare Error.
- rpc/package.json: drop the unused @wrnexus/authz dependency.
- server.ts: implement() now throws at construction time if a declared
procedure has no own handler.
Verified: reverting the service-collision check and the client timeout race
each make their new test fail, then restore green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
C1 CRITICAL: implement() looked up procedures/handlers with plain property
indexing, so any Object.prototype member name (constructor, toString, etc.)
resolved truthy and skipped the permission gate entirely. Fixed with
Object.hasOwn checks in packages/rpc/src/server.ts. Defense-in-depth guard
added in packages/dev-server/src/rpc-dispatch.ts constraining URL path
segments to a safe charset before they reach service/procedure lookups.
Added missing direct test coverage for packages/rpc/src/transport.ts,
server.ts and client.ts (previously untested), including a prototype-name
sweep in both server.test.ts and dev-server's rpc-endpoint.test.ts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>