feat(governance): RV16 — el override del veto se decide al cerrar la ventana, con 4/5 de quien participa
Cierra L-11 (override real del veto). David aprobó el 4/5 el 2026-10-01: «exigir una mayoría calificada de 4/5 en el consejo para anular un veto de emergencia es el cerrojo adecuado antes de retirar la llave Sudo». Qué cambia - La ventana de override tiene dos lados: revertir (override_council_veto) y sostener (uphold_council_veto, nuevo). Quien votó Nay puede sostener el veto; antes no tenía voz. - Nada se decide al cruzar un umbral. finalize_override (nuevo) decide UNA vez, al cerrar la ventana: se revierte si override >= ceil(4/5 * max(quórum, participación)). - El quórum se fija al vetar: max(Aye + Nay del voto original, MinOverrideQuorum). Abstain no cuenta. Así el bond que el veto devuelve no basta para revertirlo y un upgrade no lo mueve. - MinOverrideQuorum en el runtime = 100M OGC (el 10% de PILAR_4 §6.6); integrity_test exige que supere MIN_PROPOSAL_STAKE. - El periodo de voto ordinario dura al menos 14 días (MIN = DEFAULT) y el veto solo cabe dentro de él. Un voto de peso 0 en la ventana se rechaza. - spec_version 16. Pesos de uphold_council_veto y finalize_override medidos (frame-omni-bencher 0.15.0, 50 steps x 20 repeats); los demás re-medidos en el mismo banco. La revisión adversarial (nivel 1 de la directiva) tumbó la primera versión - Bloqueante: la regla de quórum no era monótona y votar «sostener» podía REVERTIR el veto. Ahora sostener nunca ayuda a revertir (test con la frontera exacta 2250/2251). - El mínimo de 48 h regalaba la vía de emergencia a cualquiera; ahora 14 días. - Las abstenciones inflaban el quórum; el quórum podía cambiar con un upgrade; la spec no subía. - 18 contrafactuales (mutaciones V1..V18), todos en rojo sin su pieza. Divergencia que queda abierta (D1 del roadmap V2): PILAR_4 §6.6 ratificó «override por 2/3» y el código implementa 4/5, que es lo que David confirmó. La constitución del DAO lo fija. Tests: gobernanza 78 (94 con runtime-benchmarks), runtime 44. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a694cbd9f0
commit
3771a15165
8 files changed
+1081
-173
No files matched your search
@@ -536,6 +536,11 @@ impl origin_chain_governance::Config for Runtime {
|
||||
type RuntimeFreezeReason = RuntimeFreezeReason;
|
||||
// RV15: votos VIVOS simultáneos por cuenta (los vencidos se descartan solos).
|
||||
type MaxActiveVotes = frame_support::traits::ConstU32<32>;
|
||||
// RV16: participación mínima para revertir un veto del council: 100M OGC, el 10%
|
||||
// del suministro que ratifica PILAR_4 §6.6 como quórum («10% quorum»). Es un
|
||||
// parámetro de la constitución del DAO y lo fija David; mientras, este. Lo pinna
|
||||
// `quorum_de_override_del_runtime` (genesis_config_presets.rs).
|
||||
type MinOverrideQuorum = frame_support::traits::ConstU128<{ 100_000_000 * OGC }>;
|
||||
type TreasuryPalletId = GovernanceTreasuryPalletId;
|
||||
// Weights INTERIM hand-derived DB-aware (ver weights.rs). Regenerable en HW.
|
||||
type WeightInfo = origin_chain_governance::weights::SubstrateWeight<Runtime>;
|
||||
|
||||
@@ -615,7 +615,7 @@ mod tests {
|
||||
use crate::{Balances, Governance, RuntimeFreezeReason, RuntimeOrigin, System};
|
||||
use frame_support::assert_ok;
|
||||
use frame_support::traits::fungible::{Inspect, InspectFreeze};
|
||||
use origin_chain_governance::{FreezeReason, MIN_PROPOSAL_STAKE};
|
||||
use origin_chain_governance::{FreezeReason, MIN_PROPOSAL_STAKE, MIN_VOTING_PERIOD_BLOCKS};
|
||||
use origin_chain_types::VoteStance;
|
||||
|
||||
let json = get_preset(&PresetId::from(PRESET_LOCAL_TESTNET)).expect("preset");
|
||||
@@ -628,7 +628,7 @@ mod tests {
|
||||
let bob = account_from_sr25519(BOB_SR25519);
|
||||
let charlie = account_from_sr25519(CHARLIE_SR25519);
|
||||
|
||||
let (titulo, cuerpo, periodo) = ([1u8; 32], [2u8; 32], 100u64);
|
||||
let (titulo, cuerpo, periodo) = ([1u8; 32], [2u8; 32], MIN_VOTING_PERIOD_BLOCKS);
|
||||
assert_ok!(Governance::submit_proposal(
|
||||
RuntimeOrigin::signed(alice.clone()),
|
||||
titulo,
|
||||
@@ -676,4 +676,22 @@ mod tests {
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/// RV16: el quórum de override del runtime es el 10% del suministro que
|
||||
/// ratifica PILAR_4 §6.6 (100M OGC). Sin este test, un typo como `{ 100_000_000 }`
|
||||
/// sin `* OGC` (10^-10 OGC) o `ConstU128<0>` pasaba toda la suite (revisión de
|
||||
/// RV16). `integrity_test` exige además que supere el bond de una propuesta.
|
||||
#[test]
|
||||
fn quorum_de_override_del_runtime() {
|
||||
use frame_support::traits::Get;
|
||||
let quorum: u128 =
|
||||
<<crate::Runtime as origin_chain_governance::Config>::MinOverrideQuorum as Get<u128>>::get();
|
||||
assert_eq!(quorum, 100_000_000 * crate::configs::OGC);
|
||||
assert_eq!(
|
||||
quorum,
|
||||
crate::configs::OGC * 1_000_000_000 / 10,
|
||||
"10% del suministro"
|
||||
);
|
||||
assert!(quorum > origin_chain_governance::MIN_PROPOSAL_STAKE);
|
||||
}
|
||||
}
|
||||
@@ -1019,7 +1019,7 @@ pub const VERSION: sp_version::RuntimeVersion = sp_version::RuntimeVersion {
|
||||
spec_name: alloc::borrow::Cow::Borrowed("origin-chain"),
|
||||
impl_name: alloc::borrow::Cow::Borrowed("origin-chain-charon"),
|
||||
authoring_version: 1,
|
||||
spec_version: 15,
|
||||
spec_version: 16,
|
||||
impl_version: 1,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
transaction_version: 1,
|
||||
@@ -1087,7 +1087,7 @@ mod tests {
|
||||
/// mismo commit en que la version subio a 12.
|
||||
#[test]
|
||||
fn spec_version_vigente_y_transaction_version_intacta() {
|
||||
assert_eq!(RUNTIME_VERSION, 15);
|
||||
assert_eq!(RUNTIME_VERSION, 16);
|
||||
assert_eq!(TRANSACTION_VERSION, 1);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user