chore(wip): checkpoint P8/C avant chantier Codex inter-agents

Sauvegarde de l'arbre de travail en cours (persistance P8, conversations
C-series, write-portal frontend, médiation d'entrée) avant d'attaquer le
support de la délégation inter-agents pour les profils Codex.

Le round-trip inter-agent question/réponse est couvert sans tokens par
les tests loopback existants (state::mcp_e2e_loopback_tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-13 21:42:53 +02:00
parent 4509f0db9d
commit fdcf16c387
76 changed files with 3783 additions and 1404 deletions

View File

@ -46,9 +46,7 @@ use domain::{
};
use uuid::Uuid;
use application::{
ChangeAgentProfile, ChangeAgentProfileInput, LaunchAgent, TerminalSessions,
};
use application::{ChangeAgentProfile, ChangeAgentProfileInput, LaunchAgent, TerminalSessions};
// ---------------------------------------------------------------------------
// FakeContexts (AgentContextStore) — manifest + md_path → content
@ -675,10 +673,7 @@ impl domain::HandoffStore for FakeHandoffs {
}
impl application::HandoffProvider for FakeHandoffs {
fn handoff_store_for(
&self,
_root: &ProjectPath,
) -> Option<Arc<dyn domain::HandoffStore>> {
fn handoff_store_for(&self, _root: &ProjectPath) -> Option<Arc<dyn domain::HandoffStore>> {
Some(Arc::new(self.clone()))
}
}
@ -860,7 +855,11 @@ async fn success_mutates_manifest_to_new_profile() {
.await
.expect("swap succeeds");
assert_eq!(out.agent.profile_id, pid(2), "returned agent carries new profile");
assert_eq!(
out.agent.profile_id,
pid(2),
"returned agent carries new profile"
);
assert_eq!(
f.contexts.profile_of(&agent.id),
Some(pid(2)),
@ -1017,7 +1016,10 @@ async fn live_agent_is_killed_and_relaunched_in_same_cell() {
assert_eq!(f.pty.spawn_count(), 1, "the new engine spawns once");
// The relaunched session is returned and pinned on the SAME cell N.
let relaunched = out.relaunched.expect("a live agent is relaunched");
assert_eq!(relaunched.node_id, host, "relaunch reopens in the same cell");
assert_eq!(
relaunched.node_id, host,
"relaunch reopens in the same cell"
);
assert_eq!(relaunched.id, sid(777), "relaunch adopts the new PTY id");
// The relaunched session is registered and tagged for this agent.
assert!(matches!(
@ -1111,8 +1113,11 @@ async fn live_swap_relaunches_with_preserved_pair_id_and_no_engine_resume() {
// A UUID-shaped pair id (so resolve_handoff can parse it) and a seeded handoff.
let pair = "11111111-1111-1111-1111-111111111111";
f.handoffs
.seed(pair, "Résumé : on a fini l'étape 2.", Some("Livrer le lot P8d"));
f.handoffs.seed(
pair,
"Résumé : on a fini l'étape 2.",
Some("Livrer le lot P8d"),
);
// Live agent on cell N with a foreign engine resumable cache.
let host = nid(5);
@ -1138,7 +1143,10 @@ async fn live_swap_relaunches_with_preserved_pair_id_and_no_engine_resume() {
// The old PTY was killed and a single relaunch happened in the SAME cell.
assert_eq!(f.pty.kills(), vec![sid(42)], "the live PTY must be killed");
let relaunched = out.relaunched.expect("a live agent is relaunched");
assert_eq!(relaunched.node_id, host, "relaunch reopens in the same cell");
assert_eq!(
relaunched.node_id, host,
"relaunch reopens in the same cell"
);
// The pair id is preserved on the persisted leaf; the engine cache is cleared.
assert_eq!(
@ -1171,7 +1179,10 @@ async fn live_swap_relaunches_with_preserved_pair_id_and_no_engine_resume() {
// The old engine resumable is NEVER replayed: the relaunch's SessionPlan is
// None (providers.json[new provider] is empty ⇒ fresh engine, fidelity carried
// by the handoff). It is emphatically NOT Resume{"engine-old"}.
let plan = f.runtime.last_plan().expect("the relaunch prepared an invocation");
let plan = f
.runtime
.last_plan()
.expect("the relaunch prepared an invocation");
assert_eq!(
plan,
SessionPlan::None,