1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//! Référence auteur typée multi-agent.
//!
//! Gradatum distingue 4 kinds d'auteurs pour permettre un audit trail précis
//! des modifications (B12 : multi-agent author pattern).
use serde::{Deserialize, Serialize};
/// Catégorie d'auteur.
///
/// Décision Q4 brainstorming the maintainer 2026-05-03 — 4 variantes couvrent tous les
/// producteurs de notes dans un environnement multi-agent :
/// humain, orchestrateur principal, sous-agent délégué, processus système.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum AuthorKind {
/// Humain. `id` = email | username | bearer subject.
Human,
/// Agent orchestrateur principal.
///
/// `id` = `"mcp-client"` | `"local-agent"` | etc.
MainAgent,
/// Sous-agent délégué par le main agent.
///
/// `id` = `"backend"` | `"tester"` | `"reviewer"` | `"editor"` | `"planner"` | ...
SubAgent,
/// Processus système automatisé.
///
/// `id` = `"legacy-vault"` | `"cron-decay"` | `"post-push-hook"` | `"migrate-tool"` | ...
System,
}
/// Référence à l'auteur d'une note.
///
/// Structuré pour permettre un audit trail précis et cross-agent.
/// Le champ `display_name` est optionnel — omis en sérialisation si absent.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct AuthorRef {
/// Catégorie de l'auteur.
pub kind: AuthorKind,
/// Identifiant opaque, interprété selon `kind`.
pub id: String,
/// Nom lisible pour affichage. Omis si `None`.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub display_name: Option<String>,
}
impl AuthorRef {
/// Construit un auteur humain sans display name.
pub fn human(id: impl Into<String>) -> Self {
Self {
kind: AuthorKind::Human,
id: id.into(),
display_name: None,
}
}
/// Construit un agent orchestrateur principal.
pub fn main_agent(id: impl Into<String>) -> Self {
Self {
kind: AuthorKind::MainAgent,
id: id.into(),
display_name: None,
}
}
/// Construit un sous-agent.
pub fn sub_agent(id: impl Into<String>) -> Self {
Self {
kind: AuthorKind::SubAgent,
id: id.into(),
display_name: None,
}
}
/// Construit un auteur système (processus automatisé).
pub fn system(id: impl Into<String>) -> Self {
Self {
kind: AuthorKind::System,
id: id.into(),
display_name: None,
}
}
}