ι State Fork — Algorithm Extraction

Language-agnostic pseudocode extracted from Phoenix Python source. Source file: fork.py (1308L).


1. ForkReason Enum (5 Values)

enum ForkReason:
    RULE_VERSION_CONFLICT    // Nodes disagree on which rule set is canonical
    INVARIANT_VIOLATION      // A state transition would violate a system invariant
    CONSTITUTIONAL_VIOLATION // A transition violates an AX-01..AX-12 axiom
    VOLUNTARY_EXIT           // A participant explicitly chooses to fork off
    GOVERNANCE_REJECTION     // A governance proposal was rejected but a minority wants to apply it

2. ForkStatus Enum (4 Values)

enum ForkStatus:
    ACTIVE      // Fork is live; nodes on this fork process events normally
    MERGED      // Fork was reconciled back into parent; no longer independent
    ABANDONED   // Fork was abandoned; state frozen
    FROZEN      // Temporary suspension (e.g., during merge negotiation)

3. ForkIsolation Enum

enum ForkIsolation:
    ISOLATED           // No communication with parent fork; fully independent
    READ_ONLY_PARENT   // Can read parent state; cannot write to parent
    BRIDGED            // Bidirectional state visibility; merge protocol active

Isolation Mode Behavior

Mode Can Read Parent Can Write Parent Events Cross Fork Merge Eligible
ISOLATED No No No Only via full merge protocol
READ_ONLY_PARENT Yes No No (inbound only) Yes — can initiate
BRIDGED Yes Conditional Yes (with proof) Yes — active negotiation

4. GENESIS_FORK_ID

// The root fork identifier from which all forks descend
GENESIS_FORK_ID = sha256("phoenix-genesis-v1")
// Fixed constant; never changes

5. Fork ID Derivation

function derive_fork_id(parent_fork_id: bytes32, divergence_point: bytes32, reason: ForkReason) -> bytes32:
    // Deterministic: same inputs always produce same fork ID
    return sha256(parent_fork_id || divergence_point || encode_reason(reason))

// divergence_point = hash of the last common event before the fork
// reason encoded as 1-byte enum value

6. Fork Creation Algorithm

function create_fork(
    parent_fork: Fork,
    reason:      ForkReason,
    initiator:   NodeId,
    isolation:   ForkIsolation,
    context:     State,
) -> Fork:

    // 1. Determine divergence point
    divergence_point = context.current_state_root

    // 2. Derive new fork ID
    new_fork_id = derive_fork_id(parent_fork.id, divergence_point, reason)

    // 3. Snapshot parent state
    fork_state = deep_copy(context.state)
    fork_state.fork_id = new_fork_id

    // 4. Apply isolation mode
    fork_state.isolation = isolation

    // 5. Register fork
    new_fork = Fork {
        id:               new_fork_id,
        parent_id:        parent_fork.id,
        divergence_point: divergence_point,
        reason:           reason,
        status:           ACTIVE,
        isolation:        isolation,
        initiator:        initiator,
        created_epoch:    context.current_epoch,
        state:            fork_state,
        checkpoints:      [],
    }

    fork_registry[new_fork_id] = new_fork
    notify_peers(new_fork)
    return new_fork

7. Checkpoint Structure

Checkpoints are used to periodically commit fork state for merge eligibility. They require 7-of-10 threshold signatures from the arbiter pool.

CHECKPOINT_THRESHOLD = 7
CHECKPOINT_TOTAL     = 10

struct Checkpoint:
    fork_id:        bytes32
    state_root:     bytes32       // Merkle root of fork state at checkpoint
    epoch:          int64
    event_count:    int64
    partial_sigs:   PartialSig[]  // collected arbiter signatures (need >= 7)
    threshold_sig:  ThresholdSig? // aggregated signature (set when threshold met)
    finalized:      bool

function create_checkpoint(fork: Fork, epoch: int64) -> Checkpoint:
    root = compute_merkle_root(fork.state)
    return Checkpoint {
        fork_id:    fork.id,
        state_root: root,
        epoch:      epoch,
        event_count: fork.state.event_count,
        partial_sigs: [],
        finalized:   false,
    }

