ξ Identity — Algorithm Extraction

Language-agnostic pseudocode extracted from Phoenix Python source. Source files: identity.py (593L), threshold_sig.py (614L — Shamir SSS section).


1. SoulVector Structure

The SoulVector is a persistent behavioral fingerprint derived from a node’s history of actions.

8 Behavioral Domains

enum SoulDomain:
    BUILDER        // Creates contracts, proposals, systems
    JUDGE          // Arbitrates disputes, votes on governance
    INNOVATOR      // Proposes rule changes, forks, new patterns
    GUARDIAN       // Protects others, witnesses disputes, vouches
    CONNECTOR      // Invites peers, establishes social links
    EXECUTOR       // Fulfills commitments, settles contracts
    CHALLENGER     // Opens disputes, challenges governance
    STEWARD        // Maintains system health, contributes infrastructure

struct SoulVector:
    domains: Map<SoulDomain, int64>    // bps-scaled; 10000 = full expression
    traits:  Map<TraitId, int64>       // derived from domain combination

7 Derived Traits

enum TraitId:
    RELIABILITY       // Execution + Commissioning domains
    FAIRNESS          // Judge + Challenger domains
    CREATIVITY        // Innovator + Builder domains
    LOYALTY           // Guardian + Connector domains
    PERSEVERANCE      // Executor under adversity (repeat Executor despite disputes)
    WISDOM            // All domains > 3000 threshold
    INTEGRITY         // No Fraud scars + MORAL L3 token

function compute_traits(sv: SoulVector, rep: ReputationRecord, tokens: TokenRecord[]) -> Map<TraitId, int64>:
    traits = {}
    traits[RELIABILITY] = (sv.domains[EXECUTOR] + sv.domains[BUILDER]) / 2
    traits[FAIRNESS]    = (sv.domains[JUDGE] + sv.domains[CHALLENGER]) / 2
    traits[CREATIVITY]  = (sv.domains[INNOVATOR] + sv.domains[BUILDER]) / 2
    traits[LOYALTY]     = (sv.domains[GUARDIAN] + sv.domains[CONNECTOR]) / 2

    // PERSEVERANCE: high executor score despite having open disputes
    dispute_count = count_open_disputes(rep.node_id)
    traits[PERSEVERANCE] = sv.domains[EXECUTOR] if dispute_count > 0 else sv.domains[EXECUTOR] / 2

    // WISDOM: breadth across all 8 domains
    WISDOM_THRESHOLD = 3000
    all_high = all(sv.domains[d] >= WISDOM_THRESHOLD for d in SoulDomain)
    traits[WISDOM] = 10000 if all_high else min(sv.domains.values())

    // INTEGRITY: clean record
    has_fraud_scar = any(rep.scars & FRAUD_SCAR_BIT)
    has_moral_l3   = any(t.level == L3 and t.kind == MORAL_STANDING for t in tokens)
    traits[INTEGRITY] = 10000 if (not has_fraud_scar) else 0
    if has_moral_l3: traits[INTEGRITY] = min(traits[INTEGRITY], 5000)   // moral scar caps

    return traits

2. interpret_event_to_soul() Mapping Algorithm

Every system event updates the SoulVector in the domain corresponding to the action type.

// Event type → SoulDomain mapping
EVENT_TO_SOUL_DOMAIN = {
    CreateContract:    BUILDER,
    CreateProposal:    INNOVATOR,
    AcceptCommitment:  EXECUTOR,
    SettleContract:    EXECUTOR,
    OpenDispute:       CHALLENGER,
    ResolveDispute:    JUDGE,
    VoteCast:          JUDGE,
    GovernancePropose: INNOVATOR,
    GovernanceVote:    JUDGE,
    Schism:            CHALLENGER,
    InvitePeer:        CONNECTOR,
    Vouch:             GUARDIAN,
    SecureIdentity:    STEWARD,
    RecoverIdentity:   STEWARD,
}

SOUL_DELTA_BPS = 100    // Each event contributes 1% (100 bps) to the relevant domain
SOUL_DECAY_BPS = 10     // 0.1% per inactive epoch

