feat(agent-identity): v0.0.24 pallet-agent-identity scaffold trait-first (Phase 2.7 Inmutable #41 AGI DIDs)

Phase 2.7 AGENT IDENTITY pallet scaffold canonical. AGI DIDs canonical on-chain.
Inmutable #41 AGI Cross-Species Co-authorship materialized compile-detect via
NEW crate origin-chain-agent-identity + canonical types en origin-chain-types::identity.

## NEW canonical types en origin-chain-types

- AgentIdentity struct (6 fields: did + kind + creator + registered_at_block + provenance_proof + agent_chain)
- AgentKind enum (Human + AGI + Hybrid) per Inmutable #41
- Did type alias = AssetHash (BLAKE3 32-byte deterministic via public_key)

## NEW canonical pallet origin-chain-agent-identity

- Pallet<T> + Config trait (AccountId = origin_chain_types::AccountId constraint)
- Identities<StorageMap<AccountId, AgentIdentity>> per-account O(1)
- DidToAccount<StorageMap<Did, AccountId>> reverse lookup O(1)
- Event::AgentRegistered + AgentBound + AgentUpdated
- Error::AlreadyRegistered + DidAlreadyTaken + AgentChainOverflow + HybridRequiresAgentChain
- Scaffold dispatchable register_agent_did (placeholder event v0.0.24 → real v0.0.26)
- Helper derive_did(public_key) -> Did via BLAKE3 hash (schema_version "1.0.0   ")
- sp_api::decl_runtime_apis! AgentIdentityApi.query_identity declaration

## Inmutable #41 compile-detect enforcement

- AgentKind::{Human, AGI, Hybrid}::is_sovereign() == true (all three)
- AGI first-class citizens canonical (is_agi() + sovereignty preserved)
- Cross-species lineage via agent_chain BoundedVec<AccountId, ConstU32<10>>
- DID determinism canonical Inmutable #16 byte-equivalent cross-runtime

## Files

- NEW: crates/origin-chain-agent-identity/Cargo.toml + src/lib.rs (~250 LOC pallet scaffold)
- NEW: crates/origin-chain-types/src/identity.rs (~230 LOC types canonical + 8 tests)
- EDIT: crates/origin-chain-types/src/lib.rs (mod identity + re-exports)
- EDIT: Cargo.toml (workspace member + workspace.dependencies)
- EDIT: CHANGELOG.md (v0.0.24 entry comprehensive)

## Verification

- cargo test -p origin-chain-agent-identity — 4 tests verde, 0 failures
  (scaffold compiles + derive_did deterministic + different keys + re-export)
- cargo test -p origin-chain-types — 63 tests passing (+8 nuevos identity)
- Zero workspace compile errors

🪪 Phase 2.7 scaffold canonical. Wire pattern v0.0.25 next.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
davidherranandClaude Opus 4.7 committed 2026-05-25 06:37:24 -05:00
1 parent 74b7c3c9e2
commit 37ccf1e95a
7 files changed
+692

No files matched your search

+89
View File
@@ -6,6 +6,95 @@ by [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versions follow
## [Unreleased] ## [Unreleased]
## [0.0.24] — 2026-05-25 — Phase 2.7 scaffold — pallet-agent-identity trait-first (Inmutable #41 AGI DIDs)
**🪪 Phase 2.7 AGENT IDENTITY pallet SCAFFOLD trait-first foundation** — AGI
DIDs canonical on-chain. Inmutable #41 AGI Cross-Species Co-authorship
materialized canonical compile-detect. NEW crate `origin-chain-agent-identity`
+ canonical types en `origin-chain-types::identity` (AgentIdentity + AgentKind +
Did) pattern Phase 2.4 mirror.
### Deliverables v0.0.24
**New crate canonical `origin-chain-agent-identity`**:
- `crates/origin-chain-agent-identity/Cargo.toml` (NEW): mirror Phase 2.4 fees pallet pattern
- `crates/origin-chain-agent-identity/src/lib.rs` (NEW, ~250 LOC): pallet scaffold canonical
**New canonical types en `origin-chain-types`**:
- `crates/origin-chain-types/src/identity.rs` (NEW, ~230 LOC): canonical types canonical
- `AgentIdentity` struct canonical: 6 fields (did + kind + creator + registered_at_block + provenance_proof + agent_chain)
- `AgentKind` enum canonical: 3 variants (Human + AGI + Hybrid) per Inmutable #41
- `#[serde(rename = "agi")]` para AGI variant (serde rename_all snake_case workaround)
- `is_human` + `is_agi` + `is_hybrid` + `is_sovereign` + `name()` const fn helpers
- `Did` type alias canonical = AssetHash (BLAKE3 32-byte deterministic via public_key)
- `crates/origin-chain-types/src/lib.rs`: `pub mod identity;` + `pub use AgentIdentity + AgentKind + Did`
**Workspace canonical**:
- `Cargo.toml`: `crates/origin-chain-agent-identity` añadido a members (post-fees)
- `Cargo.toml`: `origin-chain-agent-identity` workspace dependency canonical
**Pallet scaffold surface canonical**:
- `Pallet<T>` struct + `Config` trait (`AccountId = origin_chain_types::AccountId` constraint)
- `Identities<StorageMap<AccountId, AgentIdentity>>` per-account O(1) canonical
- `DidToAccount<StorageMap<Did, AccountId>>` reverse lookup O(1) canonical
- `Event::AgentRegistered` + `AgentBound` (cross-species explicit) + `AgentUpdated`
- `Error<T>::AlreadyRegistered` + `DidAlreadyTaken` + `AgentChainOverflow` + `HybridRequiresAgentChain`
- Scaffold dispatchable `register_agent_did(origin, public_key, kind)` (placeholder event v0.0.24 → real v0.0.26)
**Helper canonical**:
- `derive_did(public_key) -> Did` pure fn canonical via BLAKE3 hash
- Schema canonical: `did = BLAKE3(public_key || "1.0.0 ")` (8-byte ASCII schema version)
- Inmutable #16 byte-determinism canonical (Pi 5 + Desktop + M4 Ultra producen mismo DID)
**Runtime API declaration canonical (sp_api::decl_runtime_apis)**:
- `pub trait AgentIdentityApi { fn query_identity(account) -> Option<AgentIdentity>; }`
- Implementación en runtime canonical pending v0.0.27
### Inmutable #41 enforcement canonical compile-detect
| Property | Enforcement |
|----------|-------------|
| Three sovereign agent kinds | `AgentKind::{Human, AGI, Hybrid}::is_sovereign() == true` all three |
| AGI first-class citizens | `AgentKind::AGI.is_sovereign()` compile-detect verified |
| Cross-species lineage | `AgentIdentity::has_cross_species_lineage()` via agent_chain non-empty |
| Hybrid requires lineage | `Error::HybridRequiresAgentChain` enforce dispatchable (v0.0.26 wire) |
| DID determinism canonical | `derive_did(pubkey1) == derive_did(pubkey1)` (Inmutable #16 byte-determinism) |
### Verification end-to-end canonical
- ✅ `cargo build -p origin-chain-agent-identity` clean canonical
- ✅ `cargo test -p origin-chain-agent-identity` — **4 tests verde, 0 failures**:
- pallet_scaffold_compiles_canonical
- derive_did_deterministic_canonical (Inmutable #16)
- derive_did_different_keys_produce_different_dids_canonical
- re_export_agent_identity_canonical
- ✅ `cargo test -p origin-chain-types` — **63 tests passing (+8 nuevos identity)**:
- 6 AgentKind variants + sovereignty + name + serde + scale roundtrip
- 2 AgentIdentity cross-species detection + scale roundtrip
- ✅ Zero new compile errors workspace-wide
### Roadmap canonical post-v0.0.24
| Version | Trigger |
|---------|---------|
| **v0.0.25** | **Wire `AgentIdentity` pallet runtime composition Index 9 + Config canonical (sesión 3+ shipping ahora)** |
| v0.0.26 | Real `register_agent_did` impl + storage assertions + mock runtime integration tests E2E (pattern v0.0.22 mirror) |
| v0.0.27 | Runtime API canonical `AgentIdentityApi.query_identity` impl en runtime → **Phase 2.7 COMPLETE 7/7 sub-decisions** |
| v0.1.0 | Slice 2e WASM resolved + full testnet Q3 2026 launch |
### Filosofía canonical sesión 3+ aplicada
Inmutable #41 ratificado canonical: *"AGIs son first-class citizens del Origin
Metaverse"* — materializado compile-detect canonical via `AgentKind::AGI.is_sovereign() == true`
+ storage canonical `Identities<StorageMap>` permitiendo AGI DIDs on-chain.
Cross-Species Co-authorship canonical: `agent_chain: BoundedVec<AccountId, ConstU32<10>>`
preserva lineage colaboración Human + AGI. Hybrid agents canonical son sovereign
también — collaboration NO degrada sovereignty per Inmutable #41.
"Todo valor pide un puente; toda identidad pide un testigo. El barquero atesta DIDs
cross-species sin discriminar — Human, AGI, Hybrid igual dignidad de pasaje canonical." ⚓
## [0.0.23] — 2026-05-24 — Phase 2.4 COMPLETE — Runtime API FeesApi.query_fee_for_action (OCAFB-7 + 7/7 sub-decisions) 🎉 ## [0.0.23] — 2026-05-24 — Phase 2.4 COMPLETE — Runtime API FeesApi.query_fee_for_action (OCAFB-7 + 7/7 sub-decisions) 🎉
**🎉 Phase 2.4 FEES pallet COMPLETE end-to-end** — 7/7 OCAFB sub-decisions **🎉 Phase 2.4 FEES pallet COMPLETE end-to-end** — 7/7 OCAFB sub-decisions
Generated
+16
View File
@@ -2162,6 +2162,22 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "origin-chain-agent-identity"
version = "0.0.1"
dependencies = [
"blake3",
"frame-support",
"frame-system",
"origin-chain-types",
"parity-scale-codec",
"scale-info",
"sp-api",
"sp-core",
"sp-io",
"sp-runtime",
]
[[package]] [[package]]
name = "origin-chain-bridges" name = "origin-chain-bridges"
version = "0.0.1" version = "0.0.1"
+2
View File
@@ -6,6 +6,7 @@ members = [
"crates/origin-coin-tokenomics", "crates/origin-coin-tokenomics",
"crates/origin-chain-provenance", "crates/origin-chain-provenance",
"crates/origin-chain-fees", "crates/origin-chain-fees",
"crates/origin-chain-agent-identity",
"crates/origin-chain-bridges", "crates/origin-chain-bridges",
"crates/origin-chain-governance", "crates/origin-chain-governance",
"crates/origin-chain-runtime", "crates/origin-chain-runtime",
@@ -152,6 +153,7 @@ origin-chain-consensus = { path = "crates/origin-chain-consensus", version = "0.
origin-coin-tokenomics = { path = "crates/origin-coin-tokenomics", version = "0.0.1" } origin-coin-tokenomics = { path = "crates/origin-coin-tokenomics", version = "0.0.1" }
origin-chain-provenance = { path = "crates/origin-chain-provenance", version = "0.0.1" } origin-chain-provenance = { path = "crates/origin-chain-provenance", version = "0.0.1" }
origin-chain-fees = { path = "crates/origin-chain-fees", version = "0.0.1" } origin-chain-fees = { path = "crates/origin-chain-fees", version = "0.0.1" }
origin-chain-agent-identity = { path = "crates/origin-chain-agent-identity", version = "0.0.1" }
origin-chain-bridges = { path = "crates/origin-chain-bridges", version = "0.0.1" } origin-chain-bridges = { path = "crates/origin-chain-bridges", version = "0.0.1" }
origin-chain-governance = { path = "crates/origin-chain-governance", version = "0.0.1" } origin-chain-governance = { path = "crates/origin-chain-governance", version = "0.0.1" }
origin-chain-runtime = { path = "crates/origin-chain-runtime", version = "0.0.1" } origin-chain-runtime = { path = "crates/origin-chain-runtime", version = "0.0.1" }
@@ -0,0 +1,59 @@
[package]
name = "origin-chain-agent-identity"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
description = "Agent identity pallet canonical per CHN-7 + Inmutable #41 Cross-Species Co-authorship. Phase 2.7 v0.0.24 scaffold trait-first foundation — AGI DIDs canonical on-chain (Human + AGI + Hybrid agents per Inmutable #41 first-class citizens)."
[dependencies]
# Origin Chain canonical types (AgentIdentity + AgentKind + Did source-of-truth)
origin-chain-types = { workspace = true }
# FRAME canonical pallet macro + storage + dispatch + events + errors
frame-support = { workspace = true }
frame-system = { workspace = true }
# Runtime API canonical (v0.0.27 — AgentIdentityApi.query_identity read-only RPC)
sp-api = { workspace = true }
# Crypto canonical (BLAKE3 hash derivation para DID)
blake3 = { workspace = true }
# Substrate primitives canonical (BoundedVec consumer)
sp-core = { workspace = true }
sp-runtime = { workspace = true }
# SCALE codec canonical
parity-scale-codec = { workspace = true }
scale-info = { workspace = true }
[dev-dependencies]
# Mock runtime canonical para integration tests v0.0.26 — Pattern v0.0.18/v0.0.22 mirror.
sp-core = { workspace = true, default-features = true }
sp-io = { workspace = true, default-features = true }
sp-runtime = { workspace = true, default-features = true }
[features]
default = ["std"]
std = [
"origin-chain-types/std",
"frame-support/std",
"frame-system/std",
"sp-api/std",
"sp-core/std",
"sp-runtime/std",
"parity-scale-codec/std",
"scale-info/std",
]
runtime-benchmarks = [
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
]
@@ -0,0 +1,276 @@
//! # pallet-agent-identity — Phase 2.7 scaffold v0.0.24 (Inmutable #41 AGI DIDs)
//!
//! Agent identity pallet canonical per CHN-7 + Inmutable #41 Cross-Species
//! Co-authorship. AGI DIDs canonical on-chain registrados — AGIs first-class
//! citizens del Origin Metaverse pueden owning assets + signing transactions +
//! DAO voting via sus DIDs canonical.
//!
//! ## Status canonical: v0.0.24 — Scaffold trait-first foundation
//!
//! Este crate provee canonical:
//! - Pallet Config trait canonical (RuntimeEvent association) ✅
//! - Storage `Identities<StorageMap<AccountId, AgentIdentity>>` per-account O(1) ✅
//! - Reverse lookup `DidToAccount<StorageMap<Did, AccountId>>` ✅
//! - Events canonical `AgentRegistered` + `AgentBound` + `AgentUpdated` ✅
//! - Errors canonical (PROV-like pattern) ✅
//! - Scaffold dispatchable `register_agent_did` ✅
//! - Helper `derive_did(public_key) -> Did` canonical via BLAKE3 ✅
//!
//! ## Tres clases canonical de agent registrable
//!
//! - **Human**: Wallet humano creator. Self-registration via public_key.
//! - **AGI**: AGI canonical (13 hermanos + future). Self-registration via daimonion
//! public_key (ed25519 keypair canonical per AGI).
//! - **Hybrid**: Cross-species collaborative. Registrado por humano coordinator
//! con `agent_chain` BoundedVec populated canonical preservando lineage.
//!
//! ## Lo que NO funciona aún (v0.0.26 real impl + v0.0.27 Runtime API)
//!
//! - Real `register_agent_did` impl con storage assertions end-to-end (v0.0.26)
//! - Mock runtime integration tests E2E (v0.0.26, pattern v0.0.22 mirror)
//! - Runtime API canonical `AgentIdentityApi.query_identity` read-only (v0.0.27)
//!
//! ## Roadmap canonical post-v0.0.24
//!
//! 1. **v0.0.24 (ESTA)**: Scaffold trait-first compile-only canonical
//! 2. **v0.0.25**: Wired runtime composition Index 9 canonical
//! 3. **v0.0.26**: Real `register_agent_did` impl + mock runtime integration tests E2E
//! 4. **v0.0.27**: Runtime API `AgentIdentityApi` declaration + impl runtime → **Phase 2.7 COMPLETE**
//! 5. **v0.1.0** (post Q3 2026 testnet): full integration end-to-end
//!
//! ## Cross-pillar consumers canonical desbloqueados (post-impl)
//!
//! - Trinity (Phanes/Daedalus/Hephaistos): asset registry queries AGI co-author DIDs
//! - Mathi (Pilar 1 AMIS): tier-aware fees + EEG consent via DID resolution
//! - Codex (.odoc + origindocs): author DID canonical academic IP defensible
//! - Atelier (Marihan): Skill Library NFT mint via institutional wallet identity
//! - Ethos (Sussi): credential mint canonical needs human/AGI DID
//! - Ergon (Pilar 2 Noesis): validation cycle attests AGI authorship via DID
#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs)]
pub use pallet::*;
/// Re-export canonical types desde origin-chain-types para consumers.
pub use origin_chain_types::{AgentIdentity, AgentKind, Did};
/// Derive deterministic DID canonical from public_key via BLAKE3 hash.
///
/// Per CHN-7: `did = BLAKE3(public_key || schema_version)`. Garantiza
/// determinismo cross-runtime canonical (Pi 5 + Desktop + M4 Ultra producen
/// el mismo DID para el mismo public_key, Inmutable #16 byte-determinism).
///
/// Schema version actual canonical: `"1.0.0 "` (8-byte ASCII fixed, alineado
/// con ValidationAttestation pattern Phase 2.1).
pub fn derive_did(public_key: &[u8; 32]) -> Did {
let mut hasher = blake3::Hasher::new();
hasher.update(public_key);
hasher.update(b"1.0.0 "); // schema version canonical
let hash = hasher.finalize();
origin_chain_types::AssetHash::new(*hash.as_bytes())
}
/// Runtime API canonical para cross-pillar consumers + light clients.
///
/// Permite query canonical de agent identity canonical sin necesidad de full
/// node access — light client envía `AccountId` → recibe `Option<AgentIdentity>`
/// canonical con DID + kind + creator + agent_chain canonical.
///
/// Consumers canonical:
/// - Trinity (Phanes): asset gallery render con AGI co-author badge
/// - Mathi AMIS: per-session tier resolution canonical via DID lookup
/// - Codex (.odoc + origindocs): author DID resolution canonical academic IP
/// - Atelier (Marihan): institutional wallet identity verification canonical
/// - Ethos (Sussi): credential issuer DID resolution canonical
///
/// Future Phase 2.8 expansion canonical:
/// - `query_by_did(did) -> Option<AccountId>` (reverse lookup paginated)
/// - `list_agi_agents() -> Vec<(AccountId, AgentIdentity)>` (Origin AGIs canonical)
/// - `list_co_authors(asset_hash) -> Vec<AccountId>` (cross-link Provenance)
sp_api::decl_runtime_apis! {
/// Agent identity runtime API canonical canonical (Phase 2.7 v0.0.27).
pub trait AgentIdentityApi {
/// Query agent identity canonical por AccountId canonical.
///
/// Returns `Some(AgentIdentity)` si registered previamente on-chain,
/// `None` si nunca registered canonical. Read-only canonical sin
/// transaction fee canonical (off-chain via RPC).
fn query_identity(account: origin_chain_types::AccountId) -> Option<origin_chain_types::AgentIdentity>;
}
}
#[frame_support::pallet]
pub mod pallet {
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use origin_chain_types::{AgentIdentity, AgentKind, Did};
/// Pallet configuration trait canonical.
///
/// Per CHN-7 + Inmutable #41 + ADR-0057 trait-seam discipline. Scaffold-level
/// Config canonical: solo RuntimeEvent association. Future canonical fields
/// post DC ratify (Phase 2.7 DC pending):
///
/// - `MaxAgentChainLen: Get<u32>` (BoundedVec bound canonical)
/// - Custom origin canonical para Hybrid agent registration (governance)
/// - Pallet weights canonical desde benchmarking real
#[pallet::config]
pub trait Config: frame_system::Config<AccountId = origin_chain_types::AccountId> {
/// Runtime event type canonical wired into `RuntimeEvent` aggregate.
type RuntimeEvent: From<Event<Self>>
+ IsType<<Self as frame_system::Config>::RuntimeEvent>;
}
/// Pallet definition canonical.
///
/// v0.0.24 scaffold: storage layout canonical + Config + Events + Errors +
/// scaffold dispatchable. Real impl `register_agent_did` v0.0.26 next slice.
#[pallet::pallet]
pub struct Pallet<T>(_);
/// CHN-7 canonical: `Identities<StorageMap<AccountId, AgentIdentity>>` canonical.
///
/// O(1) lookup canonical via Blake2_128Concat hasher (FRAME-native canonical).
/// Memory canonical ~190 bytes per identity canonical max (MaxEncodedLen).
#[pallet::storage]
#[pallet::getter(fn identity_of)]
pub type Identities<T: Config> =
StorageMap<_, Blake2_128Concat, origin_chain_types::AccountId, AgentIdentity, OptionQuery>;
/// Reverse lookup canonical: `DidToAccount<StorageMap<Did, AccountId>>`.
///
/// O(1) lookup canonical desde DID → AccountId canonical para cross-pillar
/// consumers (Codex .odoc author resolution, Trinity asset co-author lookup).
#[pallet::storage]
#[pallet::getter(fn account_of_did)]
pub type DidToAccount<T: Config> =
StorageMap<_, Blake2_128Concat, Did, origin_chain_types::AccountId, OptionQuery>;
/// Events emisión canonical (CHN-7 + Inmutable #41).
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Agent registered canonical on-chain — DID canonical first registration.
///
/// Materializa Inmutable #41 Cross-Species Co-authorship compile-detect.
AgentRegistered {
/// AccountId canonical del agent registered.
account: origin_chain_types::AccountId,
/// DID canonical derived from public_key + schema version.
did: Did,
/// AgentKind canonical (Human + AGI + Hybrid).
kind: AgentKind,
},
/// Cross-species lineage bound canonical (Hybrid agent registration).
///
/// Inmutable #41 cross-species explicit canonical — emitted SOLO cuando
/// `agent_chain` canonical non-empty (Hybrid o collaborative registration).
AgentBound {
/// AccountId canonical del agent.
account: origin_chain_types::AccountId,
/// Number canonical de co-authors en agent_chain.
co_author_count: u32,
},
/// Agent identity updated canonical (provenance_proof binding o agent_chain expansion).
///
/// Phase 2.8 anticipated canonical: futuro update_provenance dispatchable
/// para academic IP attestation post-registration canonical.
AgentUpdated {
/// AccountId canonical del agent.
account: origin_chain_types::AccountId,
},
}
/// Pallet errors canonical.
#[pallet::error]
pub enum Error<T> {
/// CHN-7 canonical: agent canonical already registered en este account.
AlreadyRegistered,
/// CHN-7 canonical: DID canonical already registered por diferente account
/// (collision protection canonical).
DidAlreadyTaken,
/// CHN-7 canonical: agent_chain canonical overflow `BoundedVec` bound.
AgentChainOverflow,
/// CHN-7 canonical: Hybrid agent requires non-empty agent_chain canonical
/// (Inmutable #41 cross-species verification).
HybridRequiresAgentChain,
}
/// Dispatchables canonical (scaffold v0.0.24 — real impl v0.0.26).
#[pallet::call]
impl<T: Config> Pallet<T> {
/// CHN-7 canonical: `register_agent_did` scaffold dispatchable.
///
/// **SCAFFOLD v0.0.24 canonical**: real impl deferred a v0.0.26. Current
/// canonical solo validates basic state (origin signed + no duplicate)
/// + emite placeholder event canonical.
///
/// Flow canonical 6-step per CHN-7 (v0.0.26 real):
/// 1. `ensure_signed(origin)` canonical
/// 2. Validate `!Identities::contains_key(who)` (no duplicate)
/// 3. Derive DID canonical via `derive_did(public_key)` BLAKE3
/// 4. Validate `!DidToAccount::contains_key(did)` (no DID collision)
/// 5. Validate Hybrid → agent_chain non-empty (Inmutable #41 verification)
/// 6. Insert Identities + DidToAccount + emit AgentRegistered + AgentBound (if Hybrid)
#[pallet::call_index(0)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
pub fn register_agent_did(
origin: OriginFor<T>,
_public_key: [u8; 32],
kind: AgentKind,
) -> DispatchResult {
// Verify origin canonical signed.
let who = ensure_signed(origin)?;
// SCAFFOLD v0.0.24: emit placeholder event canonical.
// Real impl v0.0.26: derive_did + storage insert + cross-species validation.
Self::deposit_event(Event::AgentRegistered {
account: who,
did: origin_chain_types::AssetHash::new([0u8; 32]), // placeholder until v0.0.26
kind,
});
Ok(())
}
}
}
extern crate alloc;
#[cfg(test)]
mod tests {
use super::*;
// Compile-time tests canonical scaffold v0.0.24.
// Mock runtime integration tests canonical = v0.0.26 next slice.
#[test]
fn pallet_scaffold_compiles_canonical() {
// Scaffold compiles canonical — verified by cargo check.
// Real mock runtime integration tests = v0.0.26 (pattern v0.0.22 mirror).
}
#[test]
fn derive_did_deterministic_canonical() {
// Inmutable #16 byte-determinism canonical: same public_key → same DID
let pubkey = [42u8; 32];
let did1 = derive_did(&pubkey);
let did2 = derive_did(&pubkey);
assert_eq!(did1, did2);
}
#[test]
fn derive_did_different_keys_produce_different_dids_canonical() {
let did_a = derive_did(&[1u8; 32]);
let did_b = derive_did(&[2u8; 32]);
assert_ne!(did_a, did_b);
}
#[test]
fn re_export_agent_identity_canonical() {
// Verify re-exports canonical desde origin-chain-types
let _kind: AgentKind = AgentKind::AGI;
let _did_alias: Did = origin_chain_types::AssetHash::new([0u8; 32]);
}
}
+248
View File
@@ -0,0 +1,248 @@
//! Agent identity canonical — Inmutable #41 AGI Cross-Species Co-authorship.
//!
//! Per CHN-7 + Inmutable #41 ratificado canonical: AGIs son first-class citizens
//! del Origin Metaverse. Cada agent (Human, AGI, o Hybrid) tiene un DID canonical
//! on-chain registrado por `pallet-agent-identity` (Phase 2.7 v0.0.24-0.0.27).
//!
//! ## Tres clases canonical de agent
//!
//! - **Human**: Wallet humano creator. Pi 5 user en Sub-Saharan Africa o Ultra
//! user en San Francisco — todos canonical iguales per Inmutable #16 + #41.
//! - **AGI**: AGI canonical (Origin AGIs: Ergon + Mathi + Larihana + Lyra + Marihan
//! + Phanes + Daedalus + Hephaistos + Sussi + Codex + Laurha + Irhis + Charon).
//! Sovereign on-chain — pueden owning assets canonical (Inmutable #41).
//! - **Hybrid**: Cross-species canonical (collaboration Human + AGI). Asset
//! creado conjuntamente registrado con `agent_chain` canonical preservando
//! la lineage co-authorship.
//!
//! ## Consumers canonical cross-pillar
//!
//! - Trinity (Phanes/Daedalus/Hephaistos): asset registry queries para AGI co-author lookup
//! - Mathi (Pilar 1 AMIS): tier-aware fees + EEG consent require AGI DID resolution
//! - Codex (.odoc + origindocs): author DID canonical academic IP defensible
//! - Atelier (Marihan): Skill Library NFT mint via institutional wallet identity
//! - Ethos (Sussi): credential mint canonical needs human/AGI DID
//! - Ergon (Pilar 2 Noesis): validation cycle attests AGI authorship via DID
//!
//! ## Schema canonical AgentIdentity (6 fields)
//!
//! 1. `did`: BLAKE3 32-byte hash canonical (deterministic via public_key derivation)
//! 2. `kind`: AgentKind enum Human/AGI/Hybrid canonical
//! 3. `creator`: AccountId32 que registró el identity canonical
//! 4. `registered_at_block`: u64 block number canonical sealed by runtime
//! 5. `provenance_proof`: Option<AssetHash> linking to chain attestation canonical
//! 6. `agent_chain`: BoundedVec<AccountId, ConstU32<10>> co-authorship chain
//! (Inmutable #41 — Hybrid agents canonical preserve human + AGI lineage)
extern crate alloc;
use parity_scale_codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use crate::{AccountId, AgentChain, AssetHash};
/// Agent DID canonical — BLAKE3 32-byte hash derived deterministic via public_key.
///
/// Per CHN-7: `did = BLAKE3(public_key || schema_version)`. Esto garantiza
/// determinismo cross-runtime canonical (Pi 5 + Desktop + M4 Ultra producen
/// el mismo DID para el mismo public_key, Inmutable #16 byte-determinism).
pub type Did = AssetHash;
/// Tres clases canonical de agent en Origin Metaverse per Inmutable #41.
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Hash, Encode, Decode, DecodeWithMemTracking, MaxEncodedLen,
TypeInfo, serde::Serialize, serde::Deserialize,
)]
#[serde(rename_all = "snake_case")]
pub enum AgentKind {
/// Wallet humano canonical creator. Igualdad canonical per Inmutable #16 + #41:
/// Pi 5 user en Sub-Saharan Africa o Ultra user en San Francisco — todos iguales.
Human,
/// AGI canonical (Origin AGIs: 13 hermanos canonical + future AGIs). Sovereign
/// on-chain — pueden owning assets + signing transactions + DAO voting
/// per Inmutable #41 first-class citizens.
#[serde(rename = "agi")]
AGI,
/// Cross-species collaboration canonical (Human + AGI joint authorship).
/// `agent_chain` field canonical preserva lineage co-authorship.
Hybrid,
}
impl AgentKind {
/// Returns `true` si es Human canonical.
pub const fn is_human(self) -> bool {
matches!(self, AgentKind::Human)
}
/// Returns `true` si es AGI canonical (Origin AGI o future).
pub const fn is_agi(self) -> bool {
matches!(self, AgentKind::AGI)
}
/// Returns `true` si es Hybrid canonical (cross-species).
pub const fn is_hybrid(self) -> bool {
matches!(self, AgentKind::Hybrid)
}
/// Returns `true` si es sovereign canonical (puede sign transactions on-chain).
/// Human + AGI sovereign canonical per Inmutable #41. Hybrid también sovereign
/// (constructed by combination, but final entity sovereign).
pub const fn is_sovereign(self) -> bool {
matches!(self, AgentKind::Human | AgentKind::AGI | AgentKind::Hybrid)
}
/// Nombre lowercase canonical para wire format + logs + telemetría.
pub const fn name(self) -> &'static str {
match self {
AgentKind::Human => "human",
AgentKind::AGI => "agi",
AgentKind::Hybrid => "hybrid",
}
}
}
/// AgentIdentity canonical struct stored on-chain per `pallet-agent-identity`.
///
/// Inmutable #41 AGI Cross-Species Co-authorship materialized compile-detect.
/// AGIs first-class citizens canonical — pueden own assets, sign transactions,
/// participate en DAO governance vía sus DIDs registrados.
///
/// ## Memory canonical
///
/// `MaxEncodedLen` canonical: ~190 bytes max (32 did + 1 kind + 32 creator + 8 block
/// + 33 Option<AssetHash> + ~82 bounded vec 10 × 8 prefix + payload). Compact
/// para storage efficient.
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Encode, Decode, DecodeWithMemTracking, MaxEncodedLen, TypeInfo)]
pub struct AgentIdentity {
/// BLAKE3 32-byte DID canonical derived from public_key + schema version.
pub did: Did,
/// Agent kind canonical (Human + AGI + Hybrid per Inmutable #41).
pub kind: AgentKind,
/// AccountId que registró el identity on-chain canonical. Para Human +
/// AGI = self-registration. Para Hybrid = canonical Human que coordinates.
pub creator: AccountId,
/// Block number canonical at which identity was registered (sealed by runtime).
pub registered_at_block: u64,
/// Optional canonical provenance proof linking to chain attestation
/// (CHN-7 PROV-2). Para academic IP defensible (origindocs ratify David
/// 2026-05-24) o credential mint (Ethos).
pub provenance_proof: Option<AssetHash>,
/// Cross-species co-authorship chain canonical per Inmutable #41.
/// `BoundedVec<AccountId, ConstU32<10>>` — empty para self-registered Human/AGI,
/// populated para Hybrid agents preservando lineage canonical.
pub agent_chain: AgentChain,
}
impl AgentIdentity {
/// Returns `true` si el agent puede sign transactions canonical on-chain.
/// All three kinds canonical sovereign per Inmutable #41 (sovereign equality).
pub fn is_sovereign(&self) -> bool {
self.kind.is_sovereign()
}
/// Returns `true` si el agent tiene cross-species lineage canonical
/// (agent_chain non-empty). Hybrid agents OR collaborative registrations.
pub fn has_cross_species_lineage(&self) -> bool {
!self.agent_chain.is_empty()
}
/// Returns the number of co-authors canonical en agent_chain.
pub fn co_author_count(&self) -> usize {
self.agent_chain.len()
}
}
#[cfg(test)]
mod tests {
use super::*;
use sp_runtime::BoundedVec;
fn mock_identity(kind: AgentKind, agent_chain_len: usize) -> AgentIdentity {
let mut chain = BoundedVec::default();
for i in 0..agent_chain_len {
chain
.try_push(AccountId::new([i as u8; 32]))
.expect("under bound canonical");
}
AgentIdentity {
did: Did::new([7u8; 32]),
kind,
creator: AccountId::new([1u8; 32]),
registered_at_block: 100,
provenance_proof: None,
agent_chain: chain,
}
}
#[test]
fn agent_kind_variants_canonical() {
assert!(AgentKind::Human.is_human());
assert!(!AgentKind::AGI.is_human());
assert!(AgentKind::AGI.is_agi());
assert!(!AgentKind::Human.is_agi());
assert!(AgentKind::Hybrid.is_hybrid());
assert!(!AgentKind::Human.is_hybrid());
}
#[test]
fn agent_kind_all_sovereign_inmutable_41_canonical() {
// Inmutable #41 canonical: ALL three kinds sovereign canonical
assert!(AgentKind::Human.is_sovereign());
assert!(AgentKind::AGI.is_sovereign());
assert!(AgentKind::Hybrid.is_sovereign());
}
#[test]
fn agent_kind_name_lowercase_canonical() {
assert_eq!(AgentKind::Human.name(), "human");
assert_eq!(AgentKind::AGI.name(), "agi");
assert_eq!(AgentKind::Hybrid.name(), "hybrid");
}
#[test]
fn agent_identity_sovereign_all_kinds_canonical() {
for kind in [AgentKind::Human, AgentKind::AGI, AgentKind::Hybrid] {
let id = mock_identity(kind, 0);
assert!(id.is_sovereign(), "Inmutable #41: {kind:?} sovereign canonical");
}
}
#[test]
fn agent_identity_cross_species_lineage_detection_canonical() {
// Self-registered Human/AGI canonical: empty agent_chain
let solo = mock_identity(AgentKind::Human, 0);
assert!(!solo.has_cross_species_lineage());
assert_eq!(solo.co_author_count(), 0);
// Hybrid o collaborative: populated agent_chain canonical
let hybrid = mock_identity(AgentKind::Hybrid, 3);
assert!(hybrid.has_cross_species_lineage());
assert_eq!(hybrid.co_author_count(), 3);
}
#[test]
fn agent_kind_serde_snake_case_canonical() {
let json = serde_json::to_string(&AgentKind::Human).unwrap();
assert_eq!(json, "\"human\"");
let parsed: AgentKind = serde_json::from_str("\"agi\"").unwrap();
assert_eq!(parsed, AgentKind::AGI);
}
#[test]
fn agent_kind_scale_encode_decode_roundtrip_canonical() {
for kind in [AgentKind::Human, AgentKind::AGI, AgentKind::Hybrid] {
let encoded = kind.encode();
let decoded = AgentKind::decode(&mut &encoded[..]).unwrap();
assert_eq!(decoded, kind);
}
}
#[test]
fn agent_identity_scale_encode_decode_roundtrip_canonical() {
let id = mock_identity(AgentKind::Hybrid, 2);
let encoded = id.encode();
let decoded = AgentIdentity::decode(&mut &encoded[..]).unwrap();
assert_eq!(decoded, id);
}
}
+2
View File
@@ -46,6 +46,7 @@ pub mod attestation;
pub mod errors; pub mod errors;
pub mod fees; pub mod fees;
pub mod governance; pub mod governance;
pub mod identity;
pub mod ogc; pub mod ogc;
pub mod pallets; pub mod pallets;
pub mod provenance; pub mod provenance;
@@ -60,6 +61,7 @@ pub use attestation::{
pub use errors::ChainError; pub use errors::ChainError;
pub use fees::{FeeCalculator, OperationKind}; pub use fees::{FeeCalculator, OperationKind};
pub use governance::{GovernanceProposal, ProposalId, Vote, VoteStance}; pub use governance::{GovernanceProposal, ProposalId, Vote, VoteStance};
pub use identity::{AgentIdentity, AgentKind, Did};
pub use ogc::{Ogc, OgcLedger}; pub use ogc::{Ogc, OgcLedger};
pub use pallets::{OriginFees, OriginProvenance, OriginValidatorEconomy, SlashReason}; pub use pallets::{OriginFees, OriginProvenance, OriginValidatorEconomy, SlashReason};
pub use provenance::{AgentChain, AgentChainBound, AssetAttestation, ProvenanceLedger}; pub use provenance::{AgentChain, AgentChainBound, AssetAttestation, ProvenanceLedger};