λ Reputation — Algorithm Extraction

Language-agnostic pseudocode extracted from Phoenix Python source. Source files: pure_core.py (579L), tokens.py (149L).


1. Five Reputation Domains

Domain Measures Decay Rate (bps/epoch) Access Grants
Execution Task completion quality 500 (5%) Parallel task slots, reduced cooldowns
Commissioning Task creation & scoping 300 (3%) Stake-setting authority, high-rep executor access
Arbitration Dispute fairness 1000 (10%) Arbiter pool membership, dispute vote weight
Governance Rule participation 200 (2%) Proposal rights, governance vote weight
Social Relationships & vouching 100 (1%) Recovery guardian eligibility, gossip priority

Domains are independent: no cross-domain transfer. Each computed separately.

enum ReputationDomain:
    EXECUTION
    COMMISSIONING
    ARBITRATION
    SOCIAL
    GOVERNANCE

// decay_rates_bps: source-verified from pure_core.py
decay_rates_bps = {
    EXECUTION:     500,
    COMMISSIONING: 300,
    ARBITRATION:   1000,
    GOVERNANCE:    200,
    SOCIAL:        100,
}

2. apply_decay() Pseudocode with Quadratic Entropy

function apply_decay(rep: Map<Domain, int64>, inactive_epochs: Map<Domain, int64>) -> Map<Domain, int64>:
    result = copy(rep)
    for domain in ReputationDomain:
        if inactive_epochs[domain] == 0:
            continue    // active this epoch; no decay

        base_rate = decay_rates_bps[domain]

        // Quadratic entropy multiplier: higher rep decays proportionally faster
        // entropy = ilog2(1 + rep[domain]/1000) + 1
        entropy = max(1, ilog2(1 + result[domain] / 1000) + 1)

        effective_rate = min(base_rate * entropy, 5000)    // cap at 50% per epoch

        decay_amount = (result[domain] * effective_rate) / 10000

        result[domain] = max(0, result[domain] - decay_amount)

    return result

// Properties:
// - Exponential: higher scores decay faster (quadratic multiplier)
// - Floor: score never goes below 0
// - Cap: max decay is 50% per epoch (5000 bps)
// - Activity resets: if inactive_epochs == 0 for domain, no decay that epoch

Entropy Multiplier Examples

Rep Score entropy = ilog2(1 + score/1000) + 1 effective_rate (EXECUTION, base=500)
0 1 500 bps (5%)
1000 ilog2(2)+1 = 2 1000 bps (10%)
7000 ilog2(8)+1 = 4 2000 bps (20%)
10000 ilog2(11)+1 = 4 2000 bps (20%)

3. 14-Action Reputation Delta Table

Full table from pure_core.py action_table:

Action Delta (bps) Domain Notes
CreateProposal +1000 Commissioning Initiating new work contracts
CreateContract +1000 Commissioning Creating governance proposals
AcceptCommitment +500 Execution Accepting a task commitment
SettleContract +500 Execution Completing a contract successfully
OpenDispute +2000 Arbitration Initiating dispute resolution
ResolveDispute +2000 Arbitration Resolving a dispute as arbiter
Schism -1000 Social Creating a network split
InvitePeer +500 Social Inviting a new participant
Vouch +500 Social Vouching for another node’s identity
SecureIdentity +1500 Social Setting up identity recovery (SSS)
RecoverIdentity +2000 Social Recovering lost identity via guardians
VoteCast +200 Arbitration Casting any governance vote
GovernancePropose +2500 Governance Submitting a governance proposal
GovernanceVote +2500 Governance Voting on a governance proposal
function calculate_reputation_delta(action: string, actor: Node) -> (int64, Domain):
    (base_delta, domain) = action_table[action]
    adjusted = apply_gain_ceiling(base_delta, actor.reputation[domain])
    adjusted = apply_anti_bias(adjusted, action, actor)
    adjusted = apply_sentinel_dampening(adjusted, actor.sentinel_status)
    return (adjusted, domain)