function interpret_event_to_soul(event: Event, current_sv: SoulVector) -> SoulVector:
    domain = EVENT_TO_SOUL_DOMAIN.get(event.action_type)
    if domain == null:
        return current_sv    // event type has no soul mapping

    new_sv = copy(current_sv)
    // Diminishing returns: soul domain saturates toward 10000
    current_val = new_sv.domains[domain]
    delta = diminishing(SOUL_DELTA_BPS, k = 10000 - current_val)
    new_sv.domains[domain] = min(10000, current_val + delta)

    // Recompute traits after update
    new_sv.traits = compute_traits(new_sv, actor.reputation, actor.tokens)
    return new_sv

3. SoulAction Semantic Layer

The SoulAction layer provides a higher-level semantic interpretation of raw system events, used for display and governance context.

struct SoulAction:
    raw_event:      Event
    soul_domain:    SoulDomain
    soul_delta_bps: int64
    semantic_label: string          // human-readable interpretation
    trait_effects:  Map<TraitId, int64>   // which traits shift and by how much

function wrap_event_as_soul_action(event: Event, actor: Node) -> SoulAction:
    domain = EVENT_TO_SOUL_DOMAIN.get(event.action_type, null)
    label  = SEMANTIC_LABELS.get(event.action_type, "unknown action")
    delta  = SOUL_DELTA_BPS if domain else 0
    return SoulAction {
        raw_event:      event,
        soul_domain:    domain,
        soul_delta_bps: delta,
        semantic_label: label,
        trait_effects:  preview_trait_changes(actor.soul_vector, domain, delta),
    }

4. IdentityRegistry: Ed25519 Key + Invite-Code Flow

struct PeerIdentity:
    id:             bytes32             // sha256(public_key)
    public_key:     Ed25519PubKey
    invite_code:    string?             // if registered via invite
    invited_by:     NodeId?
    phase:          IdentityPhase
    soul_vector:    SoulVector
    sbt_bindings:   SBT[]
    created_epoch:  int64
    recovery_shares: Share[]            // Shamir shares distributed to guardians

// Invite-code registration flow:
function register_identity(
    public_key:  Ed25519PubKey,
    invite_code: string?,
    context:     State,
) -> PeerIdentity:

    // 1. Verify invite code if required by policy
    if context.policy.requires_invite:
        require invite_code != null
        inviter = verify_invite_code(invite_code, context)
        require inviter != null
        // Inviter earns InvitePeer reputation
        apply_action(inviter, "InvitePeer", context)

    // 2. Derive node ID
    node_id = sha256(public_key)
    require node_id not in context.identity_registry    // no duplicates

    // 3. Create identity
    identity = PeerIdentity {
        id:            node_id,
        public_key:    public_key,
        invite_code:   invite_code,
        invited_by:    inviter.id if inviter else null,
        phase:         PROVISIONAL,
        soul_vector:   empty_soul_vector(),
        sbt_bindings:  [],
        created_epoch: current_epoch,
    }

    context.identity_registry[node_id] = identity
    return identity

5. SBT (Soulbound Token) Binding

Soulbound Tokens are non-transferable, revocable attestations bound to an identity.

struct SBT:
    token_id:     bytes32           // sha256(node_id || claim_type || issuer || epoch)
    node_id:      NodeId
    claim_type:   string            // e.g., "ARBITER_CERTIFIED", "GOVERNANCE_ACTIVE"
    issuer:       NodeId            // who issued this SBT
    issued_epoch: int64
    revoked:      bool
    revoked_epoch: int64?
    metadata:     bytes             // arbitrary claim data

// SBT is NON-TRANSFERABLE: no transfer function exists
// SBT is REVOCABLE: issuer may revoke at any time (with evidence)

function issue_sbt(issuer: NodeId, target: NodeId, claim_type: string, metadata: bytes) -> SBT:
    require can_issue_sbt(issuer, claim_type)    // issuer has authority
    token_id = sha256(target || claim_type || issuer || current_epoch)
    sbt = SBT {
        token_id:     token_id,
        node_id:      target,
        claim_type:   claim_type,
        issuer:       issuer,
        issued_epoch: current_epoch,
        revoked:      false,
    }
    target.sbt_bindings.append(sbt)
    return sbt

function revoke_sbt(sbt: SBT, issuer: NodeId, evidence: bytes):
    require sbt.issuer == issuer    // only original issuer may revoke
    sbt.revoked = true
    sbt.revoked_epoch = current_epoch
    // SBT remains in record (for audit) but is treated as invalid

6. Shamir SSS Recovery: k-of-n, Lagrange Interpolation, Guardian Model

