Pipeline + anisette audit: findings, corrected _install analysis, anisette list fix#57
Merged
Conversation
Broad audit of the install/refresh/update/backup/restore pipeline (2026-07-03). Orchestration (perform/_install/_refresh/_backup/_activate/finish/run) and the InstallAppOperation worker verified sound: finish() fires exactly once on every path, context.error is checked at each operation entry, and the recently added cert-serial-mismatch guard in _refresh routes through self.finish(operation, .failure) exactly like the pre-existing appNotFound guard (RefreshGroup lifecycle intact). Correct the _install context-parameter gotcha: the error poisoning of group.context is via AppOperationContext.error -> authenticatedContext.error (shared group.context, first-error-wins, intentional) and is identical whether the placeholder install reuses restoreContext or a fresh context, so the previously suggested fresh-context fix does not stop it. The concrete stuck-on-1.0 mechanism is a failed BackupAppOperation poisoning group.context so the real reinstall fails fast. Left as-is: device-critical, untestable here, and the real lever is a design question. No blind change. Register the fablize plugin (fivetaku/fablize) in the plugin index. https://claude.ai/code/session_01PT8zpkUrgTRaGeKmbvVyNe
Audit follow-up. The anisette server list opened with no row selected, so the active server (persisted in menuAnisetteURL) showed no checkmark until the user re-tapped a row. Initialize the list selection from menuAnisetteURL on appear so the current server is reflected immediately. UI-only — does not touch the auth / provisioning path. https://claude.ai/code/session_01PT8zpkUrgTRaGeKmbvVyNe
Contributor
|
Download the artifacts for this pull request (nightly.link): |
Contributor
|
Builds for this Pull Request are available at |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Broad, evidence-based audit of the core operation pipeline (install / refresh / update / backup / restore / activate) and the anisette subsystem (fetch operation, manager, server-list UI). Both are structurally sound; this PR records the verified findings, corrects a stale analysis in
gotchas.md, and ships one safe UI-only anisette fix.Type of change
Changes
AnisetteServerList.swift). The list opened with no row selected, so the active server (persisted inmenuAnisetteURL) showed no checkmark until the user re-tapped a row. It now initializes the selection frommenuAnisetteURLon appear. UI-only — does not touch the auth/provisioning path._installcontext analysis (gotchas.md). The prior gotcha claimed a "fresh throwaway context" would stop the error-poisoning that can strand a row on the AltBackup1.0placeholder. It does not:AppOperationContext.error's setter propagates to the sharedauthenticatedContext(=group.context, first-error-wins, intentional), so any context poisonsgroup.contextidentically. The concrete stuck-on-1.0 mechanism is a failedBackupAppOperation(.backup)poisoninggroup.contextso the real reinstall fails fast atInstallAppOperation.swift:34. Left as-is (device-critical, untestable here, and the real lever is a design decision).fablizeplugin in.claude/plugin_index.md.Audited sound (no change needed)
perform→_install/_refresh/_backup/_activate/_deactivate→finish→run, and theInstallAppOperationworker:finish()fires exactly once on every path,context.erroris checked at each operation entry, and the recently merged cert-serial-mismatch guard routes throughself.finish(operation, .failure)exactly like the pre-existingappNotFoundguard (RefreshGroup lifecycle intact).provisioningSucceededflag against the post-success disconnect race,maxProvisioningRetriescap on the -45061 loop);AnisetteManagervalidates URLs with a safe literal fallback; the server-list URL field is debounced. ThedidReceivedefaultcase intentionally does not finish on an unrecognized result (it waits for the next message — correct for the state machine), so it is not a blind-fixable hang. Dev-only note: "Reset adi.pb" gates the actual keychain clear behind#if !DEBUG; left as-is.Testing
Build and upload MiniStoreis the compile check. The anisette change is a one-line@Stateinitialization on appear; no auth/provisioning code was touched.Checklist
develop(nevermain)CLAUDE.md🤖 Generated with Claude Code