4. Tiered Gain Ceiling Formula

Diminishing returns on reputation gain based on current score:

// gain_ceiling_tiers: (score_threshold, max_gain_bps)
gain_ceiling_tiers = [
    (10000,  5000),   // score < 10000: gain capped at 5000 bps
    (100000, 3000),   // score < 100000: gain capped at 3000 bps
    (∞,      1000),   // score >= 100000: gain capped at 1000 bps
]

function apply_gain_ceiling(base_delta: int64, current_score: int64) -> int64:
    if base_delta <= 0: return base_delta    // penalties not subject to ceiling
    for (threshold, cap_bps) in gain_ceiling_tiers:
        if current_score < threshold:
            return min(base_delta, cap_bps)
    return min(base_delta, 1000)    // floor tier

5. Offense Penalties

Severity Table

Severity Penalty (bps) Scar Applied Ban Duration
Minor 1500 (15%) No None
Moderate 3000 (30%) No None
Severe 5000 (50%) Yes — reduces max_score None
Critical 8000 (80%) Yes — reduces max_score N epochs (configurable)
Fraud 10000 (100%) Yes — permanent scar Permanent
function calculate_damage(severity: Severity, current_score: int64) -> DamageResult:
    penalty_bps = severity_to_bps[severity]
    damage = (current_score * penalty_bps) / 10000

    scar = severity in [SEVERE, CRITICAL, FRAUD]
    permanent = severity == FRAUD
    ban_epochs = get_ban_duration(severity)    // 0 for Minor/Moderate

    return DamageResult {
        damage:    damage,
        scar:      scar,
        permanent: permanent,
        ban:       ban_epochs,
    }

// Double jeopardy protection: same event cannot trigger same penalty twice
function apply_penalty(node: Node, event_id: bytes32, severity: Severity):
    if event_id in node.penalized_events[severity]:
        return    // already penalized for this event at this severity
    node.penalized_events[severity].add(event_id)
    result = calculate_damage(severity, node.reputation[domain])
    node.reputation[domain] = max(0, node.reputation[domain] - result.damage)
    if result.scar:
        apply_scar(node, result)

Scar Rules

function apply_scar(node: Node, damage: DamageResult):
    // Scar = permanent reduction in max_score ceiling
    node.max_score[domain] = max(0, node.max_score[domain] - damage.damage)
    // Score may not exceed max_score (enforced on every update)
    node.reputation[domain] = min(node.reputation[domain], node.max_score[domain])

    if damage.permanent:
        // Fraud scar: max_score permanently locked at current level
        node.fraud_locked = true
        // Reputation can never increase above current max_score for this domain

6. Anti-Bias: 90% Correlation Dampening

Prevents reputation farming by repeatedly using the same counterparty or action pattern.

ANTI_BIAS_THRESHOLD = 0.90    // 90% correlation triggers dampening
ANTI_BIAS_REDUCTION = 0.50    // reduce gain by 50%

function apply_anti_bias(delta: int64, action: string, actor: Node) -> int64:
    if delta <= 0: return delta    // penalties not dampened by anti-bias

    // Check: is arbitration reputation > 90% from interactions with same counterparty?
    if action in ARBITRATION_ACTIONS:
        correlation = compute_counterparty_correlation(actor, domain=ARBITRATION)
        if correlation >= ANTI_BIAS_THRESHOLD:
            return (delta * 5000) / 10000    // 50% reduction

    return delta

function compute_counterparty_correlation(actor: Node, domain: Domain) -> float:
    // Returns fraction of domain rep earned from most frequent single counterparty
    rep_by_counterparty = aggregate_rep_by_source(actor, domain)
    if total_rep == 0: return 0.0
    max_single = max(rep_by_counterparty.values())
    return max_single / total_rep

7. Sentinel Dampening

When the integrity monitor flags a node, reputation gains are suppressed.

