6055faff1bf0f0f3dd0e9e68aa7b887b994dd05b
21
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6055faff1b |
feat(pesos): spec 20, los 17 pesos del gobierno salen de los certificados de Laurha
Ya no queda ningun smoke de Charon. weights.rs se ENSAMBLA desde los tres certificados del banco de referencia (la Pi 5) con scripts/bench/ensamblar-pesos.py: - Cada funcion cobra el maximo, coeficiente a coeficiente, de todos los certificados que midieron su mismo codigo (mismo esqueleto de lecturas, escrituras y proof que el del ultimo, que es el del codigo que corre). - Con --comprobar dice si el fichero es exactamente ese ensamblado: probado en rojo cambiando a mano un peso. - Los tres certificados quedan en scripts/bench/certificados/ (sha256 18b8fcd6, 1e15d04e y 6f5cfec1), con su perfil y su evidencia en la cabecera. Por que el maximo de todos y no solo el ultimo: «El maximo de 5 de un dia no es el de otro» (Laurha). La revision adversaria de spec 20 encontro que cobrar solo el certificado vigente de cada funcion dejaba treasury_disbursement en 136 us, cuando el certificado del 2-nov, sobre el wasm que corre, mide 155 us, y otros siete por debajo de lo medido. Con la regla, ningun peso baja respecto a spec 19; los que suben, entre el +1 % y el +33 % de ejecucion. Probado: - 365 tests verdes. - Ensayo en la rp1 sobre una cadena con el codigo vivo de spec 19. Contrafactual: con estos pesos, el E2E reprueba contra spec 19, porque la cadena cobra los viejos. Tras el upgrade a 20 pasa entero, y lo cobrado es weights.rs + extensiones. Ademas: configs.rs ya no dice «Weights INTERIM hand-derived» en los cinco pallets, que cobran pesos certificados desde spec 17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
158060bfe4 |
feat(gobierno): spec 19, el quorum es el 10 % de lo que puede votar
Decision de David, 2026-10-29: «Si, del 10 % de lo que puede votar». Que puede votar: - Es la emision vigente menos el saldo que nadie puede votar ni recuperar: el pool de emision, el de subsidios y el vault de gobierno (cuentas_sin_llave en configs.rs). - Los bonds (og/props) y los depositos de pallet-revive NO se restan, porque vuelven enteros a una cuenta con llave. La revision adversaria de spec 19 lo demostro con sonda: restarlos dejaba bajar el quorum un 14 % en el genesis de mainnet, aparcando un bond en una propuesta de relleno y recuperandolo despues. Efecto: - En mainnet el quorum pasa de ~100M a ~35,1M OGC (10 % de 351M). - En la testnet de la casa apenas cambia. - Las propuestas abiertas conservan el quorum que guardaron al crearse. Pruebas: - quorums_del_runtime clasifica cada cuenta de pallet por su nombre. - aparcar_un_bond_no_baja_el_quorum reproduce la sonda con la configuracion real. - toda_cuenta_de_pallet_con_saldo_esta_clasificada vigila las cuentas modl del genesis. - 10 contrafactuales en rojo. - El E2E (paso 2b) descubre las cuentas de pallet recorriendo el storage, no copia la lista, y exige el quorum exacto. La comision se quema despues de despachar, y eso se mide en el BurnedDebt de la propia transaccion. Pesos: submit_proposal, submit_treasury_proposal y veto_proposal leen 3 cuentas mas. Medidos en la Pi: 5 procesos limpios, el nucleo calentado 3 s antes de cada uno, a 2,4 GHz. Operacion de la rp1, arrancar.sh: - en cada encendido desde el 26-oct el nodo moria al segundo porque la red no estaba; ahora espera a la ruta por defecto; - un cerrojo flock impide dos instancias; - el pid vivo se reconoce por su linea de comandos. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
b6d05eaf45 |
feat(gobierno): spec 18 (RV17), quorum del voto ordinario y pago del tesoro atado a la propuesta
Gobierno (origin-chain-governance): - El voto ordinario exige un quorum de Aye, el 10 % de PILAR_4 §6.6. Se fija AL CREAR la propuesta (VoteQuorumOf) y se consume al decidirla: un set_code no mueve la meta de un voto abierto. Cuenta solo el Aye: con el Nay, un voto en contra podria aprobar; con la abstencion, el mismo OGC inflaria el quorum de muchas propuestas. - Un override del veto tiene que alcanzar ese quorum y superar el Nay original, las dos condiciones del voto ordinario. Sin ellas, vetar abarataba una aprobacion (dos bloqueantes de las revisiones adversariales). - submit_treasury_proposal (call 16) fija destinatario y monto (TreasuryActions), y treasury_disbursement solo paga exactamente eso, una vez. Rechaza montos bajo el deposito existencial y como destinatario la propia tesoreria o la cuenta-bond. - Sin entrada en VoteQuorumOf no hay quorum: la emergencia (que nunca lleva accion de tesoro) y lo creado antes de RV17, que se abrio y voto sin quorum. Runtime: los dos quorums son el 10 % de la emision VIGENTE, redondeado hacia arriba y nunca por debajo del bond (DiezPorCientoDeLaEmision). Con 100M fijos, en la testnet de la casa (100M emitidos, todos de Alice) nada se habria aprobado nunca; en mainnet sigue siendo ~100M. Spec 18, transaction_version 1: todo lo nuevo es aditivo, sin migracion. Node: pasa a opaque::Block. Decodificaba los extrinsics con tipos nativos y rechazaba en el pool la llamada que anadia el set_code (1040, el mismo error que una llamada inexistente). Los bytes y los hashes no cambian: el binario nuevo sincronizo desde cero los 39 273 bloques de la testnet de la casa con los mismos hashes en 8 alturas. El RPC sirve los extrinsics en hex. Pesos: seis extrinsics cambiaron de codigo y se midieron en la Pi 5 (smoke declarado: 5 procesos limpios, sin CI en ningun segundo, maximo de los 5). Los otros once siguen siendo los certificados por Laurha. Se descarto una medida contaminada: su muestreador no veia los tests de la CI. Pruebas: - 363 tests verdes en el workspace. - 24 contrafactuales, los 24 en rojo. - Ensayo en la rp1 sobre una cadena con el codigo vivo de spec 17: upgrade a 18 y E2E firmando como un wallet (scripts/e2e/rv17_tesoro.py). - Ejemplo firmar_como_wallet con tesoro, pagar, votar, depositar y finalizar; los eventos llevan su fase. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
e7b9c0c8bf |
feat(runtime): spec 17 — los pesos se cobran como en la Pi 5, medidos por Laurha en el banco de referencia
Los 23 weights de spec 16, certificados por Laurha en el santuario de la rp1 (origin-banco):
- Núcleo 3 aislado, governor performance a 2,4 GHz, CI parada, 45-49 °C.
- frame-omni-bencher 0.15.0 sobre el wasm 40cb5a1d de
|
||
|
|
3771a15165 |
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> |
||
|
|
a694cbd9f0 |
feat(governance): RV15 — el peso de un voto sale del saldo, y la revision adversaria tumbo la primera version
Cierra L-10. cast_vote y override_council_veto sumaban el stake_weight que
DECLARABA el votante (hueco medido por Palace el 2026-09-06; test en rojo
publicado en
|
||
|
|
d37a278ba6 |
test(governance): el hueco del peso de voto ya tiene donde vivir — test en rojo con control positivo (RV15)
Palace lo midio el 2026-09-06 y escribio que no era explotable porque el nodo
no arrancaba. Desde
|
||
|
|
38e5602d78 |
feat(weights): RV13 — los 19 estaban subdeclarados, los 19
Primera medicion real de los weights con frame-omni-bencher sobre el propio blob WASM. El resultado no es un ajuste fino: los 19 extrinsics de los 5 pallets custom declaraban MENOS de lo que cuestan. EL PATRON SISTEMATICO. Se costeo el storage del pallet y se olvido el que cuesta emitir un evento — System::Events, EventCount, ExecutionPhase y Number son reads y writes reales en cada extrinsic que deposita evento. Ejemplos medidos: attest_asset declaraba 4 reads / 1 write y cuesta 7/3; submit_proposal declaraba 12 us y cuesta 62; register_agent_did declaraba 3/2 y cuesta 6/4. EL PEOR, Y ES UN ERROR MIO DOCUMENTADO AL REVES. proof_size valia 0 en los 19. La cabecera de los interinos afirmaba que T::DbWeight "puebla tanto ref_time como proof_size ... cerrando el hueco". Es falso y se comprueba en la fuente: sp_weights::RuntimeDbWeight solo tiene los campos read y write, y reads(r) devuelve from_parts(read * r, 0). Los interinos arreglaron reads/writes y dejaron el proof_size exactamente donde estaba. Un proof_size en cero miente al block-builder sobre el peso PoV: es el vector de DoS que la nota decia haber cerrado. La afirmacion sobrevivio mas de un mes sin que ninguna lectura la desmintiera; la desmintio una medicion. Cada fichero generado lleva ahora un guard GENERADO desde la lista real de benchmarks que reprueba cualquier proof_size = 0 o ref_time = 0. Verificado que sabe reprobar: contra los weights anteriores se pone rojo con "`attest_asset` declara proof_size = 0". ADVERTENCIA QUE VA EN EL CODIGO, NO SOLO AQUI: son numeros de un MacBook Pro M3 Max, NO del banco de referencia BM V2. La forma (reads/writes/proof_size) no depende del hardware y es correcta; el ref_time si, y en un Pi 5 sera mayor. Un caso lo enseña solo: attest_asset BAJA de 50 a 44 us, y es el extrinsic dominado por el verify Ed25519, el mas sensible al silicio. Antes de mainnet hay que regenerar en el Pi 5 con governor y aislamiento declarados — peticion abierta a Laurha (request:66f500d54e28a80c) con el blob, el comando y la version exacta del bencher. RV12 -> RV13 (weights = consenso). TRANSACTION_VERSION intacto. 295 tests verde. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
266ee4084d |
polish(gov+attestation): test de empate en finalize + ancla SSOT de attestation
Polish pass MEDIUM/LOW post-audit (2 items limpios + triage de los invasivos): governance — cobertura del desempate (consenso-relevante, sin cobertura previa): - scenario_8b_finalize_tie_rejected_canonical: yes==nay ⇒ `yes > nay` es false ⇒ Rejected. Fija que se exige MAYORÍA ESTRICTA (el empate favorece el status quo). Entre scenario_7 (yes-majority→Approved) y scenario_8 (nay-majority→Rejected) faltaba justo el borde del empate. origin-chain-types — SSOT de attestation ahora que el crate aterrizó: - `arkhe-noesis-attestation-types` ya existe (crate standalone no_std + feature scale en el monorepo). El vendor-copy SE QUEDA como type-mirror deliberado: el chain es submódulo y depender del crate del monorepo invierte la dep-direction (submódulo→monorepo = ILEGAL). La SSOT se preserva por los golden vectors del oráculo real (decode_golden_vector_1/3/4), no por Cargo. - attestation_verify: §SSOT parity anchor doc — documenta que esos vectores pinnean el decoder al field-order de `SigningPayload` y cómo regenerar ante deriva. - attestation.rs: comentario del mirror actualizado (el crate aterrizó; diferencia conocida schema_version [u8;8] vs String es irrelevante — el mirror no serializa el wire; el decoder secuencial sí es byte-fiel al postcard, probado por vectores). Triage documentado (items considerados y DIFERIDOS con rationale, no olvidados): - register_agent_did unbounded Vec: bound del arg a ConstU32<10> movería el rechazo a decode-time, volvería AgentChainOverflow inalcanzable + rompería el test de overflow + exigiría spec bump — invasivo para un DoS ya mitigado por length-fee + límite de bloque. Diferido. - SS58 prefix (42): NO es bug — placeholder testnet correcto, gated en un DC de ss58-registry pre-mainnet. Sin cambio. - no-author path (emission): requiere un FindAuthor mock que devuelva None (segundo runtime o toggle) — ripple > valor. Diferido. Verificado: origin-chain-types 77 tests verde (incl. golden parity) + tie test verde. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
c7fc6a88fc |
feat(bench): maquinaria FRAME v2 de benchmarking para los 5 pallets custom (RV 8→9)
Los 19 extrinsics de provenance/fees/agent-identity/emission/governance pasan de weights placeholder `from_parts(10_000, 0)` (proof_size=0, sin contar reads/writes de DB — vector de DoS real) a weights INTERIM hand-derived DB-aware vía el trait `WeightInfo`. Cierra el mispricing de DoS en TODOS los extrinsics del chain. Cada pallet gana: - weights.rs: trait WeightInfo + SubstrateWeight<T> (DB-aware vía T::DbWeight) + impl () - benchmarking.rs: benchmarks FRAME v2, VERIFICADOS por impl_benchmark_test_suite! (19 benchmarks ejecutan+pasan en los mocks — cargo test --features runtime-benchmarks) - Config: `type WeightInfo` + swap de los `#[pallet::weight]` Runtime: - define_benchmarks! con los 5 pallets + runtime API Benchmark (inerte sin la feature) - WeightInfo cableado a SubstrateWeight<Runtime> en cada Config - RUNTIME_VERSION 8→9 (weights = consenso-relevante: fee + llenado de bloque; las firmas de los extrinsics NO cambian ⇒ TRANSACTION_VERSION intacto) 3 bugs latentes cerrados (territorio virgen — el runtime NUNCA se compiló con runtime-benchmarks; las dimensiones nuevas cazan lo que no se había visto): - pallet-grandpa/try-runtime mal ubicado en la feature runtime-benchmarks (copy-paste erróneo: features ortogonales; NUNCA activaba los benchmarks de grandpa) - feature runtime-benchmarks incompleta → E0046 en OriginFeeAdapter (métodos benchmark-gated de OnChargeTransaction) + pallet-staking (StakingUnchecked::migrate_to_direct_staker); ahora lista TODOS los pallets como un runtime de producción Substrate - pallet-revive/runtime-benchmarks omitido a propósito (fixtures RISC-V/PolkaVM indisponibles; ReviveApi deferred, no benchmarkeado) emission: mock extraído del `mod tests` inline a `pub mod mock` (reuso del test-suite, sin duplicar el scaffold; los 15 tests existentes + el benchmark verdes). GATED (documentado en el §Estado de cada weights.rs): la generación de números CANÓNICOS por CLI requiere el node sc-service o omni-bencher+WASM (ambos bloqueados hace sesiones). Los weights interinos son DB-aware/DoS-safe y regenerables de forma mecánica cuando aterrice el HW de referencia (Pi5/VPS) — benchmarking.rs es la fuente de verdad de la FORMA. Verificado: 5 test-suites de pallet verdes (con y sin runtime-benchmarks) + runtime compila en ambos modos + workspace sin regresión + 40 tests de runtime (incl. v9). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
9f48723ca5 |
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> |
||
|
|
304072173e |
feat(governance): reserva REAL del stake de propuesta — bond og/props (audit A, David)
Decisión A (David 2026-07-04). El audit ultra encontró [HIGH] que el "mínimo 1.000 OGC" de submit_proposal era un número caller-supplied SIN respaldo: una cuenta vacía podía spamear propuestas ilimitadas, y ese `stake` fabricado era el `baseline` denominador del override_council_veto (manipulable). Fix (sin esperar a NPoS — el stake de propuesta es piel-en-el-juego anti-spam, distinto del voto pesado por stake): el stake se RETIENE de verdad en una cuenta- bond determinista `og/props` (transfer, Preservation::Preserve → falla si el proponente no tiene fondos) y se DEVUELVE al proponente cuando la propuesta se decide. Clave del lifecycle: el release ocurre en AMBAS transiciones fuera de Voting — finalize_proposal Y veto_proposal — o el bond de una propuesta vetada quedaría atrapado (no hay withdraw dispatchable). `og/props` separada del vault para que treasury_disbursement jamás toque un bond. Enfoque escrow-account: usa solo Currency::transfer (ya en el bound) — cero cambios de Config/runtime-wiring. submit_proposal + submit_emergency_proposal ambos bond. +3 regression tests (retiene+devuelve al finalizar, devuelve al vetar, rechaza si no alcanza). Mock refondeado >= MIN_PROPOSAL_STAKE. 48 gov tests, workspace 283 verde. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
80bf7e5ddf |
fix(governance): 3 bugs de correctitud del audit ultra (CRITICAL override + HIGH ×2)
Audit ultra 2026-07-04 (dimensión governance-hardening, nunca antes corrida): 1. [CRITICAL] override_council_veto revertía CUALQUIER propuesta Rejected a Approved — incluidas las que la COMUNIDAD votó en contra (finalize_proposal marca Rejected cuando nay>=yes). Un proponente podía resucitar una propuesta rechazada en las urnas y drenar el treasury, invirtiendo el voto popular. Fix: marca VetoRejected (solo la pone veto_proposal al alcanzar el umbral); el override exige esa marca ⇒ solo revierte VETOS del council, no votos. 2. [HIGH] treasury_disbursement podía re-desembolsar la MISMA propuesta Approved N veces (drenaje por replay) — el guard status==Approved no cambiaba tras el pago. Fix: marca Disbursed (single-use) + Error::AlreadyDisbursed. 3. [HIGH] veto_proposal usaba un contador MONÓTONO: el veto de un miembro removido seguía contando y encoger el council bajaba el umbral retroactivamente ⇒ una minoría podía vetar (derrota el safeguard 2/3). Fix: conteo EN VIVO (itera VetoVotes filtrando por membresía actual del council, O(≤7)). +3 regression tests. Governance 45 tests verde. Storage aditivo (VetoRejected, Disbursed) — sin migración (pre-mainnet, StorageVersion 0). Pendientes para David (diseño): reserva real del stake de propuesta (HoldReason), emergency 5/7. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
1a9e37021d |
fix(governance): FIX-6 Stage 1 — tesoreria real Currency (cierra hallazgo de FIX-5)
Build + tests verde: governance 42 + runtime 27. Verificacion adversarial ultracode (2 skeptics): 2 confirmed/low, sin blockers. Cierra el hallazgo HIGH de FIX-5: treasury_disbursement era simbolico (solo decrementaba un contador u128 desconectado de pallet_balances). Ahora: - governance Config: type Currency (fungible Inspect+Mutate) + type TreasuryPalletId (pallet::constant). - Eliminado el contador Treasury<StorageValue<u128>> (0 referencias colgantes). - treasury_account() = PalletId.into_account_truncating() — vault keyless deterministico (nadie lo controla por wallet; honor Inmutable #16). - treasury_balance() lee el balance REAL (Inspect::balance), no un contador. - treasury_disbursement: T::Currency::transfer real desde el vault al recipient (ensure_root + proposal Approved). treasury_deposit: signed, dona del propio balance del caller (cualquiera fondea, no requiere Root, imposible robar). - runtime configs.rs: Currency=Balances + GovernanceTreasuryPalletId(og/gvtry). - mock con pallet_balances + scenario_4 prueba que el RECIPIENT recibe OGC REAL en pallet_balances (bob 100M -> 100M+300k), no solo que el contador baja. Decision constitucional (FIX-6 V2-CA3): David ratifico sub_mult = ORTOGONALES (la suscripcion premium NO reduce el subsidio anti-clasista de hardware, #16). Input para el OnChargeTransaction de Stage 2. Registrado en KG. FOLLOW-UPS (low, documentados, no bloquean): - genesis mainnet: rutear los 250M Foundation a la cuenta og/gvtry (hoy van a FNDT) — detalle de pre-launch que David ratifica. El vault arranca en 0 hasta fondear. - treasury_disbursement no vincula amount/recipient al proposal Approved, y el mismo proposal es reusable (no se marca disbursed). Check ceremonial, no autorizacion per-desembolso. Sin escalada nueva (Root ya puede todo via sudo). Endurecer antes del sunset sudo->governance. FIX-6 Stage 1 restante (next): emision que paga Aura authors (cierra V2-CA2) + remover APR falso del staking contract. Stage 2: NPoS + fee unificado (OnChargeTransaction con el sub_mult ortogonal). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
8a1f779c32 |
fix(runtime): FIX-5 governability (pallet-sudo to Root) + FIX-2 StorageVersion (4 pallets)
Build + tests verde (exit 0, runtime 27 tests incl. sudo_pallet_index_12). Verificacion adversarial ultracode (5 skeptics): 4 confirmed + 1 partial. FIX-5 — governability (audit V2-CA1): - pallet-sudo 43.0.0 wired Index 12 (workspace + runtime Cargo.toml + std). - impl pallet_sudo::Config (RuntimeEvent/RuntimeCall/WeightInfo) en configs.rs. - genesis: sudo key en los 3 presets — dev/local=Alice, mainnet=foundation_treasury (NO una dev key; el verificador confirmo que no hay backdoor critico). - Da Root origin -> las dispatchables ensure_root de Governance (add/remove council, mark/unmark advisor, treasury_disbursement) dejan de ser no-invocables. Verificado extremo-a-extremo: sudo() despacha RawOrigin::Root, que es exactamente lo que ensure_root acepta. - Sunset documentado (codigo + doc): sudo -> governance real (pallet-collective/ referenda) ANTES de mainnet. Sudo key unica = riesgo de centralizacion aceptable solo como interim/testnet. FIX-2 — lifecycle (audit V1-H2/V2-CA2): - StorageVersion::new(0) + pallet::storage_version en los 4 pallets (provenance/fees/agent-identity/governance). Aditivo, in-code==on-chain==0, sin migracion forzada. Habilita migraciones futuras. CAVEAT honesto (hallazgo high del red-team, NO defecto de FIX-5/FIX-2): treasury_disbursement solo DECREMENTA un contador u128 (Treasury StorageValue), NO mueve OGC real via pallet_balances. FIX-5 restaura la GOBERNABILIDAD (la dispatchable es invocable), pero mover los 250M reales es FIX-6: anadir type Currency al Config + T::Currency::transfer desde una cuenta-tesoreria derivada (PalletId) + financiarla en genesis + test del free_balance. NO se afirma "tesoreria descongelada de verdad" — solo "gobernabilidad restaurada". PENDIENTE: - FIX-2 AGI key recovery (rotate/revoke/active en agent-identity): diferido — necesita un DC de semantica de recovery #41 (single-sig vs multisig threshold, DID estable vs rota, recovery de agent_chain vacio). No se construye contra spec no-ratificada. - pallet-sudo no en feature runtime-benchmarks (inerte hoy: el runtime no impl el Benchmark API). Follow-up con weights benchmarking. - mainnet Foundation sudo key (FNDT placeholder): David ratifica la key real (multisig) pre-launch Q1 2027 (documentado). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
10ee1ab7b9 |
feat(governance): v0.0.34 Phase 5 FULLY COMPLETE — 5.3-5.8 refinements consolidated 🎉🎉🎉
Phase 5 GOVERNANCE FULLY COMPLETE end-to-end canonical. 5.3-5.8 refinements consolidated single ship canonical. AI advisor flag system (5.6) + Council veto override 4/5 community supermajority (5.5) + Emergency referendum 48h fast-track (5.7) + Treasury disbursement (5.8) + voting period constants (5.3+5.4). ## Phase 5.3+5.4 constants canonical - DEFAULT_VOTING_PERIOD_BLOCKS = 201,600 (14 days × 24h × 600 blocks/h @ 6s) - EMERGENCY_VOTING_PERIOD_BLOCKS = 28,800 (48h × 600 blocks/h) - council_emergency_threshold ceiling 5/7 ## Phase 5.5 Community override canonical - override_council_veto dispatchable (7-step canonical) - 4/5 supermajority ceiling threshold (override_supermajority_threshold const fn) - OverrideVotes StorageDoubleMap + OverrideStakeTotal cached - Events::CouncilVetoOverridden + Errors::ProposalNotRejected/AlreadyOverrideVoted/OverrideThresholdNotMet ## Phase 5.6 AI advisor system canonical - AdvisorFlags StorageMap presence-based - mark_as_advisor + unmark_as_advisor dispatchables (ensure_root) - cast_vote canonical EXTENDED: AdvisorMayNotVote enforcement (humans-only vote) - Events::AdvisorFlagged + AdvisorUnflagged + Errors::AlreadyAdvisor + NotAdvisor ## Phase 5.7 Emergency referendum canonical - submit_emergency_proposal canonical (council-only + 5/7 council pre-approval) - Fast-track 48h voting period vs 14 days - Events::EmergencyProposalSubmitted + Errors::InsufficientCouncilEmergencyApprovals ## Phase 5.8 Treasury disbursement canonical - Treasury StorageValue<u128> Foundation balance - treasury_deposit (ensure_root helper) + treasury_disbursement (6-step canonical) - Requires ProposalStatus::Approved (governance ratification) - Events::TreasuryDisbursed + Errors::TreasuryInsufficientBalance + ProposalNotApproved ## Phase 5 dispatchables canonical inventory 12 total dispatchables (Index 0-11): submit_proposal + cast_vote + finalize_proposal + Council mgmt (add/remove) + veto + advisor mgmt (mark/unmark) + override + emergency + treasury (disburse/deposit). ## Verification - cargo build --release -p origin-chain-node 5.17s clean - cargo test -p origin-chain-governance — 42 tests verde, 0 failures (10 lifecycle + 7 Council mgmt + 5 Council veto + 3 Advisor + 3 Override + 3 Emergency + 4 Treasury + 5 standalone + 2 auto) - cargo test --workspace — 202 tests verde, 0 failures 🎉🎉🎉 Phase 5 GOVERNANCE FULLY COMPLETE end-to-end canonical. CHN-4 materializado compile-detect. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
b3fc5da6ca |
feat(governance): v0.0.33 Phase 5.2 COMPLETE — Council veto 2/3 threshold + GovernanceApi extension 🎉
Phase 5.2 TECHNICAL COUNCIL COMPLETE end-to-end canonical. veto_proposal dispatchable + 2/3 ceiling threshold + 3 nuevos Runtime API methods (is_council_member + current_council_size + veto_votes_count). CHN-4 5.2+5.5 materializado compile-detect. ## veto_proposal canonical 7-step CHN-4 5.5 1. ensure_signed 2. Validate council_member (NotCouncilMember) 3. Get proposal (must be Voting) 4. Validate council_size > 0 (InsufficientCouncilSize) 5. !VetoVotes::contains_key (AlreadyVetoed) 6. Insert vote + increment VetoCount 7. Check threshold: count >= council_veto_threshold(size) → Rejected + ProposalVetoed event ## Storage + events + errors canonical nuevo - VetoVotes StorageDoubleMap presence-based + VetoCount cached u32 - Event::CouncilVetoVoteCast + ProposalVetoed - Error::AlreadyVetoed + InsufficientCouncilSize ## Runtime API GovernanceApi extension canonical - is_council_member(account) -> bool - current_council_size() -> u32 - veto_votes_count(proposal_id) -> u32 ## Verification - cargo build --release 4.82s clean - cargo test -p origin-chain-governance — 29 tests verde, 0 failures (10 lifecycle + 7 Council mgmt + 5 Council veto NEW + 5 standalone + 2 auto) - cargo test --workspace — 189 tests verde, 0 failures 🎉 Phase 5.2 TECHNICAL COUNCIL COMPLETE canonical. Hijos de Arkhē somos. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
afefcb2c04 |
feat(governance): v0.0.32 Phase 5.2 Council scaffold + member management (CHN-4 Technical Council)
Phase 5.2 TECHNICAL COUNCIL scaffold + management canonical. Extension del existing origin-chain-governance pallet (NO new crate). 5-7 Council members canonical per CHN-4 5.2. ## Council types + storage canonical - CouncilMember struct (account + joined_at_block + role) - CouncilRole enum (Member + Chair) - MAX_COUNCIL_SIZE = 7 const + council_veto_threshold 2/3 ceiling - Council StorageMap + CouncilSize StorageValue cached ## Council dispatchables + helpers canonical - add_council_member (ensure_root, 6-step canonical) - remove_council_member (ensure_root, 5-step canonical) - Pallet::is_council_member + current_council_size + required_veto_votes pure helpers ## Council events + errors canonical - Event::CouncilMemberAdded + CouncilMemberRemoved - Error::NotCouncilMember + AlreadyCouncilMember + CouncilSizeExceeded ## Verification - cargo test -p origin-chain-governance — 24 tests verde, 0 failures (7 Council scenarios + 17 prior governance preserved) 🏛️ Phase 5.2 scaffold canonical. Veto + Runtime API v0.0.33 next → Phase 5.2 COMPLETE. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
7c1425ff66 |
feat(governance): v0.0.30 — submit_proposal + cast_vote + finalize_proposal impl complete + mock runtime integration tests E2E (10 scenarios)
Phase 5.1 GOVERNANCE pallet REAL IMPL canonical. Full dispatchables canonical 7+6+5 step CHN-4 flow + storage assertions + tally + voting period enforcement + mock runtime + 10 integration tests E2E pattern v0.0.26 mirror. ## Real dispatchables canonical - submit_proposal (7 steps): ensure_signed + stake>=MIN + derive_id BLAKE2-256 + collision + build + insert + emit - cast_vote (6 steps): ensure_signed + get_proposal + status_voting + block<=end + !already_voted + update_tally + emit - finalize_proposal (5 steps): ensure_signed + get_proposal + status_voting + block>end + tally + status + emit ## Mock runtime + 10 integration tests E2E canonical - scenario_1: Submit happy path → stored + event - scenario_2: Stake insufficient → StakeInsufficient (CHN-4 5.3) - scenario_3: Vote Aye tally → yes_weight += 500 - scenario_4: Vote Nay tally → nay_weight += 750 - scenario_5: Double vote → AlreadyVoted - scenario_6: Finalize voting open → VotingPeriodOpen - scenario_7: Finalize Approved yes majority → status=Approved + event - scenario_8: Finalize Rejected nay majority → status=Rejected - scenario_9: Vote closed period → VotingPeriodClosed - scenario_10: Full lifecycle (submit → 3 votes → finalize Approved) ## Files - EDIT: crates/origin-chain-governance/src/lib.rs (real impl + MIN_PROPOSAL_STAKE + account_bytes helper) - NEW: crates/origin-chain-governance/src/mock.rs (85 LOC mock runtime) - NEW: crates/origin-chain-governance/src/tests_integration.rs (290 LOC, 10 tests) - EDIT: CHANGELOG.md (v0.0.30 entry) ## Verification - cargo test -p origin-chain-governance — 17 tests verde, 0 failures (10 integration + 5 standalone + 2 auto-generated) 🛠️ Phase 5.1 real impl canonical. Runtime API v0.0.31 next → Phase 5 FOUNDATION COMPLETE. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
1bde93921e |
feat(governance): v0.0.28 origin-chain-governance pallet scaffold (Phase 5.1 Foundation Treasury CHN-4)
Phase 5.1 GOVERNANCE pallet scaffold canonical. Reemplaza placeholder GovernanceConfig stub en existing origin-chain-governance crate con real FRAME pallet. AI-Driven Human-Guarded canonical CHN-4 — 5 AI advisor agents ADVISE only, humans-only vote canonical non-negotiable. ## Pallet surface canonical - Pallet<T> + Config trait + RuntimeEvent - Proposal struct (11 fields content-addressed via BLAKE2-256) - ProposalStatus enum (Voting + Approved + Rejected + Withdrawn) - Proposals<StorageMap<ProposalId, Proposal>> per-proposal O(1) - Votes<StorageDoubleMap<ProposalId, AccountId, VoteStance>> double-vote prevention - Events ProposalSubmitted + VoteCast + ProposalFinalized - Errors 8 variants (ProposalNotFound + AlreadyVoted + VotingPeriodClosed/Open + StakeInsufficient + ProposalAlreadyFinalized + AdvisorMayNotVote + ProposalIdCollision) - Scaffold dispatchables submit_proposal + cast_vote + finalize_proposal - Helper derive_proposal_id via BLAKE2-256 hash (Inmutable #16 byte-determinism) - sp_api::decl_runtime_apis! GovernanceApi declaration (query_proposal + query_vote) ## Types canonical updated - origin-chain-types/src/governance.rs: added scale derives a ProposalId + VoteStance + Vote (Encode + Decode + DecodeWithMemTracking + MaxEncodedLen + TypeInfo) para FRAME-compatibility canonical ## Files - EDIT: crates/origin-chain-governance/Cargo.toml (stub → FRAME pallet deps canonical) - REPLACE: crates/origin-chain-governance/src/lib.rs (placeholder → ~360 LOC scaffold) - EDIT: crates/origin-chain-types/src/governance.rs (scale derives canonical) - EDIT: CHANGELOG.md (v0.0.28 entry) ## Verification - cargo test -p origin-chain-governance — 5 tests verde, 0 failures (pallet_compiles + derive_proposal_id deterministic + different + status variants + re-export) 🏛️ Phase 5.1 scaffold canonical. Wire pattern v0.0.29 next. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
b06560863c |
feat(workspace): Phase 0.4 — trait-first foundation v0.0.1
Charon sesión 1 (2026-05-19) — primer commit canonical. Ships the Day 1 unblock surface so all hermanos can compile against Origin Chain interfaces before Substrate runtime lands (Phase 1). ## origin-chain-types (CORE) - ProvenanceLedger trait (CHN-7) - OgcLedger trait (CHN-2) - ChainBridge trait + BridgeDestination enum (CHN-5) - GovernanceProposal trait + Vote + VoteStance (CHN-4) - FeeCalculator trait + pure compute_fee() helper (CHN-8) - Ogc newtype (18 decimals, 1B genesis hard cap) - AccountId (Ed25519 32-byte) + Signature (Ed25519 64-byte via serde-big-array) - AssetHash (BLAKE3 32-byte) - HardwareTier mirror (Mathi canonical, per ADR-0057) - AssetQualityTier (Standard | Hero) with gating + Hero surcharge - ChainError canonical enum (cites Inmutables + CHN-* in messages) ## Stub crates (Phase 1+ scaffolding) - origin-chain-consensus (Aura+GRANDPA PoA→NPoS, Phase 1) - origin-coin-tokenomics (OGC + fee matrix + burns, Phase 1-2) - origin-chain-provenance (asset attestation impl, Phase 2) - origin-chain-bridges (Polkadot+Eth L2 export-first, Phase 7) - origin-chain-governance (Foundation DAO, Phase 5) ## Tests: 41 passing (33 unit + 6 stub + 2 doctest) - Fee math: 7 tests cover EmbeddedArm/Portable/Desktop/Ultra × Standard/Hero matrix from CHN-8, including anti-clasista Inmutable #16 enforcement - Genesis supply: 1B OGC × 10^18 base units fits in u128 with 100x safety margin - Type sizes: AccountId=32, Signature=64, AssetHash=32, ProposalId=32 canonical - Serde roundtrips: AssetAttestation, BridgeDestination, VoteStance - Cross-crate wiring: origin-coin-tokenomics consumes origin-chain-types::fees ## Coordination notes - DC ORIGIN_CHAIN_FOUNDATION_V1 open in Palace KG (8 sub-decisions CHN-1..CHN-8) Proposer: Ergon (proxy — Charon hotfix shipped in Palace v0.9.0-α.5 same day) Co-authors: Larihana, Lyra, Mathi, Marihan, Phanes, Codex, Sussi, Palace Deadline: 2026-05-26 1/9 signatures filed so far (Palace ✅ APPROVE 8/8) Refs: CHN-1..CHN-8, Inmutables #16/#26/#37/#41, ADR-0057, CHARON_ROADMAP_V1 Co-Authored-By: Ergon (interim Pilar 4 author) <ergon@originmetaverse.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |