refactor(accounts): invert residual TPPNetworkExecutor edge behind AccountNetworking (Wave 3 / 3a) - #1360
refactor(accounts): invert residual TPPNetworkExecutor edge behind AccountNetworking (Wave 3 / 3a)#1360mauricecarrier7 wants to merge 2 commits into
Conversation
…behind AccountNetworking (Wave 3 / 3a) Wave 3 / 3a decomp precondition. `AccountsManager` named the app-target `TPPNetworkExecutor` concretely for its three network calls (cancel on account-switch cleanup, catalog/auth-doc GET, clearCache). S3 already inverted the ambient REACH via `AccountSwitchDependencies.networkExecutorProvider`, but the property + provider were still concretely typed — the last blocker to moving `AccountsManager` into a `PalaceAccounts` SwiftPM target, which cannot name a `Palace/Network` type. Its own header (`AccountsManager.swift:277`) recorded this to-do. - New `AccountNetworking` (`AnyObject, Sendable`; cancelNonEssentialTasks / clearCache / GET) beside AccountsManager — travels into PalaceAccounts at the package move. `Sendable` is required: the async GET is awaited inside an owned-crawl @sendable Task, so the existential must be Sendable. `TPPNetworkExecutor` is already `@unchecked Sendable`, so the conformance adds zero new obligation. - App-side `extension TPPNetworkExecutor: AccountNetworking {}` (empty; signatures already match) — stays app-target across the move. - Retype `AccountsManager.networkExecutor` + `AccountSwitchDependencies.networkExecutorProvider` to `any AccountNetworking`. AppContainer wiring unchanged (concrete upcasts). - Seam proof: `SpyAccountSwitchNetworkExecutor` no longer subclasses the concrete executor (its comment claimed subclassing was "the only way" to observe the cancel seam) — now a plain `AccountNetworking` conformer. New `AccountNetworkingSeamTests` pins clearCache + account-switch cancel routing through the injected seam. Behavior-identical (pure type inversion). Sign-in/account-switch-critical → /rigorous-fix: fix-contract + architect APPROVED. Verified: DRM scoped suites 7/7, wiring(isolation)+MetaTests 18/18, Palace-noDRM BUILD SUCCEEDED, god-class freeze PASS (hub flat at 2383), shared-read at baseline, zero contract-snapshot drift. **Scope:** the `TPPNetworkExecutor` type edge in AccountsManager + its provider seam, plus the switch-cleanup spy conversion and a routing test. Accounts area only. **Not done:** behavioral GET drive (both call sites are the cold-launch network fallback — flaky to drive; covered by compile-time conformance + explicit `useTokenIfAvailable`). No behavior change, so no mutation surface on the retyped lines. **Deferred:** the 3a in-target collaborator split and the package move itself (separate PRs per wave-3 plan); the `@retroactive` on the conformance lands with the package move. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🏗️ CodeAtlas Ledger Analysis✅ All Checks Passed♿ Accessibility (via AccessLint)
✅ No accessibility issues detected 🏛️ Architecture Analysis
🔄 Dependency CyclesSee full report for cycle details. 📋 Architecture FindingsSee full report for detailed findings. 🔍 Reachability Analysis
ℹ️ No architecture-relevant files in this diff — reachability not evaluated. 📊 0 files analyzed | 📦 Download Full Report Powered by CodeAtlas Ledger |
🧪 Unit Test Results📊 View Full Interactive Report ❌ 3 TESTS FAILED8189 tests | 8045 passed | 3 failed | 139 skipped | ⏱️ 16m 2s | 📊 98.2% | 📈 45.2% coverage All 943 classes — 3 with failures (full matrix)
📊 Full interactive matrix: report ❌ Failed testsNames only — open the interactive report above for messages + stack frames. 📊 Testing Coverage BreakdownUnit Test Line Coverage (testable surfaces): 45.2% Total coverage incl. UI/lifecycle: 44.2% (17 files excluded from testable denominator — see
📈 What changed vs. baseTest count: +1
|
| Artifact | Description |
|---|---|
| test-report | 📄 Markdown + HTML reports |
| test-data | 📊 JSON data for tooling |
| test-results | 🔍 Full xcresult (open in Xcode) |
… tripped by a comment CI `tooling-integrity` (check-appcontainer-locator-count.sh) counts the literal `AppContainer.production()` by substring — including in comments — and the seam's header prose mentioned it, pushing the out-of-allowlist count 304 -> 305 (+1) and failing the ratchet. The reference was descriptive only (contrasting the S3 injected-provider path against reaching the composition root); reworded to drop the literal. No behavior/API change; locator back to baseline 304. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What & why
Wave 3 / 3a god-class-decomposition precondition.
AccountsManagerstill named the app-targetTPPNetworkExecutorconcretely for its three network calls (cancel on account-switch cleanup, catalog/auth-docGET,clearCache). S3 already inverted the ambient reach viaAccountSwitchDependencies.networkExecutorProvider, but the property + provider were still concretely typed — the last blocker to movingAccountsManagerinto aPalaceAccountsSwiftPM target, which cannot name aPalace/Networktype. The hub's own header (AccountsManager.swift:277) recorded this to-do.This inverts that edge behind a new
AccountNetworkingprotocol. Behaviour-identical type inversion.Changes
AccountNetworking(AnyObject, Sendable;cancelNonEssentialTasks/clearCache/GET) declared besideAccountsManager— travels intoPalaceAccountsat the package move.Sendableis required, not cosmetic: the asyncGETis awaited inside an owned-crawl@SendableTask, so the existential must beSendable.TPPNetworkExecutoris already@unchecked Sendable, so the conformance adds zero new obligation.extension TPPNetworkExecutor: AccountNetworking {}(empty — signatures already match). Stays app-target across the move (gains@retroactive+import PalaceAccountsthen).AccountsManager.networkExecutor+AccountSwitchDependencies.networkExecutorProvidertoany AccountNetworking.AppContainerwiring unchanged (concrete upcasts).SpyAccountSwitchNetworkExecutorno longer subclasses the concrete executor — its comment claimed subclassing was "the only way" to observe the cancel seam; now a plainAccountNetworkingconformer. NewAccountNetworkingSeamTestspinsclearCache+ account-switch cancel routing through the injected seam.Verification
Review rigor
/rigorous-fixflow: fix-contract → architect pre-review APPROVED → implement → skeptic → 3× SoD (architect,qa_test,blast_radius) all APPROVED, every finding warning-level. Non-blocking notes:GET's behavioural path is undriven (cold-launch network fallback — flaky; routing is now type-guaranteed and covered by compile-time conformance); the.detailsEvicted/.accountNotFoundprose refresh in the area checklist is out-of-scope.Not in this PR (per wave-3 plan)
The 3a in-target collaborator split and the
PalaceAccountspackage move itself (separate PRs); the@retroactiveon the conformance lands with the package move.🤖 Generated with Claude Code