enum SentinelStatus: NORMAL, WARN, CRITICAL

function apply_sentinel_dampening(delta: int64, status: SentinelStatus) -> int64:
    if delta <= 0: return delta    // penalties not dampened
    match status:
        NORMAL:   return delta
        WARN:     return (delta * 5000) / 10000    // WARN → 50% of gain
        CRITICAL: return 0                          // CRITICAL → 0% (no gain)

8. Experience Token Levels

enum TokenLevel: L0=0, L1=1, L1_5=15, L2=2, L3=3
enum TokenKind:  EPISTEMIC_MASTERY, MORAL_STANDING, SYSTEMIC_INTEGRITY
enum L2SubLevel: L2A_CORRELATION, L2B_CAUSAL
enum IrreversibilityType: EPISTEMIC, MORAL, SYSTEMIC

Token Level Hierarchy

Level Name Minting Condition
L0 Raw Token Auto-minted on first event completion
L1 Episode Full commit → deliver → confirm cycle completed
L1.5 (Witness) WitnessToken 3 or more disputes witnessed as observer
L2a Correlation 5+ same-pattern repetitions across events
L2b Proto-Causal L2a + context_diversity >= 2 + 3 counterparties
L3 Mastery / Scar / Systemic Promotion from L2b only (not L2a)

All tokens are non-transferable — bound permanently to issuing node identity.


9. L3 Permanence Rules

// L3 decay behavior depends on IrreversibilityType:
function apply_l3_decay(token: TokenRecord, epochs_elapsed: int64) -> TokenRecord:
    match token.irreversibility_type:
        EPISTEMIC:
            // Linear decay over 100 epochs
            decay_per_epoch = token.initial_weight / 100
            token.weight = max(0, token.initial_weight - decay_per_epoch * epochs_elapsed)

        MORAL:
            // No decay — permanent moral scar
            // token.weight unchanged forever
            pass

        SYSTEMIC:
            // No decay + quarantine flag set
            // Node placed in reduced-trust mode
            token.quarantine = true
            // token.weight unchanged

    return token

10. WitnessToken Rules

WITNESS_MAX_WEIGHT    = 0.30   // Max 30% of reputation weight per WitnessToken
WITNESS_PORTFOLIO_CAP = 0.40   // Max 40% of total portfolio may be WitnessTokens (INV-ET-06)

// WitnessToken minting:
function mint_witness_token(node: Node, dispute_id: bytes32) -> WitnessToken | null:
    witnessed = count_witnessed_disputes(node)
    if witnessed < 3: return null    // minimum threshold
    return WitnessToken {
        node_id:   node.id,
        level:     L1_5,
        weight:    min(compute_witness_weight(node), WITNESS_MAX_WEIGHT),
        dispute_id: dispute_id,
        minted_epoch: current_epoch,
    }

function enforce_portfolio_cap(node: Node):
    witness_weight = sum(t.weight for t in node.tokens if t.level == L1_5)
    total_weight   = sum(t.weight for t in node.tokens)
    if total_weight > 0 and witness_weight / total_weight > WITNESS_PORTFOLIO_CAP:
        // Scale down witness token weights proportionally
        scale = (WITNESS_PORTFOLIO_CAP * total_weight) / witness_weight
        for t in node.tokens:
            if t.level == L1_5: t.weight *= scale

11. Token Promotion Conditions

function can_promote_to_l2b(node: Node, l2a_token: Token) -> bool:
    // L2b requires: L2a exists + context diversity >= 2 + 3 distinct counterparties
    return (
        l2a_token.level == L2A_CORRELATION
        AND compute_context_diversity(node) >= 2
        AND count_distinct_counterparties(node) >= 3
    )

function can_promote_to_l3(node: Node, l2_token: Token) -> bool:
    // L3 can only be promoted from L2b (not L2a)
    return l2_token.level == L2B_CAUSAL

