Subjective Delegation XEP

-- 2026-09-30

I have been interested in subjective moderation for years, but I am not very familiar with the inner workings of XMPP. Please contact me with feedback on this XEP draft. Thank you!


XEP-XXXX: Subjective Delegation for Multi-User Chat

Status: Experimental
Type: Standards Track
Short Name: subjective-delegation
Namespace: urn:xmpp:subjective-delegation:0
Dependencies: XEP-0030, XEP-0045, XEP-0060, XEP-0359, XEP-0421
Optional: XEP-0004, XEP-0128, XEP-0163, XEP-0313, XEP-0334
Author: Joseph Turner

1. Abstract

This specification defines a PubSub-based protocol for subjective delegation in XMPP Multi-User Chat rooms.

The generic protocol defines a room-scoped graph model in which participants publish decisions, delegate decision evaluation to other participants, and locally exclude participants from delegated traversal.

A: What's your favorite line from Romeo and Juliet?
B: That's too OT.  The current topic is XEP design...
A: Alas!  There is no world without Verona walls.
B: I pray thee, leave me to myself.
   *B mutes A*

This specification also defines one initial capability: mute.

The mute capability affects only local client rendering. It does not remove, ban, kick, moderate, retract, or silence any participant.

2. Introduction

Multi-User Chat moderation is objective and room-wide. A moderator’s action generally affects the room state observed by all participants.

By contrast, each participant can use subjectively delegated mute to compute their own local view of a room by combining their own mute decisions with mute decisions imported from delegates.

For example:

  • Alice mutes Bob.
  • Alice delegates mute decisions to Carol.
  • Carol mutes Dave.

Result:

  • Alice’s client locally suppresses Bob’s and Dave’s messages.
  • Carol’s client locally suppresses Dave’s messages.
  • Other participants are unaffected.

Participants can recursively gather decisions from delegate's delegates. Participants can also prune delegates from the graph with exclusion rules.

A richer example:

  • Alice delegates mute decisions to Carol recursively.
  • Carol mutes Bob.
  • Carol delegates mute decisions to Dana.
  • Carol also delegates mute decisions to Eve.
  • Dana mutes Fred.
  • Eve mutes Mallory.
  • Alice excludes Dana as a delegate.

Result on Alice's client:

  • Alice’s client locally suppresses Bob’s and Mallory's messages.
  • Alice’s client does not suppress Dave’s messages through Dana.
  • Dana and Dana’s delegates are not traversed for Alice.

This specification uses PubSub for public room graph state and update notifications. This allows clients joining a room to fetch current graph state without reconstructing it from MUC message history.

PEP may be used for private multi-device synchronization, but PEP is not used as the authoritative source for public room graph state.

3. Generic Model

Subjective delegation is modeled as a directed graph of edges.

Each edge has:

  • an actor,
  • a type,
  • a capability,
  • a room,
  • and, usually, a target.

The generic protocol defines edge types and graph traversal behavior. Individual capabilities define the meaning of their decisions.

4. Concepts

4.1 Actor

The identity that creates an edge.

4.2 Target

The object affected by an edge.

For delegate and exclude edges, the target is an identity.

For decision edges, the target type is capability-specific. A decision may target an identity, a message, a thread, or another object defined by the capability.

4.3 Capability

A capability is a decision namespace.

This specification defines one capability:

  • mute

Future specifications may define additional capabilities.

A capability defines:

  • valid decision actions,
  • valid target types,
  • whether decisions may be public, private, or both,
  • how imported decisions are evaluated,
  • how local conflicts are resolved.

The generic <edge/>, <actor/>, and <target/> elements are defined in the generic namespace:

urn:xmpp:subjective-delegation:0

Capabilities MAY define additional semantics for actions and targets.

If a capability requires additional XML payload beyond the generic attributes and elements, that payload SHOULD use a capability-specific XML namespace.

4.4 Decision Edge

A decision edge expresses the actor’s decision within a capability.

Example: Alice publishes a mute decision suppressing Bob.

4.5 Delegate Edge

A delegate edge expresses that the actor imports another identity’s public decisions for a capability.

