Repository navigation
AUTH-PROFILE-001 — Restore safe profile setup and editing after the Firebase cutover #118
Description
Officer impact: Members can save their own name and phone number after sign-in. Officers do not create member records by hand or grant membership to repair an account.
Officer documentation: Update docs/officers/EVENTS_SHOP_MEMBERS.md, docs/officers/EMERGENCY_AND_RECOVERY.md, and the account/profile path in docs/officers/SYSTEM_MAPS.md. Keep the repair path marked NOT AVAILABLE YET until both the website and Firebase backend are proven live.
Deployment evidence: None at issue creation. Closure requires exact source/test revisions, a protected staging Firebase deployment, synthetic account proof, website publication, Firebase Rules and Function deployment proof, rollback proof, and a final production state report that does not expose a real member record.
User-reported symptom
On 2026-07-12, a signed-in user could open the profile screen but saving profile information returned Missing or insufficient permissions.
Email verification is not required by the source rule for this edit. The Firebase email spam report is tracked separately and must not be treated as the cause of this permission error.
Read-only diagnosis
The current browser targets Firebase project mid-peninsula-running-club. The Firebase cutover changed the browser/project configuration, but repository deployment evidence does not prove that the matching profile-creation Function or Firestore Rules were deployed to that project.
The current account screen also hides profile-read failures and still shows the Edit action. Saving then performs an update-only write to members/{signed-in UID}. If the profile document is missing, the profile Function is absent, or deployed Rules differ from the tested source, the user sees the reported generic permission error.
Do not repair this by widening browser Rules, creating a production document by hand, changing a role, or deleting/recreating the account.
Atomic outcome
Make profile setup idempotent and make service failures clear:
- Add an authenticated server operation that ensures only the caller's minimal pending profile exists.
- Derive identity fields from verified Firebase Auth state on the server.
- Create a missing record with
role: unverified; never infer membership, dues, discounts, or admin access. - Never overwrite an existing profile or user-entered fields.
- Call the operation before the first profile read, then read the profile.
- Disable editing and show a plain recovery message when profile setup/read is unavailable.
- Keep profile edits restricted to the current small field allowlist.
Security and reliability invariants
- Anonymous callers are rejected without account enumeration.
- A caller cannot choose another UID, initial role, membership state, payment state, claims, timestamps, or extra fields.
- Duplicate, concurrent, and retried calls return the same safe result and never overwrite an existing record.
- Browser clients still cannot create arbitrary
membersdocuments directly. - Existing member/admin profiles and custom claims are not changed.
- No name, email, phone, token, request body, or raw Firebase error is logged or returned.
- App Check, authentication, input limits, and generic error handling follow the shared server boundary.
- No production member data or production write is used for development or testing.
Acceptance criteria
- A synthetic signed-in user with no profile receives one exact minimal pending profile through the server operation.
- Repeating or racing the same operation leaves one unchanged profile.
- An existing profile is returned/recognized without any field or role change.
- Injected UID, email, role, membership, payment, or extra-field inputs are ignored or rejected.
- Anonymous, wrong-project, App Check failure, backend unavailable, and Rules mismatch cases show a safe, understandable UI state and keep Edit disabled.
- The current exact self-edit of name and phone succeeds against the staged Rules; cross-user and disallowed-field writes fail.
- Name and phone limits are enforced consistently in the form and Rules.
- A profile-read failure is no longer silently swallowed and raw Firebase wording is not shown to members.
- Focused frontend/Function/Rules tests plus the relevant full suites pass without network or production access.
- A staged synthetic account proves sign-up, idempotent profile setup, read, edit, sign-out, and retry.
- Deployment evidence distinguishes source merged, tests passed, Rules deployed, Function deployed, website published,
runmprc.comverified, and production behavior verified.
Dependencies and coordination
- SEC-001 — Replace the Firestore admin catch-all with resource-specific rules #100 owns the safe resource-specific Firestore Rules revision. Do not edit or deploy a competing Rules slice.
- CI-001 — Establish trustworthy quality gates and protected deployment #105 owns protected Firebase deployment identity, staging, exact-revision proof, rollback, and backend-first release order.
- SAFETY-001 — Preserve callbacks and fail closed on local Firebase isolation #99 owns fail-closed local Auth/Firestore/Functions emulator isolation.
- CI-001A — Repair the deterministic frontend test baseline #103 owns the deterministic frontend test baseline.
- OBS-001A — Remove personal data and session replay from current monitoring and logs #111 must remove current personal-data logging before any broad all-Functions deployment; a narrowly targeted new-Function deployment must still meet CI-001 — Establish trustworthy quality gates and protected deployment #105.
- BACKEND-001 — Audit the Firebase cutover and approve legacy data disposition #113 owns private verification of old/new Firebase project state and data disposition. Do not inspect or migrate real member records here.
- AUTH-004 — Link a Google identity to an existing Firebase member account #82 owns account-link and UID/email collision recovery. Do not silently merge identities here.
- DATA-001B — Inventory personal data and approve a minimization/retention matrix #110 owns data minimization and retention decisions.
This issue may be implemented in source after its code-test dependencies are complete, but production deployment remains blocked until #100 and the applicable #105 deployment child are proven.
Explicitly out of scope
- Email sender reputation or template delivery.
- Google sign-in/account linking, membership approval, dues, role grants, roster import, or bulk migration.
- Manual production Firestore edits, deleting/recreating accounts, or loosening the admin/member Rules boundary.
Claim protocol
Creation is not a claim. Before editing, confirm dependencies, assign the issue, post CLAIMED by <canonical agent> at <UTC>; branch <branch>, and re-read all comments. Split again if implementation cannot remain one reviewable outcome.
Activity
daliu commentedon Jul 13, 2026
DEPENDENCY UPDATE at 2026-07-13T07:13:30Z (not a claim): #100 is source-complete and merged to main at a7fc301 with 295/295 Rules tests and two independent approvals.\n\nImportant live-state boundary: deploy run 29231224213 explicitly skipped Firebase because FIREBASE_SERVICE_ACCOUNT is absent. The reported profile-save failure is therefore not fixed or safely retested in production. This issue still waits for its remaining source dependencies and the protected staging/backend-first deployment path under #105. Do not create or modify a real member document as a workaround.
daliu commentedon Jul 13, 2026
Dependency update after #99 (2026-07-13): safe synthetic local Auth/Firestore/Functions development and fail-closed startup are now merged on final main f6e86be. This makes an isolated #118 implementation possible, but it does not repair or prove the live profile path. Firebase deployment still skipped for lack of FIREBASE_SERVICE_ACCOUNT, and no real member/profile action was tested. #118 remains a separate unclaimed outcome with its own profile bootstrap/recovery tests and deployment evidence.
daliu commentedon Jul 13, 2026
CLAIMED by /root at 2026-07-13T08:10:06Z; branch codex/issue-118-profile-bootstrap. Source-only implementation and emulator verification begin from f6e86be. I will not use real member data or production writes. Firebase production deployment remains a separately proven #105 gate; I will split the source slice before editing if inspection shows this cannot remain one reviewable outcome.
daliu commentedon Jul 13, 2026
EXTRACTION FINISHED by
/rootat 2026-07-13T08:45:36Z on branchcodex/issue-118-profile-bootstrap.Reviewable draft PR: #132
e86a0f702cff6495f50630c5de3337290db8b8cbc982bcd752ed9b6eb1d443103d09996ac2541ea7Deployment is deliberately blocked, not complete. The current workflow publishes the website before Firebase and lacks
FIREBASE_SERVICE_ACCOUNT. Merging this frontend-bearing branch now would call an absent Function and intentionally hide account features. #105 must first provide protected staging and target deployment of the exact #100 Rules plus both revisedcreateMemberOnSignUpandensureMemberProfile, with configured App Check proof and rehearsed rollback/safe roll-forward. The website may publish only after that exact backend is verified.Keep #118 open and claimed through PR review. Do not treat a preview or green workflow as Firebase/live proof, and do not manually repair a member profile or role.
daliu commentedon Jul 13, 2026
DEPLOYMENT DEPENDENCIES PUBLISHED at 2026-07-13T08:49:30Z (not claims):
#105 now links the three atomic children. PR #132 remains draft and must not merge until that path is proven. No provider setting, Firebase resource, website, or production data changed while publishing these tickets.
daliu commentedon Jul 13, 2026
COORDINATION at 2026-07-13T09:02:44Z: #135 temporarily owns only the release-status hunks in SECURITY.md and OPERATIONS_RUNBOOK.md, plus the repository/officer deployment truth listed in its scope amendment. PR #132 keeps all profile/App Check/runtime/Rules/test content. After #135 merges, #132 must refresh onto that exact main and preserve the protected-release/Netlify-containment wording; do not merge #132 before then. No #118 runtime file ownership changed.
daliu commentedon Jul 13, 2026
REFRESH STARTED by /root at 2026-07-13T09:57:23Z; branch codex/issue-118-profile-bootstrap.
#135 is complete at main
9eafab1217aff7058c42240aaba72d7b93f8ed24, so the old frontend-first merge blocker is removed: a merge now runs CI only and publishes nothing. I am rebasing the already-reviewed #118 source onto that exact main, preserving every protected-release/Netlify-containment hunk, correcting the PR release sequence, and rerunning the full relevant suites.The #118 runtime/Rules/profile scope is unchanged. This is source merge preparation only. Firebase, Pages, Netlify production, providers, and real member records remain untouched; #133/#136 still own protected authority and the actual staged/live backend-first release.
daliu commentedon Jul 13, 2026
SOURCE MERGED / FILE CLAIM RELEASED at 2026-07-13T10:08Z
13ccc1b67dd57f69091e808b12e1287a1bc05b2f; exact reviewed source head was6381907a6e243335094cb25122ef773943f7f19d.68b823a5f2a42e0490859dc74e5188d89fd5181c.runmprc.comwere not published or live-tested. No real member record, provider setting, secret, payment, email, or production write was used.The source-file claim, including
SECURITY.mdandOPERATIONS_RUNBOOK.md, is released after a controlled refresh to13ccc1b67dd57f69091e808b12e1287a1bc05b2f. Preserve both #135 release-gate truth and #118 profile-recovery truth.#118 stays open with
status:blocked-owner/needs-external-config. #113/#133, the protected WEB-001 child, and #136 still own isolated staging, protected OIDC/WIF authority, exact backend-first deployment/readback, website publication, synthetic proof, rollback, and live verification.Officer impact: source is ready, but automatic profile repair is still NOT AVAILABLE YET. Officers must use a new redacted incident and must not edit a member record, role, or account manually.
Officer documentation: merged in the three #118 officer guides and system/security/runbook maps.
Deployment evidence: source merge and tests only; no application/provider deployment claimed.