Repository navigation
OAUTH-001A2H — Reject precision-unsafe Strava activity IDs before client return #600
Description
Officer impact: None — this is an internal, undeployed server response-validation correction. Safe activity IDs keep the same result; after a future protected Function release, a precision-unsafe activity ID receives the existing generic Strava activity-load failure. No officer action or verified current procedure changes.
Officer documentation: None — no screen wording, navigation, officer duty, collected or stored field, permission, account ownership, data movement, provider configuration, or deployment procedure changes. The existing Strava activity-failure procedure already covers the generic outcome.
Deployment evidence: None at issue creation. Source, tests, review, merge, website publication, exact runmprc.com state, Firebase deployment/readback, Strava/provider configuration or calls, production-data action, migration, and live behavior must be recorded separately. Synthetic tests must make no provider call.
Outcome
Reject a parsed successful Strava activity response when a selected activity ID is not a positive JavaScript safe integer. Keep every admitted ID in the existing numeric client shape and route every rejected payload through the existing fixed internal / Strava activity data could not be loaded. result.
Canonical tracker: #88. This is an atomic follow-up to complete/released OAUTH-001A2E/#325, whose contract explicitly recorded unsafe Long-number precision and React-key collision as residual risk. Exact clean main at publication: 57ac85b.
Confirmed defect
functions/strava.js currently admits a selected activity id when it is a positive finite integer no larger than the rounded signed-64-bit ceiling represented by Number. That includes values greater than Number.MAX_SAFE_INTEGER.
JavaScript cannot distinguish every mathematical integer above the safe ceiling. For example, adjacent large integers can parse to the same Number. The current projection returns that rounded ID to the browser, where it is used only as a React list key; it is not displayed, persisted, used in a provider request, or treated as membership, authorization, payment, or account authority.
Stored and authorization athlete IDs already require positive safe integers. This child aligns only the successful activity projection.
Security and compatibility invariant
- Preserve App Check, Auth, stored-connection, stored-token, refresh, provider URL/header, and concurrent-request order.
- Keep the current successful activity/statistics snapshot boundary.
- Require each selected activity ID to be a primitive positive safe integer.
- A missing, nonnumeric, nonfinite, fractional, nonpositive, or unsafe selected activity ID invalidates the entire activities payload.
- Return only fixed internal / Strava activity data could not be loaded., with no details, cause, provider value, token, or raw error.
- Validate activities before reading the optional statistics JSON body.
- Preserve that both bearer HTTP requests may already have started concurrently; do not claim cancellation or absence of the statistics request.
- Add no write, delete, timestamp, log, retry, provider call, or response field.
- Preserve exact output bytes and numeric type for IDs from 1 through Number.MAX_SAFE_INTEGER.
- Do not stringify, BigInt-convert, or otherwise guess at an ID already rounded by JSON/Number transport.
Smallest safe scope
- functions/strava.js
- use the existing isPositiveSafeInteger helper for selected activity IDs;
- remove the now-unused rounded Long ceiling constant and range helper;
- change no other Strava path.
- functions/strava.test.js
- add one separately named OAUTH-001A2H precision-safe activity-ID block;
- add only the focused unsafe rejection and safe-ceiling compatibility evidence;
- update the old rounded-Long acceptance control to the safe-integer ceiling.
No browser/service type, UI, stored athlete-ID, provider request, persistence, root doc, officer guide, Rules, package, workflow, or generated file is in scope.
Trustworthy test-first proof
Before runtime edits:
- use an otherwise valid successful activity payload with id Number.MAX_SAFE_INTEGER + 1;
- require the existing fixed internal failure;
- prove activities JSON is read once and statistics JSON is not read;
- prove both already-concurrent bearer requests occurred exactly once;
- prove exact connection/secret reads and zero write, delete, timestamp, or console log;
- prove a Number.MAX_SAFE_INTEGER activity ID still returns byte-for-byte as a number.
The untouched runtime must fail only the new unsafe-ID expectation while the safe-ceiling control and existing suite remain green.
Required green proof
- focused Strava tests pass;
- Functions lint and full Functions tests pass;
- frontend, TypeScript, non-mutating lint, SPA, repository safety, diagnostic build, Rules, and real demo-only commerce-emulator gates pass;
- diff/sensitive-output review passes;
- three independent exact-head reviews approve security/design, tests/compatibility, and scope/docs/claims;
- hosted exact-head and exact-main CI pass before closure;
- preview, production, Firebase, provider, data, migration, and live states are recorded separately.
Migration and deliberate behavior change
No schema, Rules, index, stored-data, package, client, provider, or production-data migration. Safe current IDs retain the same numeric response. A legitimate provider ID above Number.MAX_SAFE_INTEGER will now receive the existing generic activity-load failure because the current numeric transport cannot represent it losslessly.
A future lossless string/raw-JSON ID representation and any React-key/type migration remain separate work.
Explicit exclusions and residuals
Raw response-byte/memory bounds before response.json; lossless Long/string representation; React-key migration; token/athlete/account ownership binding; refresh concurrency/versioning/lifetime; scope policy; provider endpoint migration; disconnect/revoke/audit; reconciliation; IAM/encryption; App Check/Auth changes; stored connection/token/refresh/exchange changes; browser types/UI; Rules; packages; provider configuration; deployment; production data; migration; and live testing.
This child does not complete canonical #88 or any OAUTH-001A refresh-concurrency outcome.
Dependencies and coordination
- OAUTH-001A2E — Validate successful Strava activity and statistics responses before client return #325 is complete, closed, and claim-released; it explicitly leaves this precision residual.
- OAUTH-001A2 — Redact Strava activity-data failures #233, OAUTH-001A2B — Redact Strava activity-load browser failures #250, OAUTH-001A1B — Validate Strava refresh success before token write/use #284, OAUTH-001A1C — Validate stored Strava tokens before stats refresh or bearer use #287, OAUTH-001A2C — Validate stored Strava connection metadata before secret or provider use #313, OAUTH-001A2D — Isolate Strava account data across user and service changes #323, OAUTH-001A2F — Reject unexpected Strava stats request bodies before side effects #510, and OAUTH-001A2G — Redact Strava statistics connection-record read failures #549 are complete/released foundations.
- Active AUTH-MAIL-002C2A — Bind verification results to the current identity service #571 owns only verification-action 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.
- Live issue, PR, remote-branch, and claim audit found no competing activity-ID precision 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:43:48Z on branch codex/issue-600-strava-activity-id, exact released base 57ac85b.
Exact ownership:
Invariant: after all existing App Check/Auth, stored connection/token, refresh, and provider-request behavior, each selected activity ID must be a primitive positive safe integer. An unsafe ID invalidates the complete activities payload and returns only fixed internal / Strava activity data could not be loaded., before statistics JSON is read. Both already-concurrent bearer HTTP requests may have started. No provider value, token, error detail, write, delete, timestamp, or log is added. IDs from 1 through Number.MAX_SAFE_INTEGER keep the exact numeric client shape.
Immutable exclusions: athlete/stored-account IDs; browser/service types and UI; provider URLs/headers/request order; raw response bytes; lossless Long/string migration; React-key migration; token/account/scope/refresh/revoke/audit/reconciliation/IAM/configuration; App Check/Auth; persistence; Rules; packages; workflows; root/officer docs; deployment; production data; migration; provider/live testing; canonical #88 completion.
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. Active #571, coordinating #504, and draft #462 are disjoint; no competing activity-ID precision 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 — this is an internal, undeployed server response-validation correction. Safe IDs keep the same result; a future protected Function release would route a precision-unsafe ID to the existing generic activity-load failure.
Officer documentation: None — no screen wording, navigation, officer duty, collected/stored field, permission, ownership, data movement, provider configuration, or deployment procedure changes.
Deployment evidence: none at claim time; source/tests/merge will not be described as website publication, runmprc.com verification, Firebase deployment/readback, Strava/provider action, production-data change, migration, or live behavior.
daliu commentedon Aug 2, 2026
TRUSTWORTHY RED recorded before runtime edits.
This is the claimed precision residual, not refresh concurrency, provider cancellation, or a lossless string-ID migration.
daliu commentedon Aug 2, 2026
IMPLEMENTATION CANDIDATE — exact reviewed-head request
Outcome: selected successful activity IDs now use the existing positive-safe-integer predicate. The obsolete rounded Long source constant, single-use range helper, and its sole Number.isInteger alias were removed. IDs from 1 through Number.MAX_SAFE_INTEGER retain the exact number projection. The first unsafe integer takes the existing fixed activity-data failure before statistics JSON is read; both already-concurrent bearer requests still occur.
Trustworthy RED on untouched source: exactly 1 intended failure after 688 existing/control passes. An otherwise valid activity with id Number.MAX_SAFE_INTEGER + 1 resolved successfully. The safe-ceiling positive control passed before the runtime change.
Pinned local verification:
Three independent exact-head reviews are in progress.
Officer impact: None — this is an internal, undeployed server response-validation correction. Safe IDs keep the same result; a future protected Function release would route a precision-unsafe ID to the existing generic activity-load failure.
Officer documentation: None — no screen wording, navigation, officer duty, collected/stored field, permission, ownership, data movement, provider configuration, or deployment procedure changed. The existing failure procedure already covers the generic result.
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; Strava or another provider was not configured or contacted; production data, migration, and live behavior were not accessed, changed, or verified.
daliu commentedon Aug 2, 2026
PR VERIFICATION AND PREVIEW EVIDENCE
PR #601 hosted CI run 30733062824 passed all five required jobs for exact head 426b123.
Netlify deploy preview 6a6ecc961614c10008c6b73d 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, Strava/provider configuration or contact, production-data action, migration, or live-behavior proof.
daliu commentedon Aug 2, 2026
COMPLETE / CLOSED / CLAIM RELEASED
Outcome: Strava activity responses now reject positive numeric IDs above the JavaScript safe-integer ceiling before any activity data can return to the browser. Safe numeric IDs remain compatible.
287bfa55af969daea189dad35d7d7ac1875fd1c3via OAUTH-001A2H — Reject precision-unsafe Strava activity IDs #601; parent57ac85b9f0248068e60dd741154877f1d539f3e4, tree8351062fdd7d5f8f3bbef985620bb3f1748a91dd, and patch SHA-25698f68df14c8911ec29c531b93110be3e64ef5046be18dae7044cdf3d728ff849match the reviewed candidate.30733062824; and exact-main CI30733206686, with all five jobs green.6a6ecc961614c10008c6b73dwas ready, HTTP 200, noindex, and unpublished. Exact-main production attempt6a6ecdce9660310008ce2464is 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: lossless Long/string transport, React-key migration, raw-response byte bounds, refresh concurrency, provider governance, deployment, and live verification. No production secret or member data was used.