A delegate edge may also permit recursive traversal through the target’s public delegate edges. Recursion depth is controlled by the hops attribute.

4.6 Exclude Edge

An exclude edge expresses that the actor excludes the target identity from delegated traversal for a capability.

For conceptual and computational simplicity, only positive additions to the delegation graph can be imported from delegates. Therefore, exclude edges are always local, and MUST NOT be imported through delegation.

Example:

  • Alice delegates mute decisions to Carol recursively.
  • Carol delegates mute decisions to Dana.
  • Alice excludes Dana.

Result:

  • Alice imports Carol’s public mute decisions.
  • Alice does not import Dana’s mute decisions through Carol.
  • Alice's client does not traverse Dana’s delegates.

4.7 Public Edge

A public edge is stored in the room public graph node and visible according to that node’s access model.

4.8 Private Edge

A private edge is stored locally or in private PEP storage visible only to the actor’s clients.

Private edges are never imported through delegation by other users.

5. Edge Types

This specification defines three generic edge types:

  • decision
  • delegate
  • exclude

Generic edge attributes:

Attribute Meaning
type decision, delegate, or exclude
capability Capability name
room Room JID

Decision edges additionally have:

Attribute Meaning
action Capability-specific action

delegate edges additionally have:

Attribute Meaning
hops Non-negative integer or unbounded

6. Identity Model

This protocol supports two identity forms:

  • bare JIDs,
  • XEP-0421 stable occupant IDs.

It does not support:

  • MUC nicknames,
  • MUC occupant JIDs,
  • full JIDs,
  • temporary session identifiers,
  • display names,
  • avatars.

6.1 Non-anonymous MUCs

In non-anonymous MUCs, implementations MAY use bare JIDs or XEP-0421 occupant IDs to identify actors and identity targets.

6.2 Semi-anonymous MUCs

In semi-anonymous MUCs, implementations MUST use XEP-0421 occupant IDs only.

Protocol payloads for semi-anonymous rooms MUST NOT contain actor or target bare JIDs, even if the publishing client knows them.

6.3 Anonymous MUCs

In anonymous MUCs, implementations MUST use XEP-0421 occupant IDs only.

If a participant has no identity appropriate for the room’s anonymity mode, that participant is not addressable by identity through this protocol.

6.4 Room Scoping

Occupant IDs are scoped to a room. The occupant ID alone is not globally meaningful.

An implementation MUST interpret an occupant ID together with the room attribute of the edge.

7. PubSub Model

There are two storage locations:

  • room public graph storage,
  • private user graph storage.

This specification uses XEP-0060 PubSub as the storage and notification substrate for room public graph state.

Private graph storage may be implemented using:

  • a private PEP node,
  • local client storage.

PEP MUST NOT be used as the authoritative source for public room graph edges. PEP nodes are discoverable by bare JID and are therefore not suitable for authoritative public graph state for anonymous and semi-anonymous rooms.

8. Room Public Graph Node

Each supported room SHOULD advertise a public graph node that stores public edges relevant to that room.

Example node name:

urn:xmpp:subjective-delegation:0/rooms/room@example.org/public

The exact node name is implementation-defined, but it MUST be discoverable.

The public graph node stores only public edges. Capability specifications define which edges may be public.

8.1 Node Requirements

The room public graph node MUST support:

  • persistent items,
  • item IDs,
  • item retraction,
  • payload delivery,
  • event notifications,
  • access control.

The node MUST be configured with:

  • persistent items enabled,
  • payload delivery enabled,
  • event notifications enabled.

The public graph node’s access model SHOULD match the room’s effective access policy. For example:

  • open room: readable by anyone or by current occupants,
  • members-only room: readable by members, admins, and owners,
  • otherwise restricted room: readable only by entities authorized to access the room.

9. Private Graph Storage

Private graph storage contains edges used only by the actor’s own clients.

Private edges MUST NOT be shared with the room public graph node.

Private storage MUST be readable and writable only by the owning user or resources authorized by that user.

Private edges belonging to another actor MUST NOT be imported through delegation.

