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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
use Vec;
use ;
use LogLine;
use crate;
use crate::;
/// Sela um valor serializável como Signed Fact (Paper II: Cycle of Truth).
///
/// Executa o ciclo completo: `canonize → blake3 → ed25519`:
/// 1. Canoniza o valor em bytes determinísticos
/// 2. Calcula o CID (BLAKE3 hash dos bytes canônicos)
/// 3. Assina o CID com Ed25519
///
/// O resultado é um `SignedFact` imutável que pode ser verificado por qualquer pessoa
/// que tenha acesso ao fato, sem necessidade de confiar em terceiros.
///
/// # Erros
///
/// - `SealError::Canonical` se a canonicalização falhar
///
/// # Exemplo
///
/// ```rust
/// use ed25519_dalek::SigningKey;
/// use json_atomic::{seal_value, errors::SealError};
/// use serde::Serialize;
///
/// #[derive(Serialize)]
/// struct Fact {
/// message: String,
/// timestamp: u64,
/// }
///
/// // Chave de exemplo (em produção, derive de seed/keystore)
/// let sk = SigningKey::from_bytes(&[0u8; 32]);
/// let fact = Fact {
/// message: "Hello, World!".into(),
/// timestamp: 1735671234,
/// };
///
/// let signed = seal_value(&fact, &sk)?;
/// println!("CID: {}", signed.cid_hex());
/// # Ok::<(), SealError>(())
/// ```
/// Verifica a integridade e autenticidade de um Signed Fact.
///
/// Valida que:
/// 1. O CID corresponde aos bytes canônicos (recalcula BLAKE3)
/// 2. A assinatura Ed25519 é válida para o CID e a chave pública
///
/// Retorna `Ok(())` se o fato estiver íntegro e autenticado, ou um erro
/// se houver qualquer problema de integridade ou assinatura.
///
/// # Erros
///
/// - `VerifyError::CanonicalMismatch` se o CID recalculado não corresponder
/// - `VerifyError::BadSignature` se a assinatura for inválida
///
/// # Exemplo
///
/// ```rust
/// use ed25519_dalek::SigningKey;
/// use json_atomic::{seal_value, verify_seal, errors::SealError};
/// use serde::Serialize;
///
/// #[derive(Serialize)]
/// struct Fact {
/// data: String,
/// }
///
/// // Chave de exemplo (em produção, derive de seed/keystore)
/// let sk = SigningKey::from_bytes(&[0u8; 32]);
/// let fact = Fact { data: "test".into() };
///
/// let signed = seal_value(&fact, &sk)?;
/// verify_seal(&signed)?; // Verifica integridade e autenticidade
/// # Ok::<(), SealError>(())
/// ```
/// Sela um LogLine completo como Signed Fact (Paper II: Signed Fact de ação verificada).
///
/// Conveniência para selar um `LogLine` do `logline-core` diretamente.
/// Equivalente a `seal_value(line, sk)`, mas com tipo específico para LogLine.
///
/// # Exemplo
///
/// ```rust
/// use ed25519_dalek::SigningKey;
/// use json_atomic::{seal_logline, errors::SealError};
/// use logline_core::*;
///
/// // Chave de exemplo (em produção, derive de seed/keystore)
/// let sk = SigningKey::from_bytes(&[0u8; 32]);
/// let line = LogLine::builder()
/// .who("did:ubl:alice")
/// .did(Verb::Approve)
/// .when(1735671234)
/// .if_ok(Outcome { label: "ok".into(), effects: vec![] })
/// .if_doubt(Escalation { label: "doubt".into(), route_to: "auditor".into() })
/// .if_not(FailureHandling { label: "not".into(), action: "notify".into() })
/// .build_draft()?;
///
/// let signed = seal_logline(&line, &sk)?;
/// println!("LogLine CID: {}", signed.cid_hex());
/// # Ok::<(), SealError>(())
/// ```