Skip to content

OAUTH-001A2H — Reject precision-unsafe Strava activity IDs - #601

Merged
daliu merged 1 commit into
mainfrom
codex/issue-600-strava-activity-id
Aug 2, 2026
Merged

daliu merged 1 commit into
mainfrom
codex/issue-600-strava-activity-id

Conversation

@daliu

@daliu daliu commented Aug 2, 2026 •

Copy link
Copy Markdown
Contributor

Outcome

A successful parsed Strava activities response is now rejected when a selected activity ID is not a positive JavaScript safe integer. Safe IDs retain the exact existing numeric client shape. Unsafe IDs use only the existing fixed internal / Strava activity data could not be loaded. result.

Closes #600.
Canonical tracker: #88.
Follows complete/released OAUTH-001A2E/#325.

Defect and invariant

The previous predicate admitted positive finite integers through the rounded signed-64-bit ceiling, including values above Number.MAX_SAFE_INTEGER that JavaScript Number cannot represent uniquely. The value was returned as a non-authoritative browser projection/React key, not persisted or used for provider requests, membership, authorization, or payment.

This PR uses the existing isPositiveSafeInteger helper for only the selected activity ID. It removes the obsolete source Long ceiling, single-use range helper, and sole Number.isInteger alias. App Check/Auth, stored connection/token validation, refresh, provider URLs/headers, concurrent request order, parsed-response snapshotting, fixed error shape, writes/logs, statistics behavior, and output type for admitted IDs remain unchanged.

Both bearer HTTP requests may already have started concurrently. Invalid activities stop before statistics JSON is read; this PR makes no cancellation claim.

Trustworthy test-first proof

On untouched source, the test-only patch produced exactly one intended failure after 688 existing/control passes: an otherwise valid activity with id Number.MAX_SAFE_INTEGER + 1 resolved successfully instead of taking the fixed failure path.

The same test helper proves activities JSON once, statistics JSON zero, both bearer requests exactly once, exact connection/secret reads, zero writes/deletes/timestamps/logs, and no provider/token detail. The Number.MAX_SAFE_INTEGER positive control passed before the runtime change and returned the exact ID as a number.

Exact scope

  • functions/strava.js — only selected activity-ID admission and removal of its now-unused source constants/helper.
  • functions/strava.test.js — one separately named OAUTH-001A2H block and the existing exact-bounds control updated from rounded Long to safe ceiling.

Exact base: 57ac85b.
Exact head: 426b123.
Exact tree: 8351062fdd7d5f8f3bbef985620bb3f1748a91dd.
Binary patch SHA-256: 98f68df14c8911ec29c531b93110be3e64ef5046be18dae7044cdf3d728ff849.

Verification

  • Focused Strava: 689/689.
  • Functions lint: passed.
  • Full Functions: 69 suites passed / 2 intentionally skipped; 7,492 passed / 64 intentionally skipped.
  • Frontend: 951/951.
  • TypeScript: passed.
  • Frontend lint: 118 files / 113 reviewed legacy errors / 6 reviewed warnings.
  • SPA: 11/11.
  • Workflow/release/artifact/dependency safety: 93/93.
  • Diagnostic build: passed.
  • Rules emulator: 418/418.
  • Real demo-only commerce emulator: 63/63.
  • Audit snapshot: root 59 total with zero critical; root production 4; Functions 8. No dependency file changed and no forced update was applied.

Security and compatibility review

  • No authorization, App Check, provider request, stored athlete ID, persistence, log, timestamp, retry, schema, Rules, index, package, client type, UI, or response field change.
  • Primitive safe IDs from 1 through Number.MAX_SAFE_INTEGER keep the exact numeric projection.
  • Missing and malformed ID behavior stays within the same fixed activity-data failure.
  • The deliberate change is that a legitimate provider ID above the safe ceiling now fails generically because the current Number transport cannot represent it losslessly.
  • Tests use invented local values only; no Firebase network, Strava host, production data, or real member data.

