// // NetworkIsolationTests.swift // PocheTests // // Author: Simon-Pierre Boucher // Contact: contact@spboucher.ai // import Foundation import SwiftData import Testing @testable import Poche /// CLAUDE.md §7: no network request of any kind in the agent path. This /// tripwire registers a URLProtocol spy on the default URL loading system /// and fails if anything in the exercised path issues a request. /// (It cannot see custom-configuration sessions — but Poche must not /// create any URLSession at all, so any hit here is already a breach.) final class NetworkSpyProtocol: URLProtocol { // Test-serial access only. nonisolated(unsafe) static var requestCount = 0 override class func canInit(with request: URLRequest) -> Bool { requestCount += 1 return false } override class func canonicalRequest(for request: URLRequest) -> URLRequest { request } } @MainActor struct NetworkIsolationTests { @Test func agentToolPathMakesNoNetworkRequest() async throws { NetworkSpyProtocol.requestCount = 0 URLProtocol.registerClass(NetworkSpyProtocol.self) defer { URLProtocol.unregisterClass(NetworkSpyProtocol.self) } let container = try ModelContainer( for: Note.self, TaskItem.self, ConversationRecord.self, TurnRecord.self, configurations: ModelConfiguration(isStoredInMemoryOnly: true) ) let store = PocheStore(container: container) let index = SemanticIndex() let executor = ActionExecutor(bridge: EventKitBridge(), store: store) let confirm = ConfirmCenter(executor: executor) // Exercise validation, proposal, store writes and semantic search. let reminderTool = CreateReminderTool(confirm: confirm) _ = try await reminderTool.call( arguments: .init(title: "Test réseau", dueDate: "2030-06-01T10:00:00", list: nil) ) store.addNote(title: "Idée", content: "Comparer les embeddings locaux") let searchTool = SearchMyDataTool(store: store, index: index) _ = try await searchTool.call(arguments: .init(query: "embeddings")) #expect(NetworkSpyProtocol.requestCount == 0) } }