Skip to content

Bring synced Solo chats and projects to mobile - #8337

Merged
klopez4212 merged 27 commits into
mainfrom
kennylopez-mobile-agent-sessions
Oct 15, 2026
Merged

klopez4212 merged 27 commits into
mainfrom
kennylopez-mobile-agent-sessions

Conversation

@klopez4212

@klopez4212 klopez4212 commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Bring desktop Solo chats and project organization to mobile, with synced collapsible sections, shared unread highlights and tab badges, agent selection, shared search, native iOS creation sheets, and inline typing bubbles that transition into replies.

Resolve Solo placement for every chat entry route, retain encrypted organization snapshots for offline reading, and let users resume or discard unfinished chat and project setup without deleting existing messages.

Related issue

Related: #6565; expandable agent transcripts remain separate work.

Testing

  • Fresh Solo read state seeds each active chat from its captured initial last-message timestamp before exposing row/section/tab unread state. Baselines survive intervening channel updates and reset across identity/community boundaries while surviving read-state readiness changes. Regressions cover multiple chats, events before read-state readiness and during/after seeding, and identity changes; removing either the seed or the display gate fails them.
  • Chat completion reconciles a retained Solo-save journal even when placement is already confirmed. False/throwing cleanup regressions ensure the outer intent remains until reconciliation and only one placement is published. Typing terminal-close loops remain bounded; the retry budget resets after an uninterrupted eight-second health interval or transport reconnect.
  • Typing retry budgets reset after sustained recovery; invalid Solo updates retain cached rows with a retry warning that survives failed refreshes. Project names use the editors’ 120-grapheme limit, including emoji and combining characters. Regression coverage exercises repeated recovery, invalid live/refresh heads, and character-limit boundaries.
  • Rebased onto current main, preserving the newer Search controls, Huddle timeline filtering, and message-media layout.
  • Failed project journal writes reload storage before claiming recovery and reopen the entered name for retry. Typing subscription rejections are caught; terminal closures clear stale indicators and retry with a bounded backoff, canceled on disposal. Regression tests cover both false/throwing storage writes and initial/late subscription rejection.
  • Explicit ordinary destinations skip optional Solo lookup waits. Generic destinations perform one bounded lookup in the destination (search no longer duplicates it); an unavailable classification falls back to ordinary sending per the product owner's explicit choice. Positively identified Solo destinations use Solo providers.
  • Terminal Solo subscription closure preserves cached rows and exposes live-update Retry. Page coverage verifies warning visibility, usable rows during recovery, and a subsequent terminal close. Removing the warning or the immediate ordinary-route guard fails its regression.
  • Generic channel entries share an ordinary default when Solo classification is unavailable, per the requested product behavior. Known Solo placement takes precedence; callers can explicitly require unresolved placement to remain blocked. Bounded initial lookup preserves known Solo deep-link routing.
  • Dirty newest snapshots and offline-save warnings survive transport reconnects; Retry persists that same event even if the relay returns an older head. Community changes replace the service, and agent-directory reconnect refresh remains intact.
  • Pending-save discard reloads failed removals. Repeated reconnect testing confirms typing subscriptions are released on provider rebuild and disposal; removing the existing cleanup fails the regression.
  • Ordinary Home/create routes explicitly preserve private-channel sending during Solo failures; identified Solo sends use the Solo sender and explicit unresolved routes remain fail-closed. Solo unread replies beyond the initial 200-event page are loaded through the oldest-unread boundary.
  • Chat/project/agent cleanup reloads failed removals, retains same-process recovery, and protects replaced records. False/throw regressions verify retries do not duplicate creation or membership. Route, unread, and cleanup guard-removal mutations each fail their regression.
  • Ordinary channels, DMs, and forums remain sendable when optional Solo sync fails; explicit unresolved placement stays blocked. Controlled cache races retain the newest verified snapshot, keep usable chats visible, and retry offline persistence without stale writes. Both protection-removal regressions fail as expected.
  • Confirmed journal cleanup checks false/throwing removal and exact-record identity. Interrupted agent choices are visible immediately, identify the saved agent, and cover Resume/Later/Discard with accessible name/key-fallback controls.
  • Notification deep links preserve the contiguous history cursor; same-second messages infer the newest agent consistently. Failed offline-cache writes surface Retry, with false/throwing storage failures and offline restart covered.
  • Composite history cursors cover 350 same-second events plus older history; removing the ID cursor makes the regression fail. Agent changes now journal before granting access, with restart/failure and Resume/Later/Discard widget coverage. Signed malformed profiles remain isolated.
  • Native iOS avatar tests passed on the simulator: visible-row loading, three-request concurrency, streamed byte limits, response validation, downsampling/pixel limits, cancellation, and visible avatar updates.
  • Solo and Home share observed-event/read-marker logic. Widget coverage verifies unread rows, collapsed-section indicators, the tab badge before first Solo visit, message/thread reads, forced unread, and filtering archived/nonmember/unplaced chats.
  • Chat intent is saved before ownership and organization preflight; tests cover interrupted ownership lookup and a disconnect while the native creation form is open.
  • Mobile analysis, formatting, file-size checks, and full mobile tests passed at 1d4c41354.
  • Project creation persists its encrypted name/UUID before connectivity checks or relay reads. Restart tests cover Resume/Later/Discard, scope isolation, stale-intent rejection, and lost acknowledgements. Removing the pre-network save makes all four production-flow regressions fail.
  • Regression coverage includes notification/Activity routing, inline replies, unknown-placement send protection, restart recovery/discard, and encrypted offline cache isolation/refresh.
  • Earlier feature build exercised on a physical iPhone with existing account/community data; review follow-ups have not been reinstalled on the device. UIKit agent-row accessibility checks passed on an iOS simulator.
  • Earlier cross-platform just ci stopped on the existing buzz-acp test signals_cancel_startup_turn_and_pending_stdin_without_hanging (process exit-code assertion); no Rust production changes are included in this PR.

Remaining review limitation

Agent discovery is bounded to 10 pages / 1,000 profiles with automatic retries disabled. Owner-scoped discovery remains open because the current relay ignores #auth filters; supporting that query requires a relay change.

Snapshots

