Skip to content

feat(mobile): hard-block under-18 users on the store age signal - #4665

Merged
brow merged 49 commits into
mainfrom
mobile-age-signal-gate
Sep 15, 2026
Merged

brow merged 49 commits into
mainfrom
mobile-age-signal-gate

Conversation

@brow

@brow brow commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

What changed?

Buzz mobile checks the app-store age signal at launch and hard-blocks the app behind a full-screen 18+ notice when the store says the signed-in person is under 18.

No age signal (e.g. declined permission, indeterminate value, unsupported OS versions) results in no block.

The age value is never persisted. It is read, used to compute one boolean, and discarded. Nothing is written to disk, and neither the age value nor the range is logged or sent to analytics.

Platform notes:

  • New dependency com.google.android.play:age-signals:0.0.4. This is the only way to read the Play signal. Its AAR declares minSdkVersion 23, below the app's 24, so it forces no minSdk bump, and it self-declares its own consent activity, so no AndroidManifest change is needed.
  • iOS entitlement and linking. DeclaredAgeRange autolinks from the import. Runner.entitlements now declares com.apple.developer.declared-age-range, and the call remains behind #available(iOS 26.0, *).

Why?

App stores now expose a declared-age range, and Buzz's Terms require users to be 18 or older. This wires the store signal to that rule with the smallest change that is defensible.

Absent signals, declined or undeterminable results, and unsupported OS versions allow the app through. A transient native request failure does not become evidence that access is allowed: the app remains gated until a retry produces a result. Only an affirmative under-18 signal produces the permanent restriction screen.

How is it tested?

Added tests:

  • age_signal_provider_test covers the 17/18 boundary, open-ended ranges, no-signal, transient recovery, bounded retry exhaustion, malformed payloads, and request-once behavior
  • age_gate_app_test proves authenticated content remains unmounted while the signal is pending or retryable, and verifies the retry path
  • age_restriction_page_test asserts the block screen offers no bypass affordance
  • community_provider_test verifies age restriction clears push state, persists inactive leases, and retries a failed tombstone
  • AgeSignalPayloadTest pins the Android success payload to exactly {status, ageUpper} and verifies failures return the distinct retryable platform error

Deployment note

Enable the Declared Age Range capability and regenerate signing profiles carrying the entitlement. This relops/App Store Connect task is not performed by this PR.

🤖 This PR was authored with an agent.

Age restriction screen
Age restriction screen

npub12wpjffj7q5qjsky5jvk4ldwlxmse5xll3d8gytk4wqd0c5y7jvwspg37n6 and others added 4 commits August 3, 2026 21:11
Co-authored-by: Tom Brow <tomb@block.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz>
Co-authored-by: Tom Brow <tomb@block.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz>
Co-authored-by: Tom Brow <tomb@block.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is 7c789dee09d198469bded1cb5be902eaf5562ad9...6ba37f8ee0da00dc70a7061f5a832f81f550cef1.
A new review must complete for this exact range. When manual authorization
is required, a Block organization member must comment exactly
@buzz-security-review 6ba37f8ee0da00dc70a7061f5a832f81f550cef1 to authorize a new review.
Any previous review applies only to its recorded range.

@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@builderbot review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-14T23:51:43.702050Z 6ba37f8 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b6769a0a80

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread mobile/ios/Runner/AppDelegate.swift Outdated
@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@buzz-security-review b6769a0

Signed-off-by: Tom Brow <tomb@block.xyz>
@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@builderbot review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4fbb4fdc47

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread mobile/android/app/src/main/kotlin/xyz/block/buzz/mobile/MainActivity.kt Outdated
Signed-off-by: Tom Brow <tomb@block.xyz>
Co-authored-by: Codex <noreply@openai.com>
Ai-assisted: true
@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@builderbot review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 3ab80dd504

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@buzz-security-review 3ab80dd

Signed-off-by: Tom Brow <tomb@block.xyz>
@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@builderbot review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0a46c3f995

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread mobile/lib/app.dart Outdated
Signed-off-by: Tom Brow <tomb@block.xyz>
Co-authored-by: Codex <noreply@openai.com>
Ai-assisted: true
@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@builderbot review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d4a7643fc4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread mobile/lib/app.dart
Signed-off-by: Tom Brow <tomb@block.xyz>
Co-authored-by: Codex <noreply@openai.com>
Ai-assisted: true
@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@brow

brow commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@builderbot review

@jedwards27 jedwards27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed by :bot: Jude’s code review agent.

Verdict: REQUEST CHANGES

Reviewed: c045321a7fb3ca8939f28519ce7a555a6f597728..475f2731b05dfb368b4a77467fb756d0219d82b4 (exact live head 475f2731b05dfb368b4a77467fb756d0219d82b4)

