feat(persistence): P5 — ProviderSessionStore (resumable_id par provider)

Range le resumable_id du moteur par (conversation, provider) dans
providers.json, support de reprise non exclusif (le handoff reste la source de
fidélité au swap cross-profile) — §19.2/§19.3.

- domaine : port ProviderSessionStore (get/set par provider)
- infra : FsProviderSessionStore — providers.json map plate, set en
  read-modify-write atomique (tmp+rename) sérialisé par conversation
  (coexistence multi-providers garantie), get absent ⇒ None, corrompu ⇒
  StoreError::Serialization

Tests : 6 cas P5 (coexistence claude+codex, 12 set concurrents sans perte,
corruption, isolation) ; cible conversation_log 30 verts, suites complètes
sans régression.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 13:14:34 +02:00
parent 75e4f57a71
commit f3046f3dd8
6 changed files with 467 additions and 4 deletions

View File

@ -33,7 +33,9 @@ pub mod store;
pub use clock::SystemClock;
pub use conversation::InMemoryConversationRegistry;
pub use conversation_log::{FsConversationLog, FsHandoffStore, HeuristicHandoffSummarizer, WINDOW};
pub use conversation_log::{
FsConversationLog, FsHandoffStore, FsProviderSessionStore, HeuristicHandoffSummarizer, WINDOW,
};
pub use eventbus::TokioBroadcastEventBus;
pub use fileguard::RwFileGuard;
pub use input::{MediatedInbox, MillisClock, SystemMillisClock};