SPB Git

spb/poche Public

Agent personnel 100 % on-device — SwiftUI + Apple Foundation Models + EventKit + SwiftData. Aucune API, aucun serveur.

Swift 100%
2.2 KB · 62 lines swift
Raw Blame History
1//2//  NetworkIsolationTests.swift3//  PocheTests4//5//  Author:  Simon-Pierre Boucher6//  Contact: contact@spboucher.ai7//89import Foundation10import SwiftData11import Testing12@testable import Poche1314/// CLAUDE.md §7: no network request of any kind in the agent path. This15/// tripwire registers a URLProtocol spy on the default URL loading system16/// and fails if anything in the exercised path issues a request.17/// (It cannot see custom-configuration sessions — but Poche must not18/// create any URLSession at all, so any hit here is already a breach.)19final class NetworkSpyProtocol: URLProtocol {20    // Test-serial access only.21    nonisolated(unsafe) static var requestCount = 02223    override class func canInit(with request: URLRequest) -> Bool {24        requestCount += 125        return false26    }2728    override class func canonicalRequest(for request: URLRequest) -> URLRequest {29        request30    }31}3233@MainActor34struct NetworkIsolationTests {35    @Test func agentToolPathMakesNoNetworkRequest() async throws {36        NetworkSpyProtocol.requestCount = 037        URLProtocol.registerClass(NetworkSpyProtocol.self)38        defer { URLProtocol.unregisterClass(NetworkSpyProtocol.self) }3940        let container = try ModelContainer(41            for: Note.self, TaskItem.self, ConversationRecord.self, TurnRecord.self,42            configurations: ModelConfiguration(isStoredInMemoryOnly: true)43        )44        let store = PocheStore(container: container)45        let index = SemanticIndex()46        let executor = ActionExecutor(bridge: EventKitBridge(), store: store)47        let confirm = ConfirmCenter(executor: executor)4849        // Exercise validation, proposal, store writes and semantic search.50        let reminderTool = CreateReminderTool(confirm: confirm)51        _ = try await reminderTool.call(52            arguments: .init(title: "Test réseau", dueDate: "2030-06-01T10:00:00", list: nil)53        )5455        store.addNote(title: "Idée", content: "Comparer les embeddings locaux")56        let searchTool = SearchMyDataTool(store: store, index: index)57        _ = try await searchTool.call(arguments: .init(query: "embeddings"))5859        #expect(NetworkSpyProtocol.requestCount == 0)60    }61}62