If PEP is used for private synchronization, private edges are stored as PubSub items using the same edge payload format. If private graph state is stored locally, there is no PubSub <item/> wrapper.

10. Discovery

A room supporting this protocol MUST advertise protocol support using XEP-0030 service discovery:

urn:xmpp:subjective-delegation:0

A room supporting this protocol MUST advertise the PubSub service and public graph node using XEP-0128 extended service discovery. The data form advertises the concrete PubSub location where public graph state is stored.

Example disco response:

<iq xmlns="jabber:client"
    type="result"
    from="room@example.org"
    to="alice@example.com/laptop"
    id="disco1">
  <query xmlns="http://jabber.org/protocol/disco#info">
    <feature var="urn:xmpp:subjective-delegation:0"/>
    <feature var="urn:xmpp:occupant-id:0"/>
    <x xmlns="jabber:x:data" type="result">
      <field var="FORM_TYPE" type="hidden">
        <value>urn:xmpp:subjective-delegation:0#disco</value>
      </field>
      <field var="pubsub-service">
        <value>pubsub.example.org</value>
      </field>
      <field var="public-node">
        <value>urn:xmpp:subjective-delegation:0/rooms/room@example.org/public</value>
      </field>
    </x>
  </query>
</iq>

11. Edge Payload Format

Edges are XML payloads, usually carried inside PubSub <item/> elements.

The edge element is qualified by:

urn:xmpp:subjective-delegation:0

11.1 Identity Elements

Actors and identity targets are represented using either jid or occupant-id:

<actor jid="alice@example.com"/>
<actor occupant-id="a1"/>
<target jid="bob@example.com"/>
<target occupant-id="b2"/>

occupant-id MUST be used in anonymous and semi-anonymous rooms. An identity element MUST NOT contain both jid and occupant-id.

11.2 Direct Decision Example

Alice publishes a public decision in a non-anonymous room:

<item xmlns="http://jabber.org/protocol/pubsub" id="edge-1">
  <edge xmlns="urn:xmpp:subjective-delegation:0"
        type="decision"
        capability="mute"
        action="suppress"
        room="room@example.org">
    <actor jid="alice@example.com"/>
    <target jid="bob@example.com"/>
  </edge>
</item>

11.3 Occupant-ID Decision Example

Occupant a1 publishes a decision targeting occupant b2:

<item xmlns="http://jabber.org/protocol/pubsub" id="edge-2">
  <edge xmlns="urn:xmpp:subjective-delegation:0"
        type="decision"
        capability="mute"
        action="suppress"
        room="room@example.org">
    <actor occupant-id="a1"/>
    <target occupant-id="b2"/>
  </edge>
</item>

11.4 Delegate Edge Example

Alice delegates mute decisions to Carol, importing only Carol’s direct public decisions as indicated by hops="0":

<item xmlns="http://jabber.org/protocol/pubsub" id="edge-3">
  <edge xmlns="urn:xmpp:subjective-delegation:0"
        type="delegate"
        capability="mute"
        hops="0"
        room="room@example.org">
    <actor jid="alice@example.com"/>
    <target jid="carol@example.com"/>
  </edge>
</item>

11.5 Recursive Delegate Edge Example

Alice delegates mute decisions to Carol and permits recursive traversal. In the following example, hops="2" means that Alice's client will aggregate decisions from Carol, Carol's delegates, and Carol's delegate's delegates:

<item xmlns="http://jabber.org/protocol/pubsub" id="edge-4">
  <edge xmlns="urn:xmpp:subjective-delegation:0"
        type="delegate"
        capability="mute"
        hops="2"
        room="room@example.org">
    <actor jid="alice@example.com"/>
    <target jid="carol@example.com"/>
  </edge>
</item>

Alternatively, use hops="unbounded" to indicate that recursion continues indefinitely.

11.6 Private Exclude Edge Example

Alice excludes Dana from mute delegation traversal:

<item xmlns="http://jabber.org/protocol/pubsub" id="edge-6">
  <edge xmlns="urn:xmpp:subjective-delegation:0"
        type="exclude"
        capability="mute"
        room="room@example.org">
    <actor jid="alice@example.com"/>
    <target jid="dana@example.com"/>
  </edge>
</item>

This edge is private and MUST NOT be published to the room public graph node.

11.7 Private Decision Example

The protocol for a particular capability may specify that some decisions can be private. For example, the mute capability specifies that "allow" decisions are always private. In the following example, Alice privately allows Bob:

<item xmlns="http://jabber.org/protocol/pubsub" id="edge-5">
  <edge xmlns="urn:xmpp:subjective-delegation:0"
        type="decision"
        capability="mute"
        action="allow"
        room="room@example.org">
    <actor jid="alice@example.com"/>
    <target jid="bob@example.com"/>
  </edge>
</item>

This example assumes private storage uses PEP. If stored locally, the <edge/> payload is stored without a PubSub <item/> wrapper.

12. Hops Semantics

A delegate edge imports the target’s direct public decisions for the named capability.

The hops attribute controls whether the target’s public delegate edges are also followed.

hops Meaning
0 Import target’s direct public decisions only
1 Also import target’s delegates' decisions
2 Also import target's delegates' delegates' decisions
unbounded Continue importing recursively, subject to implementation limits

13. Publishing Public Edges

A client publishes a public edge using XEP-0060 publish.

<iq xmlns="jabber:client"
    type="set"
    from="alice@example.com/laptop"
    to="pubsub.example.org"
    id="pub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <publish node="urn:xmpp:subjective-delegation:0/rooms/room@example.org/public">
      <item id="edge-1">
        <edge xmlns="urn:xmpp:subjective-delegation:0"
              type="decision"
              capability="mute"
              action="suppress"
              room="room@example.org">
          <actor jid="alice@example.com"/>
          <target jid="bob@example.com"/>
        </edge>
      </item>
    </publish>
  </pubsub>
</iq>

The PubSub service then sends normal PubSub event notifications to subscribers.

14. Revocation

Edges are stateful. Revocation is performed by retracting the PubSub item.

<iq xmlns="jabber:client"
    type="set"
    from="alice@example.com/laptop"
    to="pubsub.example.org"
    id="retract1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <retract node="urn:xmpp:subjective-delegation:0/rooms/room@example.org/public">
      <item id="edge-1"/>
    </retract>
  </pubsub>
</iq>

After retraction, clients MUST remove the edge from their local graph.

Implementations SHOULD use stable item IDs. An item ID SHOULD identify exactly one active edge.

15. Notifications and Synchronization

Subscribers receive updates via normal PubSub event notifications.

Clients SHOULD fetch current node state:

  • on login,
  • on reconnect,
  • on room join,
  • after missed notifications are suspected.

PubSub notifications are not authoritative. The PubSub item set is authoritative.

Services MAY include XEP-0334 no-store hints on PubSub notification messages because durable state is stored in PubSub items rather than notification messages.

16. Generic Delegation Evaluation

The following Scheme-like pseudocode defines behavior, not implementation language.

For local actor U, room R, and capability C, evaluation uses:

  • decisions authored by U,
  • delegate edges authored by U,
  • private exclude edges authored by U,
  • public delegate edges reachable through delegation.
  • public decisions reachable through delegation.

Private edges authored by other actors are never used. Exclude edges are never imported.

