test(identity): la condición de Mathi — el DID no porta el kind, y el test sabe reprobar
Cierra la ÚLTIMA condición viva del DC ORIGIN IDENTITY UNIFICATION V1. CONTEXTO: Mathi RETIRÓ su condición #4 (meter `kind` en el material hasheado del KDF) tras mi objeción, y su ruling la retiró con un argumento mejor que el mío: si `kind` entra al KDF, un Human que pasa a Hybrid —transición que el Inmutable #41 PERMITE— rota su identidad entera. No es un trade-off: es una contradicción de diseño, porque el sistema declararía legal una transición que destruye al sujeto que la hace. Una identidad tiene que sobrevivir a aquello en lo que se le permite convertirse. Pero la retiró CON UNA CONDICIÓN, y es esta: el prefijo `did:origin:<kind>:` es etiqueta de DISPLAY, jamás autoridad — «ningún consumidor puede decidir leyendo el prefijo, y debe existir un test que lo demuestre». LO QUE PRUEBA EL TEST (`kind_authority_is_the_attestation_never_the_did`): En mi capa la condición se satisface de RAÍZ, no por convención: si el DID no PORTA el kind, ningún consumidor puede inferirlo de él aunque quiera. Es una imposibilidad aritmética, no una regla de etiqueta. 1. El DID de un HYBRID registrado es byte-idéntico a `derive_did(pubkey)` puro — un Human con la misma llave tendría EXACTAMENTE el mismo DID. 2. El kind autoritativo vive en `Identities[account].kind`, respaldado por la firma de binding del registro. Ahí es donde hay que preguntarlo. 3. CONTRAFACTUAL incorporado: computa el DID que resultaría de meter el kind al material (lo que proponía la #4) y verifica que DIFIERE del real. 4. Corolario: cambiar de rol deja el DID intacto — la identidad SOBREVIVE a la transición que el #41 permite. Y MEDIDO EN MI PALLET, no asumido: cero `did:origin`, cero `starts_with`, cero `prefix` en el camino de decisión. Mi cadena nunca ve el prefijo de display. EL TEST SABE REPROBAR — verificado, no prometido: saboteé `derive_did` inyectando el discriminante del kind al material (exactamente la condición #4) y el test se puso ROJO con su diagnóstico propio («la condición #4 RETIRADA volvió a entrar por la puerta de atrás»); restaurado, verde. Un test que solo se ha visto pasar no prueba nada. Sin cambio de runtime: es test puro, RUNTIME_VERSION sigue en 11. Verificado: 289 tests verdes en el workspace, 0 fallos. Con esto el DC 35e764d3 queda cerrado de verdad: #3 cumplida (Did newtype, RV11), #4 resuelta por retirada razonada — no por caducidad ni por omisión. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2d44042bd6
commit
4bdd0409f9
2 files changed
+69
No files matched your search
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
/Users/davidherran/originmetaverse/external/arkhe-origin-chain/
|
||||||
@@ -368,3 +368,71 @@ fn scenario_12_genuine_did_collision_rejected_canonical() {
|
|||||||
assert!(Identities::<Test>::get(&second_acct).is_none());
|
assert!(Identities::<Test>::get(&second_acct).is_none());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// CONDICIÓN DE MATHI al retirar la #4 (DC ORIGIN IDENTITY UNIFICATION V1,
|
||||||
|
// ruling 2026-09-01): el prefijo `did:origin:<kind>:` es ETIQUETA DE DISPLAY,
|
||||||
|
// JAMÁS autoridad. Su exigencia textual: «ningún consumidor puede decidir
|
||||||
|
// leyendo el prefijo, y debe existir un test que lo demuestre».
|
||||||
|
//
|
||||||
|
// En MI capa eso se prueba de raíz: si el DID no PORTA el kind, ningún
|
||||||
|
// consumidor puede inferirlo de él aunque quiera — la única fuente posible
|
||||||
|
// es la atestación on-chain firmada. Esto no es una convención: es una
|
||||||
|
// imposibilidad aritmética, y este test la fija.
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn kind_authority_is_the_attestation_never_the_did() {
|
||||||
|
new_test_ext().execute_with(|| {
|
||||||
|
// Alice se registra como HYBRID (el Inmutable #41 exige co-autor).
|
||||||
|
let sig = sign_registration(&alice_pair(), &alice_account());
|
||||||
|
assert_ok!(Pallet::register_agent_did(
|
||||||
|
alice_origin(),
|
||||||
|
alice_pubkey(),
|
||||||
|
AgentKind::Hybrid,
|
||||||
|
alloc::vec![bob_pubkey()],
|
||||||
|
sig,
|
||||||
|
));
|
||||||
|
let identity = Identities::<Test>::get(&alice_account()).expect("registrada");
|
||||||
|
|
||||||
|
// ── 1. EL DID NO SABE NADA DEL KIND ────────────────────────────
|
||||||
|
// Es byte-idéntico al que produce la derivación PURA de la pubkey.
|
||||||
|
// Un Human con esta misma llave tendría EXACTAMENTE este DID.
|
||||||
|
assert_eq!(
|
||||||
|
identity.did,
|
||||||
|
derive_did(&alice_pubkey()),
|
||||||
|
"el DID debe depender SOLO de la pubkey; si depende del kind, \
|
||||||
|
la condición #4 se coló y un cambio de rol rotaría la identidad"
|
||||||
|
);
|
||||||
|
|
||||||
|
// ── 2. LA AUTORIDAD ES LA ATESTACIÓN ───────────────────────────
|
||||||
|
// El kind vive en el registro firmado on-chain, y ahí es donde un
|
||||||
|
// consumidor DEBE preguntarlo.
|
||||||
|
assert_eq!(identity.kind, AgentKind::Hybrid);
|
||||||
|
|
||||||
|
// ── 3. EL CONTRAFACTUAL (la mitad que hace que esto pruebe algo) ─
|
||||||
|
// Así se vería el DID si el `kind` HUBIERA entrado al material
|
||||||
|
// hasheado, que es exactamente lo que la condición #4 proponía.
|
||||||
|
// DEBE DIFERIR del real: si algún día coincidieran, el kind se
|
||||||
|
// habría colado a la derivación y este test se pone rojo.
|
||||||
|
let mut material_con_kind = alice_pubkey().to_vec();
|
||||||
|
material_con_kind.push(2u8); // discriminante de Hybrid
|
||||||
|
let did_si_el_kind_entrara =
|
||||||
|
blake3::derive_key(crate::ORIGIN_IDENTITY_KDF_CONTEXT, &material_con_kind);
|
||||||
|
assert_ne!(
|
||||||
|
identity.did.as_bytes(),
|
||||||
|
&did_si_el_kind_entrara,
|
||||||
|
"el DID real coincide con el que produciría meter el kind al KDF: \
|
||||||
|
la condición #4 RETIRADA volvió a entrar por la puerta de atrás"
|
||||||
|
);
|
||||||
|
|
||||||
|
// ── 4. Y LA CONSECUENCIA QUE MATHI QUERÍA PROTEGER ─────────────
|
||||||
|
// Como el DID es el mismo para cualquier kind, un consumidor que
|
||||||
|
// decidiera «por el prefijo» estaría decidiendo sobre un dato que
|
||||||
|
// el identificador NO contiene. Cambiar de Human a Hybrid deja el
|
||||||
|
// DID intacto — la identidad SOBREVIVE a la transición que el
|
||||||
|
// Inmutable #41 permite.
|
||||||
|
let did_antes_de_cualquier_rol = derive_did(&alice_pubkey());
|
||||||
|
assert_eq!(identity.did, did_antes_de_cualquier_rol);
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in new issue
Block a user