Risk: high — this changes the native store-age bridge, launch authorization state machine, cross-process notification fencing, signing entitlement, and local/remote push cleanup on both mobile platforms.

Blocking findings

[P1] Keep snapshot dedupe coherent across ordinary and strict writers

mobile/lib/shared/community/community_provider.dart:239-240,323-349

_CommunitySnapshotSync tracks independent successful fingerprints for the ordinary and age-gate writers even though both replace the same native community snapshot and NSE signing-key set. The reachable sequence ordinary [] -> strict [C] -> remove C -> ordinary [] leaves the ordinary fingerprint at [], so the final clear is suppressed. A seam reproduction expected native writes [[], []] but observed only [[]].

That can leave removed community C and its signing key usable by the notification extension while remote revocation is pending, violating local account-removal/sign-out isolation.

Author action: use resource-coherent dedupe state, or invalidate the other writer’s cached fingerprint after every successful replacement. Add the exact interleaving regression and assert that the final ordinary clear reaches native snapshot/key storage.

Verification owner: author for code/test; reviewer for exact-head regression and community/push-suite rerun.

[P2] Do not make the notification-service expiry handoff wait for asynchronous cleanup

mobile/ios/NotificationService/NotificationService.swift:104-135

serviceExtensionTimeWillExpire() calls finish(), which consumes contentHandler immediately. When the restriction fence changed, finish() then waits for interactionDeletionDeadline.deleteAll before handing off restricted fallback content. That helper permits a five-second wait. If deletion never returns before the system terminates the already-expiring extension, a second expiry callback cannot recover the nil handler and iOS may deliver the original gateway payload rather than the privacy-safe restricted fallback.

Author action: preserve an exactly-once synchronous handoff of the restricted fallback when expiry/fence change is known; perform interaction deletion and notification purge best-effort afterward. Add a deadline-seam regression with a changed fence and deletion callback that never completes.

Verification owner: author for code/test; reviewer for deterministic Swift regression and full BuzzPushKit/mobile gates; Mobile release QA for a real NSE deadline exercise.

Product/UI and boundary review

No additional blocking product/UI defect was found. Tests and source bind inclusive upper age 17 to restriction, 18 and open-ended ranges to allowance, explicit no-signal to allowance, and malformed/missing/timeout/transient results to a gated retry. Authenticated content and its navigator remain unmounted until allowance; affirmative under-18 state is full-screen with no in-app bypass. iOS normalizes Apple’s exclusive bound (18 -> 17), while Android forwards Play’s inclusive ageUpper. The reviewed payload/logging/storage paths expose only status plus upper bound to Flutter and do not persist raw age evidence.

Validation at matching clean HEAD

  • just mobile-check — PASS (format unchanged; analysis clean).
  • Focused changed-boundary Flutter suites (features/age_gate, community provider/storage, push bridge, widget root) — 95/95 PASS.
  • swift test --package-path mobile/ios/BuzzPushKit — PASS: 68 XCTest + 33 Swift Testing cases.
  • Full just mobile-test reached 2,118 cases but failed one unrelated voice_note_recording_test.dart temp-directory teardown (PathNotFoundException); an independent run also saw unrelated huddle timing flakiness. Changed age/community/push coverage stayed green, and CI’s exact-head Mobile and Mobile Swift lanes are green.
  • Android native unit execution was unavailable locally because this checkout has no Gradle wrapper; exact-head CI Mobile is green.
  • Fresh exact-head checks reported no failed or pending check. Authorize Security Review passed, but Run Codex Security Review, Post Codex Security Review, and CI Security were skipped; the exact-range security-review execution evidence remains an external gate/status concern, not a third author defect.

Manual/native evidence and residual risk

The supplied screenshot matches the implemented restriction layout, but it is not independent device/provenance proof. No independent physical Android/iOS store-signal run, TalkBack/VoiceOver and system-back/focus exercise, real NSE deadline observation, or signed release/profile validation of the Android dependency and iOS entitlement was available. Mobile release/device QA owns those confidence gaps. They do not replace the two concrete code defects above.

Any head change invalidates this verdict until its delta and affected evidence are reviewed.

@jedwards27 jedwards27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:bot: Jude’s code review agent — REQUEST CHANGES

Reviewed exact head 475f2731b05dfb368b4a77467fb756d0219d82b4 against base c045321a7fb3ca8939f28519ce7a555a6f597728.

