feat(governance): flujo 5/7 de emergencia REAL — dos fases (audit B, David · RV 7→8)

Decisión B (David 2026-07-04). El audit ultra encontró que el gate 5/7 de
submit_emergency_proposal era TAUTOLÓGICO: `council_size >= threshold(council_size)`
es siempre true, y solo exigía UN council member — así que un solo miembro
fast-trackeaba una propuesta a 48h (vs 14 días) sin la pre-aprobación 5/7.

Fix (flujo de dos fases, como anticipaba el propio doc "gather signatures then
promote"):
- FASE 1: `endorse_emergency_proposal` (nueva, call_index 12) — un council member
  endosa por content-id (blake2 de title++body).
- FASE 2: `submit_emergency_proposal` ahora exige `live_endorsements >= 5/7 real`
  (conteo EN VIVO, solo miembros aún en el council — consistente con el fix de
  veto). Limpia los endosos consumidos tras promover.

+2 tests (flujo 5/7 completo con boundary 4→5, y regresión "un solo miembro NO
fast-trackea"). RUNTIME_VERSION 7→8 (call aditiva + metadata; TRANSACTION_VERSION
intacto). Workspace 284 verde.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
davidherranandClaude Fable 5 committed 2026-07-05 20:01:33 -05:00
1 parent 304072173e
commit 9f48723ca5
3 files changed
+166 -10

No files matched your search

+15 -7
View File
@@ -251,7 +251,14 @@ pub const IMPL_NAME: &str = "origin-chain-charon";
/// (polvo ~10^-10 OGC) a `ConstantMultiplier` calibrado — un transfer ≈ 1 MILLI_OGC,
/// el #16 Pi5 0.1× = ahorro real, quema deflacionaria medible. Comportamiento ⇒
/// spec bump; TRANSACTION_VERSION intacto.
pub const RUNTIME_VERSION: u32 = 7;
/// v8: hardening de governance (audit ultra 2026-07-04 + decisiones A/B David) —
/// correctitud: `override_council_veto` solo revierte vetos del council (no votos
/// populares), `treasury_disbursement` single-use (anti-replay), veto con conteo
/// en vivo. (A) reserva REAL del stake de propuesta (bond `og/props`). (B) flujo
/// 5/7 de emergencia real: nueva dispatchable `endorse_emergency_proposal`
/// (call_index 12) + gate real (antes tautológico). Nuevas storage/errors/evento
/// + 1 call aditiva ⇒ spec bump; TRANSACTION_VERSION intacto (call_index nuevo).
pub const RUNTIME_VERSION: u32 = 8;
/// Canonical authoring version per Substrate semver canonical.
pub const AUTHORING_VERSION: u32 = 1;
@@ -844,12 +851,13 @@ mod tests {
use super::*;
#[test]
fn runtime_version_v7_hard_cap_and_fee_teeth() {
// v7 = economía Level A (David 2026-07-03): techo duro 1B (emisión =
// transfer del pool Ecosystem, no mint) + fees con dientes (ConstantMultiplier
// calibrado, transfer ≈ 1 MILLI_OGC). Cambios de comportamiento, no de
// formato de extrinsic ⇒ TRANSACTION_VERSION intacto.
assert_eq!(RUNTIME_VERSION, 7);
fn runtime_version_v8_governance_hardening() {
// v8 = hardening de governance (audit ultra 2026-07-04 + decisiones A/B):
// correctitud (override/treasury/veto) + bond de propuesta (A) + flujo 5/7
// de emergencia real con endorse_emergency_proposal (B, call_index 12).
// Call aditiva + storage/metadata nuevos ⇒ spec bump; los extrinsics
// EXISTENTES no cambian formato ⇒ TRANSACTION_VERSION intacto.
assert_eq!(RUNTIME_VERSION, 8);
assert_eq!(TRANSACTION_VERSION, 1);
}