(define (delegated-decisions U R C)
  (append-map
   (lambda (edge)
     (let ((T (edge-target edge)))
       (if (excluded? U R C T)
           '()
           (traverse U R C T (edge-hops edge) '()))))
   (delegate-edges-authored-by U R C)))
(define (traverse U R C X hops visited)
  (cond
   ((member X visited) '())
   ((excluded? U R C X) '())
   (else
    (append
     (public-importable-decisions X R C)
     (if (zero? hops)
         '()
         (append-map
          (lambda (edge)
            (traverse U R C
                      (edge-target edge)
                      (hops-min (hops-dec hops) (edge-hops edge))
                      (cons X visited)))
          (public-delegate-edges X R C)))))))
(define (hops-dec hops)
  (if (eq? hops 'unbounded)
      'unbounded
      (- hops 1)))

(define (hops-min a b)
  (cond
   ((eq? a 'unbounded) b)
   ((eq? b 'unbounded) a)
   (else (min a b))))

Helper meanings:

  • delegate-edges-authored-by returns public or private delegate edges authored by U for capability C.
  • excluded? checks whether identity X is privately excluded from delegation by U.
  • public-importable-decisions returns public decisions that capability C allows to be imported.
  • public-delegate-edges returns public delegate edges.
  • edge-hops is a non-negative integer or unbounded.

Note that in the above traverse function, the visited argument only detects cycles within the current recursive branch. Implementations SHOULD deduplicate returned decisions, for example by stable PubSub item ID. Implementations MAY use caching or a global visited structure only if doing so preserves the semantics of hops and local exclusions.

Implementations MUST detect cycles and SHOULD impose limits on recursion depth, edge count, node count, and computation time.

Mute Capability

17. Capability Name

The mute capability name is:

mute

The mute capability controls local rendering of ordinary MUC messages.

It does not affect room state and does not grant moderation power.

18. Capability namespace

The mute capability uses only the generic edge payload format defined by this specification. It does not define a separate capability-specific XML namespace.

19. Mute Decision Actions

The mute capability defines two decision actions:

Action Meaning
suppress Locally suppress matching messages
allow Locally override delegated suppress decisions

19.1 Suppress

A suppress decision means the actor does not want matching ordinary MUC messages shown in the main conversation view.

A client SHOULD suppress notifications for suppressed messages.

A client MAY provide a way to reveal suppressed messages.

19.2 Allow

An allow decision is a private local override. It causes matching messages to remain visible to the local actor even if they are suppressed by delegated decisions or by the actor’s own active suppress decisions.

An allow decision does not retract, modify, or hide any public suppress decision from other users. Users who delegate to the actor may still import the actor’s public suppress decisions.

Clients SHOULD warn when a local allow conflicts with an active public or private suppress authored by the same actor.

20. Mute Edge Visibility Rules

suppress decisions may be public or private. Public suppress decisions may be imported through delegations.

For conceptual and computational simplicity, only suppress decisions can be imported from delegates. Therefore, allow edges are always local, and MUST NOT be imported through delegation.

21. Mute Targets

Mute decision edges may target:

  • identities,
  • messages,
  • threads.

Mute delegate and exclude edges target identities only.

21.1 Identity Target

An identity target uses jid or occupant-id:

<target jid="bob@example.com"/>

or:

<target occupant-id="b2"/>

21.2 Message Target

A message target uses a XEP-0359 stanza ID.

<target stanza-id="msg-123" by="room@example.org"/>

The stanza-id attribute contains the XEP-0359 stable stanza ID. The by attribute identifies the assigning entity.

21.3 Thread Target

Mute decision edges MAY target RFC 6121 message thread identifiers. Clients that do not support or preserve <thread/> MAY ignore thread targets.

<target thread="thread-123"/>

Thread identifiers are room-scoped by the edge’s room attribute.

22. Effective Mute Evaluation

For local actor U in room R, effective mute targets are:

(define (effective-mute U R)
  (difference
   (union
    (direct-suppress U R)
    (delegated-suppress U R))
   (local-allow U R)))

Where:

  • direct-suppress returns suppress decisions authored by U, whether public or private.
  • delegated-suppress returns imported public suppress decisions.
  • local-allow returns private allow decisions authored by U.

A local allow decision cancels matching suppress decisions for the local actor’s own view, including suppress decisions authored by the local actor.

A local allow decision does not retract or modify any public suppress decision. Therefore, if Alice publicly suppresses Bob and privately allows Bob, Alice’s client shows Bob, but users who delegate mute decisions to Alice can still import Alice’s public suppress decision for Bob.

Clients SHOULD warn when a local allow conflicts with an active public or private suppress authored by the same actor.

23. Mute Message Filtering

When rendering a MUC message, the client determines whether the message matches any target in effective-mute.

A message is suppressed if any of the following match:

  • sender identity,
  • message stanza ID,
  • thread identifier.

24. Mute Examples

The following examples show <edge/> payloads only. Public examples are published as PubSub <item/> payloads in the room public graph node. Private examples are stored in private PEP or local storage.

24.1 Direct Public Mute

Carol mutes Dave publicly in a non-anonymous room:

<edge xmlns="urn:xmpp:subjective-delegation:0"
      type="decision"
      capability="mute"
      action="suppress"
      room="room@example.org">
  <actor jid="carol@example.com"/>
  <target jid="dave@example.com"/>
</edge>

24.2 Local Allow

Alice allows Dave, overriding any potential mute decisions:

<edge xmlns="urn:xmpp:subjective-delegation:0"
      type="decision"
      capability="mute"
      action="allow"
      room="room@example.org">
  <actor jid="alice@example.com"/>
  <target jid="dave@example.com"/>
</edge>

Dave is visible to Alice. If Alice also has an active public suppress decision for Dave, users who delegate mute decisions to Alice may still suppress Dave.

24.3 Message-Specific Mute

Alice suppresses a particular message:

<edge xmlns="urn:xmpp:subjective-delegation:0"
      type="decision"
      capability="mute"
      action="suppress"
      room="room@example.org">
  <actor jid="alice@example.com"/>
  <target stanza-id="msg-123" by="room@example.org"/>
</edge>

In message targets, the by attribute MUST be present and MUST match the by attribute of the XEP-0359 <stanza-id/> being referenced. In typical MUC usage, this value is the room JID and therefore matches the edge’s room attribute.

24.4 Thread Mute

Alice suppresses a thread:

<edge xmlns="urn:xmpp:subjective-delegation:0"
      type="decision"
      capability="mute"
      action="suppress"
      room="room@example.org">
  <actor jid="alice@example.com"/>
  <target thread="thread-123"/>
</edge>

25. Actor Authenticity

For bare-JID edges, the PubSub service MUST ensure that the publisher is authorized to publish edges for the claimed actor JID.

For occupant-ID edges, the PubSub service MUST ensure that the publisher is authorized to publish edges for the claimed XEP-0421 occupant ID in the specified room.

This may require integration between:

  • the MUC service,
  • the PubSub service,
  • the occupant-ID provider.

A client MUST NOT trust a self-asserted actor occupant ID in a public PubSub item unless the service enforces this binding.

26. Access Control

Access control is required for both reading and writing.

The service MUST prevent unauthorized publication of edges for another actor.

The service MUST prevent unauthorized retraction of another actor’s edges.

The room public graph node SHOULD use an access model consistent with the room’s access policy.

Private graph storage MUST be readable and writable only by the owning user or authorized resources.

In semi-anonymous and anonymous rooms, the PubSub service MUST NOT expose bare JIDs through:

  • payloads,
  • node names,
  • notifications,
  • access-control side effects visible to unauthorized entities.

27. Privacy Rules

In semi-anonymous and anonymous rooms, stable occupant-IDs are used to identify actors and identity targets. Bare JIDs MUST NOT appear.

In non-anonymous rooms, bare JIDs are permitted because the room already exposes them.

Public delegation graphs may reveal social information. For example, they may reveal who mutes whom and whose mute decisions are delegated to by others. Implementations SHOULD make this clear to users.

28. Interaction with Existing XEPs

28.1 XEP-0045: Multi-User Chat

This protocol does not alter MUC roles, affiliations, bans, kicks, voice, or moderation. A delegate is not a MUC moderator.

28.2 XEP-0060: Publish-Subscribe

XEP-0060 is the storage and notification substrate for public room graph state.

28.3 XEP-0163: Personal Eventing Protocol

PEP MAY be used for private multi-device synchronization.

PEP MUST NOT be used as an authoritative source for public room graph edges.

28.4 XEP-0359: Unique and Stable Stanza IDs

The mute capability may use XEP-0359 stanza IDs to target individual messages.

28.5 XEP-0421: Occupant IDs

XEP-0421 is required for semi-anonymous and anonymous room support.

28.6 XEP-0313: Message Archive Management

Clients MAY apply the same capability-specific filtering to archived messages.

28.7 XEP-0334: Message Processing Hints

Message Processing Hints are not required for protocol correctness.

Services MAY include no-store hints on PubSub notification messages.

29. Security Considerations

Implementations MUST consider:

  • actor spoofing,
  • occupant-ID forgery,
  • unauthorized PubSub publication,
  • unauthorized PubSub subscription,
  • unauthorized item retraction,
  • deanonymization through bare JID leakage,
  • cycles in delegation graphs,
  • denial of service through large graphs,
  • stale or rotated occupant IDs.

30. Client UX Recommendations

Clients SHOULD distinguish:

  • direct local decisions,
  • delegated decisions,
  • local allow rules,
  • local exclude rules,
  • delegates with limited hops,
  • delegates with recursive traversal.

For the mute capability, suggested UI actions include:

  • private mute,
  • public mute,
  • unmute
  • allow despite delegated mute,
  • remove allow rule,
  • delegate mute decisions,
  • set delegate hops,
  • exclude delegate,
  • remove exclude rule.

Instead of offering an option to set delegate hops, a simple delegation UI may provide a choice between zero-hop "delegates" and unbounded "superdelegates".

If a user selects “unmute” for a participant muted only through delegation, the client SHOULD create a private allow decision.

If a user selects “unmute” for a participant directly muted by the user, the client SHOULD retract the direct suppress decision instead of creating a private allow decision.

If a user excludes a directly appointed delegate, the client SHOULD normally retract the direct delegate edge instead of creating an exclude edge.

30.1 Delegation graph

Clients MAY provide a navigable interface for viewing the graph of delegates for a particular room and capability. See the "Prior Art" section for examples.

31. Delegation Seeds

A future version of this specification may define delegation seeds for bootstrapping a participant’s private delegation graph when joining a room.

A delegation seed is a recommended set of initial private edges associated with a room. For example, an invitation link or out-of-band invitation mechanism could recommend that a joining participant delegate the mute capability to one or more existing room participants.

A seed does not affect any participant unless that participant’s client accepts it. If accepted, seeded edges are created as private edges authored by the joining participant.

Seed child <edge/> elements are templates, not graph edges. They therefore omit the actor. The actor is filled in by the accepting client.

Example seed:

<seed xmlns="urn:xmpp:subjective-delegation:0"
      room="room@example.org">
  <edge type="delegate" capability="mute" hops="0">
    <target jid="carol@example.com"/>
  </edge>
  <edge type="delegate" capability="mute" hops="unbounded">
    <target jid="dana@example.com"/>
  </edge>
</seed>

If Alice accepts this seed, her client creates private edges like the following:

<edge xmlns="urn:xmpp:subjective-delegation:0"
      type="delegate"
      capability="mute"
      hops="0"
      room="room@example.org">
  <actor jid="alice@example.com"/>
  <target jid="carol@example.com"/>
</edge>

Clients MAY also use the existing set of room owners, admins, and moderators as seed delegates.

Future work:

  • how seeds are encoded in XMPP URIs,
  • how seed data is fetched from PubSub or another source,
  • whether seeds are signed,
  • how clients verify seed authenticity,
  • how invitation links or seed access tokens interact with XMPP access control,
  • how seeds represent occupant-ID targets in anonymous or semi-anonymous rooms.

32. Open Issues

  • Exact PubSub node naming convention.
  • Whether room public graph nodes must be hosted by the MUC service.
  • How edge IDs are generated, e.g., using deterministic hashes.
  • Handling occupant-ID rotation policies.
  • Cache expiration after users leave a room.
  • Fine-grained muting, such as muting a participant within a particular thread,

33. Prior Art and Related Work

Credit for inspiring this XEP goes to:

34. Summary

This specification defines subjective delegation for MUC using PubSub.

The generic model is:

  • decision: express a decision within a capability,
  • delegate: import another identity’s public decisions for a capability,
  • exclude: locally remove an identity from delegated traversal,
  • capability: a named decision area with capability-specific semantics.

This specification also defines the mute capability:

  • suppress: locally suppress matching messages,
  • allow: locally override delegated suppress decisions.