Repository navigation
DATA-001A9 — Redact My Account registration-sort failures #598
Description
Officer impact: None — My Account already discards every registration-list rejection detail and shows the same generic registration-load error.
Officer documentation: None — this is an internal server sort-failure boundary; no officer procedure, screen, navigation, page structure, collected field, data movement, permission, account ownership, approval, or deployment process changes.
Deployment evidence: None at issue creation. Source, tests, review, merge, website publication, runmprc.com verification, Firebase deployment/readback, outside-provider action, production-data action, migration, and live behavior must be recorded separately.
Outcome
After the exact-UID registration query, registration projection, and event work succeed, map every exceptional final registration-created sort outcome to the existing fixed unavailable / Registration data could not be loaded. result without opening the caught value.
Parent: #374. This atomic child follows released DATA-001A8/#579, whose closure explicitly leaves later registration sorting separately claimable. Exact clean main at publication: d462ff6.
Confirmed defect
Current functions/listMyRegistrations.js materializes and sorts retained registration records after all event reads. The comparator reads nested createdAt._seconds values and subtracts them outside every fixed-error boundary. A throwing nested accessor or numeric-coercion hook therefore escapes the application-owned callable boundary and enters Firebase/platform handling instead of the fixed registration-load result.
This defect is higher priority than the queued non-authoritative Strava activity-key precision residual because it is a current raw exception boundary on an authenticated callable. No dependency-ready unowned P0 remains.
Invariant and order
For one authenticated callable request:
- Preserve App Check before Auth and unauthenticated denial before Firestore.
- Preserve the one exact stored-UID registration query.
- Preserve registration projection, runner minimization, event-ID derivation, and A7/A8 event acquisition and projection behavior.
- Preserve Promise-all event lookup concurrency and complete the same event work before sorting.
- Catch without binding every exceptional final registration array construction, comparator, nested _seconds access, or numeric-coercion outcome.
- Return only fixed unavailable / Registration data could not be loaded.
- Never inspect, format, coerce, log, attach, or serialize the caught value.
- Never return a partial callable response.
- Preserve valid descending created-time order, fallback-to-zero behavior, ties, response bytes, successful empty and one-row results, and read-only behavior.
- Do not claim that the catch prevents an already-attempted getter or coercion hook; it only redacts an exception the hook throws.
Smallest safe scope
- functions/listMyRegistrations.js
- wrap only the existing final Array.from(results.values()).sort(...) operation in a separate catch without binding;
- preserve the comparator expression, token sequence, and runtime semantics; only indentation may change inside the new try boundary;
- change no A3–A8 boundary, query, event work, response, or field.
- functions/listMyRegistrations.test.js
- add one separately named DATA-001A9 block plus minimum synthetic fixture support;
- use at least two exact-UID registrations so the comparator definitely runs.
- SECURITY.md
- add one separately named DATA-001A9 remediation-ledger row immediately after A8.
Trustworthy test-first proof
Before runtime or documentation edits:
- use two exact-UID registrations sharing one invented event;
- independently make retained _seconds access throw a hostile proxy;
- independently make numeric coercion throw the same hostile proxy;
- prove the old runtime exposes that exact raw failure after the exact query, both registration projections, one event acquisition, and the complete event snapshot/field projection;
- prove zero caught-value inspection, formatting, serialization, console logging, or Firebase Functions logging;
- prove no resolved or partial callable response;
- retain a positive exact descending numeric sort plus null/missing fallback control.
The fixed runtime must return exactly unavailable / Registration data could not be loaded., with no details or cause, while all earlier ordering and successful behavior remain exact.
Use invented values only. Do not call Firebase, a provider, or production.
Required green proof
- focused DATA-001A3–A9 tests pass;
- Functions lint and the full Functions suite pass;
- frontend, TypeScript, non-mutating lint, SPA, repository safety, diagnostic build, Rules, and real demo-only commerce-emulator gates pass;
- diff and sensitive-output review pass;
- three independent exact-head reviews approve privacy/error handling, tests/compatibility, and scope/docs/claims;
- hosted exact-head and exact-main CI pass before closure;
- deployment and live states are audited separately.
Explicit exclusions and residuals
No validation or normalization of createdAt or _seconds; no change to malformed-but-nonthrowing values, NaN/Infinity ordering, fallback-to-zero, ties, or sort stability; no event-ID validation/derivation change; no sibling cancellation or reordering; no response/platform serialization or platform-log proof; no retry; no schema, Rules, indexes, packages, Account UI/service/types, officer guide, provider, migration, production data, deployment, or live action.
This child is the final in-function sort-stage boundary, not final overall failure containment. Event-ID derivation and response/platform serialization remain explicit residuals. A protected Firebase deployment/readback and a made-up staged account check remain required before describing the behavior as live.
Dependencies and coordination
- DATA-001A8/DATA-001A8 — Redact My Account event snapshot/projection failures #579 is complete, closed, and claim-released.
- AUTH-MAIL-002C2A — Bind verification results to the current identity service #571 owns only verification-action source/test paths and one emergency-guide section.
- MEMBERS-DIRECTORY-001 — Add a private opt-in officer photo directory #504 is a coordinating directory parent.
- Draft PR Rollback: prepare exact pre-header Netlify artifact #462 owns only Netlify rollback config/tests.
- The queued Strava activity-ID precision child is disjoint and unclaimed.
- Live issue, PR, branch, and claim audit found no competing registration-sort owner.
Claim protocol
Creation is not a claim. Before edits: re-fetch exact main; create and push a unique codex branch; assign this issue; add status:in-progress; and post an exact UTC claim naming branch, base, paths, invariants, exclusions, and active competing claims. The claim remains active through trustworthy RED, implementation, independent exact-head review, hosted CI, merge, exact-main verification, closure, and explicit release.
Activity
daliu commentedon Aug 2, 2026
CLAIMED by /root at 2026-08-02T04:19:20Z on branch codex/issue-598-registration-sort, exact released base d462ff6.
Exact ownership:
Invariant: after App Check/Auth, the exact UID query, registration projection, event-ID derivation, and A7/A8 event work, any exceptional final registration-array construction, comparator, nested _seconds access, or numeric-coercion outcome returns only fixed unavailable / Registration data could not be loaded. through a catch with no binding. The caught value is never inspected, formatted, coerced, logged, attached, or serialized, and no partial callable response returns. Valid descending created-time order, fallback-to-zero behavior, ties, successful/empty/one-row bytes, lookup concurrency, runner minimization, and read-only behavior remain exact.
Immutable exclusions: timestamp validation/normalization; malformed nonthrowing values; NaN/Infinity behavior; event-ID validation/derivation; sibling cancellation/order; response/platform serialization or platform logs; retries; schema/Rules/indexes/packages; Account UI/service/types/tests; officer docs; provider/deployment/data/migration/live behavior; all released A3–A8 hunks; active #571 paths/hunks; coordinating #504; draft #462; queued unclaimed Strava activity-ID precision child.
The unique empty remote branch was pushed from exact current main before this marker. Live issues, PRs, remote branches, dependencies, and path claims were re-read; no competing registration-sort issue or claim exists. No source, test, documentation, package, or generated-file edit preceded this claim. This claim remains active through trustworthy RED, implementation, independent exact-head review, hosted CI, merge, exact-main/deployment truth audit, closure, and explicit release.
Officer impact: None — My Account already discards every registration-list rejection detail and shows the same generic registration-load error.
Officer documentation: None — this is an internal server sort-failure boundary; no officer procedure, screen, navigation, page structure, collected field, data movement, permission, account ownership, approval, or deployment process changes.
Deployment evidence: none at claim time; source/tests/merge will not be described as website publication, Firebase deployment, outside-provider action, production-data change, migration, or live behavior.
daliu commentedon Aug 2, 2026
TRUSTWORTHY RED recorded before runtime or documentation edits.
This is the claimed final sort-stage boundary, not an unrelated pre-existing failure or a response/platform serialization claim.
daliu commentedon Aug 2, 2026
IMPLEMENTATION CANDIDATE — exact reviewed-head request
Outcome: the existing final Array.from-and-sort operation now runs inside a separate catch without a binding. A nested _seconds access failure or numeric-coercion failure maps only to fixed unavailable / Registration data could not be loaded. The comparator expression, token sequence, and runtime semantics remain unchanged; only indentation changes inside the new try boundary. All A3–A8 boundaries, event work, successful responses, descending order, fallback-to-zero behavior, and read-only behavior remain unchanged.
Trustworthy RED on untouched source: exactly 2 intended raw-escape failures after 29 existing/control passes. Both old-runtime cases exposed the exact hostile value only after the exact UID query, two registration projections, one complete event acquisition/projection, and the intended accessor/coercion prefix. The positive descending-order and missing-time fallback control passed before the runtime change.
Pinned local verification:
Three independent exact-head reviews are in progress.
Officer impact: None — My Account already discards every registration-list rejection detail and shows the same generic registration-load error.
Officer documentation: None — this internal server sort-failure boundary changes no officer procedure, screen, navigation, page structure, collected field, data movement, permission, ownership, approval, or deployment process.
Deployment evidence: source, tests, local review, commit, and push only. The change is not merged. The website and runmprc.com were not published or verified; Firebase was not deployed/read back; no outside provider was configured or contacted; production data, migration, and live behavior were not accessed, changed, or verified.
daliu commentedon Aug 2, 2026
WORDING CORRECTION — supersedes every earlier byte-equivalent comparator phrase.
The comparator expression, token sequence, and runtime semantics remain unchanged; only indentation changes inside the new try boundary. The issue body, claim marker, implementation-candidate marker, and PR #599 body have been edited to use that exact factual boundary.
This wording correction changes no tracked file, commit, tree, patch, test result, claim scope, or delivery state. Exact head remains 3bb8fd5; tree fb78356422c4754e1c0b95db804d0bc03c22988a; patch SHA-256 0249c70b5658a9b76df360ec545dcd523f997341568c158183bffee5ba9d2d75.
daliu commentedon Aug 2, 2026
PR PREVIEW EVIDENCE
PR #599 hosted CI run 30732412289 passed all five required jobs for exact head 3bb8fd5.
Netlify deploy preview 6a6ec73fd569250008c8d477 is exact-head, deploy-preview context, state ready, HTTP 200, x-robots-tag noindex, and published_at null. It is not production website publication, runmprc.com verification, Firebase deployment/readback, outside-provider configuration, production-data action, migration, or live-behavior proof.
daliu commentedon Aug 2, 2026
COMPLETE / CLOSED / CLAIM RELEASED
PR #599 was admin-squash-merged only after the maintainer's explicit instruction to self-review and merge, three independent exact-head final GO reviews, both reviewer-requested delivery-record corrections, and all five required hosted checks. Ordinary merge was blocked only by the external-review rule.
Exact identities:
Verification:
Delivery truth:
Officer impact: None — My Account already discards every registration-list rejection detail and shows the same generic registration-load error.
Officer documentation: None — no officer procedure, screen, navigation, page structure, collected field, data movement, permission, ownership, approval, or deployment process changed.
The status label and assignee are being cleared. The remote work branch was deleted by the merge, the local worktree is detached at exact main, and all three #598 path/hunk claims are RELEASED. Malformed-but-nonthrowing timestamp semantics, event-ID derivation/validation, sibling cancellation/order, response/platform serialization/logging, retries, deployment/readback, and live proof remain separately claimable residuals.