Moteur : le tampon des votes (ld_engine::buffer) — réconciliation, poids des états, intention à la place du vote vu ; trustinWallet : casts_simulated (lot V, ADR 0012)

Testés d'abord (vus rouges) : une voix par identité, la dernière dans l'ordre de la
chaîne quel que soit l'ordre de lecture, un « pour » prouvé sur une version retenue
écarté (le vote d'avant reste), le vote simulé au bloc 0, ce que pèse chaque état
chaîne fermée ou ouverte, la bascule SIMULATED_ADOPTS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-11-02 05:44:00 +01:00
co-authored by Claude Opus 5.5
parent e7dda2ff47
commit ee37c3b4d5
3 changed files with 413 additions and 1 deletions
+28 -1
View File
@@ -23,7 +23,10 @@
//! administrator; it is reiterated by the person who raised it only —
//! `lifts_objection` / `reiterates_objection`;
//! - each person reads their own messages only — `reads_message`
//! (2026-10-31, lot F, ADR 0010).
//! (2026-10-31, lot F, ADR 0010);
//! - while the chain is closed, the vote is simulated: whoever may ask for a
//! ballot votes on the server, marked as simulated — `casts_simulated`
//! (2026-11-02, lot V, ADR 0012).
use serde::{Deserialize, Serialize};
@@ -152,6 +155,16 @@ pub fn chain_vote_counts(member: bool) -> bool {
member
}
/// While the chain is closed (no vote account yet), a group that votes on the
/// chain votes in simulation (Yvv, 2026-11-02: « Simule le vote à tout endroit »,
/// ADR 0012): whoever may ask for a ballot casts a simulated vote, written by the
/// server, marked as such, for the identity of the session — there is no wallet.
/// One person signed in two ways may then hold two voices: accepted while the
/// simulation lasts, every simulated vote is set aside when the chain opens.
pub fn casts_simulated(identity: &Identity, group: &Group, granted: bool, chain_open: bool) -> bool {
!chain_open && asks_ballot(identity, group, granted)
}
/// Access management stays with trustinWallet's administrators.
pub fn manages_access(identity: &Identity) -> bool {
identity.admin
@@ -276,6 +289,20 @@ mod tests {
assert!(!chain_vote_counts(false), "a former member, or an account without identity, does not vote");
}
#[test]
fn while_the_chain_is_closed_whoever_may_ask_a_ballot_votes_in_simulation() {
let ml = group("monnaie-libre");
let invited = who(IdentityKind::Invite, false, false);
let member = who(IdentityKind::G1, true, false);
assert!(casts_simulated(&invited, &ml, true, false));
assert!(casts_simulated(&member, &ml, false, false));
assert!(!casts_simulated(&invited, &ml, false, false), "not without opening the group");
// The chain open: a ballot to sign, never a simulated vote.
assert!(!casts_simulated(&member, &ml, false, true));
// A managed group votes on the server, never in simulation.
assert!(!casts_simulated(&invited, &group("essai"), true, false));
}
#[test]
fn in_a_managed_group_every_member_votes_on_the_server() {
let essai = group("essai");