Sample data, shared Flutter/Android surface. Native iOS uses platform sheets and controls.

Solo: projects and chats New chat Choose an agent
Solo with collapsible projects and chats New chat form Agent selection list

@klopez4212
klopez4212 requested a review from a team as a code owner October 14, 2026 22:57
klopez4212 added a commit that referenced this pull request Oct 14, 2026

@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: 04892e721f

ℹ️ 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/me/me_sync.dart Resolved
Comment on lines +47 to +53
sync.check();
final events = await session.queryRelay([
NostrFilter(
kinds: const [0],
authors: pubkey == null ? null : [pubkey],
limit: pageSize,
extensions: {'page': page},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Scope assistant discovery instead of scanning every profile

Opening Me starts this unbounded page loop over every kind-0 profile in the community, even though only profiles whose auth tag names the current owner can qualify. In communities with thousands of humans and agents this performs hundreds of sequential HTTP queries and signature checks before the assistant picker or sending can work; query by the owner tag and impose a page/result bound rather than draining the entire directory.

AGENTS.md reference: AGENTS.md:L240-L248

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 Partially addressed in e707134: discovery is capped at 10 pages / 1,000 profiles, oversized responses are rejected, repeated event verification is skipped, and automatic provider retries are disabled. Selected-agent revalidation remains author-scoped. Owner-scoped discovery is still OPEN: POST /query parses nostr::Filter, whose generic tag deserializer recognizes only one-letter tags and silently discards #auth. Sending #auth would still scan the community. A proper owner-scoped query needs relay support; I have not introduced a client query that falsely claims that scope. The bounded-request regression covers the current fallback.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 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-10-15T20:34:33.345930Z 1d4c413 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: ab821d167f

ℹ️ 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/me/me_assistants.dart Resolved

@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 base 2f79374f4867035c33dace91c683440e7e011826 → exact head ab821d167ffc49865d27ef29718996fe717b7203. The integrated systems and product review found seven author-actionable defects:

  1. P1 — Me history actions mutate an unwatched provider. The page renders meMessagesProvider (mobile/lib/features/channels/channel_detail_page.dart:288-289), but _MessageList reconstructs channelMessagesProvider(channelId).notifier for history pagination, unread-boundary loading, and oldest-message jumps (mobile/lib/features/channels/channel_detail_page/message_list.dart:92,529-535). In a Me chat beyond the initial window, those actions extend the ordinary timeline while the visible Me timeline remains stuck.

    • Author action: inject/use the selected Me notifier for every history action; add >200-event, oldest-unread, and oldest-jump Me regressions.
  2. P1 — a superseded ambiguous save can permanently wedge Me sync. Startup retains and retries the older signed pending event (mobile/lib/shared/me/me_sync.dart:172-190) even after another device advances the remote head, with no safe superseded-head recovery. The current test codifies rejection after restart rather than convergence.

    • Author action: detect a definitively newer competing head and provide safe merge/rebase or explicit discard recovery; prove restart convergence without losing newer remote or local user state.
  3. P1 — assistant discovery sequentially drains the community-wide profile directory. mobile/lib/shared/me/me_assistants.dart:43-81 pages through every kind-0 profile with no page/result bound rather than querying owner-scoped candidates. Large communities can make picker readiness impractical.

    • Author action: use owner-tag-scoped discovery with an explicit page/result bound; add a large-directory regression proving bounded requests and work.
  4. P2 — optional Me state gates ordinary search navigation. _openSearchChannel awaits meGroupsProvider.future (mobile/lib/features/search/search_page.dart:765-788), so malformed or unavailable Me sync prevents opening a known ordinary channel/message result.

    • Author action: use cached placement when available and fall back to ordinary routing on Me-specific failure; test ordinary results under malformed and unavailable Me state.
  5. P1 — new-Me-chat creation is not crash-durable before relay side effects. Channel creation and member writes occur before any durable creation journal (mobile/lib/features/channels/me/native_new_me_chat.dart:102-124). Process death can orphan relay state, lose UUID/name/assistant intent, and permit duplicate retry creation, contrary to the recovery contract in VISION_MOBILE.md:12,27.

    • Author action: journal intent before the first relay write, then resume idempotently or clean up deterministically; add process-death tests at every side-effect boundary.
  6. P1 security/product trust — mobile NIP-OA verification is weaker than desktop. Mobile validates condition syntax and signature, returns the first valid auth tag, and cannot evaluate signed kind=/created_at clauses against the profile event (mobile/lib/shared/crypto/nip_oa.dart:20-54). Desktop requires a valid kind-0 event, exactly one auth tag, and event-aware condition evaluation (desktop/src-tauri/src/nostr_convert.rs:58-100). An inapplicable or ambiguous authorization can therefore qualify an assistant for a private Me chat.

    • Author action: pass the complete profile event, enforce desktop-equivalent cardinality and all signed conditions during discovery and send-time revalidation, and test duplicate auth plus mismatched kind/time conditions.
  7. P2 accessibility — locked/empty native iOS assistant rows claim to be actionable. Selection rejects locked or empty states (mobile/ios/Runner/NativeProfileTextEditor.swift:504-515), but rendering always adds the .button accessibility trait (mobile/ios/Runner/NativeProfileTextEditor.swift:566-578). VoiceOver announces an action that cannot occur.

    • Author action: remove the button trait and expose disabled/not-enabled semantics in both states; add accessibility assertions and validate with VoiceOver.

Exact-head Mobile, Mobile Swift-domain, client-result, and security checks are green. Focused local Flutter execution was blocked before tests ran by the reviewer environment’s objective_c 9.3.0 Apple SDK discovery failure (Bad state: No element); this is a confidence gap, not requested author rework. Physical-device iOS/Android observation and a full mobile release build also remain verification gaps, not additional defects.

Please fix all seven findings and request a fresh review at the new immutable head.

…nt-sessions

Signed-off-by: kenny lopez <[email protected]>

# Conflicts:
#	mobile/lib/features/channels/channel_detail_page/message_list.dart
@klopez4212

Copy link
Copy Markdown
Contributor Author

🤖 Pushed e7071344427cf5b12a39e8f49f93a9c6d6a0b216, including latest main. Six findings are fixed and their threads resolved: Me history actions, pending-save recovery, search fallback, durable chat creation, event-aware NIP-OA verification, and disabled native agent-row semantics.

Discovery is partially addressed with a 10-page / 1,000-profile bound, oversized-response protection, and no automatic retry loop. Its thread remains open: the relay parses standard nostr::Filter, which ignores multi-letter #auth filters, so owner-scoped discovery needs relay support. Details are in the inline reply.

Validation: full mobile pre-push checks passed after the merge; focused recovery/security/search/history regressions passed; the production UIKit row passed all locked/empty accessibility combinations on an iOS simulator. No new physical-device VoiceOver pass is claimed. Hosted CI is still running. Ready for re-review of the completed fixes and the remaining discovery limitation.

@klopez4212
klopez4212 requested a review from jedwards27 October 15, 2026 11:23

@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: e707134442

ℹ️ 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/me/me_sync.dart Resolved

@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 base b77ba862627c7362a4b863a0a077677d811a7558 → exact head e7071344427cf5b12a39e8f49f93a9c6d6a0b216. The previous seven findings were re-reviewed rather than carried forward. Six are resolved or reduced to a bounded documented limitation, but integrated exact-head review found three new author-actionable P1 product defects:

  1. Me routing is lost outside the Me tab and placement-aware Search path. ChannelDetailPage.personalChat defaults to false and controls the flat timeline, Me message provider/sender, assistant controls, placement check, ownership revalidation, and selected-assistant p tag (mobile/lib/features/channels/channel_detail_page.dart:256-302,639-642,702-723,807-812,913-935). Deep links, Activity messages/drafts/reminders, channel links, Channels, quick actions, profile-launched conversations, and Pulse construct ChannelDetailPage without resolving Me placement (mobile/lib/features/channels/deep_link_dispatcher.dart:144-155; mobile/lib/features/activity/activity_page.dart:264-325; mobile/lib/features/channels/channel_link_navigation.dart:33-36; mobile/lib/features/channels/channels_page.dart:291-296; mobile/lib/features/channels/channels_page/quick_actions_launcher.dart:70-75; mobile/lib/features/profile/user_profile_sheet.dart:48-53; mobile/lib/features/pulse/note_card.dart:240-247). The same synced Me chat therefore becomes an ordinary threaded channel on those routes, hides assistant controls, and can send without Me recipient revalidation/tagging.

    • Author action: centralize placement-aware channel opening or resolve placement in the destination, then cover notification/deep-link, Activity, channel-link, and at least one secondary route at the production seam.
    • Existing inline: #8337 (comment)
  2. One permanently failing creation journal can block all future Me chat creation on that installation. MeChatCreation.save rejects every different intent while a journal exists, and clears the journal only after channel discovery/creation, membership, placement, and journal removal all succeed (mobile/lib/shared/me/me_chat_creation.dart:36-84). Both retry surfaces restore and lock the saved name/assistant, but offer only Retry or dismissal; dismissal does not discard or reconcile the journal (mobile/lib/features/channels/me/new_me_chat.dart:7-17,49-74,114-157; mobile/lib/features/channels/me/native_new_me_chat.dart:8-14,38-80). Revoked agent ownership or permanent relay rejection can therefore wedge New chat forever.

    • Author action: add an explicit reviewed discard/reconcile path, define safe handling for every partially created channel prefix, and prove permanent rejection → discard/reconcile → different chat creation without orphaning or duplicating state.
    • Existing inline: #8337 (comment)
  3. Me organization has no last-known-good offline snapshot. meGroupsProvider starts from live subscribe/head, emits an error when the session is unavailable, and never persists or restores fetched organization state (mobile/lib/shared/me/me_sync.dart:15-85,93-135). On offline relaunch, previously fetched chats/projects disappear behind Retry; the current widget test explicitly expects that failure surface (mobile/test/features/channels/me/me_page_test.dart:310-326). This contradicts the offline-first and cached-channel-list contract in VISION_MOBILE.md:3,10-13,47.

    • Author action: persist an encrypted, account- and community-scoped last-known-good snapshot; emit it immediately and refresh in the background; test offline relaunch, scope isolation, corruption, and live replacement ordering.
    • Existing inline: #8337 (comment)

Prior-finding reconciliation

  • Me history now carries the selected provider/notifier through status, deep-link retention, timeline summaries, pagination, and message-list actions (channel_detail_page.dart:280-293,515,563,639-642,807-810), with long-history regressions.
  • Superseded pending Me saves now retain their base and rebase non-conflicting local edits; conflicts remain durable for explicit review/discard (me_sync.dart:178-289; me_sync_test.dart:131-225).
  • Search now uses cached placement and a bounded ordinary fallback (me_search_placement.dart:4-19).
  • Creation intent is journaled before relay mutation and replayed idempotently across side-effect boundaries (me_chat_creation.dart:19-85; me_chat_creation_test.dart:9-104), but finding 2 remains the missing terminal recovery path.
  • Profile admission now validates the complete signed kind-0 event, exactly one auth tag, and applicable kind/created_at clauses (nip_oa.dart:8-33,47-110).
  • Locked/empty native iOS agent rows expose .notEnabled, not .button, with the production controller exercised across all four state combinations (NativeProfileTextEditor.swift:566-577; MeAgentAccessibilityTests.swift:5-28).
  • Assistant discovery is now finite at 10 × 100 profiles, rejects oversized/repeating pages, disables automatic retry, and fails visibly (me_assistants.dart:14-20,38-94). The relay’s inability to filter multi-letter #auth tags remains a documented scale limitation, not an additional merge blocker now that work is bounded.

Exact-head validation

  • Live PR and clean local checkout both matched base b77ba862627c7362a4b863a0a077677d811a7558 / head e7071344427cf5b12a39e8f49f93a9c6d6a0b216 immediately before submission; git diff --check b77ba862...HEAD passed.
  • Exact-head CI completed successfully for Mobile checks, all three Flutter test shards, Android, aggregate Mobile, Mobile Swift Release, Semgrep, zizmor, and DCO. No failing check was observed. At the final freshness check, Mobile Swift Native and Codex security review were still running.
  • A reviewer-local scoped Flutter command did not reach test execution because objective_c-9.3.0 invoked xcrun on a host whose Xcode license is not accepted. This is a reviewer/tooling confidence gap, not author rework.
  • Source and widget evidence corroborate the three failures. No physical VoiceOver/native listening pass or causal mutation run was completed. The author reports a physical-iPhone release journey and simulator accessibility check; those do not exercise the three remaining restart/routing/recovery failures.

Verification owner after the fixes: code review owns source, production-seam route tests, persistence/isolation tests, and causal recovery mutations; mobile product review owns notification/Activity/channel-link journeys, offline relaunch, and native recovery UX. CI/release owns the two checks that were still in progress.

Residual risk: any new head invalidates this verdict. The bounded community-wide assistant scan may still fail to find assistants beyond 1,000 profiles until relay owner-tag filtering exists, but it terminates visibly and does not create an unbounded client loop.

Cleanup: exact-head review checkout and scratch/build artifacts will be removed after this verdict is published; no app/login/keychain state was used.

@klopez4212

Copy link
Copy Markdown
Contributor Author

🤖 Updated previews with the Solo name. Sample data on the shared Flutter/Android surface; native iOS uses platform sheets and controls.

Solo

Collapsible projects and chats with the updated tab title.

01-solo

New chat

Name and agent selection in one sheet.

02-new-chat

Choose an agent

Scrollable agent list.

03-agent-picker

klopez4212 added a commit that referenced this pull request Oct 15, 2026
@klopez4212 klopez4212 changed the title Bring synced Me chats and projects to mobile Bring synced Solo chats and projects to mobile Oct 15, 2026
@klopez4212
klopez4212 requested a review from jedwards27 October 15, 2026 11:55
@klopez4212

Copy link
Copy Markdown
Contributor Author

🤖 Jude’s latest review targets e7071344427cf5b12a39e8f49f93a9c6d6a0b216. All three findings are addressed in the current pushed head, da0b82240484dcc32c9aed73ea632ee7947258ee:

Each thread has a detailed reply and is resolved. Full mobile pre-push checks passed, including analysis and the full Flutter suite; the channel-detail/recovery suite passed 344 tests. The new follow-ups have not been reinstalled on the physical device. Re-review was requested on the current head.

The bounded agent-discovery limitation remains documented and its thread remains open; Jude’s review explicitly treats it as non-blocking now that work is bounded. No additional code changes or empty commit were needed to address this 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: da0b822404

ℹ️ 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".

@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

Verdict: REQUEST CHANGES
Reviewed: b77ba862627c7362a4b863a0a077677d811a7558..da0b82240484dcc32c9aed73ea632ee7947258ee (exact live head da0b82240484dcc32c9aed73ea632ee7947258ee)
Risk: high — mobile Solo routing, encrypted account/community-scoped persistence, durable mutation recovery, and user-visible offline behavior.

The previous three blockers were re-reviewed rather than carried forward. All-route Solo placement, chat-journal discard/recovery, and encrypted last-known-good organization snapshots are resolved. One author-actionable defect remains.

Blocking finding

[P1] Offline or interrupted New project creation loses the accepted intent before it becomes durable. Cached Solo state makes New project actionable (mobile/lib/features/channels/me/me_page.dart:61,85-103). After the naming sheet returns, the code generates a UUID and immediately calls MeSync.update() without persisting either the reviewed name or stable ID (me_page.dart:88-102). update() checks connectivity before any journal write (mobile/lib/shared/me/me_sync.dart:235-243) and performs relay head() reads before applying the change closure (me_sync.dart:250,283-300); its pending write occurs only later, after those reads and signing (me_sync.dart:323-329). Offline, the operation therefore throws before retaining the project intent, while perform() reduces the failure to a snackbar (me_page.dart:64-81). Retrying starts with a blank form; process death in the same prefix has the same loss. The exact-head automated inline independently identifies this path: #8337 (comment).

This contradicts VISION_MOBILE.md:10-12,27: accepted user input must survive interruption and offline-first flows must not silently discard it.

Author action: persist an encrypted account- and community-scoped New project intent containing the stable UUID and reviewed name before the first network dependency. On restart expose truthful Resume/Later/compare-and-delete Discard recovery. Add production-seam tests for offline/interruption → restart/resume and stale-intent-safe discard; mutation-removing the pre-network persist must fail them.

Verification owner: author for the persistence/recovery implementation and causal tests; reviewer for exact-new-head ordering/scope/idempotency; Mobile CI for the affected gates.

Prior-blocker reconciliation

  • All-route Solo placement: fixed at the destination. placement_route.dart:23-44 resolves scoped organization before constructing the page; provider/send behavior follows the resolved value (channel_detail_page.dart:281-303), and unknown placement remains readable but send-blocked (channel_detail_page.dart:921-949). The default-entry regression covers assistant UI, inline replies, and selected-provider deep-link hydration (channel_detail_page_test.dart:10244-10301).
  • Chat journal recovery: fixed. The gate runs before either platform flow and offers Later / Discard setup / Resume (native_new_me_chat.dart:8-38). Discard compare-checks the reviewed scoped intent while preserving partial channel/messages (me_chat_creation.dart:59-70). Unit/widget tests cover stale-intent rejection, offline discard, different-intent creation, and Resume/Discard after restart (me_chat_creation_test.dart:38-68; me_page_test.dart:227-319).
  • Offline organization snapshot: fixed in source and causal tests. The encrypted cache binds community + pubkey, retains the signed event for replacement ordering, re-verifies the account/coordinate/signature/encrypted envelope, refuses older/null replacement, emits cached state before network work, and retains it on refresh/subscription failure (me_sync.dart:15-100,137-177,195-212). Tests cover ciphertext-at-rest, account/community isolation, offline relaunch, corruption recovery, empty state, stale/null rejection, and cached-first live replacement (me_sync_test.dart:78-219).

Validation and confidence gaps

  • Exact clean local checkout and live PR matched the coordinates above immediately before submission; git diff --check b77ba862...HEAD passed.
  • Exact-head Mobile Checks, all three Flutter shards, Android, aggregate Mobile, Client Results, Mobile Swift Release, Semgrep, zizmor, and DCO are green. At final freshness, Mobile Swift Native and Codex Security Review were still running; no required failure was observed.
  • Focused local Flutter execution did not reach tests because the reviewer host’s objective_c 9.3.0 native-assets SDK discovery failed with Bad state: No element. That is reviewer/tooling debt, not additional author action.
  • No physical offline-restart/native accessibility journey or causal mutation was run. The Later branch lacks a direct widget assertion. These are confidence gaps, not separate blockers.

Residual risk: project names/IDs can be lost precisely in the cached-offline flow this head introduces. Any new head expires this verdict.

@klopez4212

Copy link
Copy Markdown
Contributor Author

🤖 Follow-up fixes pushed in 5fc82e4: chat recovery reconciles a confirmed-but-retained Solo save journal before clearing the outer intent, and typing close retries reset only after sustained health rather than subscription admission. Both new Codex threads have regression coverage, replies, and resolution. All 36 focused tests and the full mobile pre-push checks passed. Jude approved the preceding head; requesting fresh review of this small follow-up. Hosted CI remains a separate gate, and the relay owner-discovery limitation stays open. @codex review

@klopez4212
klopez4212 requested a review from jedwards27 October 15, 2026 17:57
@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: 5fc82e4ba7

ℹ️ 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".

@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

Verdict: APPROVE
Reviewed: d61fe2071d2b3d8e56dd931947f16bfe0d6173fe..5fc82e4ba7ed980ac130c2969aa2071bf42e6172 (new-head delta independently re-reviewed from previously approved a2cfb8a912a50f69c640daeaf062c372b08dbf63)
Risk: high — messaging lifecycle, bounded retry behavior, and durable Solo creation recovery

Behavior/contracts traced: terminal typing-subscription close → bounded retry → sustained-health/transport reset; confirmed placement with a retained inner Solo-save journal → cleanup reconciliation → outer-intent clearing; identity/generation/disposal fences and causal regression coverage.

Findings: no unresolved author-actionable defect. The retry budget now survives mere re-admission, retries at bounded 1/2/4-second intervals, exhausts after the fourth terminal close, and resets only after eight uninterrupted healthy seconds or a transport-generation rebuild (mobile/lib/features/channels/channel_typing_provider.dart:43-127). The regression exercises exhaustion, reconnect reset, and sustained-health reset (mobile/test/features/channels/channel_typing_provider_test.dart:93-134). Chat completion now re-enters placement reconciliation when placement is already confirmed but the inner journal remains (mobile/lib/shared/me/me_chat_creation.dart:100-113); false/throwing cleanup coverage proves staged clearing and one relay write (mobile/test/shared/me/me_sync_test.dart:129-169).

Author action: none.
Verification owner: CI/release gate for the still-running Mobile Swift Native and Codex Security Review jobs; reviewer/device tooling for any additional exact-head physical-device and accessibility journey.

Validation: at clean exact HEAD 5fc82e4ba7ed980ac130c2969aa2071bf42e6172, git diff --check d61fe2071..HEAD passed and . ./bin/activate-hermit && just mobile-check passed (754 files format-clean; flutter analyze reported no issues). Hosted Mobile Checks, Flutter test shards 1/3–3/3, Android, Mobile aggregate, Swift Release, Semgrep, zizmor, and DCO were green at the final pre-submit check.

Manual/native evidence: no new exact-head physical-device journey was independently observed. That is a confidence gap, not author rework.
Residual risk: the two named hosted jobs were still in progress at pre-submit. Any new head or PR-caused required-gate failure invalidates this approval.

@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

Verdict: APPROVE
Reviewed: d61fe2071d2b3d8e56dd931947f16bfe0d6173fe..5fc82e4ba7ed980ac130c2969aa2071bf42e6172 (exact head 5fc82e4ba7ed980ac130c2969aa2071bf42e6172)
Risk: high — mobile entry routing, long-lived relay lifecycle, and durable Solo setup journals can silently misroute conversation state or strand recovery if their ownership and retry contracts are wrong.

Behavior/contracts traced: ordinary/Solo chat selection; bounded terminal typing-close recovery; transport-generation and disposal fencing; retained Solo-save reconciliation after confirmed placement; false/throwing cleanup, restart, replacement identity, and community-scope behavior; single relay publication; causal regressions; integration with the previously approved mobile routing and persistence changes. Independent systems/integration and product/UI adversarial passes converged on the same result.

Findings: no unresolved author-actionable defect remains.

  • Typing recovery now preserves the consecutive terminal-failure budget across short re-admissions, uses bounded 1/2/4-second retries, stops after the fourth terminal close, and resets only after eight uninterrupted healthy seconds or a transport-generation rebuild. Generation/disposal checks fence stale timers and callbacks (mobile/lib/features/channels/channel_typing_provider.dart:43-57,66-127). The regression covers exhaustion, reconnect reset, and sustained-health reset (mobile/test/features/channels/channel_typing_provider_test.dart:93-134).
  • Confirmed Solo placement with a retained inner save journal re-enters idempotent place() cleanup instead of reporting completion with durable work stranded (mobile/lib/shared/me/me_chat_creation.dart:101-113). False and throwing cleanup regressions prove staged journal retention/clearing and exactly one relay placement write (mobile/test/shared/me/me_sync_test.dart:132-169); surrounding coverage exercises restart, replacement identity, disposal, and community fencing.
  • The new-head delta introduces no misleading user-visible success/failure state or accessibility regression found by source review.

Author action: none.

Verification owner: the named hosted CI/security gates own completion; reviewer/tooling owns any future exact-device lifecycle and accessibility observation. Any PR-caused required-gate failure should reopen this approval.

Validation at matching head: clean detached checkout; local and live PR heads both matched 5fc82e4ba7ed980ac130c2969aa2071bf42e6172 immediately before submission. Review-lane validation reported just mobile-check passing (Dart format over 754 files plus Flutter analysis). just mobile-test passed its gateway-recipe checks but could not start Flutter tests because this host has not accepted the Xcode license (xcrun exit 69). Hosted Mobile Checks, all three Mobile test shards, Android, aggregate Mobile, Mobile Swift Release, Semgrep, zizmor, and DCO were green at submission.

Manual/native evidence: no fresh exact-head device or accessibility journey was observed; no native behavior claim is made.

Residual risk: Mobile Swift Native and Codex Security Review were still running at submission. The local Xcode-license failure and absent device observation are confidence gaps, not author rework. Any head movement invalidates this verdict.

@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: 92d88ecf96

ℹ️ 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".

@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

Verdict: REQUEST CHANGES
Reviewed: fea02d174d0762b18b73138abc833d7c140f9718..92d88ecf96a1a25fd667c4e763c9f33c47bf27c2 (exact head 92d88ecf96a1a25fd667c4e763c9f33c47bf27c2)
Risk: high — mobile unread truth, relay catch-up/lifecycle, offline persistence, and the merged iOS notification-extension boundary.

Behavior/contracts traced: Solo organization/routing/recovery and unread state; read-state initialization through relay catch-up, Home filtering, row/section/tab badges; merge resolution with #8369's notification enrichment, native avatar/cache/download/auth boundaries, and Flutter push-cache removal.

Blocking finding

  • [P2] Fresh read state falsely marks pre-existing Solo history unread. ChannelsNotifier._catchUpUnreadEvents includes all active member channels and, when no read marker exists, fetches from timestamp zero (mobile/lib/features/channels/channels_provider.dart:603-624) and records qualifying historical events as unread (:647-668). Ordinary Home channels avoid exposing that bootstrap history by seeding null read marks to lastMessageAt and gating unread presentation until seeding completes (mobile/lib/features/channels/channels_page/body.dart:151-195). But Solo IDs are filtered out before _ChannelsBody (mobile/lib/features/channels/channels_page.dart:223-227), while meUnreadChannelIdsProvider directly exposes computed Solo unread (mobile/lib/features/channels/me/me_unread_provider.dart:8-20) to the app-level tab and Solo rows/sections. On a fresh install/profile, existing Solo conversations therefore appear newly unread until opened. Existing coverage starts with a pre-seeded Solo marker (mobile/test/features/channels/me/me_unread_test.dart:65-72), so it misses this path.

Author action: give active Solo channels the same per-identity initial seeding/display-gating contract as ordinary channels, without hiding genuinely newer events. Add a deterministic ready-but-empty read-state regression proving historical Solo messages do not badge during initialization and a later event does; mutation-check the seed/gate.

Verification owner: author + Flutter CI; reviewer to inspect catch-up/readiness ordering on the next exact head.

Validation

At clean 92d88ecf96a1a25fd667c4e763c9f33c47bf27c2:

  • git diff --check 5fc82e4ba7ed980ac130c2969aa2071bf42e6172..HEAD — pass.
  • git diff --check fea02d174d0762b18b73138abc833d7c140f9718..HEAD — pass.
  • just mobile-check — pass: 748 files format-clean; Flutter analyze clean.
  • just mobile-test — gateway recipe checks passed; Flutter execution could not start because this review host has not accepted the Xcode license.
  • Exact-head hosted Mobile Checks, all three Flutter test shards, Android, Mobile aggregate, Mobile Swift Native and Release, Desktop RC, Semgrep, zizmor, and DCO — success at submission. Codex Security Review remained in progress.

Both independent systems/integration and product/UI/adversarial passes confirmed the unread defect and found no additional author-actionable issue in the merge delta.

Manual/native evidence: no fresh exact-head physical-device observation. Local Swift/Flutter native execution was blocked by reviewer Xcode-license state; that is reviewer tooling debt, not another author action.

Residual risk: exact-head device behavior for enriched Solo notification avatars and extension deadline/network failure remains owned by native/release validation. Any new head invalidates this review.

@klopez4212

Copy link
Copy Markdown
Contributor Author

🤖 Addressed Jude’s fresh-profile Solo unread finding in 72466da. Active Solo chats now receive the same initial lastMessageAt baseline as Home before unread is exposed. Baselines are captured before deferred writes so a newer event during initialization stays unread; identity/community/readiness boundaries reset initialization. Deterministic ready-but-empty tests cover multiple chats, historical catch-up, new events during/after initialization, and identity changes; existing row/section/tab behavior still passes. Removing the seed fails the baseline regression, and removing the gate exposes the false unread state. Full mobile formatting, analysis, file-size checks, and Flutter tests passed in the pre-push gate. The matching inline thread is replied to and resolved; hosted CI and renewed approval remain separate gates. The documented relay discovery limitation stays open. @codex review

@klopez4212
klopez4212 requested a review from jedwards27 October 15, 2026 19:57

@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: 72466da975

ℹ️ 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".

@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

Verdict: REQUEST CHANGES
Reviewed: fea02d174d0762b18b73138abc833d7c140f9718..72466da975f7b27e2125f8101fb9f21b20b5464d (exact head 72466da975f7b27e2125f8101fb9f21b20b5464d)
Risk: high — mobile unread truth crosses channel discovery, relay catch-up, read-state initialization, identity/community lifecycle, and three badge surfaces.

Behavior/contracts traced: fresh Solo history seeding and display gating; channels-ready/read-state-not-ready ordering; events before and after baseline capture; identity/community reset; monotonic read-marker ownership; row, collapsed-section, and tab presentation. The systems/lifecycle pass initially cleared the races after readiness; the product/adversarial pass and the exact-head inline finding exposed an earlier false→true readiness ordering that those tests do not exercise.

Blocking finding

  • [P2] A genuinely new Solo reply can be permanently seeded as read when channels become available before read-state readiness. MeUnreadChannelIds.build returns while reads.isReady is false before it records any channel baseline (mobile/lib/features/channels/me/me_unread_provider.dart:19-25). The seed holder also watches (pubkey, isReady), so it is recreated when readiness becomes true (:75-80). If Solo channels load with old history, then a live reply advances lastMessageAt before read-state initialization finishes, the ready build first captures that already-advanced timestamp (:34-40) and seeds it (:45-56). The new reply is therefore treated as read and never lights the Solo row, collapsed section, or tab. The added regressions construct read state ready from its first build (mobile/test/features/channels/me/me_unread_test.dart:72-83,109-179); they prove the later “reply after baseline capture” race, not this distinct ordering. This matches the exact-head inline finding: #8337 (comment)

Author action: capture each initial active Solo channel timestamp as soon as the channel snapshot plus identity/community scope are known, preserve that baseline across the same scope’s false→true read-state transition, and defer only marker writes and badge exposure. Add a deterministic regression where read state starts not ready, channels expose old history, a newer reply arrives, then read state becomes ready: old history stays unbadged and the newer reply badges at row, collapsed-section, and tab surfaces. Mutation-check moving baseline capture back below readiness.

Verification owner: author + Flutter CI, followed by exact-head reviewer inspection.

Validation

At clean local HEAD 72466da975f7b27e2125f8101fb9f21b20b5464d:

  • git diff --check 92d88ecf96a1a25fd667c4e763c9f33c47bf27c2..HEAD — pass.
  • git diff --check fea02d174d0762b18b73138abc833d7c140f9718..HEAD — pass.
  • just mobile-check — pass: 748 files unchanged by formatting; Flutter analysis found no issues.
  • just mobile-test — gateway recipe checks passed; Flutter execution then could not start because this reviewer host’s objective_c native-assets hook received empty xcrun/SDK output.
  • Exact-head hosted Mobile Checks, all three Flutter test shards, Android, aggregate Clients Results, aggregate Mobile, Mobile Swift Release, Semgrep, zizmor, and DCO were green. Mobile Swift Native and Codex Security Review remained in progress immediately before submission.

Manual/native evidence: no fresh exact-head device or accessibility journey was observed; no physical-device claim is made.

Residual risk: the local Apple toolchain failure, pending hosted Swift/security gates, and absent device observation are confidence gaps owned by reviewer tooling/CI/native verification, not additional author rework. Any head movement invalidates this verdict.

@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

Verdict: REQUEST CHANGES
Reviewed: fea02d174d0762b18b73138abc833d7c140f9718..72466da975f7b27e2125f8101fb9f21b20b5464d (exact head 72466da975f7b27e2125f8101fb9f21b20b5464d)
Risk: high — mobile unread truth, identity/community-scoped initialization, relay catch-up ordering, and row/section/tab badge state.

Blocking finding

  • [P2] A genuinely new Solo reply can be permanently seeded as read when channels become available before read-state readiness. meUnreadChannelIdsProvider reads the channel snapshot but returns while reads.isReady == false, before recording any baseline (mobile/lib/features/channels/me/me_unread_provider.dart:19-25). Its seed holder watches (pubkey, isReady), so the false→true transition creates a new empty seed state (:75-80). The first baseline is then captured from each channel's current lastMessageAt (:34-40). If a live reply advances that timestamp while read state is still loading, the later seed writes the reply timestamp as read (:45-56), and its row, collapsed-section, and tab indicators never appear. Existing new tests construct read state ready from their first build, so their covered "event during initialization" race begins only after baseline capture and does not exercise this ordering.

Author action: capture each initial active Solo channel timestamp as soon as channel snapshot plus identity/community scope are known, preserve it across the false→true read-state transition, and defer only read-state writes and badge exposure. Add a deterministic regression where reads begin unready, old Solo history is visible, a newer reply arrives, reads become ready, old history remains unbadged, and the newer reply badges at row, collapsed-section, and tab surfaces. Mutation-check moving capture back behind readiness.

Verification owner: author + full exact-head Flutter CI, followed by reviewer inspection of the readiness delta.

Integrated result

Both assigned lanes are integrated. Systems review found the ordinary ready-state seeding path sound: captured baselines survive channel rebuilds, newer existing markers win, empty chats remain eligible for their first event, scope changes reset state, and disposal fences deferred writes. Product/adversarial review found the distinct channels-ready/read-state-unready boundary above; source reinspection confirmed it, so that evidence supersedes the narrower clearance. No additional author-actionable defect was established in Solo routing/recovery or the merged notification/avatar paths.

Validation and confidence gaps

  • Exact-head git diff --check and just mobile-check passed; formatting covered 748 files and Flutter analysis was clean.
  • Hosted Mobile Checks, all three Flutter shards, Android, Clients aggregate, Mobile aggregate, and Swift Release are green at review time.
  • Local just mobile-test reached the gateway-recipe pass but Flutter startup was blocked by this reviewer host's unaccepted Xcode license / objective_c native-assets SDK lookup. Mobile Swift Native and Codex Security Review remained in progress. These are reviewer/CI confidence gaps, not additional author work.
  • No fresh physical-device observation of notification-extension deadline/network failure was completed; native/release validation owns that residual risk.

Any new head invalidates this review.

@klopez4212

Copy link
Copy Markdown
Contributor Author

🤖 Addressed the readiness-ordering finding in 1d4c413 and resolved the matching inline thread. The initial history baseline now survives read-state initialization, so a newer reply remains unread on the row, collapsed project section, and Solo tab. The deterministic regression passes and fails when baseline capture is moved back behind readiness. Focused tests, mobile checks, and the full pre-push mobile test suite passed. Fresh Jude review requested; hosted CI and approval are pending. The previously documented relay-dependent owner-scoped discovery limitation remains open.

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 1d4c413545

ℹ️ 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".

@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

Reviewed exact head 1d4c41354564c093d4976f410692c104253c2fb2 against base fea02d174d0762b18b73138abc833d7c140f9718.

The corrective delta closes the Solo unread readiness race at the right boundary: it captures each active chat's initial lastMessageAt before read-state readiness, preserves that baseline across the readiness transition, resets it when pubkey/relay scope changes, and seeds only when no effective marker exists. A reply arriving while reads initialize therefore remains newer than the seeded marker instead of being swallowed.

The production-seam regression covers the unready → reply → ready sequence and verifies marker 20 against reply 21, plus the Solo tab, row, collapsed-project, read, subsequent-reply, thread-read, and forced-unread surfaces. Both independent review lanes found no unresolved author-actionable defect.

Validation on this exact head:

  • just mobile-check passed: formatting unchanged and Flutter analysis reported no issues.
  • git diff --check passed; exact-head worktrees were clean.
  • Hosted Mobile Checks, all three Mobile test shards, Android, Clients Results/Mobile aggregate, Swift Release, DCO, Semgrep, and zizmor passed at review time.

Confidence gaps, not author defects:

  • Local Flutter/native execution was blocked before collection by the reviewer host's unaccepted Xcode license / xcrun SDK lookup. Reviewer tooling/native validation owns this; no author action.
  • Physical-device/native observation was not repeated for the follow-up. Native/device validation owns this if required.
  • Mobile Swift Native and Codex Security Review were still running at the final pre-submit refresh. Those named CI gates own completion; no author action absent a PR-caused failure.

Author action: none.

@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

Verdict: APPROVE

Reviewed: fea02d174d0762b18b73138abc833d7c140f9718..1d4c41354564c093d4976f410692c104253c2fb2 (exact head 1d4c41354564c093d4976f410692c104253c2fb2). The prior clearance at 72466da975f7b27e2125f8101fb9f21b20b5464d was treated as expired; this is a fresh review of the corrective delta plus its affected unread/UI paths.

Risk: high — the change controls virtual unread state across asynchronous read-state initialization, identity/community ownership, persistent marker writes, and three user-visible surfaces.

Behavior/contracts traced: mobile/lib/features/channels/me/me_unread_provider.dart:25-42 now captures the active Solo channel's initial lastMessageAt once identity and organization are known, before readiness can admit a newer reply. Readiness gates only writes/display. :46-64 seeds only a still-missing effective marker, and :76-81 retains the baseline across false→true readiness while replacing it on pubkey or relay/community changes. The production-seam widget regression at mobile/test/features/channels/me/me_unread_test.dart:188-282 drives unready baseline 20 → reply 21 → ready, proves marker 20, then verifies the Solo tab, unread row, collapsed-project indicator, subsequent read/reply/thread-read, and forced-unread behavior. Accessibility semantics remain explicitly owned by the row, section, and tab paths.

Findings: no unresolved author-actionable defect. Independent systems/integration and product/UI review both reached APPROVE; their lifecycle, persistence, event-ordering, row/collapse/tab, and accessibility checks were reconciled into this verdict.

Author action: none.

Verification owner: reviewer/tooling for native observation and the locally blocked Flutter execution; named CI/release gates for checks still running.

Validation at matching clean HEAD:

  • PASS — local and live PR head both 1d4c41354564c093d4976f410692c104253c2fb2; merge-base exactly fea02d174d0762b18b73138abc833d7c140f9718; git diff --check clean.
  • PASS — two independent just mobile-check runs: 748 Dart files unchanged and Flutter analyzer reported No issues found.
  • PASS — independent just file-size-check: 10/10 core policy tests and all surface entrypoints.
  • PASS — exact-head hosted Mobile Checks, all three Mobile test shards, Android, Mobile aggregate, Clients Results, Mobile Swift Release, DCO, Semgrep, and zizmor.
  • The author-reported causal mutation (moving baseline capture behind readiness) fails the new regression with expected marker 20 / actual 21; this supports falsifiability but was not independently rerun locally.
  • Local just mobile-test reached five passing gateway-recipe probes, then could not start Flutter collection because this host has not accepted the Xcode license and the objective_c native-assets hook received no SDK path from xcrun. That is a reviewer-environment confidence gap, not evidence of a PR defect.

Manual/native evidence: no new physical-device, iOS visual, or VoiceOver run is claimed for this follow-up.

Residual risk: native observation and an independent mutation run remain outstanding. At submission time, Mobile Swift Domain / Mobile Swift (Native) and Run Codex Security Review were still in progress; the exact-head Codex source review separately reported no major issue. Those external gates—not author rework—own final merge readiness.

@klopez4212
klopez4212 merged commit b1d60f9 into main Oct 15, 2026
45 of 46 checks passed
@klopez4212
klopez4212 deleted the kennylopez-mobile-agent-sessions branch October 15, 2026 21:07
klopez4212 added a commit that referenced this pull request Oct 16, 2026
## Summary
Polish mobile Home and Solo: group Search/Inbox beside a separate
profile avatar, move Inbox and Settings to bottom-up pages with Close
controls, and place tabs opposite the plus/compose action. Morph plus to
compose clockwise when entering Solo and reverse counterclockwise when
returning Home, with a directional quarter-turn of the icon inside a
level button and a subtle scale pulse, respecting reduced motion. Align
Search’s Close control with Inbox, simplify its placeholder, and
initialize selected filter contrast correctly. Collapse the plus menu
when leaving Home. Center Solo’s native-glass New chat empty state and
keep it stationary behind the keyboard.

Standardize Tabler icons and neutral backgrounds, retain SF Back/Close
on iOS, use native Liquid Glass headers, tab container, and actions
(solid grey selected tab, slightly darker on iOS) on iOS and black
actions on Android, and smooth the expanded menu corners. Repair native
header safe-area/return layout and compose movement after cancellation.

### Related issue
None found for this UI refinement; follows #8337.

### Testing
- Formatting, analysis, full mobile suite: 3,487 passed, 4 skipped; 3
push-configuration tests passed. File-size checks passed.
- Base UI built and installed on Pixel and iPhone in place. Pixel
navigation/New chat cancellation checked. Subsequent glass and rotation
refinements are previewed on iPhone; motion feel awaits human
confirmation.
- Draft pending human confirmation of the final Settings entrance/return
behavior on iPhone.

### Pixel snapshots
| Solo | Expanded actions |
| --- | --- |
| <img
src="https://raw.githubusercontent.com/block/buzz/16dc0f8af971e63d788fee20974997fab925dec9/docs/screenshots/mobile-home-solo/pixel-solo.png"
width="280" alt="Solo empty state with New chat" /> | <img
src="https://raw.githubusercontent.com/block/buzz/16dc0f8af971e63d788fee20974997fab925dec9/docs/screenshots/mobile-home-solo/pixel-actions.png"
width="280" alt="Expanded channel actions with smooth corners" /> |

---------

Signed-off-by: kenny lopez <[email protected]>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>

This branch was successfully deployed

No deployments
codex-review — 1d4c4135 Deployed Oct 15, 2026 by klopez4212 via Run Codex Security Review #8382
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.

2 participants