feat(orchestrator): modèle de désignation d'orchestrateur + sink de diagnostic

Introduit le modèle AgentManifest { version, entries, orchestrator } et la
garde d'écriture directe may_write_directly(..., &OrchestratorDesignation) :
seul l'orchestrateur désigné peut écrire directement, les autres passent par
le rendez-vous médié. Câble la désignation à travers domain → application →
infrastructure → app-tauri (context_guard, service, lifecycle, ports).

Ajoute crates/application/src/diag.rs : sink de diagnostic best-effort, sans
dépendance, qui miroite les traces du rendez-vous inter-agents de
l'orchestrateur vers un fichier de log persistant (utile au lancement via
AppImage où stderr est jeté), avec la même discipline « zéro dépendance,
ne casse jamais le rendez-vous ».

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-20 08:56:17 +02:00
parent 40982d44da
commit 287681c198
57 changed files with 1758 additions and 420 deletions

View File

@ -186,7 +186,11 @@ fn split_seconds_frac(s: &str) -> Option<(i64, i64)> {
return Some((s.parse::<i64>().ok()?, 0));
};
let sec = sec.parse::<i64>().ok()?;
let mut d3: String = frac.chars().take_while(char::is_ascii_digit).take(3).collect();
let mut d3: String = frac
.chars()
.take_while(char::is_ascii_digit)
.take(3)
.collect();
while d3.len() < 3 {
d3.push('0');
}
@ -257,7 +261,10 @@ mod tests {
fn wall_clock_to_ms_same_day_when_future() {
let now_10h = DAY_START + 10 * 3_600_000;
// 15:00 est dans le futur ⇒ même jour.
assert_eq!(wall_clock_to_ms(now_10h, 15, 0, 0), DAY_START + 15 * 3_600_000);
assert_eq!(
wall_clock_to_ms(now_10h, 15, 0, 0),
DAY_START + 15 * 3_600_000
);
}
#[test]
@ -282,7 +289,8 @@ mod tests {
#[test]
fn parse_absolute_ms_epoch_seconds_and_millis() {
assert_eq!(parse_absolute_ms("1700000000"), Some(1_700_000_000_000)); // s ⇒ ×1000
assert_eq!(parse_absolute_ms("1700000000000"), Some(1_700_000_000_000)); // ms tel quel
assert_eq!(parse_absolute_ms("1700000000000"), Some(1_700_000_000_000));
// ms tel quel
}
#[test]