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.
Native public page slices: legal documents
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.comandNEXT_PUBLIC_SUPABASE_URL=https://fxefojytwimjiqxseqag.supabase.co.NEXT_FALLBACK_ORIGINis one exact HTTPS staging Next deployment origin, with no path, credentials or query. The hostname filter acceptstuturuuu.vercel.app, thetuturuuu-*.vercel.appprefix, 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_SECRETmust 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.
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 inapps/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:skr-studio) or
the i9, in a separate exact-source checkout with dependencies restored, run:
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.