function add_checkpoint_sig(checkpoint: Checkpoint, partial_sig: PartialSig) -> bool:
    if partial_sig.signer not in eligible_arbiters(checkpoint.fork_id):
        return false
    checkpoint.partial_sigs.append(partial_sig)
    if len(checkpoint.partial_sigs) >= CHECKPOINT_THRESHOLD:
        checkpoint.threshold_sig = aggregate_threshold_sig(
            checkpoint.partial_sigs[:CHECKPOINT_THRESHOLD]
        )
        checkpoint.finalized = true
    return true

8. Merge Protocol Conditions

A fork may merge back into its parent only when all conditions are met:

function can_merge(fork: Fork, parent: Fork) -> (bool, string):
    // 1. Fork must be ACTIVE (not abandoned or already merged)
    if fork.status != ACTIVE:
        return (false, "fork not active")

    // 2. Must have at least one finalized checkpoint
    if not any(c.finalized for c in fork.checkpoints):
        return (false, "no finalized checkpoint")

    // 3. No open disputes on the fork
    if has_open_disputes(fork.id):
        return (false, "open disputes on fork")

    // 4. Merge proposal must have quorum from both fork and parent validators
    if not has_merge_quorum(fork, parent):
        return (false, "insufficient quorum")

    // 5. State delta must not violate parent invariants
    delta = compute_state_delta(fork.state, parent.state)
    if violates_invariants(delta, parent):
        return (false, "state delta violates parent invariants")

    return (true, "")

function execute_merge(fork: Fork, parent: Fork) -> MergeResult:
    assert can_merge(fork, parent)[0]

    delta = compute_state_delta(fork.state, parent.state)

    // Apply reputation discount for fork participants
    FORK_REP_DISCOUNT = 5000    // 50% discount on fork-local rep gains

    merged_rep = {}
    for node_id, rep in delta.reputation_changes:
        for domain, delta_value in rep:
            if delta_value > 0:
                merged_rep[node_id][domain] = (delta_value * (10000 - FORK_REP_DISCOUNT)) / 10000
            else:
                merged_rep[node_id][domain] = delta_value    // penalties applied in full

    // Apply merged state to parent
    apply_state_delta(parent, delta, rep_override=merged_rep)

    fork.status = MERGED
    return MergeResult {
        fork_id:   fork.id,
        parent_id: parent.id,
        applied_at: current_epoch,
        rep_discount: FORK_REP_DISCOUNT,
    }

9. Fork Detection Integration

enum ForkDetectionResult:
    ALREADY_FORKED         // peer.fork_id != my_fork_id
    IN_SYNC                // peer.state_root == my_state_root
    PEER_BEHIND            // peer_root is ancestor of my_root
    I_AM_BEHIND            // my_root is ancestor of peer_root
    UNPLANNED_FORK         // divergence; trigger fork creation

function detect_fork(
    peer_fork_id: bytes32, peer_root: bytes32,
    my_fork_id:   bytes32, my_root:   bytes32,
) -> ForkDetectionResult:
    if peer_fork_id != my_fork_id: return ALREADY_FORKED
    if peer_root == my_root:       return IN_SYNC
    if is_ancestor(peer_root, my_root): return PEER_BEHIND
    if is_ancestor(my_root, peer_root): return I_AM_BEHIND
    return UNPLANNED_FORK    // divergence detected

// On UNPLANNED_FORK:
// - Record divergence point
// - create_fork(reason=RULE_VERSION_CONFLICT or INVARIANT_VIOLATION)
// - Notify governance

10. Fork-Local State Properties

// Each fork carries its own copy of:
struct ForkState:
    fork_id:       bytes32
    parent_id:     bytes32         // null for genesis fork
    state_root:    bytes32         // Merkle root of this fork's state
    epoch:         int64
    event_count:   int64
    reputation:    Map<NodeId, Map<Domain, int64>>
    tokens:        Map<NodeId, TokenRecord[]>
    rule_version:  string          // rule set hash active on this fork
    isolation:     ForkIsolation

// Events on a fork do NOT propagate to parent (unless BRIDGED mode)
// Rule version can diverge from parent
// Reputation accumulates independently

11. Dependencies

Module Interaction
θ Consensus Consensus failure triggers fork creation
κ Rule Engine Rule version conflict triggers fork; each fork uses own rule version
λ Reputation Fork carries rep snapshot; merge applies discount
η Proof Store Each fork maintains its own Merkle event log
π Governance Governance rejection can trigger voluntary fork
[[concepts/ι-state-fork ι State Fork]] · [[spec/S07-fork-protocol S07 Fork Protocol Spec]] · [[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.