isRetryableStatus used an unbounded status >= 500, so a garbage status like
1000 landed in the retryable bucket. This function is the sole gate the
client and HTTP transport trust for retry safety, and an out-of-range value
must fail closed. Bounded on both sides.
408 Request Timeout was non-retryable while the same file documented
transport as covering "connection, timeout, 5xx" - a genuine timeout
surfaced as 408 was classified differently from the identical timeout
surfaced as 504. Now retryable.
There was no code for "the callee answered but not with a ServiceResult" - a
proxy's HTML error page, a truncated body. Task 8 was already papering over
it by hand-setting retryable: false beside a transport code that
retryableFor says is always retryable, which is exactly how the two drift
apart. Added RPC_MALFORMED and made that path use failure() so retryability
is derived from the code rather than written next to it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
no-explicit-any is off repo-wide in eslint.config.js, so the disable comment
the plan mandated is itself an unused-directive warning. The test's schema
binding also needs the _ prefix the lint config requires for a value read
only via typeof.
Separately: bun test strips type-only imports before resolution, so the
red-first step does not reproduce for type-only tests. Recorded so later
implementers do not chase it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Eleven TDD tasks covering phase 1: contract and immutable procedure builder,
error classification, the signed subject-context token, the Transport seam
with an in-process transport for tests, implement() with fail-closed identity
and permission checks, the typed client proxy, the HTTP transport, router
discovery of app/services, and the mounted endpoint with its two independent
external-access guards.
Phases 2-4 (retry and circuit breaking, app-to-app streaming, identity for
pubsub and queue) are documented as deferred with the reason each needs its
own design pass.
Task 10 is called out as the highest-risk: if /__wrnexus/rpc/* is reachable
from the public internet, every permission check in the workspace is
bypassable, so the plan requires the gateway block and the app-side check to
be verified as working independently of each other.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>