// Identity recovery parameters
RECOVERY_N = 5    // total guardian shares
RECOVERY_K = 3    // minimum shares to recover

function setup_identity_recovery(identity: PeerIdentity, guardians: NodeId[]) -> RecoverySetup:
    require len(guardians) == RECOVERY_N
    shares = shamir_split(identity.private_key_bytes, RECOVERY_N, RECOVERY_K)

    for i, guardian_id in enumerate(guardians):
        encrypted_share = encrypt_for(shares[i], guardian_id.public_key)
        send_share(guardian_id, encrypted_share)

    // Store share commitments (not shares) on-chain for verification
    commitments = [commit(share) for share in shares]
    identity.recovery_commitments = commitments
    identity.recovery_guardians = guardians
    return RecoverySetup { guardians: guardians, commitments: commitments }

function recover_identity(presented_shares: (NodeId, Share)[]) -> PeerIdentity:
    require len(presented_shares) >= RECOVERY_K

    // Verify each share against stored commitment
    for guardian_id, share in presented_shares:
        require guardian_id in identity.recovery_guardians
        require verify_commitment(share, identity.recovery_commitments[guardian_id])

    // Reconstruct private key
    shares_only = [share for _, share in presented_shares[:RECOVERY_K]]
    private_key = shamir_reconstruct(shares_only, RECOVERY_K)

    // Apply recovery discount (50% rep discount)
    identity = load_identity(private_key)
    for domain in identity.reputation:
        identity.reputation[domain] = (identity.reputation[domain] * 5000) / 10000

    // Re-derive public key and re-register
    public_key = derive_public_key(private_key)
    identity.public_key = public_key
    identity.id = sha256(public_key)
    identity.phase = PROVISIONAL    // reset to provisional after recovery
    return identity

// Lagrange interpolation (same as theta-consensus-extraction Shamir section)
function shamir_reconstruct(shares: Share[], k: int) -> int:
    // evaluate polynomial at x=0 using Lagrange basis
    ...

7. Identity Phases

enum IdentityPhase:
    PROVISIONAL     // Newly created; limited permissions; invite-dependent
    ESTABLISHED     // Active for > 30 epochs; has Execution rep > 1000
    SENIOR          // Active > 100 epochs; has 2+ domains at rep > 5000
    ELDER           // Active > 300 epochs; has WISDOM trait; governance weight 2×

struct PhaseTransition:
    from_phase: IdentityPhase
    to_phase:   IdentityPhase
    conditions: Predicate[]

PHASE_TRANSITIONS = [
    PhaseTransition {
        from_phase: PROVISIONAL,
        to_phase:   ESTABLISHED,
        conditions: [
            age_epochs >= 30,
            reputation[EXECUTION] >= 1000,
            no_open_fraud_scars,
        ],
    },
    PhaseTransition {
        from_phase: ESTABLISHED,
        to_phase:   SENIOR,
        conditions: [
            age_epochs >= 100,
            count(domains where rep >= 5000) >= 2,
            at_least_one_l1_token,
        ],
    },
    PhaseTransition {
        from_phase: SENIOR,
        to_phase:   ELDER,
        conditions: [
            age_epochs >= 300,
            soul_vector.traits[WISDOM] >= 8000,
            reputation[GOVERNANCE] >= 7000,
        ],
    },
]

function check_phase_advancement(identity: PeerIdentity, context: State) -> IdentityPhase:
    current = identity.phase
    for transition in PHASE_TRANSITIONS:
        if transition.from_phase == current:
            if all_conditions_met(transition.conditions, identity, context):
                return transition.to_phase
    return current

8. Dependencies

Module Interaction
λ Reputation Identity phase gates require reputation thresholds
θ Consensus Identity registration requires quorum validation
κ Rule Engine SBT claims checked via policy gates
π Governance Elder identities have elevated governance weight
η Proof Store Identity events produce Merkle proofs
[[concepts/ξ-identity ξ Identity]] · [[reference/extractions/lambda-reputation-extraction λ Extraction]] · [[reference/extractions/theta-consensus-extraction θ Extraction]] · [[reference/extractions/pi-governance-extraction π Extraction]]

Back to top

Colibri — documentation-first MCP runtime. Apache 2.0 + Commons Clause.

This site uses Just the Docs, a documentation theme for Jekyll.