Repository navigation
Closed
Description
Split from #572. The Security defense-in-depth section of #572 was resolved by #580 (open-redirect guard, hardened during review to an unforgeable out-of-band brand + http(s)-only external validation; fail-closed origin guard; decode-error leak removed; the PE-decode-reject item declined as a false positive and the action-ownership item deferred — both documented). This issue tracks the remaining lower-severity items from #572 that #580 did not touch.
@rangojs/router/testing refinements
- medium —
dispatch()json route lacks the nested-Promise guard production enforces.src/testing/dispatch.tsstill does a bareJSON.stringify(result)(~L180); production (src/rsc/response-route-handler.ts) uses a replacer that throwsRESPONSE_NOT_SERIALIZABLEon a nested unresolved promise. Adispatchjson test of() => ({ data: fetchSomething() })(forgotten await) goes green while production would 500. Reuse production's replacer sodispatchrejects exactly as production does. (Not touched by feat(testing): #542 capability + coverage polish for @rangojs/router/testing #581.) - low —
dispatchresolves cache config withexecutionContext=undefined, diverging from production.src/testing/dispatch.ts. (Not touched by feat(testing): #542 capability + coverage polish for @rangojs/router/testing #581.) - low (verify) —
renderToFlightString/renderServerTreescoped route map. feat(testing): #542 capability + coverage polish for @rangojs/router/testing #581 added arouteNameoption but not a scopedrouteMap;setRequestContextParamsstill rebuildsctx.reverseagainst the global route map, so a server component that reverses stays order-dependent on whatever router registered last. Add arouteMapoption (likerenderHandler) or document.src/testing/flight.ts. - low (verify) —
renderRoutestill stamps synthetic ids onto the consumer's handle object. feat(testing): #542 capability + coverage polish for @rangojs/router/testing #581 addedcloneHandleSeedfor the seed maps, butensureSyntheticIdstill writeshandle[field] = idonto the passed object. Confirm no consumer-owned loader/locationState/handle object is mutated; clone before stamping if it is.src/testing/render-route.tsx.
Cross-seam
- low — Prerendered route served on a prerender hit never records its
cache({ tags })into the document tag union.src/cache/.../cache-lookup.ts. - low — Document-cache tag union can miss first-write segment-DSL tags when combined with proactive/background segment caching (documented caveat; the proactive path widens the window).
Self-review
- low —
loaderParentIdregex residual edge for a slot name matchingD<digits>.(e.g.@D3.foo).src/segment-system.tsx. Pathological, but could be hardened by validating slot names at definition time.
File/line references are from the #572 audit; re-confirm against current main before fixing (the codebase moved with #580 and #581).
Metadata
Metadata
Assignees
Labels
No labels
Activity
ivogt commentedon Jun 14, 2026
PR #583 (open) addresses the first two
@rangojs/router/testingitems:dispatch()json nested-Promise guard — extracted production's replacer into a sharedrsc/json-route-result.ts(lightweight, to avoid draggingresponse-route-handler's virtual-module graph into the testing bundle);dispatchnow 500s on a forgotten await exactly like production.routeMapforrenderToFlightString/renderServerTree— added arouteMapoption (mirroringrenderHandler) soctx.reverse()is no longer order-dependent on the global map.Re-verified the other two testing items against current
main:renderRoutesynthetic-id stamping: already addressed by feat(testing): #542 capability + coverage polish for @rangojs/router/testing #581 — a stablesyntheticIdsWeakMapmakes the id idempotent andrender-route.tsxnow documents the input-mutation contract. Cloning a handle risks breaking method/identity, so the documented-mutation approach stands. Considering this done.dispatchexecutionContext=undefined: correct for an in-process harness (no platform execution context exists); leaving as-is.Still open here: the cross-seam (prerender tag-union) and self-review (
loaderParentIdregex) items.fix(testing): dispatch json nested-Promise guard + scoped routeMap fo…
fix(testing): dispatch json nested-Promise guard + scoped routeMap fo…
ivogt commentedon Jun 16, 2026
Status after #583:
Resolved:
dispatch()JSON nested-Promise guard.routeMapforrenderToFlightString/renderServerTree/renderHandler.dispatchexecutionContext=undefinedis intentional for the in-process harness.renderRoutesynthetic-id stamping is handled/documented by feat(testing): #542 capability + coverage polish for @rangojs/router/testing #581.Still tracked here:
_requestTags, butPrerenderEntrycurrently carriessegments/handles, so a document-cache entry built on top of a prerender hit can be untagged.loaderParentIdhas a low-severity regex edge for slot names like@D3.foo; the current fix handles names like@Detail, but theD<digits>.pattern can still match inside a user-controlled slot name.The first-write segment DSL tag-union caveat looks stale on current
main:CacheScope.cacheRoute()records resolved DSL tags early, and document cache drains the render stream before snapshotting_requestTags. Leaving that as verify-only unless there is a concrete repro.fix(testing): #582 dispatch() json route enforces the forgotten-await…
fix(testing): #582 close three @rangojs/router/testing fidelity gaps …
fix(router): #582 reject "." in slot names + document prerender tag-u…
fix(router): #582 reject "." in slot names + document prerender tag-u…
fix(cache): #582 record route-level cache({ tags }) into the document…
fix(cache): #582 record route-level cache({ tags }) into the document…
ivogt commentedon Aug 30, 2026
Remaining items from the last status comment are done or declined.
@rangojs/router/testing: nested-Promise JSON guard and scopedrouteMaplanded in fix(testing): dispatch json nested-Promise guard + scoped routeMap for flight primitives (#582) #583 (src/rsc/json-route-result.ts,src/testing/flight.ts).renderRoutesynthetic-id stamping is the documented WeakMap contract from feat(testing): #542 capability + coverage polish for @rangojs/router/testing #581.dispatchexecutionContext=undefinedis intentional for the in-process harness.loaderParentId@D3.fooedge:assertValidSlotNamerejects.at definition time (src/route-definition/dsl-helpers.ts);loaderParentIdstrips/D\d+\..*$/(src/segment-system.tsx). Pinned insrc/__tests__/urls.test.tsx._requestTags: declined as intentional indocs/prerender-api-design.md— a prerender hit does not record runtimecache({ tags })into the document union.