Trust & Content Distribution

How trust relationships enable automatic content approval and efficient message distribution across the federated network.

Auto-Approval for Trusted Connections

When receiving actions from connected users, the system can automatically create approval (APRV) tokens, enabling content to spread through the network via trusted relationships.

Auto-Approval Conditions

For an action to be auto-approved, ALL of the following must be true:

  1. Approvable action type: Action type has approvable=true behavior
    • Applies to: POST, MSG, REPOST
  2. Addressed to us: action.audience == our_id_tag
  3. From different user: action.issuer != our_id_tag
  4. Setting enabled: federation.auto_approve = true in settings
  5. Connection established: Issuer has bidirectional connection with us

Auto-Approval Flow

Inbound action received
         │
         ▼
┌─────────────────────────────┐
│ Check auto-approval         │
│ conditions (all 5)          │
└───────────┬─────────────────┘
            │
    ┌───────┴───────┐
    │               │
    ▼               ▼
Conditions      Conditions
met             not met
    │               │
    ▼               ▼
┌─────────────┐  No action
│ Update      │  (standard
│ action      │  processing)
│ status='A'  │
└──────┬──────┘
       │
       ▼
┌─────────────────────────────┐
│ Create APRV token           │
│ - aud = original issuer     │
│ - sub = action_id           │
└───────────┬─────────────────┘
            │
            ▼
┌─────────────────────────────┐
│ Deliver APRV to issuer      │
│ (notification)              │
└───────────┬─────────────────┘
            │
            ▼
┌─────────────────────────────┐
│ Broadcast APRV + action     │
│ to our followers            │
└─────────────────────────────┘

Trust Indicator

Trust = Bidirectional Connection

The system checks issuer_profile.connected.is_connected() to determine trust. A connection is established when both parties have sent CONN tokens to each other.

Subscriber Fan-Out

For subscribable actions (like CONV), messages need to be delivered to all subscribers. The fan-out mechanism ensures efficient message distribution across the federated network.

Subscribable Actions

Actions with subscribable=true behavior can have subscribers:

  • CONV (Conversation) - subscribers receive messages in the group

Fan-Out Algorithm

schedule_subscriber_fanout(action_id, parent_id, issuer):
    1. Walk parent chain to find subscribable root:
       current = parent_id
       while current:
           parent_action = fetch_action(current)
           if is_subscribable(parent_action.type):
               subscribable_root = parent_action
               break
           current = parent_action.parent_id

    2. Check if we own the subscribable root:
       is_local = (subscribable_root.audience == null
                   && subscribable_root.issuer == our_id_tag)
                  || subscribable_root.audience == our_id_tag

       if not is_local:
           return  // Remote owner handles fan-out

    3. Get subscribers:
       subscribers = query_subscriptions(subscribable_root.action_id)
                     .filter(status = 'A')  // Active only

    4. Create delivery tasks:
       for subscriber in subscribers:
           if subscriber != our_id_tag
              && subscriber != issuer:  // Exclude self and sender
               schedule_delivery_task(
                   action_id,
                   subscriber,
                   key = "fanout:{action_id}:{subscriber}"
               )

Local vs Remote Fan-Out

Scenario 1: Local CONV Owner Sends Message

Alice (CONV owner) sends MSG
         │
         ▼
┌─────────────────────────────┐
│ ActionCreatorTask           │
│ - Creates MSG               │
│ - Calls schedule_delivery() │
└───────────┬─────────────────┘
            │
            ▼
┌─────────────────────────────┐
│ schedule_subscriber_fanout()│
│ - Finds CONV (subscribable) │
│ - CONV is local (we own it) │
│ - Gets all SUBS             │
│ - Schedules delivery to each│
└───────────┬─────────────────┘
            │
            ▼
    Bob, Charlie receive MSG
    (all other subscribers)

Scenario 2: Remote Subscriber Sends Message

Bob (subscriber, not owner) sends MSG
on his instance
         │
         ▼
┌─────────────────────────────┐
│ schedule_subscriber_fanout()│
│ - Finds CONV (subscribable) │
│ - CONV is NOT local         │
│ - No local fan-out          │
└───────────┬─────────────────┘
            │
            ▼
┌─────────────────────────────┐
│ schedule_delivery()         │
│ - Deliver to CONV owner     │
│   (Alice)                   │
└───────────┬─────────────────┘
            │
            ▼ (federation)
┌─────────────────────────────┐
│ Alice's instance receives   │
│ MSG at /inbox               │
└───────────┬─────────────────┘
            │
            ▼
┌─────────────────────────────┐
│ schedule_subscriber_fanout()│
│ - CONV is local to Alice    │
│ - Fan out to all except Bob │
└───────────┬─────────────────┘
            │
            ▼
    Charlie, others receive MSG

When delivering certain actions (like APRV), related actions are bundled together in a single delivery to provide context.

Bundling Use Cases

  1. APRV + Approved POST: When broadcasting an approval, include the approved content
  2. INVT + Subject CONV: When inviting, include the conversation details

Delivery Payload Structure

{
  "token": "eyJhbGciOi...MAIN_ACTION_TOKEN",
  "related": [
    "eyJhbGciOi...RELATED_ACTION_TOKEN_1",
    "eyJhbGciOi...RELATED_ACTION_TOKEN_2"
  ]
}
Inbox receives action with related tokens
         │
         ▼
┌─────────────────────────────┐
│ Store related tokens        │
│ - Status = 'W' (waiting)    │
│ - ack_token = main action   │
└───────────┬─────────────────┘
            │
            ▼
┌─────────────────────────────┐
│ Process main action         │
│ - Verify signature          │
│ - Check permissions         │
│ - Store action              │
│ - Execute on_receive hook   │
└───────────┬─────────────────┘
            │
            ▼
┌─────────────────────────────┐
│ process_related_actions()   │
│ - Get tokens with           │
│   ack_token = main action   │
│ - For each:                 │
│   - Skip permission check   │
│   - Verify signature        │
│   - Store action            │
└─────────────────────────────┘

Key point: Related actions skip permission checks because they are pre-approved by the main action issuer. The trust flows from the APRV issuer to the related content.

APRV Broadcast Example

Alice approves Bob's POST
         │
         ▼
┌─────────────────────────────┐
│ Create APRV                 │
│ - sub = Bob's post action_id│
│ - Check: subject.broadcast  │
└───────────┬─────────────────┘
            │
            ▼
┌─────────────────────────────┐
│ schedule_broadcast_delivery │
│ - Get Alice's followers     │
│ - Include Bob's POST token  │
│   as related action         │
└───────────┬─────────────────┘
            │
            ▼
┌─────────────────────────────┐
│ For each follower:          │
│ POST /inbox                 │
│ {                           │
│   token: APRV_token,        │
│   related: [POST_token]     │
│ }                           │
└─────────────────────────────┘

See Also