You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
0.0.7 normative scope amendment — 2026-08-13. RFC 0001 Stage 3 supersedes the pinned 1.14.15 acceptance row below. This issue keeps one fetch/retry/dedupe/trace transport path,
proves unary and reconnect semantics plus header-safe dedupe, and documents/deprecates the current
no-op port/timeout options. Any dependency move is a separate whole-family, lock-only
decision targeting stable v1.15.0 with frozen-install and no-mixed-version evidence. No oRPC v2
migration and no exact manifest pins land here.
Summary
NetScript's HTTP transport policy — which procedures are GET, and which requests are deduplicated
and cached — is three literals sitting inside createHttpClientLink. oRPC v2 is in public beta and
its main branch already carries feat(rpc): restrict RPC handlers to POST, PUT, PATCH and DELETE by default plus a MethodOverrideHandlerPlugin. Once #1349 makes the link publicly composable, that
policy becomes observable to every contribution and every app, and the v2 migration stops being a
one-function change. Consolidating it behind one NetScript-owned function now is cheap; doing it
after a public extension seam exists is not.
Evidence
Corpus: research/external/orpc.md §0 (v2 beta dist-tag 2.0.0-beta.25; the two v2 commits
verified absent from the 1.14.15 tarball), §6 "Upgrade implications" — "Plan the remediation so
the transport policy lives behind one NetScript-owned function, not scattered across link
construction — otherwise the v2 migration touches every client call path"; research/repo-audit/services-sdk.md §0, §3.1, gap register S21/S22.
Source at baseline fac9e339042c (re-verified for this draft):
packages/sdk/src/client/http-client-link.ts:17,82 — inferRPCMethodFromContractRouter is
imported from @orpc/client and applied inline as method:. Repo-wide, grep -rn 'inferRPCMethodFromContractRouter\|StrictGetMethodPlugin\|fallbackMethod' packages plugins
returns only these two lines — there is no owned policy function anywhere.
packages/sdk/src/client/http-client-link.ts:109 — filter: ({ request }) => request.method === 'GET', i.e. the dedupe policy re-derives the method
decision from the wire instead of from the contract.
packages/sdk/src/client/http-client-link.ts:110-125 — the force-cache group condition is a
second, independent literal keyed off context?.cache.
packages/sdk/src/client/http-client-link.ts:103-107 — ClientRetryPlugin default frozen at retry: 0; research/repo-audit/services-sdk.md §3.2 lists the three upstream client plugins
(BatchLinkPlugin, RetryAfterPlugin, SimpleCsrfProtectionLinkPlugin) that are unreachable.
packages/sdk/src/desktop/application/desktop-rpc-client.ts:18-20 — the second transport makes
its own independent decisions (customJsonSerializers), so there is already policy divergence
across two links with no shared source of truth.
Version state: deno.json:215-221 pins ^1.14.6 (@orpc/otel^1.14.7); deno.lock resolves 1.14.6, which drags @orpc/shared@1.14.6and@orpc/shared@1.14.7 into one graph — a
known instanceof ORPCError hazard the pinned client already ships a Symbol.hasInstance
workaround for (research/external/orpc.md §6).
Current surface
Three coupled decisions with no owner: the contract-derived method, the GET-only dedupe filter, and
the force-cache grouping. They are consistent today only because one function wrote all three. A
consumer reading the SDK cannot discover the policy without reading the link body, and nothing
prevents the desktop link, a future in-process link (#451), or a contribution from disagreeing with
it. deno task deps:latest reports all seven oRPC packages at 1.14.6/1.14.7 → 1.14.15, and the
1.14.6 → 1.14.15 public export list for @orpc/server is byte-identical, so the bump itself is
mechanical.
Target contract
Per RFC-A §3.11:
One exported-internal function — e.g. resolveTransportPolicy(contract, options) — returns the
full policy object: method, fallbackMethod, maxUrlLength, the dedupe predicate, and the
cache-group descriptors. Every link (HTTP, desktop, and any future one) consumes it; no link
re-derives policy from request.method.
The policy is derived from the contract and procedure metadata, not from the wire. When NetScriptProcedureMeta.policy.cache is present (RFC-A §3.6) it is an input to the policy
function, not a second mechanism.
Contributions never observe the HTTP method. They observe procedure path, input, context and
metadata. This is the forward-compat rule that keeps the v2 migration inside one function.
A documented policy-override point exists for the v2 transition (a single transportPolicy?
option, resolved before contributions compose), so MethodOverrideHandlerPlugin-style adaptation
is a config change rather than a code change.
oRPC is bumped 1.14.6 → 1.14.15 and the duplicated @orpc/shared copies collapse to one,
using the .llm/tools/deps/ wrappers rather than hand-rolled registry reads.
Acceptance
The complete @orpc/* v1 dependency family is upgraded together and resolves once at stable
v1.15.0; no v2 API or behavior is introduced.
One NetScript-owned transport-policy function resolves method, cache, retry, dedupe, tracing,
and fetch/link behavior. HTTP and desktop clients consume it without policy literals.
Do not change server-side handler method policy (StrictGetMethodPlugin and friends are
unused today); server-side transport policy is out of scope.
Docs/consumer proof
The SDK reference gains one short "transport policy" section stating where the method and cache
decisions are made and that they are contract-derived — replacing the current situation where the
only answer is "read http-client-link.ts". Consumer proof is the scaffold runtime E2E: the
generated app's showcase calls behave identically before and after, and the pinned-behaviour test
names the exact procedures whose method would change under oRPC v2, so the migration's blast radius
is a list rather than a guess.
Provenance
Seed run plan-fable5-remediation-roadmap--seed, PR #1347, 2026-08-08. Sourced from research/external/orpc.md §0/§6 (the explicit forward-compat recommendation) and research/repo-audit/services-sdk.md (S21, S22); all cited lines re-verified against worktree
baseline fac9e339042c, including the repo-wide grep proving there are exactly two policy call
sites. No GitHub mutation was performed.
Filed from planning seed PR #1347 · source Draft-ID T1-04 · live issue #1351.
Important
0.0.7 normative scope amendment — 2026-08-13. RFC 0001 Stage 3 supersedes the pinned
1.14.15acceptance row below. This issue keeps one fetch/retry/dedupe/trace transport path,proves unary and reconnect semantics plus header-safe dedupe, and documents/deprecates the current
no-op
port/timeoutoptions. Any dependency move is a separate whole-family, lock-onlydecision targeting stable v1.15.0 with frozen-install and no-mixed-version evidence. No oRPC v2
migration and no exact manifest pins land here.
Summary
NetScript's HTTP transport policy — which procedures are GET, and which requests are deduplicated
and cached — is three literals sitting inside
createHttpClientLink. oRPC v2 is in public beta andits
mainbranch already carriesfeat(rpc): restrict RPC handlers to POST, PUT, PATCH and DELETE by defaultplus aMethodOverrideHandlerPlugin. Once #1349 makes the link publicly composable, thatpolicy becomes observable to every contribution and every app, and the v2 migration stops being a
one-function change. Consolidating it behind one NetScript-owned function now is cheap; doing it
after a public extension seam exists is not.
Evidence
research/external/orpc.md§0 (v2betadist-tag2.0.0-beta.25; the two v2 commitsverified absent from the 1.14.15 tarball), §6 "Upgrade implications" — "Plan the remediation so
the transport policy lives behind one NetScript-owned function, not scattered across link
construction — otherwise the v2 migration touches every client call path";
research/repo-audit/services-sdk.md§0, §3.1, gap register S21/S22.fac9e339042c(re-verified for this draft):packages/sdk/src/client/http-client-link.ts:17,82—inferRPCMethodFromContractRouterisimported from
@orpc/clientand applied inline asmethod:. Repo-wide,grep -rn 'inferRPCMethodFromContractRouter\|StrictGetMethodPlugin\|fallbackMethod' packages pluginsreturns only these two lines — there is no owned policy function anywhere.
packages/sdk/src/client/http-client-link.ts:109—filter: ({ request }) => request.method === 'GET', i.e. the dedupe policy re-derives the methoddecision from the wire instead of from the contract.
packages/sdk/src/client/http-client-link.ts:110-125— theforce-cachegroup condition is asecond, independent literal keyed off
context?.cache.packages/sdk/src/client/http-client-link.ts:103-107—ClientRetryPlugindefault frozen atretry: 0;research/repo-audit/services-sdk.md§3.2 lists the three upstream client plugins(
BatchLinkPlugin,RetryAfterPlugin,SimpleCsrfProtectionLinkPlugin) that are unreachable.packages/sdk/src/desktop/application/desktop-rpc-client.ts:18-20— the second transport makesits own independent decisions (
customJsonSerializers), so there is already policy divergenceacross two links with no shared source of truth.
deno.json:215-221pins^1.14.6(@orpc/otel^1.14.7);deno.lockresolves1.14.6, which drags@orpc/shared@1.14.6and@orpc/shared@1.14.7into one graph — aknown
instanceof ORPCErrorhazard the pinned client already ships aSymbol.hasInstanceworkaround for (
research/external/orpc.md§6).Current surface
Three coupled decisions with no owner: the contract-derived method, the GET-only dedupe filter, and
the
force-cachegrouping. They are consistent today only because one function wrote all three. Aconsumer reading the SDK cannot discover the policy without reading the link body, and nothing
prevents the desktop link, a future in-process link (#451), or a contribution from disagreeing with
it.
deno task deps:latestreports all seven oRPC packages at1.14.6/1.14.7 → 1.14.15, and the1.14.6 → 1.14.15 public export list for
@orpc/serveris byte-identical, so the bump itself ismechanical.
Target contract
Per RFC-A §3.11:
resolveTransportPolicy(contract, options)— returns thefull policy object:
method,fallbackMethod,maxUrlLength, the dedupe predicate, and thecache-group descriptors. Every link (HTTP, desktop, and any future one) consumes it; no link
re-derives policy from
request.method.NetScriptProcedureMeta.policy.cacheis present (RFC-A §3.6) it is an input to the policyfunction, not a second mechanism.
metadata. This is the forward-compat rule that keeps the v2 migration inside one function.
transportPolicy?option, resolved before contributions compose), so
MethodOverrideHandlerPlugin-style adaptationis a config change rather than a code change.
1.14.6 → 1.14.15and the duplicated@orpc/sharedcopies collapse to one,using the
.llm/tools/deps/wrappers rather than hand-rolled registry reads.Acceptance
@orpc/*v1 dependency family is upgraded together and resolves once at stablev1.15.0; no v2 API or behavior is introduced.
and fetch/link behavior. HTTP and desktop clients consume it without policy literals.
tracing, fetch, or link plugins.
portandtimeoutremain accepted and deprecated; their no-op/migration behavior is explicitand regression-tested rather than silently removed.
simulation without adopting oRPC v2.
deno why @orpc/sharedproves one resolved copy; root check/test/publish dry-run and thescaffold runtime E2E pass.
Boundaries
it does not perform it.
must additionally prove no contribution can reach the method decision.
BatchLinkPlugin/RetryAfterPlugin/SimpleCsrfProtectionLinkPluginhere — those become reachable through the contribution chain in[sdk-client S3] feat(sdk): expose the typed oRPC client-contribution seam #1349.
deps: collapse to a single Zod instance,0.0.6, blocked) — thatis a different duplicated dependency; this issue's dedup target is
@orpc/sharedonly.policy function, and stays its own issue.
StrictGetMethodPluginand friends areunused today); server-side transport policy is out of scope.
Docs/consumer proof
The SDK reference gains one short "transport policy" section stating where the method and cache
decisions are made and that they are contract-derived — replacing the current situation where the
only answer is "read
http-client-link.ts". Consumer proof is the scaffold runtime E2E: thegenerated app's showcase calls behave identically before and after, and the pinned-behaviour test
names the exact procedures whose method would change under oRPC v2, so the migration's blast radius
is a list rather than a guess.
Provenance
Seed run
plan-fable5-remediation-roadmap--seed, PR #1347, 2026-08-08. Sourced fromresearch/external/orpc.md§0/§6 (the explicit forward-compat recommendation) andresearch/repo-audit/services-sdk.md(S21, S22); all cited lines re-verified against worktreebaseline
fac9e339042c, including the repo-wide grep proving there are exactly two policy callsites. No GitHub mutation was performed.
Filed from planning seed PR #1347 · source Draft-ID T1-04 · live issue #1351.