Skip to content

perf(ios): publish refreshed chats independently of model catalogs - #283

Merged
sambitcreate merged 2 commits into
mainfrom
feature/perf-ios-chat-loading
Sep 28, 2026
Merged

sambitcreate merged 2 commits into
mainfrom
feature/perf-ios-chat-loading

Conversation

@sambitcreate

@sambitcreate sambitcreate commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

A successful iOS chat refresh previously waited for the model catalog, and a catalog failure discarded the fresh transcript result. Publish the transcript independently while retaining structured task ownership, cache admission, live model selection and credential-revocation fences. Overall load completion and progress bootstrap still await the catalog. If revocation arrives after publication, the removal path now clears mounted messages synchronously before cleanup can suspend.

Validation: the initial loader regression fails seven assertions on original source. The follow-up held-purge regression reproduces two failures before redaction; fixed production passed all 213 chat XCTests. Final focused tests passed 2/2 after one documented simulator-launch retry. Fresh-context follow-up review independently passed three targeted race/error cases without retry, with no actionable findings. Release-policy checks passed. Ordinary catalog 503 retains the transcript and selected model.

Evidence: docs/performance/ios-chat-loading.md. No shared wire contract changes; Android already loads chat/catalog independently. No physical-device latency or energy result is claimed.

@very-hermes-bot

very-hermes-bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

Hermes Review Bot

Confidence: 5

Engine: agy/gemini-3.8-flash-high
Review mode: full
Head: cb53bbe6a8bed4f31299a0be9363671b92ec5008
Generated: 2026-09-28T03:11:28+00:00
Reviews: 1

Summary

Decouples transcript retrieval from model catalog loading during iOS chat initialization, resolving an issue where a successful transcript fetch was blocked by or discarded due to catalog latency or failures. In AidenChatViewModel.load(), refreshModelCatalog(context:) is now spawned as an independent structured child task while the chat transcript GET completes and publishes immediately via acceptRemoteChat(_:context:writeToken:). The catalog failure path swallows non-revocation errors (such as HTTP 503) without overriding visible transcripts, while credential revocation (401) fences pending operations and synchronously clears in-memory chat.messages in handleRemoval() before coordinator cleanup finishes. Maintainers should double-check that downstream progress observation or approval restoration in load() does not rely on newly advertised catalog metadata before catalogRefresh resolves.

Confidence Score: 5/5

Fully traced and verified across iOS ViewModel lifetime rules, actor isolation, cancellation handling, Android parity (AidenChatViewModel.kt), and corresponding XCTests.

📁 Important Files Changed
  • ios/AidenOnTheGo/Features/Remote/AidenChatFeature.swift: Splits the previous (chatRequest, catalogRequest) tuple await into an immediate transcript publication step and an independent refreshModelCatalog(context:) method; clears chat.messages synchronously in handleRemoval().
  • ios/AidenOnTheGoTests/AidenChatTests.swift: Adds regression tests covering catalog hold/release (including HTTP 503), chat failure with catalog success, invalidation/unpair while catalog is held, published transcript redaction prior to cleanup completion, and catalog revocation fencing held transcripts.
  • docs/performance/ios-chat-loading.md: Documents deterministic timing and failure evidence on the iPhone 17 Pro / iOS 27 simulator, measurement boundaries, and revocation redaction follow-up behavior.
  • .memory/perf-ios-chat-loading.md: Tracks project context, test run results, and architectural decisions.

Findings

No findings.

Sequence Diagram

sequenceDiagram
    autonumber
    participant V as View (AidenChatDetailView)
    participant VM as ViewModel (AidenChatViewModel)
    participant C as RemoteClient
    participant CO as Coordinator

    V->>VM: load()
    par Fetch Transcript
        VM->>C: chat(id)
    and Fetch Catalog (Child Task)
        VM->>C: modelCatalog()
    end
    C-->>VM: remoteChat (200 OK)
    VM->>VM: acceptRemoteChat()
    VM-->>V: Publish updated chat transcript
    alt Catalog Succeeds
        C-->>VM: remoteCatalog (200 OK)
        VM->>VM: resolveModelSelection()
    else Catalog Transient Failure (e.g. 503)
        C-->>VM: error (503)
        Note over VM: Suppress catalog error; retain existing transcript & selection
    else Credential Revoked (401)
        C-->>VM: error (401 credential_revoked)
        VM->>CO: handleCredentialRevocation()
        VM->>VM: handleRemoval() (chat.messages = [])
        VM-->>V: Synchronously redact messages
    end
Loading
[]

Last reviewed commit: cb53bbe6a8be
Reviews (1) · Comment /hermes review to trigger a new review · /hermes review full for full re-review

@pullfrog pullfrog Bot 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.

Important

A catalog credential_revoked response can arrive after transcript publication and leave the newly fetched transcript renderable while the installation-data purge runs.

Reviewed changes This review covers the iOS transcript/catalog refresh decoupling, its race tests, and the performance evidence.

  • Independent transcript publication. load() now publishes the fetched transcript while the structured catalog request is pending; overall load and progress bootstrap still await catalog completion.
  • Optional catalog outcome. Ordinary catalog failures no longer discard the transcript or existing model choices, and successful refresh resolves the live selection.
  • Race coverage and evidence. Tests cover held-catalog success/failure, selection preservation, chat failure, removal/unpair, and revocation while the transcript is held. The report states that 212 chat XCTests passed and makes no physical-device latency claim.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using GPT Luna | 𝕏

Comment thread ios/AidenOnTheGo/Features/Remote/AidenChatFeature.swift

@pullfrog pullfrog Bot 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.

✅ No new issues found.

Reviewed changes This review covers the revocation-redaction follow-up since the prior Pullfrog review.

  • Redacted removed chat content. handleRemoval() now clears mounted transcript messages synchronously before asynchronous installation cleanup, and the regression holds cleanup to verify redaction before the shell switches to pairing.
  • Strengthened catalog-failure coverage. The held-catalog scenario now confirms the fresh transcript remains after an ordinary catalog failure is released.
  • Recorded follow-up evidence. The performance notes document the late-revocation ordering, simulator results, and remaining measurement limits.

Pullfrog  | View workflow run | Using GPT Luna | 𝕏

@sambitcreate
sambitcreate merged commit 78cbd8f into main Sep 28, 2026
23 checks passed
@sambitcreate
sambitcreate deleted the feature/perf-ios-chat-loading branch September 28, 2026 22:07
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