Repository navigation
OAUTH-001A2I — Reject duplicate Strava activity IDs before client return #602
Description
Officer impact: After a future protected Firebase Functions release, if Strava returns two recent activities with the same identifier, My Account will show the existing generic Strava loading failure instead of risking mismatched activity rows. There is no current officer-visible change, and no new officer action becomes available.
Officer documentation: None — this is a server-only provider-response admission boundary. It changes no public page, officer duty, collected field, permission, account, deployment step, or recovery procedure; the existing generic Strava failure guidance remains accurate.
Deployment evidence: None at creation. Closure must distinguish source changed, tests passed, code merged, website preview/publication, runmprc.com, Firebase deployment, Strava/provider configuration, production data, and live behavior. A green workflow does not prove the Function is live.
Problem
The bounded Strava activity projector validates each returned activity independently but does not require identifiers to be unique within the response. The browser uses each admitted identifier as the React list key. Two otherwise-valid records with the same identifier can therefore make the UI associate one row with another.
Invariant
A successful recentActivities projection contains at most five records whose copied positive safe-integer identifiers are pairwise distinct. Any duplicate makes the whole provider payload invalid. The server must not choose a winner, reorder, deduplicate, merge, or normalize provider records.
Allowed behavior and failure cases
- A response with distinct valid identifiers returns the same records, order, numeric types, and fields as before.
- The first repeated identifier rejects the whole activities payload through the existing fixed Strava data error before statistics JSON is read.
- Validation remains bounded to at most five copied snapshots and does not invoke provider coercion/accessor hooks.
- Auth, App Check, connection/secret reads, provider request count, refresh behavior, persistence, logs, and client schema do not change.
Atomic scope
functions/strava.js: reject a copied activity identifier equal to any previously accepted copied identifier before appending it.functions/strava.test.js: add a separately named trustworthy RED and distinct-boundary compatibility proof.
Acceptance criteria
- A test-only patch on exact pre-fix source fails only because duplicate valid activity IDs are accepted.
- Duplicate IDs return the existing fixed
internalStrava-data error; activities JSON is read once, statistics JSON is not read, both already-concurrent bearer requests remain exactly once, and there are no writes, deletes, timestamps, or logs. - Distinct identifiers including
1andNumber.MAX_SAFE_INTEGERreturn in original order as numbers. - Focused and full relevant checks pass.
- Review finds no authorization, App Check, input-bound, privacy, logging, provider, persistence, compatibility, or production-fallback regression.
Dependencies and coordination
Parent: #88. The response projection boundary from #325 and safe-integer child #600 are complete, merged, and claim-released. Open #571, #504, #507, and draft PR #462 are disjoint. Create no lossless string/Long transport or React-key migration here.
Migration and compatibility
No schema or data migration. Existing unique safe numeric IDs remain byte-for-byte compatible. Previously admitted duplicate payloads now fail closed as one invalid provider response.
Explicit exclusions / stop conditions
Stop if another claimant owns either Strava file or this exact uniqueness outcome, or if work requires choosing one duplicate, lossless ID transport, client type/key changes, response-byte limits, refresh concurrency, provider governance, Firebase/website deployment, production data, or live Strava behavior. Never use a real member token or the production provider host.
Creation is not a claim. Before editing, assign the issue, create the exact branch, and post a timestamped CLAIMED marker naming the agent, branch, and base SHA.
Activity
daliu commentedon Aug 2, 2026
CLAIMED by
/rootat2026-08-02T05:06:20Z; branchcodex/issue-602-strava-activity-ids; exact base287bfa55af969daea189dad35d7d7ac1875fd1c3.Exact ownership is only the duplicate-ID comparison hunk in
functions/strava.jsand one separately namedOAUTH-001A2I unique activity IDstest block infunctions/strava.test.js. No client, string/Long transport, response-size, response-status, refresh, provider, documentation, deployment, data, or live outcome is claimed. This authoritative timestamp supersedes the earlier typed time; no tracked edit preceded the durable claim.daliu commentedon Aug 2, 2026
CLAIM TIMESTAMP CORRECTION: the durable claim comment was posted before any tracked edit; the current UTC audit time is
2026-08-02T05:06:26Z. Branch, exact base, ownership, and exclusions are unchanged. Worktree remains clean.daliu commentedon Aug 2, 2026
TRUSTWORTHY RED on exact base
287bfa55af969daea189dad35d7d7ac1875fd1c3. Test-only diff SHA-256:d3c034b1c0f54323897c13f4fdd47dacb50d3c7f1c588f2e996ef599b8812c3d.Pinned Node 20 focused Strava run: 691 total, 690 passed, exactly one failed. The sole failure is
OAUTH-001A2I unique activity IDs > rejects a repeated valid ID before statistics JSON, because old runtime returns success. The distinct1andNumber.MAX_SAFE_INTEGERordered numeric compatibility control passes. No runtime edit preceded this RED.daliu commentedon Aug 2, 2026
IMPLEMENTATION CANDIDATE on exact base
287bfa55af969daea189dad35d7d7ac1875fd1c3. Exact two-file patch SHA-256:216d029f805fd5ffc5667e44ec1cab2fae97e71b346780d6a7dc14db3dfeffba.Outcome: after each provider activity is copied and fully validated, the at-most-five projector compares its safe numeric ID with prior accepted snapshots. Equality rejects the whole payload before append and before statistics JSON. The bounded nested loop makes at most ten primitive comparisons and invokes no raw provider getter, coercion, iterator, or new intrinsic. Distinct IDs retain provider order and numeric type.
Verification:
git diff --check: pass; worktree contains only the two claimed files.Self-review covers authorization/App Check ordering, copied-input bounds, PII/logging, provider request count, persistence, schema/type/order compatibility, and production fallback. Two independent code/test reviews are GO with no findings; officer/documentation review is pending.
Officer impact: duplicate provider rows fail through the existing generic Strava data error. Officer documentation: None — no officer procedure or available surface changes. Deployment evidence: source/test candidate only; no website,
runmprc.com, Firebase, provider, production-data, or live action/verification.daliu commentedon Aug 2, 2026
PR OPEN: #603 at exact head
945a647d2519fa6b87077122befd39bf08f62c80, tree56fb8e3bd2ee741dfbb14fbf3ce4a5e09ccbb5c1, patch SHA-256216d029f805fd5ffc5667e44ec1cab2fae97e71b346780d6a7dc14db3dfeffba. Exact two-file scope and all local gates are green. Claim remains active until hosted checks, exact-head review, merge, post-main verification, closure, and explicit release.daliu commentedon Aug 2, 2026
DELIVERY REVIEW GO on exact head
945a647d2519fa6b87077122befd39bf08f62c80. Three independent reviews found no code, test, compatibility, officer, documentation, or scope issue. Hosted CI30733746716passed all five required jobs. Exact-head preview6a6ed206d8ef7f0008e89b1eis ready, HTTP 200,noindex, and unpublished.This remains source/review evidence only. No website production publication,
runmprc.comverification, Firebase deployment, Strava/provider action, production-data action, or live behavior is claimed. Claim remains active through merge and exact-main audit.daliu commentedon Aug 2, 2026
COMPLETE / CLOSED / CLAIM RELEASED
Outcome: the bounded Strava activity projector now rejects a provider payload when two otherwise-valid rows share the same copied safe-integer ID. It fails the whole payload before statistics JSON instead of returning duplicate React keys. Distinct IDs remain ordered numeric values.
dff1a40194bd1f25938ac16564a6ce27bbb9eab5via OAUTH-001A2I — Reject duplicate Strava activity IDs #603; parent287bfa55af969daea189dad35d7d7ac1875fd1c3, tree56fb8e3bd2ee741dfbb14fbf3ce4a5e09ccbb5c1, and patch SHA-256216d029f805fd5ffc5667e44ec1cab2fae97e71b346780d6a7dc14db3dfeffbamatch the reviewed candidate.30733746716; and exact-main CI30733851679, with all five jobs green.6a6ed206d8ef7f0008e89b1ewas ready, HTTP 200,noindex, and unpublished. Exact-main production attempt6a6ed2d81ba2a10008a53e38is error/unpublished. GitHub deployments for the merge SHA are empty.runmprc.com: still advertises WEB-002A — Publish bounded Shop and Events permissions containment #473 control/source9ad6837756cdd409d296009fde5082eeeae5c059/39ab8649df411262c8109a3c81a57bc38f1e168b; this merge is not claimed live there.Residual work remains separately scoped: response-status admission, response-byte limits, lossless String/Long transport, client key migration, refresh concurrency/reconciliation, provider governance/configuration, Firebase deployment, and live verification. No production secret, provider call, or member data was used.