From 7f8129371a4d4c35a68aefbf139959a7c833cc41 Mon Sep 17 00:00:00 2001 From: tarikskalic33 <228550385+tarikskalic33@users.noreply.github.com> Date: Wed, 29 Jul 2026 13:23:43 +0200 Subject: [PATCH 1/3] feat(clients): bring AEGIS Omega App Intents package under version control The package existed only in a transient agent scratch directory (Documents\Codex\2026-07-28\...\outputs\). That is the same class of location where the holon-gram compiler was lost permanently when its container was reclaimed. Untracked agent output is one cleanup away from gone. Also makes it build off-Apple: AppIntents ships only in Apple SDKs, so the two AppIntents sources and the test exercising AEGISSessionModeIntentValue are guarded with #if canImport(AppIntents). The pure-Foundation route model and router then compile and test on Linux/Windows, keeping the routing logic verifiable without a Mac. Apple builds are unchanged. Adds three tests: route equality by payload, AEGISSessionMode raw-value round trip including rejection of an unknown value, and that clear() on a superseded handoff does not drop the current one. Router tests reset the shared singleton via defer. Co-Authored-By: Claude Opus 5 --- clients/aegis-omega-app-intents/Package.swift | 27 +++++ clients/aegis-omega-app-intents/README.md | 51 +++++++++ .../AEGISAppIntents.swift | 105 ++++++++++++++++++ .../AEGISAppShortcuts.swift | 39 +++++++ .../AEGISIntentRoute.swift | 14 +++ .../AEGISIntentRouter.swift | 32 ++++++ .../AEGISIntentRouteTests.swift | 70 ++++++++++++ 7 files changed, 338 insertions(+) create mode 100644 clients/aegis-omega-app-intents/Package.swift create mode 100644 clients/aegis-omega-app-intents/README.md create mode 100644 clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISAppIntents.swift create mode 100644 clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISAppShortcuts.swift create mode 100644 clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISIntentRoute.swift create mode 100644 clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISIntentRouter.swift create mode 100644 clients/aegis-omega-app-intents/Tests/AEGISOmegaAppIntentsTests/AEGISIntentRouteTests.swift diff --git a/clients/aegis-omega-app-intents/Package.swift b/clients/aegis-omega-app-intents/Package.swift new file mode 100644 index 000000000..deb0d7e12 --- /dev/null +++ b/clients/aegis-omega-app-intents/Package.swift @@ -0,0 +1,27 @@ +// swift-tools-version: 5.9 + +import PackageDescription + +let package = Package( + name: "AEGISOmegaAppIntents", + defaultLocalization: "en", + platforms: [ + .iOS(.v17), + .macOS(.v14), + ], + products: [ + .library( + name: "AEGISOmegaAppIntents", + targets: ["AEGISOmegaAppIntents"] + ), + ], + targets: [ + .target( + name: "AEGISOmegaAppIntents" + ), + .testTarget( + name: "AEGISOmegaAppIntentsTests", + dependencies: ["AEGISOmegaAppIntents"] + ), + ] +) diff --git a/clients/aegis-omega-app-intents/README.md b/clients/aegis-omega-app-intents/README.md new file mode 100644 index 000000000..ff9de9618 --- /dev/null +++ b/clients/aegis-omega-app-intents/README.md @@ -0,0 +1,51 @@ +# AEGIS Omega — App Intents client + +Siri / Spotlight / Shortcuts entry points that hand a single system-facing route into the app's +root scene. + +## Why this is in the repository + +It was previously stranded in a transient agent scratch directory +(`Documents\Codex\2026-07-28\build-ios-apps-ios-app-intents-2\outputs\`). That is the same class +of location where the "holon-gram compiler" (8 files, +4446/−889) was lost permanently when its +container was reclaimed — see `CLAUDE.md` § *Verified Failure Modes* V1. Work that only exists in +an agent's working directory is one cleanup away from gone. + +## Layout + +| File | Platform | Purpose | +|---|---|---| +| `AEGISIntentRoute.swift` | any | `AEGISIntentRoute` / `AEGISSessionMode` — pure `Foundation` route model | +| `AEGISIntentRouter.swift` | any | `@MainActor @Observable` singleton the root scene observes | +| `AEGISAppIntents.swift` | Apple only | `AppIntent` conformances + `AEGISSessionModeIntentValue` | +| `AEGISAppShortcuts.swift` | Apple only | `AppShortcutsProvider` phrases | + +## Cross-platform guard + +`AppIntents` ships only in Apple SDKs. The two Apple-only sources are wrapped in +`#if canImport(AppIntents)`, and the test that exercises `AEGISSessionModeIntentValue` is guarded +the same way. On Apple platforms everything compiles unchanged; on Linux/Windows the pure +`Foundation` core and its tests still build, so the routing logic stays continuously verifiable +without a Mac. + +## Build + +```bash +swift build +swift test +``` + +**Windows prerequisite:** the Swift toolchain requires MSVC's `link.exe`. Without the Visual +Studio C++ workload, `swift build` fails with `toolchain is invalid: could not find CLI tool +'link'`. Installing that workload requires an **elevated** process — a non-elevated +`setup.exe --quiet` exits `5007` and silently does nothing. + +**iOS builds require macOS + Xcode.** No Windows toolchain can produce an iOS app; on Windows only +the cross-platform core and its tests are exercised. + +## Tests + +`AEGISIntentRouteTests` covers route equality by payload, `AEGISSessionMode` raw-value round trip +(including the rejection of an unknown value), that `accept` replaces the pending handoff with a +fresh identity, and that `clear` on a superseded handoff does not drop the current one. Router +tests reset shared state via `defer`, since `AEGISIntentRouter.shared` is a singleton. diff --git a/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISAppIntents.swift b/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISAppIntents.swift new file mode 100644 index 000000000..8b987ad9e --- /dev/null +++ b/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISAppIntents.swift @@ -0,0 +1,105 @@ +// AppIntents ships only in Apple SDKs. Guarded so the pure-Swift core and its +// tests still build on Linux/Windows; on Apple platforms this compiles unchanged. +#if canImport(AppIntents) +import AppIntents + +public enum AEGISSessionModeIntentValue: String, AppEnum { + case focused + case governed + case recovery + + public static let typeDisplayRepresentation: TypeDisplayRepresentation = "Session mode" + + public static let caseDisplayRepresentations: [Self: DisplayRepresentation] = [ + .focused: "Focused", + .governed: "Governed", + .recovery: "Recovery", + ] + + var domainValue: AEGISSessionMode { + switch self { + case .focused: .focused + case .governed: .governed + case .recovery: .recovery + } + } +} + +public struct ContinueContextIntent: AppIntent { + public static let title: LocalizedStringResource = "Continue context" + public static let description = IntentDescription( + "Open AEGIS Omega with context captured from Siri, Spotlight, or another shortcut." + ) + public static let openAppWhenRun = true + + @Parameter( + title: "Context", + inputConnectionBehavior: .connectToPreviousIntentResult + ) + public var context: String? + + public init() {} + + public init(context: String?) { + self.context = context + } + + public func perform() async throws -> some IntentResult { + await AEGISIntentRouter.shared.accept(.continueContext(text: context)) + return .result() + } +} + +public struct StartGovernedSessionIntent: AppIntent { + public static let title: LocalizedStringResource = "Start governed session" + public static let description = IntentDescription( + "Open AEGIS Omega ready to begin a focused, governed, or recovery session." + ) + public static let openAppWhenRun = true + + @Parameter(title: "Objective") + public var objective: String? + + @Parameter(title: "Mode", default: .governed) + public var mode: AEGISSessionModeIntentValue + + public init() {} + + public init(objective: String?, mode: AEGISSessionModeIntentValue = .governed) { + self.objective = objective + self.mode = mode + } + + public func perform() async throws -> some IntentResult { + await AEGISIntentRouter.shared.accept( + .startSession(objective: objective, mode: mode.domainValue) + ) + return .result() + } +} + +public struct InspectEvidenceIntent: AppIntent { + public static let title: LocalizedStringResource = "Inspect evidence" + public static let description = IntentDescription( + "Open AEGIS Omega at the evidence surface, optionally focused on a reference." + ) + public static let openAppWhenRun = true + + @Parameter( + title: "Reference", + inputConnectionBehavior: .connectToPreviousIntentResult + ) + public var reference: String? + + public init() {} + + public init(reference: String?) { + self.reference = reference + } + + public func perform() async throws -> some IntentResult { + await AEGISIntentRouter.shared.accept(.inspectEvidence(reference: reference)) + return .result() + } +} +#endif diff --git a/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISAppShortcuts.swift b/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISAppShortcuts.swift new file mode 100644 index 000000000..9834d2a9c --- /dev/null +++ b/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISAppShortcuts.swift @@ -0,0 +1,39 @@ +// AppIntents ships only in Apple SDKs. Guarded so the pure-Swift core and its +// tests still build on Linux/Windows; on Apple platforms this compiles unchanged. +#if canImport(AppIntents) +import AppIntents + +public struct AEGISAppShortcuts: AppShortcutsProvider { + public static var appShortcuts: [AppShortcut] { + AppShortcut( + intent: ContinueContextIntent(), + phrases: [ + "Continue context in \(.applicationName)", + "Remember this with \(.applicationName)", + ], + shortTitle: "Continue context", + systemImageName: "brain.head.profile" + ) + + AppShortcut( + intent: StartGovernedSessionIntent(), + phrases: [ + "Start a governed session in \(.applicationName)", + "Begin a session with \(.applicationName)", + ], + shortTitle: "Start session", + systemImageName: "point.3.connected.trianglepath.dotted" + ) + + AppShortcut( + intent: InspectEvidenceIntent(), + phrases: [ + "Inspect evidence in \(.applicationName)", + "Open evidence with \(.applicationName)", + ], + shortTitle: "Inspect evidence", + systemImageName: "checkmark.seal" + ) + } +} +#endif diff --git a/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISIntentRoute.swift b/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISIntentRoute.swift new file mode 100644 index 000000000..ab76a668e --- /dev/null +++ b/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISIntentRoute.swift @@ -0,0 +1,14 @@ +import Foundation + +/// The single system-facing route passed from App Intents into the main scene. +public enum AEGISIntentRoute: Equatable, Sendable { + case continueContext(text: String?) + case startSession(objective: String?, mode: AEGISSessionMode) + case inspectEvidence(reference: String?) +} + +public enum AEGISSessionMode: String, CaseIterable, Codable, Sendable { + case focused + case governed + case recovery +} diff --git a/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISIntentRouter.swift b/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISIntentRouter.swift new file mode 100644 index 000000000..343ed230b --- /dev/null +++ b/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISIntentRouter.swift @@ -0,0 +1,32 @@ +import Foundation +import Observation + +/// Main-actor handoff point observed by the app's root scene. +@MainActor +@Observable +public final class AEGISIntentRouter { + public struct Handoff: Identifiable, Equatable, Sendable { + public let id: UUID + public let route: AEGISIntentRoute + + public init(id: UUID = UUID(), route: AEGISIntentRoute) { + self.id = id + self.route = route + } + } + + public static let shared = AEGISIntentRouter() + + public var pendingHandoff: Handoff? + + private init() {} + + public func accept(_ route: AEGISIntentRoute) { + pendingHandoff = Handoff(route: route) + } + + public func clear(_ handoff: Handoff) { + guard pendingHandoff?.id == handoff.id else { return } + pendingHandoff = nil + } +} diff --git a/clients/aegis-omega-app-intents/Tests/AEGISOmegaAppIntentsTests/AEGISIntentRouteTests.swift b/clients/aegis-omega-app-intents/Tests/AEGISOmegaAppIntentsTests/AEGISIntentRouteTests.swift new file mode 100644 index 000000000..79475edb6 --- /dev/null +++ b/clients/aegis-omega-app-intents/Tests/AEGISOmegaAppIntentsTests/AEGISIntentRouteTests.swift @@ -0,0 +1,70 @@ +import XCTest +@testable import AEGISOmegaAppIntents + +final class AEGISIntentRouteTests: XCTestCase { + + // Exercises the AppIntents-facing enum, so it can only run where AppIntents exists. + #if canImport(AppIntents) + func testSessionModesMapWithoutLosingMeaning() { + XCTAssertEqual(AEGISSessionModeIntentValue.focused.domainValue, .focused) + XCTAssertEqual(AEGISSessionModeIntentValue.governed.domainValue, .governed) + XCTAssertEqual(AEGISSessionModeIntentValue.recovery.domainValue, .recovery) + } + #endif + + @MainActor + func testRouterReplacesThePendingHandoffAtomically() { + let router = AEGISIntentRouter.shared + defer { router.pendingHandoff = nil } + + router.accept(.continueContext(text: "first")) + let first = router.pendingHandoff + + router.accept(.inspectEvidence(reference: "receipt-42")) + let second = router.pendingHandoff + + XCTAssertNotEqual(first?.id, second?.id) + XCTAssertEqual(second?.route, .inspectEvidence(reference: "receipt-42")) + } + + // The route model is pure Foundation, so these run on every platform. + func testRouteEqualityDistinguishesPayloads() { + XCTAssertEqual( + AEGISIntentRoute.continueContext(text: "a"), + AEGISIntentRoute.continueContext(text: "a") + ) + XCTAssertNotEqual( + AEGISIntentRoute.continueContext(text: "a"), + AEGISIntentRoute.continueContext(text: "b") + ) + XCTAssertNotEqual( + AEGISIntentRoute.startSession(objective: nil, mode: .focused), + AEGISIntentRoute.startSession(objective: nil, mode: .governed) + ) + } + + func testSessionModeRoundTripsThroughItsRawValue() { + for mode in AEGISSessionMode.allCases { + XCTAssertEqual(AEGISSessionMode(rawValue: mode.rawValue), mode) + } + XCTAssertNil(AEGISSessionMode(rawValue: "not-a-mode")) + } + + @MainActor + func testClearOnlyDropsTheMatchingHandoff() { + let router = AEGISIntentRouter.shared + defer { router.pendingHandoff = nil } + + router.accept(.startSession(objective: "audit", mode: .recovery)) + guard let stale = router.pendingHandoff else { return XCTFail("expected a handoff") } + + router.accept(.inspectEvidence(reference: "receipt-7")) + router.clear(stale) + + XCTAssertEqual( + router.pendingHandoff?.route, + .inspectEvidence(reference: "receipt-7"), + "clearing a superseded handoff must not drop the current one" + ) + } +} From 2884ed4bb620497b2c52b873df52a41726026c7c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 11:24:04 +0000 Subject: [PATCH 2/3] chore(manifest): refresh cognitive-state anchors --- .claude.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.claude.json b/.claude.json index db426975c..dbe5afd46 100644 --- a/.claude.json +++ b/.claude.json @@ -9,8 +9,8 @@ "provenance": { "generator": "scripts/build-cognitive-manifest.py", "repository": "Aegis-Omega/AEGIS-OMEGA", - "source_ref": "claude/blissful-rubin-mt9jS", - "parent_state_hash": "410bcd49c721e65050382ae759db7af2f41fa9f572e625174252c72a8748ea93", + "source_ref": "feat/app-intents-under-version-control", + "parent_state_hash": "e9f0ec153b0b320a1e791092f73209442ec43a982e503203d9c101ec40949cba", "signature_mode": "GITHUB_OIDC_ATTESTATION" }, "hashing": { @@ -488,5 +488,5 @@ "on_success": "broadcast-attested-verified-event-stream" } }, - "state_hash": "e9f0ec153b0b320a1e791092f73209442ec43a982e503203d9c101ec40949cba" + "state_hash": "77d2014edd826149d8fa6ced78db0ed81bd1811c1430f201ba3f64329f60ce15" } From f05304e6afaa78acbc88c3ad758fba7b2d261cd3 Mon Sep 17 00:00:00 2001 From: ssh <228550385+tarikskalic33@users.noreply.github.com> Date: Wed, 29 Jul 2026 21:40:54 +0200 Subject: [PATCH 3/3] fix(app-intents): address review findings on router access and test discovery Three findings from review of #242: - AEGISIntentRouter.pendingHandoff is now public private(set). It was publicly writable, which let a caller bypass the id-matching guard in clear(_:) and drop a handoff that had already been superseded. - Adds AEGISOmegaAppIntentsPackage so an app target can declare this package in includedPackages. Intents defined in a package are not indexed by Siri, Spotlight, or Shortcuts without that registration. - Test methods are nonisolated and async, with the main-actor hop inside each body. SwiftPM derives its test-discovery list from unapplied method references, so @MainActor on a method changes that reference's type to (Self) -> @MainActor () -> Void. Mixed isolation failed to compile off-Apple with a conflicting-'Element' error; uniform type-level isolation compiled but then failed to cast at run time, and the runner silently executed 0 tests. Verified on Windows (Swift 6.3.3, x86_64-unknown-windows-msvc): swift test -> Executed 4 tests, with 0 failures. The fifth test is inside #if canImport(AppIntents) and is correctly excluded off-Apple. Co-Authored-By: Claude Opus 5 --- .../AEGISAppIntentsPackage.swift | 18 +++++ .../AEGISIntentRouter.swift | 4 +- .../AEGISIntentRouteTests.swift | 67 ++++++++++++------- 3 files changed, 62 insertions(+), 27 deletions(-) create mode 100644 clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISAppIntentsPackage.swift diff --git a/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISAppIntentsPackage.swift b/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISAppIntentsPackage.swift new file mode 100644 index 000000000..1fafcd252 --- /dev/null +++ b/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISAppIntentsPackage.swift @@ -0,0 +1,18 @@ +// Intent definitions that live in a Swift package (rather than the app bundle) are not +// indexed by Siri / Spotlight / Shortcuts unless the app declares the package. Providing +// this type lets the app target opt in: +// +// struct MyApp: App, AppIntentsPackage { +// static var includedPackages: [any AppIntentsPackage.Type] { +// [AEGISOmegaAppIntentsPackage.self] +// } +// } +// +// AppIntents ships only in Apple SDKs, so this is guarded like the other intent sources. +#if canImport(AppIntents) +import AppIntents + +public struct AEGISOmegaAppIntentsPackage: AppIntentsPackage { + public init() {} +} +#endif diff --git a/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISIntentRouter.swift b/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISIntentRouter.swift index 343ed230b..1693eefad 100644 --- a/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISIntentRouter.swift +++ b/clients/aegis-omega-app-intents/Sources/AEGISOmegaAppIntents/AEGISIntentRouter.swift @@ -17,7 +17,9 @@ public final class AEGISIntentRouter { public static let shared = AEGISIntentRouter() - public var pendingHandoff: Handoff? + /// Read-only to callers: mutation must go through `accept(_:)` / `clear(_:)` so the + /// id-matching guard in `clear(_:)` cannot be bypassed by an external write. + public private(set) var pendingHandoff: Handoff? private init() {} diff --git a/clients/aegis-omega-app-intents/Tests/AEGISOmegaAppIntentsTests/AEGISIntentRouteTests.swift b/clients/aegis-omega-app-intents/Tests/AEGISOmegaAppIntentsTests/AEGISIntentRouteTests.swift index 79475edb6..b07706a0b 100644 --- a/clients/aegis-omega-app-intents/Tests/AEGISOmegaAppIntentsTests/AEGISIntentRouteTests.swift +++ b/clients/aegis-omega-app-intents/Tests/AEGISOmegaAppIntentsTests/AEGISIntentRouteTests.swift @@ -1,34 +1,48 @@ import XCTest @testable import AEGISOmegaAppIntents +// Every test method here is nonisolated and `async`, and the main-actor hop happens inside +// the body. SwiftPM builds its test-discovery list out of unapplied method references, so a +// method's isolation leaks into that list's element type: `@MainActor` methods produce +// `(Self) -> @MainActor () -> Void`, which off-Apple fails to compile when mixed with +// nonisolated methods and fails to *cast* at run time when it isn't. Keeping the whole class +// nonisolated keeps the element type uniform and castable, so the tests are actually invoked. final class AEGISIntentRouteTests: XCTestCase { + /// Returns the router to a known-empty state through its public API only, + /// since `pendingHandoff` is read-only to callers. + @MainActor + private func drain(_ router: AEGISIntentRouter) { + while let h = router.pendingHandoff { router.clear(h) } + } + // Exercises the AppIntents-facing enum, so it can only run where AppIntents exists. #if canImport(AppIntents) - func testSessionModesMapWithoutLosingMeaning() { + func testSessionModesMapWithoutLosingMeaning() async { XCTAssertEqual(AEGISSessionModeIntentValue.focused.domainValue, .focused) XCTAssertEqual(AEGISSessionModeIntentValue.governed.domainValue, .governed) XCTAssertEqual(AEGISSessionModeIntentValue.recovery.domainValue, .recovery) } #endif - @MainActor - func testRouterReplacesThePendingHandoffAtomically() { - let router = AEGISIntentRouter.shared - defer { router.pendingHandoff = nil } + func testRouterReplacesThePendingHandoffAtomically() async { + await MainActor.run { + let router = AEGISIntentRouter.shared + defer { drain(router) } - router.accept(.continueContext(text: "first")) - let first = router.pendingHandoff + router.accept(.continueContext(text: "first")) + let first = router.pendingHandoff - router.accept(.inspectEvidence(reference: "receipt-42")) - let second = router.pendingHandoff + router.accept(.inspectEvidence(reference: "receipt-42")) + let second = router.pendingHandoff - XCTAssertNotEqual(first?.id, second?.id) - XCTAssertEqual(second?.route, .inspectEvidence(reference: "receipt-42")) + XCTAssertNotEqual(first?.id, second?.id) + XCTAssertEqual(second?.route, .inspectEvidence(reference: "receipt-42")) + } } // The route model is pure Foundation, so these run on every platform. - func testRouteEqualityDistinguishesPayloads() { + func testRouteEqualityDistinguishesPayloads() async { XCTAssertEqual( AEGISIntentRoute.continueContext(text: "a"), AEGISIntentRoute.continueContext(text: "a") @@ -43,28 +57,29 @@ final class AEGISIntentRouteTests: XCTestCase { ) } - func testSessionModeRoundTripsThroughItsRawValue() { + func testSessionModeRoundTripsThroughItsRawValue() async { for mode in AEGISSessionMode.allCases { XCTAssertEqual(AEGISSessionMode(rawValue: mode.rawValue), mode) } XCTAssertNil(AEGISSessionMode(rawValue: "not-a-mode")) } - @MainActor - func testClearOnlyDropsTheMatchingHandoff() { - let router = AEGISIntentRouter.shared - defer { router.pendingHandoff = nil } + func testClearOnlyDropsTheMatchingHandoff() async { + await MainActor.run { + let router = AEGISIntentRouter.shared + defer { drain(router) } - router.accept(.startSession(objective: "audit", mode: .recovery)) - guard let stale = router.pendingHandoff else { return XCTFail("expected a handoff") } + router.accept(.startSession(objective: "audit", mode: .recovery)) + guard let stale = router.pendingHandoff else { return XCTFail("expected a handoff") } - router.accept(.inspectEvidence(reference: "receipt-7")) - router.clear(stale) + router.accept(.inspectEvidence(reference: "receipt-7")) + router.clear(stale) - XCTAssertEqual( - router.pendingHandoff?.route, - .inspectEvidence(reference: "receipt-7"), - "clearing a superseded handoff must not drop the current one" - ) + XCTAssertEqual( + router.pendingHandoff?.route, + .inspectEvidence(reference: "receipt-7"), + "clearing a superseded handoff must not drop the current one" + ) + } } }