Skip to main content
Web 1 adds an unprovisioned TanStack Start / Vite+ / Void Worker candidate in apps/web. The candidate builds from the isolated cloudflare/ root; prepare-build.mjs mirrors the owning package manifest there for Void framework detection without loading or renaming Next environment files. Next retains API, satellite URL bridge and service-worker ownership. The seven static public legal documents and two security documents have independently default-off native rendering slices alongside the native GET /__web1 probe. build still builds Next; build:candidate builds the candidate. The retired apps/tanstack-web app remains paused.

Inventory and ownership

apps/web/start-route-manifest.json is generated by bun apps/web/cloudflare/generate-inventory.ts; use --check to detect drift. The committed file contains route-level ownership only; ordinary module edits do not change it. CI generates the full source census with --artifact <output.json> and uploads it as web-start-census for seven days. The artifact inventories pages, API handlers, other handlers, metadata routes, proxy-only satellite bridges, the four Next beforeFiles API rewrites and the root service worker. Every entry has an owner and a native-Start or Next-fallback disposition. The summary object gives reproducible counts. In the CI artifact, for source routes, roots includes the route and inherited layouts/templates. boundaries lists first-party modules containing server actions, after(), connection() and use cache directives in that static import closure. modules records source hashes, imports and signal line numbers. The global proxy/config closure is separate. Workspace source exports are preferred; published dist exports are mapped to source for this census. Unresolved first-party imports stay visible and block declaring a slice native. This is a conservative static inventory, including dynamic imports, rather than a proof that every reachable operation executes on every request. Nonliteral imports, third-party internals, aliases reexporting framework functions, and runtime reachability need slice-specific review before migration. Proxy-only satellite patterns are explicit census entries; review them whenever src/proxy.ts changes. Except for explicitly enabled native legal or security document GET/HEAD requests, the Worker forwards every URL and method to the admitted Next origin, including all /api/*, server-action POSTs, RSC requests, _next assets and /serwist/sw.js. Calendar and Infrastructure API rewrites execute in Next; they are not reimplemented in the candidate. Satellite redirects retain their Next owner. The service worker keeps its existing root scope and /meet and /mail bypasses; Web 1 does not emit a replacement service worker or copy Web’s public assets into the candidate. Scope: Privacy, Terms, Acceptable Use, DPA, SLA, Subprocessors and Community Guidelines at /privacy, /terms, /acceptable-use, /legal/dpa, /legal/sla, /legal/subprocessors, /community-guidelines and their /en/ and /vi/ forms. Each uses the canonical @tuturuuu/legal document as Next, including every section, summary, effective date and counsel-review notice. The package remains framework-independent; Start owns its rendering adapter and reuses the existing React-only legal Markdown renderer. No database, session, server action, after(), connection() or cache-components boundary is imported into that adapter. Inherited Next marketing layouts stay on Next; the candidate uses Start’s static HTML callback to render an accessible document with document navigation and language links. The default streaming transformer injects serialization scripts even without a Scripts component; this static callback intentionally omits that hydration payload and cleans up the SSR state. It deliberately has no hydrated marketing shell or session UI. The manifest remains 838 entries: 10 native-Start and 828 Next-fallback. The two existing security routes are reclassified; the total census stays constant. Native entries retain their original Next source for migration provenance and record nativeSource for the Start adapter. The full census separately records its nativeBoundaries. Nine /[locale] entries count the native documents; the tenth native entry is the probe. English unprefixed aliases do not add census entries. WEB_START_NATIVE_LEGAL defaults to off, independently of candidate admission. Only on enables the 21 exact localized and unprefixed paths. Unset, unknown and off values forward them to the attested Next deployment, preserving path and query. This is the immediate route rollback; disabling WEB_START_CANDIDATE instead closes the entire candidate with 503. No production switch changes here. POSTs, RSC/action/router-prefetch requests, trailing slashes, unsupported locales, APIs, satellite URL bridges and the service worker retain Next ownership. Signed-in legal reads neither inspect nor refresh the session and set no cookies. Native documents are no-store/noindex, use a script-free CSP and expose x-tuturuuu-web-renderer: native-Start; fallback requests expose Next-fallback. The marker is routing evidence, not source identity. The native heads read the canonical marketingSeo copy for all seven legal documents. Next and Start share the framework-free @tuturuuu/utils/common/page-metadata URL and social metadata helper; the existing Next metadata import stays compatible. English aliases canonicalize to the unprefixed URL, Vietnamese to /vi/, with en-US, vi-VN and x-default alternates. Canonical and social URLs remain on https://tuturuuu.com while staging retains noindex, nofollow. The document title applies the shared site title template; social titles use the localized page title. legal-metadata.test.ts compares all 21 actual Start route heads against the seven Next legal layouts’ metadata generators, including title, description, canonical, hreflang, every Open Graph field and Twitter metadata. The emitted Worker suite checks those tags in actual HTML against the canonical message bundles and URL rules, alongside the existing no-egress and cookie-neutrality assertions. Regression coverage: native-legal.test.tsx checks GET/HEAD, rollback, canonical content for all seven documents in both languages, cookie neutrality and fallback boundaries. emitted.runtime.mjs exercises the actual emitted Start renderer and rollback. e2e-wave1-staging/web.spec.ts extends the #7093 acceptance suite with EN/VI reads of all seven public legal documents, robots noindex checks and a signed-in workspace fallback round trip. Shared suite infrastructure is seeded from #7093; reconcile those shared files with that PR when integrating. Other app cases remain owned by #7093.

Native security documents (slice 4)

Scope: /security/policy and /security/bug-bounty, plus their /en/ and /vi/ aliases. WEB_START_NATIVE_SECURITY=off is a separate default-off flag. Only on admits their six exact GET/HEAD paths; unset, unknown and off values immediately restore attested Next fallback with the original query. Legal rendering continues to follow WEB_START_NATIVE_LEGAL independently. Candidate admission and all RSC/action/router-header, method, host and cookie boundaries remain the same. The static adapter reads the existing security-policy and bug-bounty EN/VI namespaces. It preserves every current Next heading, report instruction, scope rule, response commitment, metric, researcher credit and action link. Vietnamese internal links retain /vi/. No Reveal/motion, hydration, session refresh or database access is included. Content is immediately visible under the existing document stylesheet and script-free CSP, with noindex and no-store. This is document styling: Product acceptance of that presentation remains a cutover prerequisite; it does not claim parity with the Next marketing shell. Both page-level Next metadata generators override inherited metadata. The security adapter therefore uses each namespace’s meta copy rather than the bounty layout’s marketingSeo copy. The shared publicHead adapter calls the framework-free page-metadata builder for canonical, hreflang and every social field. security-parity.test.tsx compares actual native route heads with those Next generators and compares the complete rendered text, headings, lists and links with the current Next pages in EN and VI. Only the Next motion wrappers are replaced in the body fixture. A without-fix control must fail when a policy instruction is removed, then pass when restored. native-security.test.ts covers both independent flags, GET/HEAD, every alias, rollback, production-host refusal, candidate admission, cookie neutrality and non-document request fallback. emitted.runtime.mjs extends the actual workerd suite with security-only rendering and security-off/legal-on rollback. e2e-wave1-staging/web.spec.ts adds EN/VI native reads and anonymous reloads. For the second hosted pass, the release owner disables only the security flag and runs the same suite with WAVE1_STAGING_SECURITY_ROLLBACK=confirmed; the rollback case requires both security documents on Next while Privacy remains native. These cases inherit the existing exact-host, distinct-Supabase and egress guards. Listing them or passing policy unit tests is not hosted acceptance.

Staging profile

apps/web/cloudflare/profile.ts declares the exact host web.staging.tutur3u.com, zone tutur3u.com, cookie domain .staging.tutur3u.com, HSTS max-age=31536000, and staging Supabase project fxefojytwimjiqxseqag. There are no wildcard hosts. The checked Void config has no routes, custom domains, schedules or external resource bindings; workers_dev and preview URLs are disabled. No provider resources are created. Requests fail closed unless all of these runtime settings are admitted:
  • WEB_START_CANDIDATE=staging (checked default: off).
  • AUTH_COOKIE_DOMAIN=.staging.tutur3u.com and NEXT_PUBLIC_SUPABASE_URL=https://fxefojytwimjiqxseqag.supabase.co.
  • NEXT_FALLBACK_ORIGIN is one exact HTTPS staging Next deployment origin, with no path, credentials or query. The hostname filter accepts tuturuuu.vercel.app, the tuturuuu-*.vercel.app prefix, or a staging-domain hostname; canonical Tuturuuu hosts are rejected. The Vercel prefix is not bound to our Vercel team, project or deployment ID and does not prove ownership. It has no default. Before forwarding any request, the release owner must verify the exact origin’s Vercel team, project, immutable deployment ID, actual Supabase project, API rewrites and satellite targets. Retain that admission receipt privately and repeat verification when the origin changes.
  • TRUSTED_PROXY_ORIGIN_SECRET must be a staging-only secret of at least 32 characters, shared only by this Worker and its staging Next origin, and distinct from production’s origin-IP-proof secret. No secret is checked in or forwarded as a raw value. Proofs authenticate the IP and timestamp, without binding the environment, host or audience; reusing the production key would let staging proofs verify in production. Before staging publication and after either key rotates, the release owner must compare their SHA-256 fingerprints privately through the approved secret store and record only a distinct-key verification receipt. Equal or unavailable fingerprints block publication. Runtime admission checks key presence and length only; it has no production fingerprint configured and cannot enforce key separation.
The staging Next deployment must return x-tuturuuu-staging-supabase-ref: fxefojytwimjiqxseqag on every response, including errors, redirects and the service-worker script. Configure that attestation only after verifying its actual database identity. Missing or mismatched attestation returns 502 without exposing the upstream body or cookies. This identity attestation fails closed after forwarding; it does not bind Vercel team ownership or prevent credentials and the signed proof from reaching an incorrectly admitted origin. Verify ownership before any request is sent. This requirement deliberately blocks enabling the candidate against an unqualified Next deployment; Web 1 does not change the current Next deployment or add its marker. Domain cookies must specify exactly .staging.tutur3u.com; host-only cookies, including __Host- cookies, retain host-only semantics on web.staging.tutur3u.com, the browser-facing response host. They are not shared with central staging or other satellites; the proxy does not widen them to the staging zone. Other or empty cookie domains return 502. Each Set-Cookie may contain at most one Domain attribute; duplicates are rejected even when their values match, regardless of attribute name casing or whitespace. The entire response is rejected without its body or any cookies. handler.test.ts covers multiple/mixed-case/equal domains, host-only cookies, and preservation of a single staging domain. The Worker preserves auth, session, webhook, x-cron-secret, RSC and action headers. It removes hop-by-hop headers, forwarded, true-client-ip, cf-connecting-ip and all x-vercel-* headers before forwarding, then replaces forwarded identity with the trusted Cloudflare client IP and staging host. The Cloudflare client IP is authenticated with the existing signed origin-IP proof. Next must use TRUSTED_PROXY=cloudflare-origin to consume that proof; ordinary Vercel mode identifies the Worker egress instead of the client. Responses stream without buffering. Status, error body, security headers, rewrite headers and individual cookies pass through. Upstream-origin Locations map back to the candidate host; external satellite redirects remain unchanged. Candidate responses are noindex and are never CDN cached.

Dormant template and owner-provided staging blockers

apps/web/cloudflare/staging.env.example is a placeholder-only input inventory. The Void config remains unbound, without routes, schedules, workers.dev or preview URLs, and both gates remain off. Do not deploy the template or put credentials in tracked files. No new crons, queues, retries or external operations are added by legal rendering; all five current schedules retain their existing owner. Release owner must provide and verify these before hosted acceptance: Run the #7093 Playwright config with WAVE1_STAGING_APP=web, WAVE1_STAGING_BASE_URL=https://web.staging.tutur3u.com and its required private inputs. Enable each slice flag only for an accepted staging deployment. The central issuer remains https://staging.tutur3u.com for the existing satellite suites; the Web suite signs in through its own candidate origin. Production/canonical hosts still fail before Chromium launches; request and WebSocket fences reject production egress and non-auth writes. The suite does not provision anything. Hosted EN/VI/session acceptance, source identity, real Next build and independent review remain release prerequisites.

Five retained infrastructure blockers

These schedules stay in apps/web/vercel.json and run only on their current Vercel owner. Web 1 neither invokes them on a schedule nor ports them. Each needs a separate bounded, idempotent Cloudflare schedule/queue port, durable stop fence, duplicate/restart tests and a transfer with no overlapping scheduler ownership before Next retirement. Reachable after() work also needs explicit ownership before its source route is retired.

Verification and cutover prerequisites

Run focused source tests from the repo root:
On Studio (skr-studio) or the i9, in a separate exact-source checkout with dependencies restored, run:
Do not run builds on the low-disk Mac. The candidate pins compatibility date 2026-10-19, matching the locked Wrangler/Miniflare supplier. The emitted suite loads every emitted JS module through Miniflare 5’s supported v4-options conversion; it does not rebundle or substitute the Worker entry. The owning web-start-candidate.yaml CI workflow qualifies source and bundle only, with no publish job or provider credentials, and retains the existing CI admission gate. Scoped Oxc checks supplement Biome; no shared formatter migration occurs here. Wrangler remains the emitted Worker runtime tool. No cf operation is substituted without authentication, target and emitted-artifact parity evidence. Before routing even a small page slice: exact-commit CI (including the real Next build and candidate build), independent security review, emitted Worker runtime acceptance and sealed restore, verified staging Next/database identity, session refresh/MFA, CSRF/action semantics, bilingual routes and satellite targets, root service-worker acceptance, a route-specific ownership decision, and an immediate rollback to the immutable Next deployment are required. The source compatibility tests use injected Next/Start fixtures. The emitted runtime suite uses the exact built Worker on workerd through Wrangler’s pinned Miniflare supplier, with outbound requests restricted to a synthetic Next fixture. It exercises the actual native Start probe, legal and security document rendering, rollback and fallback boundaries; it does not prove hosted authentication, provider staging or sealed restore acceptance. Missing checks remain prerequisites, not inferred passes. Production traffic, DNS and provisioning remain held for this implementation PR. The release owner holds the recorded automatic production cutover authority, conditional on staging acceptance and instant rollback readiness. Disabling the candidate restores 503 here; the existing Next production deployment continues to serve production throughout Web 1.