Two integration defects remain:

  1. [P1] Ordinary/strict snapshot dedupe can leave a removed community’s notification-service snapshot and signing key active. _CommunitySnapshotSync keeps independent successful fingerprints for ordinary and age-gate writers even though both replace the same native snapshot/key resource (mobile/lib/shared/community/community_provider.dart:239-240,323-329,345-349). Sequence: ordinary [] → strict [C] → remove C → ordinary []; the final clear is suppressed by the stale ordinary fingerprint. A production-seam regression reproduced Expected [[], []], Actual [[]].

    Author action: use one resource-coherent successful fingerprint, or invalidate the sibling path’s cached fingerprint after every successful replacement. Add the exact interleaving regression and prove final native snapshot/key deletion after account/community removal.

  2. [P2] Notification-service expiry can miss the restricted fallback and let iOS deliver the original gateway payload. Expiry calls finish(bestAttemptContent) (mobile/ios/NotificationService/NotificationService.swift:104-108); finish consumes contentHandler immediately (:110-112) but, after a changed restriction fence, delays fallback handoff until asynchronous interaction deletion completes (:123-135). A second expiry cannot recover because the handler is nil. If deletion misses the extension deadline, iOS may use the unmodified original content.

    Author action: synchronously hand off the privacy-safe restricted fallback once expiry/fence change is known; keep interaction deletion/purge best-effort. Add a deadline-seam regression where deletion never completes.

Verification owner: author for both fixes and causal regressions; reviewer/CI for exact-new-head community/push and BuzzPushKit gates; release QA for real notification-extension deadline and signed store-profile/device evidence.

The age-gate UX itself is sound in reviewed paths: inclusive 17 restricts, 18/open-ended/no-signal allows, malformed/transient results remain gated for retry, authenticated content stays unmounted while unresolved, and the restriction surface has no in-app bypass. mobile-check, 95 focused tests, and BuzzPushKit 68 XCTest + 33 Swift Testing cases passed. The full Flutter suite’s unrelated voice-note temp cleanup failure is not a PR defect. Native store-signal, TalkBack/VoiceOver, entitlement/signing, and real deadline observation remain confidence gaps.

@brow

brow commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@brow

brow commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@builderbot review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be88a99ee7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread mobile/ios/Runner/AppDelegate.swift Outdated
@brow
brow dismissed stale reviews from wesbillman, jedwards27, and jedwards27 September 14, 2026 20:48

blockers resolved

Signed-off-by: Tom Brow <tomb@block.xyz>
@brow

brow commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@brow

brow commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@builderbot review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d9f13315a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread mobile/lib/shared/community/community_provider.dart Outdated
Signed-off-by: Tom Brow <tomb@block.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz>
@brow

brow commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@brow

brow commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@builderbot review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: 6ba37f8ee0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@brow
brow enabled auto-merge (squash) September 15, 2026 00:17

@jedwards27 jedwards27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:bot: Jude’s code review agent — APPROVE at exact head 6ba37f8ee0da00dc70a7061f5a832f81f550cef1.

The two prior blockers are fixed:

  • mobile/lib/shared/community/community_provider.dart:230-327 now serializes suspension, restore, storage reload, and ordinary exports through one mutation tail and maintains one resource-coherent successful fingerprint. The regressions at mobile/test/shared/community/community_provider_test.dart:675-782 cover the stale ordinary [] → strict [C] → remove C → ordinary [] clear and restore/removal ordering races.
  • mobile/ios/BuzzPushKit/Sources/BuzzPushKit/BuzzNotificationHandoff.swift:3-33 takes exactly-once handoff ownership under a lock, synchronously chooses and delivers the resolved or restricted fallback, then performs cleanup best-effort. BuzzNotificationHandoffTests.swift:7-49 covers stalled cleanup plus late resolution.

Integrated review found no remaining author-actionable defect. Product behavior remains fail-closed while evidence is unresolved: 17 restricts, 18 allows, malformed/operational failures remain gated, authenticated navigation stays unmounted, and restriction/retry UI remains non-bypassable and accessible by construction.

Exact-head evidence on clean worktrees:

  • just mobile-check: PASS (format + Flutter analyzer).
  • Full Flutter suite: 2,123 PASS.
  • Focused community/age/push suite: 74/74 PASS.
  • swift test for BuzzPushKit: 68 XCTest + 38 Swift Testing PASS.
  • Causal mutations independently made each new regression fail, then were reverted; tree returned clean.
  • Current GitHub Mobile, Mobile Swift, Security, and DCO result lanes are terminal green.

Residual confidence gaps, not author defects: no independent physical-device store-age journey, signed release-profile observation, accessibility hardware pass, or real notification-service deadline exercise. Mobile release/device QA owns those checks. Any new head invalidates this approval pending delta review.

@brow
brow merged commit f78a32c into main Sep 15, 2026
87 checks passed
@brow
brow deleted the mobile-age-signal-gate branch September 15, 2026 12:21

@jedwards27 jedwards27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE

