chantier: durcissement reprise headless inter-projets + persistance profils Opencode
- Implémentation reprise de session Opencode headless (conversational_recovery) - Persistance des profils IA Opencode dans .ideai/memory avec JSON Schema - Gestion des permissions MCP pour agents externes - Tests QA verts : structured_launch_d3, conversation_log, tickets_missing_carnet, agents, ProfilesSettings
This commit is contained in:
@ -1294,6 +1294,64 @@ async fn provider_is_isolated_per_conversation() {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn provider_is_isolated_per_project_root_with_same_conversation_and_provider() {
|
||||
let project_a = TempDir::new();
|
||||
let project_b = TempDir::new();
|
||||
let store_a = FsProviderSessionStore::new(&project_a.project_path());
|
||||
let store_b = FsProviderSessionStore::new(&project_b.project_path());
|
||||
let c = conv_id(77);
|
||||
|
||||
store_a.set(c, "opencode", "engine-a").await.unwrap();
|
||||
store_b.set(c, "opencode", "engine-b").await.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
store_a.get(c, "opencode").await.unwrap(),
|
||||
Some("engine-a".to_owned())
|
||||
);
|
||||
assert_eq!(
|
||||
store_b.get(c, "opencode").await.unwrap(),
|
||||
Some("engine-b".to_owned())
|
||||
);
|
||||
assert!(
|
||||
!std::fs::read_to_string(project_a.providers_path(c))
|
||||
.unwrap()
|
||||
.contains("engine-b"),
|
||||
"project A providers.json must not contain project B's engine id"
|
||||
);
|
||||
assert!(
|
||||
!std::fs::read_to_string(project_b.providers_path(c))
|
||||
.unwrap()
|
||||
.contains("engine-a"),
|
||||
"project B providers.json must not contain project A's engine id"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn provider_unresolved_project_root_fails_closed() {
|
||||
let root = ProjectPath::new(format!(
|
||||
"{}/missing-{}",
|
||||
std::env::temp_dir().to_string_lossy(),
|
||||
Uuid::new_v4()
|
||||
))
|
||||
.unwrap();
|
||||
let store = FsProviderSessionStore::new(&root);
|
||||
let c = conv_id(78);
|
||||
|
||||
assert_eq!(
|
||||
store.get(c, "opencode").await.unwrap(),
|
||||
None,
|
||||
"unresolved root cannot produce a resumable id"
|
||||
);
|
||||
assert!(
|
||||
matches!(
|
||||
store.set(c, "opencode", "engine").await,
|
||||
Err(StoreError::Io(_))
|
||||
),
|
||||
"unresolved root must not write outside a canonical project root"
|
||||
);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// LS6 — rotation (ConversationArchive) + pagination humaine, I/O réelle.
|
||||
// Réutilise le scaffolding L2 (TempDir absolu, constructeurs déterministes).
|
||||
|
||||
Reference in New Issue
Block a user