-
Notifications
You must be signed in to change notification settings - Fork 3
perf(ios): publish refreshed chats independently of model catalogs #283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # iOS optional catalog loading | ||
|
|
||
| Branch `feature/perf-ios-chat-loading`, dedicated performance worktree. IOS-03's tuple-await dependency is replaced by a structured independent catalog child: successful transcript GET publishes through the existing request-origin/cache admission and transcript-generation fences without waiting for models. Catalog errors preserve existing catalog/selection; revocation still purges/fences authority. Live model selection is resolved at catalog completion; no captured selection is restored. Existing Bot model rules are unchanged. | ||
|
|
||
| Progress bootstrap deduplication is deferred. No protocol, transcript rendering, Android or onboarding change. Android already loads chat/catalog independently. Evidence and limitations: `docs/performance/ios-chat-loading.md`. | ||
|
|
||
| Executed final serial AidenChatTests: 212 passed, zero failures, Xcode27.0 build27A5252f, iPhone17Pro simulator iOS27.0 destination9F4FDF41-3FE3-477D-B92B-127C43FE927E. Evidence `/tmp/aiden-perf-ios-loading-final.xcresult` and `.log`. Original production source with the held-catalog regression actually executed and failed seven assertions (missing callback/current/persisted transcript before release in both catalog outcomes, plus catalog503 load error). Baseline evidence `/tmp/aiden-perf-ios-loading-baseline-retry.xcresult`; first baseline launch failed before tests, one test-without-building retry executed. Final run needed no retry. Policy20Ruby/42assertions +32Node passed (`/tmp/aiden-perf-ios-loading-policy.log`). No physical-device, latency-distribution or energy evidence. Root owns fresh-context review and PR publication; no push/release performed. | ||
|
|
||
| ## PR283 review: published transcript redaction | ||
|
|
||
| Comment4118130725 exposed the fast-transcript/late-catalog-revocation ordering. Existing `handleRemoval()` fenced late writes and cleared live state but kept settled messages while coordinator purge delayed shell dismissal. Clear `chat.messages` synchronously in that existing lifetime callback; do not publish/cache an empty chat. Added held production GET/catalog401/cleanup-gate regression proving redaction while coordinator remains connected and old disk content still exists, then disk purge/pairing completion. Original c68550e5 actually failed2 redaction assertions (`/tmp/aiden-perf-ios-redaction-before.xcresult`), no infrastructure retry. Existing ordinary503 test now also checks retained transcript after release. Android lifecycle inspected; no shared protocol/rendering changes. Final production full chat suite213/213 passed (`/tmp/aiden-perf-ios-redaction-after.xcresult`). Final test-only503 assertion enhancement verified by2/2 focused tests (`/tmp/aiden-perf-ios-redaction-final-retry.xcresult`), following one pre-XCTest launch stall interrupted after ~3minutes; log and process sample retained (`/tmp/aiden-perf-ios-redaction-final.log`, `/tmp/aiden-perf-ios-redaction-launch-sample.txt`). No further retries. Policy20Ruby42assertions/32Node passed. Same explicit iPhone17Pro iOS27.0/Xcode27.0 simulator; no physical acceptance. Root owns fresh-context review and publication. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| # iOS chat loading: optional model catalog | ||
|
|
||
| Scope: IOS-03's transcript/catalog dependency only, from `a9baa4aa3027893e5455043083465c34b4c8b4ac`. | ||
|
|
||
| `AidenChatViewModel.load()` previously started both GETs together and awaited their tuple. A successful transcript therefore could not enter cache admission or publish until the catalog succeeded; a catalog error discarded that transcript. Cached/current content could still be displayed. | ||
|
|
||
| The catalog now has its own structured child operation with independent request-context/removal checks and the existing credential-revocation handler. The transcript immediately uses the unchanged request-origin token, transcript generation, optimistic-send guards and `acceptRemoteChat` cache admission. Successful catalog publication resolves the current user selection, including Bot-owned selection rules; ordinary catalog failure preserves existing choices and does not replace transcript content with a catalog error. Revocation still purges authority and fences suspended transcript publication. | ||
|
|
||
| This does not change wire contracts, rendering, or Android. Android's `AidenChatViewModel.loadChat()` and `loadCatalog()` already run independently. Catalog data does not grant permissions. `load()` still owns and awaits both child operations; its lifetime and subsequent progress bootstrap can still include catalog latency. Progress-bootstrap deduplication/parallelization is deferred to its own ownership-focused change. | ||
|
|
||
| ## Deterministic evidence | ||
|
|
||
| The existing `AidenChatTests` URLProtocol holds the actual `/models` response until the test explicitly releases it. The actual chat GET succeeds with a new message. Before catalog release, the test requires the publication callback, the fresh visible transcript and the persisted transcript. It then releases either a successful catalog or HTTP 503 and checks content/error behavior and a nondefault model/thinking selection made during suspension. Its three-second expectation is a failure bound, not an injected RTT or a performance measurement. | ||
|
|
||
| Additional executed coverage is recorded below: chat failure with a successful catalog; removal/unpair while catalog is held; catalog revocation with a held transcript. The complete existing chat suite also covers optimistic Send/reload, rejected cache writes, restoration, permissions and stream response ownership. | ||
|
|
||
| Executed comparison on 2026-09-27, Xcode 27.0 (27A5252f), iPhone 17 Pro simulator / iOS 27.0, destination `9F4FDF41-3FE3-477D-B92B-127C43FE927E`, serial XCTest with `CODE_SIGNING_ALLOWED=NO`: | ||
|
|
||
| | Version | Held-catalog result | | ||
| | --- | --- | | ||
| | Original loader at the base commit | One regression executed, seven assertion failures: both catalog outcomes blocked publication/persistence before release; the 503 produced a transcript load error. | | ||
| | Fixed loader | Same held-catalog regression passed: transcript callback, visible message and persisted message all available before release for both success and 503; nondefault user choice retained. | | ||
|
|
||
| The first baseline attempt failed before XCTest execution because Simulator returned no process handle for the test runner. Its one `test-without-building` retry executed and produced the expected behavioral failures. Initial fixed-source chat suite: 211 tests passed. Final-source validation (including a fourth added test and stronger nondefault choice assertion): **212 chat tests executed, zero failures**. The final run launched successfully without retry. Release-policy checks passed: 20 Ruby tests / 42 assertions and 32 Node tests. | ||
|
|
||
| Local evidence: | ||
|
|
||
| - Original executed comparison: `/tmp/aiden-perf-ios-loading-baseline-retry.xcresult` and `.log`. | ||
| - Original launch-only failure: `/tmp/aiden-perf-ios-loading-baseline.xcresult` and `.log`. | ||
| - Final changed-loader suite: `/tmp/aiden-perf-ios-loading-final.xcresult` and `.log`. | ||
| - Policy: `/tmp/aiden-perf-ios-loading-policy.log`. | ||
|
|
||
| Reproduce the changed-loader suite from the repository root: | ||
|
|
||
| ```sh | ||
| DEVELOPER_DIR=/Applications/Xcode-beta.app/Contents/Developer xcodebuild test \ | ||
| -project ios/AidenOnTheGo.xcodeproj -scheme AidenOnTheGo \ | ||
| -destination 'platform=iOS Simulator,id=9F4FDF41-3FE3-477D-B92B-127C43FE927E' \ | ||
| -derivedDataPath /tmp/aiden-perf-ios-loading-derived \ | ||
| -resultBundlePath /tmp/aiden-perf-ios-loading-final.xcresult \ | ||
| -parallel-testing-enabled NO \ | ||
| -only-testing:AidenOnTheGoTests/AidenChatTests CODE_SIGNING_ALLOWED=NO | ||
| npm run test:ios-release | ||
| ``` | ||
|
|
||
| Use an unused result-bundle path when repeating the command. To reproduce the before comparison, use the original production file at the base commit with the new tests, select `AidenOnTheGoTests/AidenChatTests/testTranscriptPublishesWhileCatalogIsHeldIncludingCatalogFailure`, and restore the changed source afterward. | ||
|
|
||
| ## Measurement limits | ||
|
|
||
| This is deterministic dependency/race evidence, not production navigation latency, p50/p95, frame-time, energy, or physical-device acceptance. No 0/100/500 ms timing sweep was collected. Fresh publication no longer depends on catalog release; cached publication behavior and stream restoration were not redesigned. No dependency installation, release, or deployment is part of this change. | ||
|
|
||
| ## PR #283 revocation redaction follow-up | ||
|
|
||
| Review [4118130725](https://github.com/sambitcreate/aiden-agent/pull/283#discussion_r4118130725) found the opposite response ordering was not covered: a fresh transcript could publish before the sibling catalog reported `credential_revoked`. The coordinator waits for installation cleanup before changing the product shell to pairing, and the model's removal callback previously kept those messages. | ||
|
|
||
| The existing lifetime-removal callback now clears `chat.messages` synchronously before asynchronous cleanup. It does not publish an empty replacement to the cache or add a new request. Ordinary catalog failures do not invalidate the lifetime and keep the transcript; the existing success/503 held-catalog test explicitly checks content again after release. | ||
|
|
||
| `testCatalogRevocationRedactsPublishedTranscriptBeforePurgeCompletes` publishes a real successful chat GET, releases a held catalog 401, and holds the existing removal-cleanup seam. It verifies the shell's connection state is still connected and an independently opened cache still reads the old disk transcript, while the mounted model already has no messages. After cleanup it checks pairing state, empty model and purged disk. Against `c68550e5`, this test actually executed and failed both redaction assertions (one test, two failures); `/tmp/aiden-perf-ios-redaction-before.xcresult` and `.log`. No simulator infrastructure retry was needed for that baseline. | ||
|
|
||
| The change is local to the iOS lifetime callback; Android's independent chat/catalog loaders and separate lifecycle were inspected, and no shared contract, transcript format or rendering component changed. Follow-up validation on the same explicit iPhone 17 Pro / iOS27.0 simulator and Xcode27.0 destination above: | ||
|
|
||
| - Full `AidenChatTests`: **213 executed, zero failures**, `/tmp/aiden-perf-ios-redaction-after.xcresult` and `.log`. | ||
| - After strengthening the ordinary503 test with a post-release content assertion, the two affected tests executed and passed using `test-without-building`: `/tmp/aiden-perf-ios-redaction-final-retry.xcresult` and `.log`. The production code was unchanged from the full213 run. | ||
| - The initial final two-test run stalled after build/app launch but before XCTest started. After roughly three minutes it was interrupted and its app terminated; evidence `/tmp/aiden-perf-ios-redaction-final.log` and `/tmp/aiden-perf-ios-redaction-launch-sample.txt`. Its single infrastructure retry passed. This launch failure is retained as a limitation rather than counted as a passing test run. | ||
| - `npm run test:ios-release`:20 Ruby tests/42 assertions and32 Node tests passed; `/tmp/aiden-perf-ios-redaction-policy.log`. | ||
|
|
||
| No physical-device acceptance or timing claim is added. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.