Repository navigation
WEB-001A1 — Make Firebase Hosting builds environment-explicit #663
Description
Outcome
Prepare the source-only Firebase Hosting foundation without changing a provider or publishing a website. Every optimized browser build must explicitly select staging or production; an optimized staging build must contain only a complete synthetic/approved staging Firebase web configuration and must be rejected if any production Firebase identity is selected. Add Firebase Hosting's static build directory and SPA rewrite while making an unqualified Firebase CLI invocation fail toward the local demo namespace instead of production.
Parent: #460 (WEB-001)
This child deliberately stops before staging-project creation, cloud IAM/WIF, protected branches/environments, automatic deployment, release-marker readback, custom domains, DNS, TLS, security headers, or Netlify/Pages retirement. Those require the owner evidence in #113/#133 and later WEB-001 children.
Invariant and allowed transitions
developmentandtestuse onlydemo-mprc-localand connect Auth, Firestore, and Functions to loopback emulators.- A local/test runtime rejects a hosted-environment selector.
- An optimized build with no explicit environment or an unsupported environment fails with one fixed diagnostic before the controlled build runs.
stagingrequires every public Firebase web field and rejects missing, malformed, or production-equal project/domain/bucket/sender/app identities.productionmust be explicitly selected and preserves the reviewed existing public production web configuration.- CI compiles a synthetic staging artifact and scans executable browser files to prove the staging identity is present and known production Firebase identities are absent. Source maps are non-executable and are not publication evidence.
- Firebase Hosting serves
build/, preserves real static files, and rewrites missing SPA paths to/index.html. .firebaserchas no deploy-capable production default. Every future hosted deployment still must name its exact approved project explicitly.- Current Netlify production, GitHub Pages,
runmprc.com, Firebase projects/resources, DNS, accounts, and production data remain unchanged.
Exact scope
- Browser Firebase environment selection and focused tests in
src/services/firebase/FirebaseResources.tsand its existing test. - One dependency-free build validator, one executable-artifact verifier, and focused Node tests.
firebase.json,.firebaserc,package.json, the current CI build, the existing protected-release artifact build, and the inactive one-shot Netlify builder only as needed to make every controlled optimized build explicit.- Architecture, security, implementation, operations, and the affected officer publishing/continuity/maps/recovery/glossary pages, all marked source-only and NOT AVAILABLE YET.
No Function, Firestore Rule/index, schema, runtime backend, dependency/lockfile, CSP/header, branch-protection, provider-console, IAM, secret, DNS, custom-domain, release, deployment, account, sign-in, production-data, or live behavior change is included.
Trustworthy RED
On exact base 230d73894a69c3f5f5fda05e319fb7b9d63e3d69, add the focused source-contract tests first. They must fail because optimized Firebase selection still defaults to production, staging fields are absent, .firebaserc defaults to production, firebase.json has no Hosting block, and CI has no synthetic staging artifact scan. Record the exact focused command and intended failures before implementation.
Acceptance criteria
- Missing/unsupported optimized environment and hosted selectors in local/test fail closed.
- Complete synthetic staging configuration initializes only the synthetic project; missing/malformed/production-equal variants fail before SDK service use.
- Existing explicit production behavior and local emulator isolation remain covered.
- CI builds a synthetic staging artifact and a dependency-free verifier finds its project identity while rejecting every known production Firebase identity in executable files.
- Hosting config points only at
build, ignores source/tooling files, and has one catch-all SPA rewrite to/index.htmlwithout redirecting real assets. - An unqualified Firebase CLI default cannot target
mid-peninsula-running-club. - Focused tests, full frontend tests, standalone SPA tests, workflow/safety tests, Functions checks, Rules/emulator checks, diagnostic staging build, audits, lint, and diff review pass in proportion to the source change.
- Documentation distinguishes source changed, tests passed, merged, staging published, Firebase deployed, provider configured, website published,
runmprc.comverified, and production behavior verified.
Stop conditions
- The current identity still cannot prove club ownership of the production and staging Firebase estates.
- Any test or preview reaches a hosted Firebase service, uses real member/payment data, or requires a secret.
- A staging artifact contains a known production Firebase identity or can fall back to production.
- A Firebase deploy, Hosting channel creation, DNS/custom-domain change, Netlify/Pages retirement, IAM/environment change, or live publication would be required to finish this child.
- Existing backend-first release ordering, callback protection, emulator isolation, or inactive Netlify production containment is weakened.
Officer impact: None live — officers still use the current documented Netlify-hosted site and cannot publish Firebase Hosting yet. The source change makes future hosted builds fail closed and records that the Firebase Hosting release path is NOT AVAILABLE YET.
Officer documentation: Update OFFICER_START_HERE.md, docs/officers/PUBLISH_AND_CHECK.md, docs/officers/SYSTEM_MAPS.md, docs/officers/ACCESS_CONTINUITY.md, docs/officers/EMERGENCY_AND_RECOVERY.md, and docs/officers/GLOSSARY.md with source-only current truth and the unchanged stop/escalation path.
Deployment evidence: None at creation. Source/tests/merge do not prove a staging site, Firebase deployment, provider configuration, Netlify/Pages change, DNS/TLS, runmprc.com, production data, or live behavior. Record every surface separately.
Claim protocol
Creation is not a claim. Assign one engineering agent and post CLAIMED by <canonical agent> at <UTC>; branch <branch>; exact base <40-character SHA> before editing. Re-read #460 and open claims immediately before implementation. Provider/account work always requires separately named authorized owners.
Activity
daliu commentedon Aug 23, 2026
CLAIMED by
codexat2026-08-23T19:38:41Z; branchcodex/issue-460-firebase-hosting-foundation; exact base230d73894a69c3f5f5fda05e319fb7b9d63e3d69.Owned outcome: source-only WEB-001A1 environment isolation and inert Hosting configuration exactly as scoped in #663. The current authenticated Google identity sees only disposable
testproject-1c263, not MPRC production; therefore no project creation, Firebase deploy, Hosting channel, IAM/WIF, protected environment/branch, provider configuration, DNS, custom domain, Netlify/Pages retirement, account, production-data, or live action is authorized or included.Existing #616 runtime/test and separately named SECURITY ownership remain immutable. #113 retains estate ownership/inventory, #133 retains short-lived cloud identity and environment protection, #136 retains its backend release, and parent #460 retains automatic production-web promotion, marker/readback, rollback, headers, and DNS cutover.
No implementation, test result, merge, staging publication, Firebase deployment, provider change, website publication,
runmprc.comverification, production-data action, or live behavior is claimed by this marker.daliu commentedon Aug 23, 2026
TRUSTWORTHY RED — exact base
230d73894a69c3f5f5fda05e319fb7b9d63e3d69Test-only paths:
tests/firebase-hosting-foundation.test.jsand the separately named WEB-001A1 cases/helpers insrc/services/firebase/FirebaseResources.test.ts.Combined test diff SHA-256:
9d0132e5125472861e586cc3506c897bb92e9963ba8e570d092aaf2dbb574385.Node 20.20.2 focused source-contract command:
npx --yes --package=node@20 node --test tests/firebase-hosting-foundation.test.jsResult: 5 failed, 0 passed, for the intended baseline behavior:
demo-mprc-local;firebase.jsonhas no Hosting block;prebuild, CI, the protected artifact build, and the pinned Netlify builder do not explicitly select/verify a Firebase web environment;The existing Firebase Jest dependency tree is not installed in this isolated worktree yet, so the new runtime RED cases are recorded in source and will be run after the lockfile install before runtime implementation is accepted. No runtime, workflow, configuration, documentation, provider, Firebase project/resource, deployment, account, production-data, website, DNS, or live action is part of this RED.
daliu commentedon Aug 23, 2026
IMPLEMENTATION / PR READY — commit
e0c459f, PR #664WEB-001A1's source-only boundary is implemented and pushed: #664
GREEN evidence on Node 20 / Java 21:
demo-rules-test;demo-pay002b2-test;The first local Rules attempt started only
demo-rules-testbut its child test command failed before tests because the restricted PATH hid nested Node. The corrected explicit Node 20 / Java 21 command produced the complete 418-test pass above.Production-only audits remain existing debt and no dependency changed: root 4 findings (1 high, 2 moderate, 1 low); Functions 8 moderate. No forced fix was applied.
State separation:
runmprc.comverified for this change: no;The authenticated Google identity still sees only disposable
testproject-1c263, not MPRC production or an approved staging project. Provider work remains stopped at the #113/#133 owner gate. CI is now running on PR #664.Officer impact: None live; Firebase Hosting is not an officer publish/recovery control.
Officer documentation:
OFFICER_START_HERE.md,docs/officers/PUBLISH_AND_CHECK.md,docs/officers/SYSTEM_MAPS.md,docs/officers/ACCESS_CONTINUITY.md,docs/officers/EMERGENCY_AND_RECOVERY.md, anddocs/officers/GLOSSARY.md.Deployment evidence: local synthetic artifact and demo-only emulator only; no hosted or live surface changed.
daliu commentedon Aug 23, 2026
HOSTED CI / PREVIEW FINAL — PR #664
GitHub Actions run
32663839787completed with all five jobs successful. The existing Netlify PR integration also published ephemeral preview6a8b54d06b0d6e0008c68d87at https://deploy-preview-664--luminous-fox-7c393f.netlify.app.Static-only readback fetched the root, one deep route, and referenced JavaScript without browser execution. The deep route matched the SPA index; executable JavaScript contained only the selected synthetic
mprc-staging-ciidentity and none of the known production project/sender identities.Current state: source changed and tests/preview passed; code is not merged and independent review is required. No Firebase project/site/channel, Firebase deployment, provider configuration,
runmprc.com, DNS/TLS, production data, or production behavior changed. The automatic Netlify preview is not Firebase staging and is restricted to public signed-out review.daliu commentedon Aug 24, 2026
Merged as
a614c68d9a1a2be631a3be874a686d61e5d170a0via #664. Exact merged-commit CI run 32695600148 passed all five jobs.Officer impact: No live publishing change. The Firebase Hosting source foundation is now on
main, but officers must continue using the existing Netlify procedure until the separately controlled Firebase staging, deployment authority, release lane, and cutover are verified.Officer documentation:
OFFICER_START_HERE.md,docs/officers/PUBLISH_AND_CHECK.md,docs/officers/SYSTEM_MAPS.md,docs/officers/ACCESS_CONTINUITY.md,docs/officers/EMERGENCY_AND_RECOVERY.md, anddocs/officers/GLOSSARY.md.Deployment evidence: Netlify preview root and direct
/eventsroute verified; desktop and 390x844 live responsive checks showed no broken images or horizontal overflow. Netlify productionmain@a614c68failed closed as intended, andrunmprc.comstill identifies release control commit46e2364. Firebase Hosting was not deployed: both available console identities are denied access to the approved project, the CLI exposes only an unrelated disposable project, and #113/#133 remain the owner/IAM prerequisites.