Residuals remain: raw response-byte/memory bounds before response.json; lossless Long/string and React-key/type migration; token/athlete/account binding; refresh concurrency; scope; revoke/audit/reconciliation; IAM/provider configuration; deployment/readback and live proof. This child does not complete #88.

Migration and rollback

No schema, stored-data, client, Rules, index, package, provider, or production migration. Roll back the single merge if the narrower admission causes an unexpected regression; no data reversal is required. A future lossless ID migration requires a separately reviewed string/raw-JSON contract.

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 ID receives the existing generic Strava activity-load failure.

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: Source changed; synthetic/local tests and hosted PR CI run 30733062824 passed. Netlify deploy preview 6a6ecc961614c10008c6b73d was created for exact head 426b123 and is ready with HTTP 200, x-robots-tag noindex, and published_at null. This deploy-preview is not production publication or live proof. Code is not merged. The production website and runmprc.com were not published or verified; Firebase was not deployed or read back; Strava/provider configuration or calls, production data, migration, and live behavior were not changed or verified.

@netlify

netlify Bot commented Aug 2, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for luminous-fox-7c393f ready!

Name Link
🔨 Latest commit 426b123
🔍 Latest deploy log https://app.netlify.com/projects/luminous-fox-7c393f/deploys/6a6ecc961614c10008c6b73d
😎 Deploy Preview https://deploy-preview-601--luminous-fox-7c393f.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@daliu

daliu commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

PR VERIFICATION AND PREVIEW EVIDENCE

Hosted PR 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. This is a provider preview outcome, not production website publication, runmprc.com verification, Firebase deployment/readback, Strava configuration/contact, production-data action, migration, or live-behavior proof. The PR body now records these states separately.

@daliu

daliu commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

SELF-REVIEW: GO — no actionable findings on exact head 426b1238405770534b699d62ba40826d90fcd2a4 against base 57ac85b9f0248068e60dd741154877f1d539f3e4.

I reviewed the complete two-file diff for Auth/App Check ordering, request bounds, fixed/redacted failure behavior, numeric compatibility, provider calls, persistence, logging, and production fallback. The change rejects only positive integers that JavaScript cannot represent precisely; safe numeric IDs remain byte-for-byte compatible. It adds no writes, logs, retries, provider calls, response fields, migration, or UI behavior. Residual Long/string transport, React-key migration, raw-response byte limits, refresh concurrency, provider governance, deployment, and live verification remain outside this child.

Three independent exact-head reviews returned GO with no findings. The trustworthy RED failed only the new unsafe-integer case on the old runtime; the final focused suite passed 689/689. All five required hosted CI jobs in run 30733062824 passed. Exact-head Netlify preview 6a6ecc961614c10008c6b73d is ready, HTTP 200, noindex, and not published.

Repository policy still requires an external approval, so the ordinary merge path is expected to remain review-blocked. The maintainer explicitly instructed this task to self-review and merge when clean; an administrative squash merge is authorized only after the recorded checks and reviews above.

@daliu
daliu merged commit 287bfa5 into main Aug 2, 2026
9 checks passed
@daliu
daliu deleted the codex/issue-600-strava-activity-id branch August 2, 2026 04:55
@daliu

daliu commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

FINAL DELIVERY — COMPLETE / MERGED / CLAIM RELEASED

Exact reviewed head 426b1238405770534b699d62ba40826d90fcd2a4 was squash-merged as exact main 287bfa55af969daea189dad35d7d7ac1875fd1c3. Parent, tree, two-file scope, and patch hash match. PR CI 30733062824 and post-main CI 30733206686 passed all five jobs. No actionable review findings remained.

Deployment evidence: the exact-head preview was ready and unpublished; the exact-main Netlify production attempt is error/unpublished; GitHub deployments are empty; runmprc.com remains on the older #473 release; Firebase and Strava configuration were not changed or verified; production behavior is not claimed live.

Officer impact: unsafe provider IDs now fail through the existing Strava failure path. Officer documentation: None — the existing procedure remains accurate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAUTH-001A2H — Reject precision-unsafe Strava activity IDs before client return

1 participant