Reviewed: c045321a7fb3ca8939f28519ce7a555a6f597728..6ba37f8ee0da00dc70a7061f5a832f81f550cef1 (exact head 6ba37f8ee0da00dc70a7061f5a832f81f550cef1)

Risk: high — this changes a launch-time access gate, native store-age bridges, persisted push eligibility, and iOS notification-extension expiry behavior.

Behavior/contracts traced: Flutter launch gating and retry/restriction states; the 17/18 boundary and malformed/missing/error signals; Android/iOS native payload boundaries; community snapshot serialization, dedupe, restore, and removal persistence; push badge/notification cleanup; iOS NSE exactly-once handoff and deadline fallback; accessibility semantics and navigator mounting.

Findings: no blocking or non-blocking code defect found at this head. The two prior blockers are resolved:

  • mobile/lib/shared/community/community_provider.dart:230-327,421-477 now uses one mode-sensitive successful-resource fingerprint and one mutation tail across suspension, restore/storage reload, exports, persistence, and native clear. The ordering regressions at mobile/test/shared/community/community_provider_test.dart:675-782 cover strict→ordinary removal, restore-vs-mutation, and stale-read removal races.
  • mobile/ios/BuzzPushKit/Sources/BuzzPushKit/BuzzNotificationHandoff.swift:3-33 takes exactly-once delivery ownership before post-handoff best-effort cleanup; mobile/ios/NotificationService/NotificationService.swift:51-132 uses it for normal and expiry completion. The stalled-cleanup/late-resolution regression is at mobile/ios/BuzzPushKit/Tests/BuzzPushKitTests/BuzzNotificationHandoffTests.swift:7-49.

Product/UI review also found the boundary correct (17 restricted, 18 allowed), authenticated content unmounted while checking/retryable/restricted, cleanup enforced while access is denied, retry recoverable, and the restriction UI bounded, safe-area aware, and semantically labeled.

Author action: none.

Verification owner: Mobile release/device QA for signed store-profile behavior, the real iOS notification-service deadline, Android/iOS store-age journeys, and physical-device VoiceOver/TalkBack/large-text observation.

Validation at matching clean HEAD:

  • full flutter test: 2,123 passed
  • dart format --output=none --set-exit-if-changed . && flutter analyze: passed
  • focused Flutter community/age/push suites: 74/74 passed
  • swift test in mobile/ios/BuzzPushKit: 68 XCTest + 38 Swift Testing passed
  • just mobile-check: passed (555 files format-clean; analyzer clean)
  • git diff --check: passed
  • causal mutation proof: collapsing strict/ordinary fingerprint modes failed the exact removal regression, then restoration returned the tree clean
  • causal mutation proof: moving cleanup before fallback failed the expiry regression, then restoration returned the tree clean
  • refreshed GitHub head remained exact, mergeable, and terminal green across Mobile, Mobile Swift, Security, and DCO result lanes. The Codex run/post jobs were skipped after authorization while the repository Security Domain passed.

Manual/native evidence: source and automated boundary evidence only; no signed store profile, physical-device native prompt, accessibility pass, or real NSE deadline was independently observed.

Residual risk: native store SDK/profile behavior and deadline timing remain release/device confidence gaps, not identified author defects.

— :bot: Jude’s code review agent

baxen added a commit that referenced this pull request Sep 15, 2026
…ey-client

* origin/main:
  Fix desktop onboarding regressions (#7659)
  Deduplicate thread context by ACP session delivery (#7620)
  feat(mobile): hard-block under-18 users on the store age signal (#4665)

Signed-off-by: Bradley Axen <baxen@squareup.com>
brow added a commit that referenced this pull request Sep 15, 2026
…eway-origin

* origin/main:
  Fix desktop onboarding regressions (#7659)
  Deduplicate thread context by ACP session delivery (#7620)
  feat(mobile): hard-block under-18 users on the store age signal (#4665)
  Document incoming Buzz turn structure (#7624)
  Refresh desktop onboarding flow (#7528)

Signed-off-by: Tom Brow <tomb@block.xyz>
brow added a commit that referenced this pull request Sep 15, 2026
…ush-cache-offload

* commit '41c5ace93740261ee5a5d962c2a17e8d846c2c1b':
  perf(mobile): move profile sig checks off main thread (#7648)
  perf(mobile): avoid redundant message list sorting (#7647)
  perf(mobile): avoid reparsing unchanged Markdown (#7649)
  Fix desktop onboarding regressions (#7659)
  Deduplicate thread context by ACP session delivery (#7620)
  feat(mobile): hard-block under-18 users on the store age signal (#4665)
  Document incoming Buzz turn structure (#7624)
  Refresh desktop onboarding flow (#7528)
  Fix Apple Silicon iOS simulator builds (#7646)

Signed-off-by: Tom Brow <tomb@block.xyz>
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.

3 participants