forked from yvv/decision
Lot T3 : les tests d'abord, rouges sur les textes de T2 (aucun chiffre daté : l'exemple de N1.1 fait échouer le test des nombres ; la phrase du quorum de N1.1 vraie pour tout quorum, sur une grille de W, de quorums, de crans et de participations ; « comme d'habitude » au-delà du quorum seulement ; B^W ne compte jamais dans la toile ; l'amendement gardé qui suit celui de T2) ; textes de T2 gardés dans tests/fixtures/seed-quorum-t2.json ; wot::PLAUSIBLE public
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -782,6 +782,61 @@ mod tests {
|
||||
assert_eq!(verdict(Some(&written_by(&["m5", "t"])), &second, &["m5"]), Verdict::Refuse("revised"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_fourth_amendment_admits_the_texts_the_three_before_wrote_and_nothing_else() {
|
||||
// Lot T3 (2026-11-03): F1.2 and N1.1 were amended by M5, M6b and M6c (revision 4 in
|
||||
// production); the texts without dated figures replace the text of M6c, after it only.
|
||||
let fourth = Amendment { version: Version::Open("1.0.0"), follows: Some("t2"), ..A };
|
||||
let before: &[&str] = &["m5", "t", "t2"];
|
||||
// Production: M5, M6b, M6c, each its revision.
|
||||
assert_eq!(verdict(Some(&written_by(&["m5", "t", "t2"])), &fourth, before), Verdict::Apply);
|
||||
// A base born with the text of M5 (02/11): M6b and M6c wrote its revisions 2 and 3.
|
||||
assert_eq!(verdict(Some(&written_by(&["t", "t2"])), &fourth, before), Verdict::Apply);
|
||||
// A base born with the text of M6b, then of M6c: its revision 2, its revision 1.
|
||||
assert_eq!(verdict(Some(&written_by(&["t2"])), &fourth, before), Verdict::Apply);
|
||||
assert_eq!(verdict(Some(&intact()), &fourth, before), Verdict::Apply);
|
||||
// The last revision is not M6c's, or not by them alone, or out of order: refused.
|
||||
for applied in [
|
||||
&["m5", "t"][..],
|
||||
&["t"],
|
||||
&["m5"],
|
||||
&["t2", "t"],
|
||||
&["m5", "t2", "t"],
|
||||
&["other", "t", "t2"],
|
||||
&["m5", "t", "t2", "t2"],
|
||||
] {
|
||||
assert_eq!(verdict(Some(&written_by(applied)), &fourth, before), Verdict::Refuse("revised"), "{applied:?}");
|
||||
}
|
||||
// A typo after M6c: a revision no amendment wrote.
|
||||
let typo = Facts {
|
||||
revision: 5,
|
||||
revisions: vec![
|
||||
"initial".into(),
|
||||
"amendment".into(),
|
||||
"amendment".into(),
|
||||
"amendment".into(),
|
||||
"typo".into(),
|
||||
],
|
||||
..written_by(&["m5", "t", "t2"])
|
||||
};
|
||||
assert_eq!(verdict(Some(&typo), &fourth, before), Verdict::Refuse("revised"));
|
||||
// Any trace of a person keeps the text, with its reason.
|
||||
for (f, why) in [
|
||||
(Facts { votes: 1, ..written_by(&["m5", "t", "t2"]) }, "votes"),
|
||||
(Facts { ballots: 1, ..written_by(&["m5", "t", "t2"]) }, "ballots"),
|
||||
(Facts { typos: 1, ..written_by(&["m5", "t", "t2"]) }, "corrected"),
|
||||
(Facts { member_translations: 1, ..written_by(&["m5", "t", "t2"]) }, "translation_edited"),
|
||||
(Facts { signals: 1, ..written_by(&["m5", "t", "t2"]) }, "signalled"),
|
||||
(Facts { fingerprint: "other".into(), ..written_by(&["m5", "t", "t2"]) }, "text_differs"),
|
||||
(Facts { confirmed: true, ..written_by(&["m5", "t", "t2"]) }, "confirmed"),
|
||||
] {
|
||||
assert_eq!(verdict(Some(&f), &fourth, before), Verdict::Refuse(why), "{f:?}");
|
||||
}
|
||||
// Lot T2's own amendment never admits a revision 4.
|
||||
let third = Amendment { version: Version::Open("1.0.0"), follows: Some("t"), ..A };
|
||||
assert_eq!(verdict(Some(&written_by(&["m5", "t", "t2"])), &third, &["m5", "t"]), Verdict::Refuse("revised"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_amendments_followed_are_read_through_the_list_oldest_first() {
|
||||
let by_id = |id: &str| AMENDMENTS.iter().find(|a| a.id == id).expect("amendment");
|
||||
@@ -794,6 +849,14 @@ mod tests {
|
||||
["2026-11-02-n1-1-regles", "2026-11-03-n1-1-quorum"]
|
||||
);
|
||||
assert_eq!(earlier(AMENDMENTS, by_id("2026-11-03-f1-1-phrases")), ["2026-11-03-f1-1-quorum"]);
|
||||
assert_eq!(
|
||||
earlier(AMENDMENTS, by_id("2026-11-03-f1-2-chiffres")),
|
||||
["2026-11-02-f1-2-regles", "2026-11-03-f1-2-quorum", "2026-11-03-f1-2-phrases"]
|
||||
);
|
||||
assert_eq!(
|
||||
earlier(AMENDMENTS, by_id("2026-11-03-n1-1-chiffres")),
|
||||
["2026-11-02-n1-1-regles", "2026-11-03-n1-1-quorum", "2026-11-03-n1-1-phrases"]
|
||||
);
|
||||
assert!(earlier(AMENDMENTS, by_id("2026-10-30-i1-raison-d-etre")).is_empty());
|
||||
// Each one followed wrote the text the next replaces, and is superseded by it.
|
||||
for a in AMENDMENTS.iter().filter(|a| a.follows.is_some()) {
|
||||
|
||||
@@ -12,7 +12,9 @@ use std::time::Duration;
|
||||
|
||||
/// W is read again this often.
|
||||
pub const REFRESH: Duration = Duration::from_secs(6 * 3600);
|
||||
const PLAUSIBLE: std::ops::RangeInclusive<u32> = 100..=10_000_000;
|
||||
/// The sizes of the web of trust taken as true; anything else read is ignored. The texts of
|
||||
/// the seed are written true for every W in it (lot T3).
|
||||
pub const PLAUSIBLE: std::ops::RangeInclusive<u32> = 100..=10_000_000;
|
||||
|
||||
fn twox_128(data: &[u8]) -> [u8; 16] {
|
||||
let mut out = [0u8; 16];
|
||||
|
||||
Reference in New Issue
Block a user