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
Migrated from PR #175 on 2026-07-18. This issue is the source of truth.
Planned against dev at commit 5158299; refresh live assumptions before implementation.
Priority: P1
Effort: L
Risk: HIGH
Category: security
Why this matters
The public site and owner-operated infrastructure are currently one deployment
contract. A public-only fork still reaches Media, Photos, AMA, admin, Clerk,
Neon, Bunny, payment, calendar, email, and internal work modules. One committed operatorStack choice gives forks a small interface while keeping every
credential-backed capability fail-closed.
ADR-0008 still applies to cali.so: owner admin is available in every deployed
environment whenever the committed profile is true. A public-only fork
commits false before it has operator data or deployments; this is a site
profile, not an environment kill switch.
Current state
proxy.ts:53-60 initializes Clerk at module evaluation, before route
classification can bypass it:
The owner admin is already provider-free on the client: app/admin/layout.tsx
renders a static SiteDocument, and the partially prerendered admin routes put
owner data behind Suspense loaders that call requireOwnerPage. There is no ClerkProvider, client-side Clerk, or per-request nonce CSP. Clerk remains only
in proxy/server authentication; lib/security/headers.ts supplies one static,
nonce-free policy for public and admin shells. This static/PPR architecture is
the true-profile baseline and must not be reversed.
lib/media/photo-selection/server.ts still owns database/Bunny imports in the
same module as the public reader. lib/ama/server-env.ts:12-19 parses process
environment whenever its getters are called, with no profile gate.
Public Home, dock, footer, shortcuts, sitemap, and discovery always advertise
Photos/AMA. The legacy URL manifest intentionally expects current operator
public pages to return 200; it is an immutable true-profile contract and must
not be edited.
The committed cali.so value is true. No environment variable may override
it.
When false:
/photos, /en/photos, /ama, /en/ama, /admin, and descendants return
404;
/api/admin, /api/ama, /api/internal/ama, /api/internal/media, and
descendants return a minimal 404 before Clerk, env parsing, database,
storage, payment, calendar, email, or work adapters evaluate;
Home/nav/dock/shortcuts/footer/sitemap/discovery omit Photos and AMA;
public Preferences never probes /api/admin/session, never reads or writes
the cached localStorage.owner hint, never shows Admin, and never arms G-D;
public Home, Writing, Projects, feeds, and content build with all Operator
Stack environment variables blank;
source, packages, migrations, and snapshots remain in the clone.
When true, every current route, auth rule, feature derivation, provider
failure mode, Published Photo Selection contract, and exact output remains.
That includes the static/PPR admin shell, /admin Overview, AMA/Media/Photos
information architecture, public owner-session probe and G-D entry, owner-dock
O/A/M/P/S chords, no client Clerk, no passkey reverification, and the static
nonce-free CSP.
Required module shape
Keep provider imports behind real seams:
lib/operator-stack.ts is pure and exposes operatorStackEnabled() plus classifyOperatorPath(pathname) returning page | api | public. Use exact-or-slash-prefix matching. /amazing and /photoshop are public.
lib/site-proxy.ts owns provider-free public-content classification, 404
responses, and route decisions. It does not create a nonce or stamp CSP; lib/security/headers.ts remains the unchanged static policy source.
lib/security/clerk-proxy.ts alone imports Clerk and owns its middleware. proxy.ts classifies disabled operator routes first and dynamically imports
this module only for an enabled Clerk-owned request. Remove the module-scope clerkMiddleware(...) call.
app/admin/layout.tsx calls notFound() before rendering the existing
provider-free static SiteDocument when false. When true it preserves the
existing static/PPR document exactly; do not add ClerkProvider, a dynamic
provider wrapper, per-request nonce work, or client-side auth.
lib/media/photo-selection/public.ts is provider-free and owns the public
selection type, cache tag, and getHomepagePhotoPreview projection.
Repository, public UI, and admin invalidation import that contract instead
of making UI modules import the Drizzle repository. Public server.ts
returns null before dynamically importing lib/media/photo-selection/operator-server.ts when false; only the operator
module in that public-reader path owns DB/Bunny/repository imports and the
cached reader implementation.
getServerEnv() throws an explicit programmer error before parseServerEnv(process.env) when false. getAmaFeatures() returns every
capability false without reading env.
The interface is the test surface. Tests must prove provider modules/factories
were never evaluated, not merely that their returned functions were skipped.
Commands you will need
Purpose
Command
Expected on success
Profile/classifier
pnpm exec vitest run lib/site/site-config.test.ts lib/operator-stack.test.ts
profile plus exact/prefix/negative cases pass
Isolation
focused command in Step 3
false never evaluates Clerk module/middleware/provider
Public surfaces
focused command in Step 4
true unchanged; false omits every operator affordance/adapter
Compatibility
focused command in Step 5
fixed vectors and exact current output pass
Env gate
focused command in Step 6
false avoids schema/provider parsing
Full suite
pnpm test:unit
every baseline and newly added canonical test passes
Deleting operator source, packages, routes, migrations, snapshots, or data.
Editing content/legacy-url-manifest.json.
Making true-profile credentials optional or changing provider pair rules.
Environment-controlled Operator Stack flags or per-provider profile flags.
Static photo fallback, new CMS, alternate gallery source, or physical
tree-shaking/distribution.
Production/cloud/database access or migration execution.
Changing cali.so from committed operatorStack: true.
Steps
Step 1: Record the decision
Add Operator Stack to lib/site/CONTEXT.md: owner-only Media/AMA
capabilities plus the public Photos/AMA surfaces they publish. Create ADR 0015
for the committed all-or-nothing profile, 404/no-provider false semantics,
stable id/keyNamespace, and shared source/packages. Amend ADR-0008 and the
AMA/Media context docs only to qualify “always available” by the committed
profile, never by environment.
Reconcile the two canonical security notes at the same time. In docs/security/baseline.md and docs/security/verification.md, qualify owner
admin availability and the absence of an environment kill switch by committed operatorStack: true; document the false profile as a pre-provider 404, not an
authorization bypass. Replace the obsolete dynamic-admin/per-request-nonce CSP
description with the current provider-free static/PPR shell, server/proxy Clerk
authorization, and shared static nonce-free CSP. Preserve dated hosted evidence,
the exact siteOwner: "yes" authorization marker, and every unrelated security
control.
Record that true preserves the existing provider-free static/PPR admin:
middleware and server loaders own Clerk authorization, static CSP remains
nonce-free, and passkey reverification is not reintroduced. The profile gate is
not permission to move provider code into the static shell or flatten Suspense
loaders.
Verify:
test -f docs/adr/0015-committed-operator-stack-profile.md
rg -q "Operator Stack" lib/site/CONTEXT.md lib/ama/CONTEXT.md \
lib/media/CONTEXT.md docs/adr/0015-committed-operator-stack-profile.md
rg -qF '`operatorStack: true`' docs/security/baseline.md \
docs/security/verification.md
rg -qF 'static' docs/security/baseline.md docs/security/verification.md
! rg -n 'dynamic `/admin` surface receives a fresh nonce|Owner admin is an always-available control plane|Owner admin is always reachable and has no environment switch' \
docs/security/baseline.md docs/security/verification.md
All commands exit 0; the negative scan prints nothing.
Step 2: Add the pure route classifier
Implement the classifier and boolean reader from Required module shape. Page
prefixes: /photos, /en/photos, /ama, /en/ama, /admin. API prefixes: /api/admin, /api/ama, /api/internal/ama, /api/internal/media.
Verify: pnpm exec vitest run lib/site/site-config.test.ts lib/operator-stack.test.ts
-> the extended profile type/value plus exact paths, descendants, trailing
slashes, localized routes, APIs, /amazing, and /photoshop all pass.
Step 3: Gate proxy and layouts before provider evaluation
Implement the provider-free proxy/dynamic Clerk split and five layout guards
exactly as Required module shape states. The admin guard wraps the existing
provider-free static document directly; the other four guard the localized
AMA/Photos trees. Expand the proxy matcher to every operator prefix. Read the
pinned guides first:
Before editing, re-audit every reference-only admin layout/page. The July 2026
admin deliberately partially prerenders its paper, centered column, owner dock,
headings, and fixed fallbacks. Provider/database work must remain inside async
Suspense loaders after requireOwnerPage, with no module-scope env parse or
provider factory. Preserve every instant value, fallback dimension, route,
owner-dock item, and server authorization call. If the false build exposes a
module-scope provider initialization in one of those reference-only files, STOP
and update Scope rather than flattening PPR or making the admin dynamic.
False pages rewrite to /_not-found with status 404. False APIs return a
minimal 404, never redirect/401/403/503. True keeps Clerk protection and
public-content behavior byte-for-byte, stamps no proxy CSP/nonce, and retains
the existing static CSP from lib/security/headers.ts.
All tests pass and the reference-only diff is empty. False cases prove Clerk's
module and middleware factory were never evaluated and SiteDocument was not
rendered. True cases preserve the static/PPR admin, owner shell, current auth,
and static nonce-free CSP without adding client Clerk or passkey code.
Step 4: Remove false-profile public reachability and data access
Under false, omit the Published Photo Selection Suspense branch, Photos/AMA
cards, dock/fallback items, G-then-P/G-then-A shortcuts, footer Photos link,
sitemap entries, robots/discovery expectations, and photo adapter resolution. NavCards renders a deliberate two-card layout with unchanged mobile order.
Gate the July 2026 owner-entry machinery at the same committed seam. A false
public dock must ignore even a stale localStorage.owner === '1' hint;
Preferences must not fetch /api/admin/session, read/write that hint, render the
Admin row, or arm G-D. The admin route and /api/admin/session still receive the
same proxy-level minimal 404 as the rest of /admin and /api/admin. Under
true, preserve the current on-open session probe, cached-hint self-correction,
Admin row, unlocalized public G-D chord, and owner-dock O/A/M/P/S chords exactly.
Add explicit cases, with the Site Profile module mocked before import: false Dock
ignores a seeded owner hint; opening false Preferences makes no session request
and does not access the owner key; false G-P/G-A/G-D are inert; true Preferences
still probes, corrects the hint, and reveals Admin; true public G-D and every
owner-dock chord retain their current localized/unlocalized destinations.
Move the public selection type, cache tag, and homepage projection into the
provider-free lib/media/photo-selection/public.ts. Update every type/projection
consumer to import that module. In particular, app/_views/home-page.tsx must
not runtime-import lib/media/photo-selection/repository.ts; a false-profile
Home render test must fail if the repository or operator reader evaluates.
Make scripts/verify-legacy-url-contract.mjs profile-aware without editing the
manifest: true enforces every manifest expectation unchanged; false expects
404 only for entries classified as operator pages.
Make scripts/verify-production-security-boundary.mjs profile-aware as well.
True runs every current assertion byte-for-byte. False probes every operator
page/API prefix plus one descendant, requires a minimal 404 with no redirect or
provider/env detail, and still requires 200 plus the existing security headers
for core public pages. Add one true-profile assertion for the current read-only GET /api/admin/session contract: an unauthenticated request returns 200, { owner: false }, cache-control: no-store, and no redirect or session detail.
The same path is a minimal 404 under false.
All tests pass. True retains every current URL/label, owner probe, Admin entry,
public G-D chord, and owner-dock chords. False has no Photos/AMA card, link,
shortcut, sitemap entry, DB call, Bunny call, repository/operator module evaluation,
owner-session request, owner-hint storage access, Admin row, or G-D navigation.
Step 5: Preserve operator identity bytes through the Site Profile
Migrate identity in this complete production inventory and no other source:
Calendar event ID for bk_1 at 2026-07-10T09:00:00.000Z: 2e7bb12893ab2ef04b276d36b58a58a9b7ec143c7b0df8cbe84b5d7e8552c720.
Add fixed legacy-envelope open vectors to lib/ama/secrets.test.ts and lib/media/privacy/capture-location.test.ts before replacing AAD literals.
Preserve these four exact keyNamespace compositions: cali:ama:public-mutation, cali:ama:admin-mutation, cali:media:alt-text, and cali:media-upload:v1:<checksum>:<byteSize>:<contentType>.
In lib/operator-stack.test.ts, add source-backed compatibility assertions for
the exact template-literal composition in the three rate-limit modules, plus
fixed expected-string assertions using cali.so's committed keyNamespace.
This deliberately catches a missing colon or changed suffix without importing
provider-heavy server modules. In lib/media/admin/ui.test.tsx, exercise the
upload replay path and assert the complete local-storage key, not only storage
length. Expected strings must be literal test fixtures, never generated by the
same implementation under test.
Update the Overview and AMA Settings tests to keep the current cali.so owner
time zone output exact. Add a focused Admin Dock fallback test that fixes the
current Overview/AMA/Media/Photos/return information architecture, avatar asset,
and O/A/M/P/S chord labels. This is true-profile regression coverage; the false
profile removes the route before the owner dock can render.
All tests pass with exact current cali.so strings, all four fixed keyNamespace outputs, the fixed durable namespace/envelope vectors, and the
current owner-admin IA/chord/avatar contract.
Step 6: Make false safe without weakening true
Implement the env and photo-selection dynamic gates from Required module shape.
Update .env.example: false requires no env file for public rendering; true
retains every current required key/provider pair and documented defaulted
tunable. Document AI_GATEWAY_API_KEY as optional only for Local/CI; deployed
Vercel environments use OIDC, while non-Vercel Production rejects the static
key and cannot use Alt Text Suggestions under the current provider policy. Do
not add OPERATOR_STACK_ENABLED or any equivalent variable.
Tests pass; the scan prints nothing and exits 0. False returns all AMA features
disabled and throws the explicit programmer error before schema parsing.
All commands exit 0; true preserves current output, manifest behavior, static
admin shells/fallbacks, current IA/chords, server authorization, and static
nonce-free CSP. The unset selectors force every HTTP verifier to start the
just-built local server instead of following an inherited remote base URL or
external-link mode.
Then run the false profile inside one failure-safe shell block. The block saves
the implemented true file to a unique temporary path, arms restoration before
the temporary patch can change source, and restores from that byte-for-byte
snapshot on normal exit, command failure, or signal. apply_patch remains the
only authored temporary edit; cp is used only by the failure-safe restoration.
Blank the exact credential/provider/origin variables below so a local env file
cannot satisfy operator setup, and unset every remote verifier selector. The PUBLIC_SITE_URL= deliberately exercises issue #180's blank-safe siteConfig.canonicalUrl fallback instead of accepting a discovery origin from
a local env file. SITE_URL= remains blank independently to prove the false
profile never requires or parses an operational origin.
Defaulted numeric/model tunables are deliberately irrelevant to this
credential-free proof and need not be blanked.
The false assertion and all five false-profile commands exit 0. Core public
pages remain 200; every listed operator page/API is 404; focused test spies prove
no provider adapter ran. Every verifier uses the local false build. The trap is
armed before the patch and restores true even when a command or signal stops the
block; its cmp is the byte-for-byte gate. The final assertion, build, local
security check, and patch check prove the restored true profile. If restoration
fails, STOP immediately and use the retained unique backup path reported by the
trap before doing any other work.
The false pnpm build is also the completion gate for the reference-only PPR
audit: every admin page module may be compiled, but none may parse operator env
or initialize a provider at module scope. Do not satisfy this gate by removing
the static shell, Suspense boundaries, or current route metadata.
Test plan
Pure classifier covers exact, descendant, localized, trailing-slash, and
prefix-confusion cases.
Proxy/layout tests prove false returns 404 before provider module evaluation;
true retains the static CSP and provider-free PPR admin document.
Public tests prove false removes affordances, owner probe/hint/G-D behavior,
and data calls; true preserves both public and owner-dock navigation exactly.
Fixed vectors protect cali.so:/cali: namespaces and legacy envelopes.
Env tests prove false never parses operator env and true remains strict.
Canonical security-document checks prove both notes qualify admin availability
by committed operatorStack: true, define false as a pre-provider 404 rather
than an authorization bypass, and replace dynamic-admin/per-request-nonce
wording with the provider-free static/PPR shell, proxy/server Clerk
authorization, and shared static nonce-free CSP.
Scoped diff review proves unrelated dated hosted evidence, verification
dates, and checklist state remain intact.
Both committed profile builds/verifiers are mandatory and clear every remote
base-URL/external-link selector before starting the local production server.
Done criteria
One committed boolean controls the Operator Stack; no env override exists.
cali.so is restored to operatorStack: true byte-for-byte.
Every listed false page/API returns 404 before provider evaluation.
False omits all Photos/AMA/Admin affordances, owner-session/hint behavior,
G-D, and adapter calls.
False public build needs no operator credential.
True preserves current routes, auth, provider behavior, output, and
immutable legacy manifest expectations.
True preserves the provider-free static/PPR admin, current IA and both
dock chord sets, static nonce-free CSP, and no passkey reverification.
Fixed namespace and legacy-envelope vectors pass.
ADR/context wording distinguishes site profile from environment.
Both canonical security notes qualify admin availability and the absence
of an environment kill switch by committed operatorStack: true.
Both notes describe false-profile operator routes as 404 before Clerk,
environment parsing, or provider initialization, not as an authorization
bypass.
Obsolete dynamic-admin/per-request-nonce wording is gone; both notes
record the provider-free static/PPR admin, proxy/server Clerk
authorization, and shared static nonce-free CSP.
Unrelated dated hosted evidence, verification dates, and checklist state
remain unchanged.
Unit, localization, typecheck, build, legacy URLs, links, discovery,
security boundary, and git diff --check pass.
Both profile HTTP verifier runs target their just-built local .next
output, never an inherited external deployment.
A Verify command fails twice after a reasonable correction.
Any implementation requires an out-of-scope file.
Pinned Next 16.3 cannot dynamically isolate Clerk/provider evaluation.
Preserving false semantics would flatten the admin PPR shell, make it dynamic,
add client Clerk, restore nonce CSP, or restore passkey reverification.
A false route becomes redirect/401/403/503 instead of 404.
A true-profile compatibility vector changes.
False requires editing the immutable legacy URL manifest.
False still initializes operator env/provider code after the specified seams;
report the import path instead of weakening the true schema.
The temporary profile edit cannot be restored byte-for-byte.
Production/cloud/database access, migrations, or data deletion are required.
Maintenance notes
Do not split the profile into per-provider flags until real independent site
profiles require it. Provider credentials remain fail-closed capabilities
behind the full Operator Stack. Forks choose id and keyNamespace before
creating operator data; changing either later invalidates durable contracts.
Why this matters
The public site and owner-operated infrastructure are currently one deployment
contract. A public-only fork still reaches Media, Photos, AMA, admin, Clerk,
Neon, Bunny, payment, calendar, email, and internal work modules. One committed
operatorStackchoice gives forks a small interface while keeping everycredential-backed capability fail-closed.
ADR-0008 still applies to cali.so: owner admin is available in every deployed
environment whenever the committed profile is
true. A public-only forkcommits
falsebefore it has operator data or deployments; this is a siteprofile, not an environment kill switch.
Current state
proxy.ts:53-60initializes Clerk at module evaluation, before routeclassification can bypass it:
The owner admin is already provider-free on the client:
app/admin/layout.tsxrenders a static
SiteDocument, and the partially prerendered admin routes putowner data behind Suspense loaders that call
requireOwnerPage. There is noClerkProvider, client-side Clerk, or per-request nonce CSP. Clerk remains onlyin proxy/server authentication;
lib/security/headers.tssupplies one static,nonce-free policy for public and admin shells. This static/PPR architecture is
the true-profile baseline and must not be reversed.
lib/media/photo-selection/server.tsstill owns database/Bunny imports in thesame module as the public reader.
lib/ama/server-env.ts:12-19parses processenvironment whenever its getters are called, with no profile gate.
Public Home, dock, footer, shortcuts, sitemap, and discovery always advertise
Photos/AMA. The legacy URL manifest intentionally expects current operator
public pages to return 200; it is an immutable true-profile contract and must
not be edited.
Target interface and semantics
issue #180 supplies committed non-secret fields including:
Extend that interface only with:
operatorStack: booleanThe committed cali.so value is
true. No environment variable may overrideit.
When
false:/photos,/en/photos,/ama,/en/ama,/admin, and descendants return404;
/api/admin,/api/ama,/api/internal/ama,/api/internal/media, anddescendants return a minimal 404 before Clerk, env parsing, database,
storage, payment, calendar, email, or work adapters evaluate;
/api/admin/session, never reads or writesthe cached
localStorage.ownerhint, never shows Admin, and never arms G-D;Stack environment variables blank;
When
true, every current route, auth rule, feature derivation, providerfailure mode, Published Photo Selection contract, and exact output remains.
That includes the static/PPR admin shell,
/adminOverview, AMA/Media/Photosinformation architecture, public owner-session probe and G-D entry, owner-dock
O/A/M/P/S chords, no client Clerk, no passkey reverification, and the static
nonce-free CSP.
Required module shape
Keep provider imports behind real seams:
lib/operator-stack.tsis pure and exposesoperatorStackEnabled()plusclassifyOperatorPath(pathname)returningpage | api | public. Use exact-or-slash-prefix matching./amazingand/photoshopare public.lib/site-proxy.tsowns provider-free public-content classification, 404responses, and route decisions. It does not create a nonce or stamp CSP;
lib/security/headers.tsremains the unchanged static policy source.lib/security/clerk-proxy.tsalone imports Clerk and owns its middleware.proxy.tsclassifies disabled operator routes first and dynamically importsthis module only for an enabled Clerk-owned request. Remove the module-scope
clerkMiddleware(...)call.app/admin/layout.tsxcallsnotFound()before rendering the existingprovider-free static
SiteDocumentwhen false. When true it preserves theexisting static/PPR document exactly; do not add
ClerkProvider, a dynamicprovider wrapper, per-request nonce work, or client-side auth.
lib/media/photo-selection/public.tsis provider-free and owns the publicselection type, cache tag, and
getHomepagePhotoPreviewprojection.Repository, public UI, and admin invalidation import that contract instead
of making UI modules import the Drizzle repository. Public
server.tsreturns
nullbefore dynamically importinglib/media/photo-selection/operator-server.tswhen false; only the operatormodule in that public-reader path owns DB/Bunny/repository imports and the
cached reader implementation.
getServerEnv()throws an explicit programmer error beforeparseServerEnv(process.env)when false.getAmaFeatures()returns everycapability false without reading env.
The interface is the test surface. Tests must prove provider modules/factories
were never evaluated, not merely that their returned functions were skipped.
Commands you will need
pnpm exec vitest run lib/site/site-config.test.ts lib/operator-stack.test.tspnpm test:unitpnpm typecheck && pnpm buildgit diff --checkScope
Create:
lib/operator-stack.tslib/operator-stack.test.tslib/site-proxy.tslib/security/clerk-proxy.tslib/security/operator-proxy.test.tsapp/operator-layouts.test.tsxapp/(zh)/ama/layout.tsxapp/(en)/en/ama/layout.tsxapp/(zh)/photos/layout.tsxapp/(en)/en/photos/layout.tsxlib/media/photo-selection/operator-server.tslib/media/photo-selection/public.tslib/ama/server-env-gate.test.tslib/ama/booking/manage-token.test.tscomponents/preferences.test.tsxcomponents/admin-dock.test.tsxdocs/adr/0015-committed-operator-stack-profile.mdModify:
site.config.tslib/site/site-config.test.tsproxy.tslib/security/admin-proxy.test.tslib/public-content-proxy.test.tsapp/admin/layout.tsxapp/admin/layout.test.tsxapp/_views/home-page.tsxapp/_views/home-page.test.tsxcomponents/nav-cards.tsxcomponents/dock.tsxcomponents/dock.test.tsxcomponents/preferences.tsxcomponents/admin-dock.tsxcomponents/site-footer.tsxcomponents/site-footer.test.tsxhooks/use-dock-go-shortcuts.tshooks/use-dock-go-shortcuts.test.tsxapp/sitemap.tsapp/robots.tsapp/seo-routes.test.tsscripts/verify-public-discovery.mjsscripts/verify-legacy-url-contract.mjsscripts/verify-production-security-boundary.mjslib/media/photo-selection/server.tslib/media/photo-selection/repository.tslib/media/photo-selection/repository.test.tslib/media/photo-selection/server.test.tslib/media/photo-selection/public-ui.test.tsxcomponents/published-photo-wall.tsxlib/ama/server-env.tslib/ama/server-env.test.tsapp/admin/(protected)/AdminOverview.tsxapp/admin/(protected)/AdminOverview.test.tsxapp/admin/(protected)/ama/AmaSettings.tsxapp/admin/(protected)/ama/shared.tsxapp/admin/(protected)/ama/AmaOperations.tsxapp/admin/(protected)/ama/bookings/[bookingId]/BookingDetail.tsxapp/admin/(protected)/media/MediaLibrary.tsxlib/ama/admin/server.tslib/ama/admin/ama-settings.test.tsxlib/ama/admin/ama-operations.test.tsxlib/ama/admin/booking-detail.test.tsxlib/ama/booking/server.tslib/ama/booking/service.tslib/ama/booking/service.test.tslib/ama/booking/manage-token.tslib/ama/email/templates.tslib/ama/email/templates.test.tslib/ama/meeting/tencent.tslib/ama/meeting/tencent.test.tslib/ama/operations/handlers.tslib/ama/operations/handlers.test.tslib/ama/secrets.tslib/ama/secrets.test.tslib/ama/security/server.tslib/media/admin/server.tslib/media/admin/ui.test.tsxlib/media/privacy/capture-location.tslib/media/privacy/capture-location.test.tslib/media/storage/contract.tslib/media/storage/contract.test.tsdocs/adr/0008-owner-admin-is-always-available.mddocs/security/baseline.mddocs/security/verification.mdlib/site/CONTEXT.mdlib/ama/CONTEXT.mdlib/media/CONTEXT.md.env.exampleReference-only PPR/security audit; do not modify unless the plan is updated:
app/_components/site-document.tsxapp/site-document.test.tsxapp/admin/(protected)/layout.tsxapp/admin/(protected)/page.tsxapp/admin/(protected)/ama/page.tsxapp/admin/(protected)/ama/bookings/[bookingId]/page.tsxapp/admin/(protected)/media/page.tsxapp/admin/(protected)/photos/page.tsxapp/admin/(protected)/AdminShell.tsxapp/admin/(protected)/AdminShell.test.tsxapp/admin/login/page.tsxapp/api/admin/session/route.tslib/security/headers.tsOut of scope:
content/legacy-url-manifest.json.tree-shaking/distribution.
operatorStack: true.Steps
Step 1: Record the decision
Add Operator Stack to
lib/site/CONTEXT.md: owner-only Media/AMAcapabilities plus the public Photos/AMA surfaces they publish. Create ADR 0015
for the committed all-or-nothing profile, 404/no-provider false semantics,
stable
id/keyNamespace, and shared source/packages. Amend ADR-0008 and theAMA/Media context docs only to qualify “always available” by the committed
profile, never by environment.
Reconcile the two canonical security notes at the same time. In
docs/security/baseline.mdanddocs/security/verification.md, qualify owneradmin availability and the absence of an environment kill switch by committed
operatorStack: true; document the false profile as a pre-provider 404, not anauthorization bypass. Replace the obsolete dynamic-admin/per-request-nonce CSP
description with the current provider-free static/PPR shell, server/proxy Clerk
authorization, and shared static nonce-free CSP. Preserve dated hosted evidence,
the exact
siteOwner: "yes"authorization marker, and every unrelated securitycontrol.
Record that true preserves the existing provider-free static/PPR admin:
middleware and server loaders own Clerk authorization, static CSP remains
nonce-free, and passkey reverification is not reintroduced. The profile gate is
not permission to move provider code into the static shell or flatten Suspense
loaders.
Verify:
All commands exit 0; the negative scan prints nothing.
Step 2: Add the pure route classifier
Implement the classifier and boolean reader from Required module shape. Page
prefixes:
/photos,/en/photos,/ama,/en/ama,/admin. API prefixes:/api/admin,/api/ama,/api/internal/ama,/api/internal/media.Verify:
pnpm exec vitest run lib/site/site-config.test.ts lib/operator-stack.test.ts-> the extended profile type/value plus exact paths, descendants, trailing
slashes, localized routes, APIs,
/amazing, and/photoshopall pass.Step 3: Gate proxy and layouts before provider evaluation
Implement the provider-free proxy/dynamic Clerk split and five layout guards
exactly as Required module shape states. The admin guard wraps the existing
provider-free static document directly; the other four guard the localized
AMA/Photos trees. Expand the proxy matcher to every operator prefix. Read the
pinned guides first:
node_modules/next/dist/docs/01-app/03-api-reference/03-file-conventions/proxy.mdnode_modules/next/dist/docs/01-app/03-api-reference/04-functions/not-found.mdnode_modules/next/dist/docs/01-app/03-api-reference/03-file-conventions/layout.mdBefore editing, re-audit every reference-only admin layout/page. The July 2026
admin deliberately partially prerenders its paper, centered column, owner dock,
headings, and fixed fallbacks. Provider/database work must remain inside async
Suspense loaders after
requireOwnerPage, with no module-scope env parse orprovider factory. Preserve every
instantvalue, fallback dimension, route,owner-dock item, and server authorization call. If the false build exposes a
module-scope provider initialization in one of those reference-only files, STOP
and update Scope rather than flattening PPR or making the admin dynamic.
False pages rewrite to
/_not-foundwith status 404. False APIs return aminimal 404, never redirect/401/403/503. True keeps Clerk protection and
public-content behavior byte-for-byte, stamps no proxy CSP/nonce, and retains
the existing static CSP from
lib/security/headers.ts.Verify:
All tests pass and the reference-only diff is empty. False cases prove Clerk's
module and middleware factory were never evaluated and
SiteDocumentwas notrendered. True cases preserve the static/PPR admin, owner shell, current auth,
and static nonce-free CSP without adding client Clerk or passkey code.
Step 4: Remove false-profile public reachability and data access
Under false, omit the Published Photo Selection Suspense branch, Photos/AMA
cards, dock/fallback items, G-then-P/G-then-A shortcuts, footer Photos link,
sitemap entries, robots/discovery expectations, and photo adapter resolution.
NavCardsrenders a deliberate two-card layout with unchanged mobile order.Gate the July 2026 owner-entry machinery at the same committed seam. A false
public dock must ignore even a stale
localStorage.owner === '1'hint;Preferences must not fetch
/api/admin/session, read/write that hint, render theAdmin row, or arm G-D. The admin route and
/api/admin/sessionstill receive thesame proxy-level minimal 404 as the rest of
/adminand/api/admin. Undertrue, preserve the current on-open session probe, cached-hint self-correction,
Admin row, unlocalized public G-D chord, and owner-dock O/A/M/P/S chords exactly.
Add explicit cases, with the Site Profile module mocked before import: false Dock
ignores a seeded owner hint; opening false Preferences makes no session request
and does not access the owner key; false G-P/G-A/G-D are inert; true Preferences
still probes, corrects the hint, and reveals Admin; true public G-D and every
owner-dock chord retain their current localized/unlocalized destinations.
Move the public selection type, cache tag, and homepage projection into the
provider-free
lib/media/photo-selection/public.ts. Update every type/projectionconsumer to import that module. In particular,
app/_views/home-page.tsxmustnot runtime-import
lib/media/photo-selection/repository.ts; a false-profileHome render test must fail if the repository or operator reader evaluates.
Make
scripts/verify-legacy-url-contract.mjsprofile-aware without editing themanifest: true enforces every manifest expectation unchanged; false expects
404 only for entries classified as operator pages.
Make
scripts/verify-production-security-boundary.mjsprofile-aware as well.True runs every current assertion byte-for-byte. False probes every operator
page/API prefix plus one descendant, requires a minimal 404 with no redirect or
provider/env detail, and still requires 200 plus the existing security headers
for core public pages. Add one true-profile assertion for the current read-only
GET /api/admin/sessioncontract: an unauthenticated request returns 200,{ owner: false },cache-control: no-store, and no redirect or session detail.The same path is a minimal 404 under false.
Verify:
pnpm exec vitest run app/_views/home-page.test.tsx \ lib/media/photo-selection/public-ui.test.tsx components/dock.test.tsx \ components/preferences.test.tsx \ components/site-footer.test.tsx hooks/use-dock-go-shortcuts.test.tsx \ app/seo-routes.test.ts lib/media/photo-selection/server.test.ts \ lib/media/photo-selection/repository.test.tsAll tests pass. True retains every current URL/label, owner probe, Admin entry,
public G-D chord, and owner-dock chords. False has no Photos/AMA card, link,
shortcut, sitemap entry, DB call, Bunny call, repository/operator module evaluation,
owner-session request, owner-hint storage access, Admin row, or G-D navigation.
Step 5: Preserve operator identity bytes through the Site Profile
Migrate identity in this complete production inventory and no other source:
app/admin/(protected)/AdminOverview.tsxapp/admin/(protected)/ama/AmaSettings.tsxapp/admin/(protected)/ama/shared.tsxapp/admin/(protected)/ama/AmaOperations.tsxapp/admin/(protected)/ama/bookings/[bookingId]/BookingDetail.tsxapp/admin/(protected)/media/MediaLibrary.tsxcomponents/admin-dock.tsxlib/ama/admin/server.tslib/ama/booking/server.tslib/ama/booking/service.tslib/ama/booking/manage-token.tslib/ama/email/templates.tslib/ama/meeting/tencent.tslib/ama/operations/handlers.tslib/ama/secrets.tslib/ama/security/server.tslib/media/admin/server.tslib/media/privacy/capture-location.tslib/media/storage/contract.tsMap every existing literal without changing its current cali.so bytes:
siteConfig.idfor existingcali.so:durable/AAD bytes and providerclient identity;
siteConfig.keyNamespacefor existingcali:browser, storage, andrate-limit keys;
siteConfig.canonicalUrlwhen the literal is the site's public origin,not when it is a durable
cali.so:namespace;siteConfig.owner.displayName,.givenName, and.timeZonefor theircorresponding owner-facing values;
fields only where the current literal has that exact meaning.
Never move
ADMIN_EMAILinto config: it remains the environment-backed durableoperator-data owner, not the public contact address.
Add fixed compatibility vectors, not values recomputed by the function under
test:
Buffer.alloc(32, 5), bookingbk_1:NSuJzFywTZ3f9m3RyfdbgBKt2NAPJJmLiZfDaqHNfZQ.bk_1at2026-07-10T09:00:00.000Z:2e7bb12893ab2ef04b276d36b58a58a9b7ec143c7b0df8cbe84b5d7e8552c720.lib/ama/secrets.test.tsandlib/media/privacy/capture-location.test.tsbefore replacing AAD literals.keyNamespacecompositions:cali:ama:public-mutation,cali:ama:admin-mutation,cali:media:alt-text, andcali:media-upload:v1:<checksum>:<byteSize>:<contentType>.In
lib/operator-stack.test.ts, add source-backed compatibility assertions forthe exact template-literal composition in the three rate-limit modules, plus
fixed expected-string assertions using cali.so's committed
keyNamespace.This deliberately catches a missing colon or changed suffix without importing
provider-heavy server modules. In
lib/media/admin/ui.test.tsx, exercise theupload replay path and assert the complete local-storage key, not only storage
length. Expected strings must be literal test fixtures, never generated by the
same implementation under test.
Update the Overview and AMA Settings tests to keep the current cali.so owner
time zone output exact. Add a focused Admin Dock fallback test that fixes the
current Overview/AMA/Media/Photos/return information architecture, avatar asset,
and O/A/M/P/S chord labels. This is true-profile regression coverage; the false
profile removes the route before the owner dock can render.
Verify:
All tests pass with exact current cali.so strings, all four fixed
keyNamespaceoutputs, the fixed durable namespace/envelope vectors, and thecurrent owner-admin IA/chord/avatar contract.
Step 6: Make false safe without weakening true
Implement the env and photo-selection dynamic gates from Required module shape.
Update
.env.example: false requires no env file for public rendering; trueretains every current required key/provider pair and documented defaulted
tunable. Document
AI_GATEWAY_API_KEYas optional only for Local/CI; deployedVercel environments use OIDC, while non-Vercel Production rejects the static
key and cannot use Alt Text Suggestions under the current provider policy. Do
not add
OPERATOR_STACK_ENABLEDor any equivalent variable.Verify:
Tests pass; the scan prints nothing and exits 0. False returns all AMA features
disabled and throws the explicit programmer error before schema parsing.
Step 7: Prove true and false profiles
Verify:
First run the committed true profile:
All commands exit 0; true preserves current output, manifest behavior, static
admin shells/fallbacks, current IA/chords, server authorization, and static
nonce-free CSP. The unset selectors force every HTTP verifier to start the
just-built local server instead of following an inherited remote base URL or
external-link mode.
Then run the false profile inside one failure-safe shell block. The block saves
the implemented true file to a unique temporary path, arms restoration before
the temporary patch can change source, and restores from that byte-for-byte
snapshot on normal exit, command failure, or signal.
apply_patchremains theonly authored temporary edit;
cpis used only by the failure-safe restoration.Blank the exact credential/provider/origin variables below so a local env file
cannot satisfy operator setup, and unset every remote verifier selector. The
PUBLIC_SITE_URL=deliberately exercises issue #180's blank-safesiteConfig.canonicalUrlfallback instead of accepting a discovery origin froma local env file.
SITE_URL=remains blank independently to prove the falseprofile never requires or parses an operational origin.
Defaulted numeric/model tunables are deliberately irrelevant to this
credential-free proof and need not be blanked.
The false assertion and all five false-profile commands exit 0. Core public
pages remain 200; every listed operator page/API is 404; focused test spies prove
no provider adapter ran. Every verifier uses the local false build. The trap is
armed before the patch and restores true even when a command or signal stops the
block; its
cmpis the byte-for-byte gate. The final assertion, build, localsecurity check, and patch check prove the restored true profile. If restoration
fails, STOP immediately and use the retained unique backup path reported by the
trap before doing any other work.
The false
pnpm buildis also the completion gate for the reference-only PPRaudit: every admin page module may be compiled, but none may parse operator env
or initialize a provider at module scope. Do not satisfy this gate by removing
the static shell, Suspense boundaries, or current route metadata.
Test plan
prefix-confusion cases.
true retains the static CSP and provider-free PPR admin document.
and data calls; true preserves both public and owner-dock navigation exactly.
cali.so:/cali:namespaces and legacy envelopes.by committed
operatorStack: true, define false as a pre-provider 404 ratherthan an authorization bypass, and replace dynamic-admin/per-request-nonce
wording with the provider-free static/PPR shell, proxy/server Clerk
authorization, and shared static nonce-free CSP.
dates, and checklist state remain intact.
base-URL/external-link selector before starting the local production server.
Done criteria
operatorStack: truebyte-for-byte.G-D, and adapter calls.
immutable legacy manifest expectations.
dock chord sets, static nonce-free CSP, and no passkey reverification.
of an environment kill switch by committed
operatorStack: true.environment parsing, or provider initialization, not as an authorization
bypass.
record the provider-free static/PPR admin, proxy/server Clerk
authorization, and shared static nonce-free CSP.
remain unchanged.
security boundary, and
git diff --checkpass..nextoutput, never an inherited external deployment.
STOP conditions
add client Clerk, restore nonce CSP, or restore passkey reverification.
report the import path instead of weakening the true schema.
Maintenance notes
Do not split the profile into per-provider flags until real independent site
profiles require it. Provider credentials remain fail-closed capabilities
behind the full Operator Stack. Forks choose
idandkeyNamespacebeforecreating operator data; changing either later invalidates durable contracts.