Sync with upstream silo-apple main (2026-09-28) - #31
Merged
Merged
Conversation
…connect task - Only a connection whose hello was sent may trigger a reconnect, so a timed-out connect reports its error instead of racing into silent reconnecting - Clear reconnectTask when the loop finishes so a later background drop is not mistaken for an in-flight attempt Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…vos-backdrop perf(tvos): swap the hero backdrop as soon as the row scroll has visibly settled
…iscovery Review follow-ups: a long-resident app never renewed a display token that had expired, and a server that started returning one after an upgrade was never asked again. Keep the token's expiry in the App Group defaults, re-register a week before it lapses, and retry discovery on an older server every six hours instead of once per process. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ote-disconnects fix(ios): handle remote disconnect timeouts
Review follow-ups: the display-token slot survived a server or profile switch until the next registration succeeded, so the extension could pair a new context with the previous profile's credential, and a registration response landing after sign-out could write the old token back. TokenStore now clears the slot on profile activation, deactivation, and server retargeting, and the coordinator discards a response whose account or profile identity changed while it was in flight. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Review follow-up: the actor starts with an empty active server on every process, so background launches that retargeted to the same persisted server were clearing a valid display token. Record the issuing server with the token and clear it only when the active server actually differs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ain item Review follow-up: a failed Keychain write or delete left the previous token in place while its expiry and issuing server were removed, so the coordinator treated a stale credential as current and stopped renewing it. Metadata now changes only after the Keychain mutation succeeds, and a token with no recorded expiry is treated as needing renewal. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Review follow-up: an app backgrounded past the display token's expiry could still have a fresh access token from background work, but the extension never tried it. On a 401 or 403 with the display token, the client now retries once with the mirrored access token. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…cation-metadata-delivery fix(notifications): use a long-lived display token for push enrichment
- Route panel-less menu items to the page's first card - Prioritize the first content item while focus leaves the top menu
- Apply the content focus claim after the menu has fully resigned - Prevent focus repair from stranding focus in the top menu
…ost-down-focus fix(tvos): route top-menu Down to left-most content
The previous fix reasserted focus from onMoveCommand, but the focus engine resolves a Left/Right move to any focusable beyond the rail before that handler fires, so focus still escaped. Represent the hard edges in the focus graph instead: a hidden one-point focusable guide hugs each end of the card strip, and the rail bounces focus from a guide back to the first or last episode card. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…-episode-carousel-focus fix(tvos): retain episode rail focus at horizontal edges
- Remove tvOS Menu transition delays from detail actions - Preserve focused selection for version, audio, subtitle, and More actions
… on screen The action popover was one focusable composite whose VoiceOver element only spoke the static title, so a VoiceOver user could not hear or activate the row that Select would commit. The composite is now an adjustable button: its value is the highlighted row, swipe up/down moves the highlight, activate commits, and escape closes. Rows are hidden from the accessibility tree so the cursor never lands on a passive label. The host also always placed the panel below the trigger. On the series hero a seven-row list ran past the bottom of the screen. The host now measures the panel and opens it above the trigger when it will not fit below, or pins it to the bottom inset when neither side has room. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…-subtitles-open-pill fix(tvos): replace detail menus with instant popovers
The Home feed rewrite in Silo-Server#106 set resume stills to 184pt to match the poster rows' density, which made Continue Watching cards read as thumbnails and the progress rail hard to see. Raise the base still width to 240pt. The Poster Size setting already scales this value, so Compact and Large follow along. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…atching-card-size-9b1202 fix(ios): enlarge Continue Watching cards
…order (Silo-Server#247) * fix(player): resolve the initial subtitle intent in combined ordinal order Every Protocol V3 episode start loaded the engine twice. The pre-start subtitle intent resolved over the watch detail, which lists embedded tracks before externals, while the post-load caption policy resolved over the plan inventory, which lists externals first. The resolver is first-match within a track class, so a file with two same-language tracks produced a different pick on each side. The client then issued a subtitle_track_changed replan and a full engine reload on top of a picture that was already playing. SubtitleTrackCandidates now orders catalog tracks external-first to match the combined ordinal space, so both passes land on the same track. The auto policy logs when it still disagrees with the plan. Verified on the tvOS simulator: one engine session per episode, no replan. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(player): number subtitle candidates by combined position indexedPlayerTracks reordered tracks external-first but kept each track's catalog offset as its ordinal, so an embedded-first catalog returned ordinals like [2, 3, 0, 1]. Enumerate after partitioning so ordinals are sequential in combined order; the regression test now asserts them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(detail): preview the Auto subtitle in playback's combined order The detail screen's "Auto:" label ran its own resolver pass over the catalog in embedded-first order, while playback now resolves external-first. With an embedded and an external track of the same language the label named one track and playback started the other. The preview now searches the same combined order and maps the pick back to its catalog offset for labels. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(player): compare the auto subtitle pick against the plan's resolved index A plan can name its selected subtitle by stable identity without a numeric index. Comparing the auto pick against selectedTracks.subtitle?.index then read as a mismatch and replanned for the track already playing. Resolve through selectedSubtitleCombinedIndex, which falls back to the inventory entry the identity names. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * chore: restore the main Package.resolved on the subtitle branch The lockfile from the AetherEngine bump branch was swept into da68f6e by mistake. This PR touches no package declaration, so the lockfile must match project.yml on main. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(player): keep the Auto subtitle preview and replan guard on selectable tracks The detail preview could name an embedded track with no stream index, which SubtitleTrackCandidates already drops because the plan cannot select it. It now filters those out before resolving. The auto-policy replan guard treated an off plan's stale subtitle identity as a selection, so a .disable pick read as a mismatch and replanned. Off means nothing is selected, as subtitlePickerTracks already assumes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * chore: restore the main Package.resolved on the subtitle branch again The shared worktree's lockfile follows whichever branch was last built, and 1183fa7 swept it in. This PR declares no package change. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…x its attribution (Silo-Server#246) * docs: correct AetherEngine attribution and credit the engine in README THIRD_PARTY_NOTICES.md recorded the upstream 6.34.0 commit while the app links 653be639, a published fork revision that adds Silo's handover patches. The notices and in-app acknowledgements now name the fork branch as the modified source, the upstream tag as its base, and state the LGPL publication obligation for those patches. README.md now credits AetherEngine and its author next to the other third-party notices. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * chore(deps): move AetherEngine to the Silo-Server fork at 6.67.2 plus the handover patch The app was pinned to a personal fork of AetherEngine frozen at 6.34.0 with five local commits. It now pins Silo-Server/AetherEngine at dfe11a08, which is upstream 6.67.2 plus one re-implemented commit that lets a host request the in-place native item handover on an episode change. That keeps the tvOS autoplay fix from Silo-Server#221 while picking up 52 upstream releases, including the 6.50.0 loopback-origin exposure fix and the libzvbi GHSA-86rm-g7qf-j2fh update via FFmpegBuild 3.0.0. FFmpegBuild 3.0.0 renames the nine embedded frameworks with an Aether prefix and moves to dav1d 1.5.4, zimg 3.0.6, and libzvbi 0.2.45; LibDovi moves to 2.1.0 (dolby_vision 3.4.0). THIRD_PARTY_NOTICES.md, the in-app acknowledgements, and quietvoid's libdovi notice are updated to the resolved revisions. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs: record the FFmpegBuild 3.0.0 artifact inspection in the notices The inventory claim described a 2.4.3 debug build. A tvOS Simulator debug build against 3.0.0 was inspected: nine Aether-prefixed frameworks embedded, --enable-shared present, no GPL, version3, or nonfree flags, and no FFmpeg symbols exported by the app binary. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * chore(deps): bump the AetherEngine fork so the remote-HLS bypass honours the handover CI's iOS suite failed PlayerSurfaceLayoutTests: the synthetic next-episode handover on the nativeRemoteHLS route showed 2 item changes and 1 nil item. The fork's bypass callsite never read the handover flag. Fork 745de1cc consumes it the same way the loopback callsite does; the test now reports 1 item swap and 0 nil items. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…erver#249) * fix(ios): restore quick-play on Continue Watching still cards The play badge on Continue Watching and Next Up stills was decorative after the Home feed rewrite. Tapping it now presents the player with the item's resume position; the rest of the card still opens detail. The badge grows from 28pt to 36pt so it is a reliable touch target. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(player): carry last-used version through macOS and expose quick-play to VoiceOver The macOS player route dropped prefersLastUsedVersion, so a Continue Watching quick-play could resume a different file than the one last watched. Route, ContentView, and macOS PlayerView now forward the flag. Audio and subtitle memory already ride on the server's effective_* fields and need no extra plumbing. HomeCardTap collapses its children into one accessibility element, which hid the nested play button from VoiceOver. The card now exposes Play/Resume as a custom accessibility action. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…lo-Server#250) Replace the home, movie detail, and Movies library shots with new demo-server captures, add series detail and TV Shows library shots, and rebuild the iOS contact sheet from all 13 images. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* Gate debug launch paths and name URL schemes * Preserve deep links across cold launches * Fix play deep-link presentation * Harden deep link intent handling * fix(deeplink): drain queued Downloads links right after capability refresh A cold-launch continuum://downloads link waited for the entire DownloadManager.onAppActive() pass (reconcile, subscription sync, progress sync, retention) before it could be routed. On a slow or unreachable server that left a notification tap sitting on the initial screen until several requests timed out. onAppActive() now reports when the capability refresh completes so ContentView can mark Downloads hydrated and drain the link immediately, while the remaining sync work continues independently. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor: rename legacy Continuum identifiers to Silo Rename the remaining Continuum-era type names, files, view modifiers, color and typography tokens, notification names, Info.plist keys, os_log subsystems, gesture recognizer names, and realtime client names to Silo. Persisted contracts are intentionally unchanged so existing installs keep their state: the continuum:// URL scheme (Top Shelf, push payloads, Android parity), com.continuum.* keychain accounts, the continuumServerRegistry.* UserDefaults keys, the BGTaskScheduler and background URLSession identifiers, and the legacy migration source keys. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Quick104 <31828688+Quick104@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…e preview (Silo-Server#248) * fix(player): keep embedded stream 0 selectable and align the signature preview Two gaps from Silo-Server#247, raised in review after merge: The server emits index,omitempty on an Int, so an embedded subtitle at FFmpeg stream 0 arrives with no index. SubtitleTrackCandidates dropped it, the detail preview filtered it out, and the plan adapter could not map it to a combined ordinal. All three now read a nil embedded index as stream 0. The detail preview's signature pass skipped tracks without an index, which excludes every external sidecar, while playback's resolver scores them. It now considers every row, so a signature tie resolves to the same track. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs: describe both AetherEngine fork patches in the notices Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(detail): let the selector pick embedded subtitle stream 0 The detail selector still read the raw nil index for an embedded track at FFmpeg stream 0, so subtitleOptions marked it unselectable, the iOS and tvOS selectors disabled the row, and sanitization and persistence rejected index 0 because they only inspected non-nil catalog indices. Add SubtitleTrack.selectionIndex, which reads a missing embedded index as stream 0 and stays nil for external sidecars, and use it in subtitleOptions, the value label, the server-preferred resolver, both sanitizers, subtitle pref persistence, and the earlier ad-hoc `?? 0` sites. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…o-Server#251) * refactor: remove obsolete Apple client code and test scaffolding * refactor: finish overlay cleanup from ponytail review
…o-Server#252) * fix(player): select native subtitles and preserve sidecar timing * fix(player): preserve local subtitle selections during renewal * fix(subtitles): use external track state for Apple cue timing * fix(player): dispose rejected native subtitle candidates * fix(player): renew with the current downloaded subtitle * fix(player): preserve subtitle intent through recovery and teardown * fix(player): retain native subtitle identity for secondary selection
* feat(player): render styled ASS subtitles locally * fix(player): complete ASS subtitle routing and release sources
…stub PrairieAPI now joins the image-size probe with refresh(retryFailed: false). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Upstream's account-session rework removed ServerRegistry.signOut, discardLegacyKeychainAccountsIfUnmigrated and TokenStore.clearTokensAfterRejectedRefresh. Drop the registry tests that only exercised the removed methods, and check the persistent rejected- refresh clear through invalidateRejectedRefresh instead (first call clears, a replay of the same capture is refused). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Add upstream's API v2 client, model, decoding and projection suites (catalog, collections, library browse, downloads, auth/device, probe and contract state, metadata AI, onboarding, requests, track preferences, watch state) to PrairieNetworkingTests, together with the shared URLProtocol stub, fixture loader and the vendored Tests/Fixtures/APIv2 bodies. They run through the real HTTPClient and APIv2Client, so the new Networking/APIv2 surface is covered by real tests rather than excluded from the 95% gate. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
AuthDeviceV2Tests (QRLoginViewModel + real AuthService), APIv2ContractStateTests and APIv2ProbeTests (real ConnectionMonitor verdict state) and DiagnosticsCapabilitiesV2Tests (DiagnosticsCoordinator helpers) need app types the FFmpeg-free host only stubs. They keep running in PrairieTests/PrairieTVTests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…removed Upstream's move to /api/v2 deleted the v1 wire models (Profile, ProfilesResponse, LoginResponse, Signup/SetupRequest, device-login poll, approve and capability bodies, SubtitlePref/AudioPref, library playback prefs, AdminStats, CatalogFilters, CollectionItemsResponse, discover and library-collection wire shapes, SettingsContractCapabilities) and made UpdateProfileBody, MetadataAIStatus and DeviceLookupResponse non-Codable. Remove the Prairie gate-fill assertions that only exercised those, and update the rest to the new shapes: FileVersion(editionRaw:), string Person ids, failable SyncProgressItem, ServerEntry.legacyProfileId. RequestsV2Tests stays in PrairieTests only (it drives RequestDetailViewModel). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- ServerRegistryMigrationTests reads ServerEntry.legacyProfileId (the public profileId accessor and ServerRegistry.setProfileId are gone). - SettingValueModelsGateFillTests drops the removed contractIsAheadOfServer check. - SettingsConformanceTests (now asserts app-side SeekIntervalContract, ProfileSettingKeys and player settings batches) and WatchStateV2Tests (drives DownloadManager) stay in PrairieTests/PrairieTVTests only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Add the Foundation-only StreamRequest, catalog filter/facet/sort and audiobook playback-context types to PrairieNetworkingHost so AIModelDecodingTests, CatalogActionsAPITests and CatalogV2Tests compile there. CatalogPagingAPITests (StartupContentPrefetcher, query builder) and the two download-registry suites (DownloadManager/DownloadStore) stay in PrairieTests/PrairieTVTests only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…stry rework After the sync, persistent sessions go through AccountSessionPersistence (installing one needs the server origin), the keychain moved from the com.continuum service to org.prairieserver.prairie with the old names kept for migration, cache keys carry a v2 segment, Specials sort first, editions decode from edition_raw, and ServerRegistry no longer merges or mirrors the legacy per-entry profile. - TokenStorePersistenceTests sets the server URL before saving tokens and asserts the new keychain names plus the legacy ones. - ResponseCache, season sort, edition, requests status and settings error mapping assertions follow the new behaviour. - Drop the ServerRegistryMigrationTests cases and gate-fill assertions that only described the removed legacy-profile and pre-canonical token migration. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Add CredentialIdentity, MediaRequestAuthorization, MetadataSingleFlight, PersonalListsAPI, ServerIdentityMatching, SettingValueWrites, SharedDefaults, SharedKeychainCheckedRead, HTTPClient diagnostics classification and WatchPartyAPI tests, plus the Foundation-only watch party invitation/socket and URL scheme types they use. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
APIv2CatalogReadProjectionTests decodes a fully populated catalog item (versions with every track kind, chapters and markers, playback variants, audiobook extension, videos, extras, overlay, user data and state), a watch detail, seasons, episodes, a person and a user library, and checks each field lands on the presentation model. It also pins the legacy-ID boundary (opaque, zero, padded and negative file IDs are rejected) and the partial-page guard on finite catalog collections. HTTPClientDiagnosticsClassificationTests stays out of the host: the types it asserts are compiled for iOS/tvOS only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…en test APIv2PlaybackModelsTests covers the capability gate (every unavailable state, missing protocol version or feature, missing installation id), the playback-control WebSocket handshake and its input validation, control capabilities, sequenced progress samples and the progress/stop bodies that wrap them, mutation receipts, and the source projection onto the protocol v3 descriptor including the legacy-ID guard. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- APIv2WireModelsTests: string-enum forward compatibility, account, system and problem documents, profile projection and PATCH encoding (set/clear/unchanged), device-login poll validation, capability, start and lookup presentation, subtitle AI status/quota/job projection and create-body validation, download registry and series-monitor models, requests errors. - APIv2CatalogQueryAndSyncTests: catalog query parameters, validation and GET/POST sizing, query factories and body, catalog restart classification, page/filter/collection-tab decoding, progress sync items, batches and outcome summaries, mutation delivery, and the update-requirement classification. - APIv2PlaybackModelsTests reads sequenced samples with a non-converting decoder: the sample spells its snake_case keys out. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…gate
The sync replaced PrairieAPI's /api/v1 calls with upstream's APIv2Client.
Its files are the per-operation request/response plumbing over
HTTPClient, the same category as the PrairieAPI*.swift files the gate
already excludes:
- APIv2Client.swift: request building, auth capture, response gating.
- APIv2Client+{Collections,Diagnostics,Downloads,DownloadSubscriptions,
MetadataAI,PersonalLists,Playback,Progress,Requests,Settings,
SubtitleAI,Subtitles,WatchParty}.swift: one extension per endpoint
group, each a thin call into APIv2Client.
- APIv2Probe.swift: the live unauthenticated /api/v2/system/info probe.
The wire models, catalog projection, mutation-outcome and dispatch
classification under Networking/APIv2 stay in scope, now with tests, and
the 95% threshold is unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…rojection - MetadataRequestPoolTests drives the pool over PrairieAPI/APIv2Client on the shared stub: concurrent reads of one item share a request, a finished flight or another key dispatches again, season/episode/watch reads resolve, and a cancelled sole waiter drops its flight. - ServerIdentityProbeTests covers the identity probe's answers (id, blank id, legacy plain 404, other 404, 5xx, offline), the branding name, the bearer connections read and its availability gate, and ServerEndpoint coding and help text. - APIv2PlaybackModelsTests projects the vendored playable decision onto legacy file ids and rejects an opaque effective id. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
TokenStoreSessionTests exercises the post-sync session store against in-memory keychains: install preconditions and expected-account checks, installing for another server, verified-account binding and durable authority, the ownership fence on both sides of an await, request capture against each identity field, the mismatch-reason classifier, temporary scope begin/replace/end, session snapshots restored across session, signed-out and legacy states, token deletion, profile activation and deactivation, and expiry-event routing for persistent and temporary credentials. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- CatalogShapeModelsTests: catalog pages as card grids, server-relative artwork resolved against the decoding server (and protocol-relative URLs left alone), section/browse row conversion both ways, season download names, subtitle selection indexes, and the collection and user bodies. - WatchPartyModelsTests: forward-compatible enums, capability defaults and socket gating, strict room validation with numeric-or-string ids, suggestions, transport commands, tickets, member state and the picker. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…odies - APIv2SubtitleSearchModelsTests: provider status, stored-subtitle projection and its file-id guard, search/download bodies, and every step of SubtitleDownloadOutcome.resolve (download failure, relist failure, owner change, missing listing entry, failed registration, success) plus its error classification. - APIv2PlaybackModelsTests wraps the vendored protocol v3 start, replan and route-event requests in their v2 bodies (installation id, event id, opaque file id). The PlaybackV3 fixtures are now bundled for the networking host too. - TokenStoreSessionTests: the two account-identity mismatches share one reason, so the classifier names seven distinct causes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The vendored replan and route-event fixtures are the server's own recovered shapes and omit fields the client model requires (local_mutations, applied_quirk_ids). Build both requests from the vendored start request and plan instead, and check the v2 body adds the installation and event ids around them. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The coverage gate reports one scoped percentage. When it drops, print each partly covered Networking file's unexecuted line ranges from the result bundle, so the gap can be found from the CI log alone. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- TokenStoreFailureTests injects canonical session storage that can fail reads, writes or removes, and checks that rotations and invalidations for a foreign or stale owner are discarded, a temporary rejection is reported once, unreadable or unwritable storage blocks the runtime session instead of trusting stale credentials, and a server switch drops a push display token issued for another server. - ServerRegistryEdgeTests covers verified-identity updates and their rollback, cancelled switches and removals, a removal that rolls back when sign-out cannot persist, seeding the shared suite from the standard fallback, and moving legacy per-entry profiles into the launch store. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
TemporaryAuthScope.profileToken is not optional. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The step's final while-loop test returned 1 for a fully covered last file, which failed the job under the runner's errexit+pipefail shell and skipped the coverage gate. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The sync's Apple regression workflow compiles the whole Tests tree into PrairieTests (iOS) and PrairieTVTests (tvOS). - NetworkingPrairieGateFillTests set AuthService.shared.isLoggedIn, which only the networking host's stand-in allows. Those lines now sit behind PRAIRIE_NETWORKING_HOST, a condition set on the host and its test bundle. - LiveTVChannelListViewInspectorTests imports ViewInspector, which only the iOS test bundle links, so PrairieTVTests excludes it like its other platform-bound suites. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… builds Upstream's HTTPClient asserts in DEBUG that every request is an /api/v2 route or the health probe. Prairie's Live TV deliberately stays on its Prairie-only /api/v1/livetv routes, so every debug build (and every test that switches servers, which refreshes LiveTVFeatureStore) crashed on the assertion. Accept the /api/v1/livetv/ prefix alongside v2 and pin it in HTTPClientRequestPathTests; regenerate the v1 allowlist for the new deliberate matches. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…a relative URL ArtworkVariantURL.candidates rewrote .webp to .png/.avif only for absolute URLs. A server-relative signed path such as /artwork/.../w300.rev.webp?expires=..&sig=.. has a path extension of "webp?expires=..", so the sibling was dropped and only the WebP candidate was offered. Rewrite the path part and keep the query and fragment, as ArtworkVariantURLTests expects. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- ProfileAndQualitySettingsTests: the merge rebranded "X-Silo-Original", but it is the settings contract's private-use language tag (the code and the vendored manifest use x-silo-original), not branding. - LiveTVChannelListViewInspectorTests: ViewInspector inspects a fresh copy of the view, so tapping a tab never reached the next inspection. Check the tab bar and the Guide tab the list opens on instead. - ServerRegistryMigrationTests' relaunch test and ServerRegistryEdgeTests' suite-seeding test describe the defaults-backed registry; tvOS keeps its registry in the shared Keychain, so they are skipped there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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
Sync with upstream
Silo-Server/silo-applemain(work in progress; body will be updated once CI is green).Merge with 'Create a merge commit' — do not squash.
AI disclosure
🤖 Generated with Claude Code