function promote_token(node: Node, token: Token, new_level: TokenLevel) -> Token:
    if new_level == L3:
        irr_type = determine_irreversibility(token)   // EPISTEMIC / MORAL / SYSTEMIC
        return Token {
            ...token,
            level:                new_level,
            irreversibility_type: irr_type,
            promoted_epoch:       current_epoch,
        }

12. Derived Limits from Reputation

function max_parallel_tasks(rep: Map<Domain, int64>) -> int:
    return min(isqrt(max(rep[EXECUTION], 1)), 20)

function rate_limit_bonus(rep: Map<Domain, int64>, base_rate: int64) -> int64:
    return base_rate * max(1, ilog2(max(rep[EXECUTION], 1)))

function stake_requirement(required: int64, rep: Map<Domain, int64>) -> int64:
    return (required * 10000) / max(rep[EXECUTION], 1000)

function can_arbitrate(rep: Map<Domain, int64>) -> bool:
    return rep[ARBITRATION] >= 5000 AND rep[EXECUTION] >= 3000

function can_govern(rep: Map<Domain, int64>) -> bool:
    return rep[GOVERNANCE] >= 4000

function cooldown(base: int64, rep: Map<Domain, int64>) -> int64:
    return base - min(ilog2(max(rep[EXECUTION], 1)), base / 2)

13. Recovery: Shamir’s Secret Sharing

SSS_SHARES    = 5    // total guardian shares
SSS_THRESHOLD = 3    // required shares to recover

function setup_recovery(node: Node) -> Share[]:
    shares = shamir_split(node.secret_key, SSS_SHARES, SSS_THRESHOLD)
    // Distribute one share to each chosen guardian
    return shares

function recover_identity(shares: Share[]) -> Node:
    assert len(shares) >= SSS_THRESHOLD
    secret_key = shamir_reconstruct(shares, SSS_THRESHOLD)
    node = load_identity(secret_key)

    // Recovery penalty: 50% reputation discount on recovery
    for domain in node.reputation:
        node.reputation[domain] = (node.reputation[domain] * 5000) / 10000

    return node

14. Data Structures

struct ReputationRecord:
    node_id:             NodeId
    domain:              ReputationDomain
    score:               int64       // 0 to max_score (bps-scale, 10000 = full)
    max_score:           int64       // reduced by scars
    scars:               bitmask     // bitmask of applied scar types
    ban_until_epoch:     int64       // 0 if not banned
    last_activity_epoch: int64
    created_at:          int64

struct ReputationEvent:
    node_id:           NodeId
    domain:            ReputationDomain
    epoch:             int64
    delta:             int64
    reason:            string
    event_id:          bytes32
    consequence_hash:  bytes32       // hash of triggering event

struct TokenRecord:
    node_id:              NodeId
    kind:                 TokenKind          // EPISTEMIC / MORAL / SYSTEMIC
    level:                TokenLevel         // L0, L1, L1_5, L2A, L2B, L3
    discriminator:        string             // unique label for this token's evidence
    minted_epoch:         int64
    work_proof:           bytes32            // SHA-256 of evidence
    irreversibility_type: IrreversibilityType?  // set for L3 only
    weight:               int64             // bps-scaled contribution weight
    quarantine:           bool              // set for SYSTEMIC L3

15. Dependencies

Module Interaction
κ Rule Engine Computes reputation deltas from rule effects
θ Consensus Validates reputation changes have quorum
ι State Fork Fork carries reputation snapshot; merge applies 50% discount
η Proof Store All rep changes produce Merkle proofs
μ Integrity Sentinel status dampens gains (advisory)
[[concepts/λ-reputation λ Reputation]] · [[spec/S04-reputation S04 Reputation Spec]] · [[spec/S05-experience-tokens S05 Experience Tokens]] · [[reference/extractions/kappa-rule-engine-extraction κ Extraction]] · [[reference/extractions/theta-consensus-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.