Skip to content

chore(router): #684 follow-ups — DRY consolidations + docs-api guard over caching/PPR skills - #686

Merged
ivogt merged 2 commits into
mainfrom
chore/684-audit-followups
Jul 5, 2026
Merged

ivogt merged 2 commits into
mainfrom
chore/684-audit-followups

Conversation

@ivogt

@ivogt ivogt commented Jul 5, 2026

Copy link
Copy Markdown
Collaborator

Closes out groups A (DRY consolidations) and D (tooling) of #684. Chore-class PR: no consumer-visible behavior change; cache key strings and warning text are byte-identical to before.

Problem statement

The #685 audit wave landed three new code sites that each correctly mirrored an established idiom inline (blocked-redirect landing, host-namespaced cache key, once-per-namespace warn). Idioms copied inline drift; #684-A asks for one owner each. Separately (#684-D), the caching/PPR skills teach API surface with no existence guard — the render-callable cacheTag() drift (plan 003) recurred silently because check:docs-api only covered README + why-rango.

Changes

  1. safeSameOriginLanding(basename) — new in src/redirect-origin.ts beside the two resolvers. rsc/redirect-guard.ts:82 and resolveShellHitRedirectTarget (rsc/rsc-rendering.ts) now share the one "where does a blocked redirect go" answer.

  2. cacheKeyBase(host, pathname, searchParams?, params?) — new in src/cache/cache-key-utils.ts (the module that already owns the sort helpers). cache-scope.ts dropped its private getCacheKeyBase; document-cache.ts dropped its inline default-key template. Both tiers now compose ${host}${pathname}[:params][?search] from the one function; the JSDoc pins the byte-stability contract (changing the composition silently invalidates every persisted entry). The consumer keyGenerator branch is untouched.

  3. CFCacheStore.warnOncePerNamespace(seen, message) — private method collapsing the three open-coded namespace ?? "default" + Set dances (no-KV read invalidation, tagInvalidationTtl floor, no-TTL marker growth).

  4. check:docs-api now guards the 8 caching/PPR skills (cache-guide, caching, defer-hydration, document-cache, ppr, prerender, shell-manifest, use-cache). The shakedown immediately caught two things:

    • a real guard false-negative: class declarations sit in none of the definition-ish positions the regex matched, so Skip (src/errors.ts:267, taught by the prerender skill) MISSed. Added a class <name> alternation.
    • createHydrationGate — a suggested userland factory name in the defer-hydration recipe, allowlisted like the existing withCaching/withAuth.

    Guard now verifies 167 identifiers (was 68 over the two positioning docs).

Internal docs updated in the same PR: feature-map.md + feature-file-map.md (three shared redirect-origin rules; cache-key-utils.ts added to the Cache APIs row).

Deliberately unchanged

Case Disposition
Cache key strings (both tiers) Byte-identical; verified by the composition (params infix only ever produced by the segment tier) + existing key tests
keyGenerator document-cache branch Untouched — consumer generators own their namespacing
Warn-once emitters → structured diagnostics (#684-A4) Blocked on #651/#652; migrate all six as one batch there
warnedNullCaptures/warnedRefusedCaptures (shell-capture) Different once-guard shape (per-key, not per-namespace) — not folded

Test plan

  • pnpm run typecheck clean
  • pnpm run test:unit:all — all packages pass (router 108 targeted: document-cache, cf-cache-store-tags, shell-hit-redirect-guard; full recursive run green)
  • pnpm run lint (oxlint --deny-warnings) 0/0
  • pnpm run format clean on all touched files
  • node tools/check-docs-api.mjs — 167 identifiers verified
  • No new tests: pure consolidation; existing suites pin the behavior (key shapes via document-cache/cache-scope tests, landing via shell-hit-redirect-guard.test.ts + redirect-guard suites, warn-once via cf-cache-store-tags.test.ts)
  • No route changes → no *.gen.ts churn (verified git status empty of .gen.ts)

Notes

Groups B and C of #684 are reported on the issue directly: B (shell-HIT redirect flip e2e) is not deterministically reachable through real routing — analysis with path:line evidence in the issue comment; C investigations ran as five independent read-only agents, verdicts posted there.

…red cache key base, CFCacheStore warn-once, docs-api guard over caching/PPR skills

Issue #684 groups A (DRY consolidations) and D (tooling):

- safeSameOriginLanding() in redirect-origin.ts: the one answer to "where
  does a blocked redirect go"; redirect-guard.ts and
  resolveShellHitRedirectTarget (rsc-rendering.ts) now share it.
- cacheKeyBase() in cache-key-utils.ts: the one host-namespaced
  ${host}${pathname}[:params][?search] composition; cache-scope.ts
  (segment tier) and document-cache.ts (document tier) both ride it.
  Output byte-identical to both prior inline shapes.
- CFCacheStore.warnOncePerNamespace(): collapses the three open-coded
  once-per-namespace warn dances (no-KV read invalidation, TTL floor,
  no-TTL marker growth).
- check:docs-api now also guards the 8 caching/PPR skills (cache-guide,
  caching, defer-hydration, document-cache, ppr, prerender,
  shell-manifest, use-cache) — the cacheTag() render-callable drift
  class (plan 003). Shakedown found and fixed a guard false-negative:
  class declarations (e.g. errors.ts Skip) matched no definition-ish
  position; createHydrationGate allowlisted as a userland recipe name.
@pkg-pr-new

pkg-pr-new Bot commented Jul 5, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@rangojs/router@686

commit: 4010cc2

@ivogt
ivogt merged commit 38606cb into main Jul 5, 2026
34 checks passed
@ivogt
ivogt deleted the chore/684-audit-followups branch July 5, 2026 14:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant