<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.39 (Ruby 2.6.10) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-jennings-moq-mocha-reactions-00" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.34.0 -->
  <front>
    <title abbrev="mocha-reactions">MOCHA Reactions: Real-Time Reactions over MoQ Transport</title>
    <seriesInfo name="Internet-Draft" value="draft-jennings-moq-mocha-reactions-00"/>
    <author fullname="Cullen Jennings">
      <organization>Cisco</organization>
      <address>
        <email>fluffy@iii.ca</email>
      </address>
    </author>
    <author fullname="Suhas Nandakumar">
      <organization>Cisco</organization>
      <address>
        <email>snandaku@cisco.com</email>
      </address>
    </author>
    <date year="2026" month="July" day="06"/>
    <area>Applications and Real-Time</area>
    <workgroup>Media Over QUIC</workgroup>
    <keyword>MoQ</keyword>
    <keyword>MOQT</keyword>
    <keyword>MOCHA</keyword>
    <keyword>Reactions</keyword>
    <keyword>Emoji</keyword>
    <abstract>
      <?line 48?>

<t>This document specifies reactions for MOCHA (MoQ Open
Communication &amp; Hosting Architecture). It supports
message-targeted reactions (emoji on a specific chat message)
and standalone reactions (engagement signals such as
applause or raised hands).</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-jennings-moq-mocha-reactions/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        Media Over QUIC Working Group mailing list (<eref target="mailto:moq@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/moq/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/moq/"/>.
      </t>
    </note>
  </front>
  <middle>
    <?line 56?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>This document specifies how MOCHA enables real-time reaction
exchange using MOQT's publish/subscribe model. Two modes
are supported:</t>
      <dl>
        <dt>Message-Targeted Reactions:</dt>
        <dd>
          <t>Emoji responses referencing a specific chat message MsgID.</t>
        </dd>
        <dt>Standalone Reactions:</dt>
        <dd>
          <t>Standalone engagement signals (applause, raised hands)
directed at the channel as a whole.</t>
        </dd>
      </dl>
      <t>Both modes use the same track structure.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>See BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/>.</t>
      <t>This document uses terminology defined in <xref target="MOCHA-ARCH"/>
and MOQT primitives defined in <xref target="MoQTransport"/>. Message
identifiers (MsgID) are defined in <xref target="MOCHA-CHAT"/>.</t>
    </section>
    <section anchor="reaction-naming">
      <name>Reaction Track Naming</name>
      <section anchor="reactions-namespace">
        <name>Reactions Namespace</name>
        <artwork><![CDATA[
  ("mocha_v1", <Provider>, <OrgID>, "reactions", <TeamID>,
   <ChannelID>, <HClientID>)
]]></artwork>
        <t>HClientID and HDevID are derived per <xref target="MOCHA-IDENTITY"/>,
Section "Identifier Derivation".</t>
      </section>
      <section anchor="track-names">
        <name>Track Names</name>
        <t>Each device publishes reactions on its own track:</t>
        <artwork><![CDATA[
  react_v1_<HDevID>
]]></artwork>
      </section>
      <section anchor="object-semantics">
        <name>Object Semantics</name>
        <t>Within each group, reactions are assigned sequentially
increasing Object IDs starting at 0. Each reaction occupies
one MOQT object.</t>
      </section>
    </section>
    <section anchor="reaction-format">
      <name>Reaction Format</name>
      <section anchor="encoding">
        <name>Encoding</name>
        <t>Reactions are encoded as JSON <xref target="JSON"/> and compressed per
the MOCHA_COMPRESSION track property defined in
<xref target="MOCHA-CHAT"/>.</t>
      </section>
      <section anchor="reaction-structure">
        <name>Reaction Structure</name>
        <sourcecode type="json"><![CDATA[
{
  "type": 1,
  "value": "thumbs-up",
  "ts": 1715788800000,
  "sender": {
    "userId": "<obtained via credential, see MOCHA-IDENTITY>",
    "devId": "<obtained via credential, see MOCHA-IDENTITY>"
  },
  "target": {
    "msgId": "a1b2c3...f0a1b2"
  },
  "ext": {}
}
]]></sourcecode>
      </section>
      <section anchor="fields">
        <name>Fields</name>
        <dl>
          <dt>type (REQUIRED):</dt>
          <dd>
            <t>Integer reaction type. See <xref target="reaction-types"/>.</t>
          </dd>
          <dt>value (REQUIRED):</dt>
          <dd>
            <t>String identifying the specific reaction (e.g.,
"thumbs-up", "fire", "raise").</t>
          </dd>
          <dt>ts (REQUIRED):</dt>
          <dd>
            <t>Creation time in milliseconds since Unix epoch.</t>
          </dd>
          <dt>sender (REQUIRED):</dt>
          <dd>
            <t>Object with userId and devId fields.</t>
          </dd>
          <dt>target (OPTIONAL):</dt>
          <dd>
            <t>Object with msgId field (hex-encoded MsgID per
<xref target="MOCHA-CHAT"/>). Present for message-targeted reactions;
absent for standalone reactions. {#target-field}</t>
          </dd>
          <dt>ext (OPTIONAL):</dt>
          <dd>
            <t>Extension fields. Implementations MUST ignore unknown keys.</t>
          </dd>
        </dl>
      </section>
      <section anchor="reaction-types">
        <name>Reaction Types</name>
        <table>
          <thead>
            <tr>
              <th align="left">Value</th>
              <th align="left">Name</th>
              <th align="left">Description</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">1</td>
              <td align="left">emoji</td>
              <td align="left">Emoji reaction (heart, fire, thumbs-up)</td>
            </tr>
            <tr>
              <td align="left">2</td>
              <td align="left">vote</td>
              <td align="left">Poll or vote response</td>
            </tr>
            <tr>
              <td align="left">3</td>
              <td align="left">raise</td>
              <td align="left">Raise/lower hand</td>
            </tr>
            <tr>
              <td align="left">4</td>
              <td align="left">applause</td>
              <td align="left">Applause or cheer</td>
            </tr>
            <tr>
              <td align="left">5</td>
              <td align="left">custom</td>
              <td align="left">Application-defined reaction</td>
            </tr>
          </tbody>
        </table>
        <t>Extensible via IANA registry.</t>
      </section>
      <section anchor="value-encoding">
        <name>Reaction Value Encoding</name>
        <t>Each reaction type defines integer encodings for its values:</t>
        <t>Emoji (type 1):</t>
        <table>
          <thead>
            <tr>
              <th align="left">Integer</th>
              <th align="left">Value</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">1</td>
              <td align="left">thumbs-up</td>
            </tr>
            <tr>
              <td align="left">2</td>
              <td align="left">thumbs-down</td>
            </tr>
            <tr>
              <td align="left">3</td>
              <td align="left">heart</td>
            </tr>
            <tr>
              <td align="left">4</td>
              <td align="left">fire</td>
            </tr>
            <tr>
              <td align="left">5</td>
              <td align="left">laugh</td>
            </tr>
            <tr>
              <td align="left">6</td>
              <td align="left">sad</td>
            </tr>
            <tr>
              <td align="left">7</td>
              <td align="left">wow</td>
            </tr>
            <tr>
              <td align="left">8</td>
              <td align="left">clap</td>
            </tr>
            <tr>
              <td align="left">9</td>
              <td align="left">thinking</td>
            </tr>
            <tr>
              <td align="left">10</td>
              <td align="left">eyes</td>
            </tr>
          </tbody>
        </table>
        <t>TODO: The range of emoji values to be supported is not clear
at this point and further discussion is needed.</t>
        <t>Values 11-127 are reserved for future standard emoji.
Values 128+ are available for application-defined emoji.</t>
        <t>Raise (type 3):</t>
        <table>
          <thead>
            <tr>
              <th align="left">Integer</th>
              <th align="left">Value</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">1</td>
              <td align="left">raise</td>
            </tr>
            <tr>
              <td align="left">2</td>
              <td align="left">lower</td>
            </tr>
          </tbody>
        </table>
        <t>Vote (type 2) and Applause (type 4) value encodings are
application-defined.</t>
      </section>
      <section anchor="reaction-removal">
        <name>Reaction Removal</name>
        <t>To retract a reaction, a device publishes an object with the
same type, value, and target, plus <tt>"remove": true</tt>. The
receiver removes the matching reaction from display.</t>
      </section>
    </section>
    <section anchor="sending">
      <name>Sending Reactions</name>
      <t>To send a reaction, a device publishes a MOQT object to its
track within the reactions namespace.</t>
      <section anchor="rate-limiting">
        <name>Rate Limiting</name>
        <ul spacing="normal">
          <li>
            <t>Message-targeted: At most 1 reaction of a given type per
message per device (newer replaces older).</t>
          </li>
          <li>
            <t>Standalone: At most 1 reaction per second per device.</t>
          </li>
        </ul>
        <t>Relays MAY enforce rate limits and drop excess objects.</t>
      </section>
    </section>
    <section anchor="receiving">
      <name>Receiving Reactions</name>
      <t>A participant discovers reaction tracks via
SUBSCRIBE_NAMESPACE on the reactions namespace prefix,
then subscribes to the announced tracks.</t>
      <section anchor="processing-message-targeted-reactions">
        <name>Processing Message-Targeted Reactions</name>
        <ol spacing="normal" type="1"><li>
            <t>Look up the referenced MsgID in the local message store.</t>
          </li>
          <li>
            <t>Display the reaction on that message.</t>
          </li>
          <li>
            <t>Same sender + same type + same target: newer replaces older.</t>
          </li>
          <li>
            <t>If remove=true, remove the matching reaction.</t>
          </li>
        </ol>
      </section>
      <section anchor="processing-standalone-reactions">
        <name>Processing Standalone Reactions</name>
        <ol spacing="normal" type="1"><li>
            <t>Display as a transient signal (e.g., floating emoji,
applause indicator).</t>
          </li>
          <li>
            <t>For raise-hand: maintain a queue until "lower" is received.</t>
          </li>
        </ol>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>TODO</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>TODO</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-normative-references">
      <name>Normative References</name>
      <reference anchor="MoQTransport">
        <front>
          <title>Media over QUIC Transport</title>
          <author fullname="Suhas Nandakumar" initials="S." surname="Nandakumar">
            <organization>Cisco</organization>
          </author>
          <author fullname="Victor Vasiliev" initials="V." surname="Vasiliev">
            <organization>Google</organization>
          </author>
          <author fullname="Ian Swett" initials="I." surname="Swett">
            <organization>Google</organization>
          </author>
          <author fullname="Alan Frindell" initials="A." surname="Frindell">
            <organization>Meta</organization>
          </author>
          <date day="12" month="May" year="2026"/>
          <abstract>
            <t>   This document defines Media over QUIC Transport (MOQT), a publish/
   subscribe protocol that runs over QUIC and WebTransport.  MOQT
   leverages the features of these transports, such as streams,
   datagrams, priorities, and partial reliability.  MOQT operates both
   point-to-point and through intermediate relays, enabling scalable
   low-latency delivery.  Despite its name, MOQT is media agnostic and
   can be used for a wide range of use cases.

            </t>
          </abstract>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-moq-transport-18"/>
      </reference>
      <reference anchor="MOCHA">
        <front>
          <title>*** BROKEN REFERENCE ***</title>
          <author>
            <organization/>
          </author>
          <date/>
        </front>
      </reference>
      <reference anchor="MOCHA-ARCH">
        <front>
          <title>*** BROKEN REFERENCE ***</title>
          <author>
            <organization/>
          </author>
          <date/>
        </front>
      </reference>
      <reference anchor="MOCHA-CHAT">
        <front>
          <title>*** BROKEN REFERENCE ***</title>
          <author>
            <organization/>
          </author>
          <date/>
        </front>
      </reference>
      <reference anchor="MOCHA-IDENTITY">
        <front>
          <title>*** BROKEN REFERENCE ***</title>
          <author>
            <organization/>
          </author>
          <date/>
        </front>
      </reference>
      <reference anchor="JSON">
        <front>
          <title>The JavaScript Object Notation (JSON) Data Interchange Format</title>
          <author fullname="T. Bray" initials="T." role="editor" surname="Bray"/>
          <date month="December" year="2017"/>
          <abstract>
            <t>JavaScript Object Notation (JSON) is a lightweight, text-based, language-independent data interchange format. It was derived from the ECMAScript Programming Language Standard. JSON defines a small set of formatting rules for the portable representation of structured data.</t>
            <t>This document removes inconsistencies with other specifications of JSON, repairs specification errors, and offers experience-based interoperability guidance.</t>
          </abstract>
        </front>
        <seriesInfo name="STD" value="90"/>
        <seriesInfo name="RFC" value="8259"/>
        <seriesInfo name="DOI" value="10.17487/RFC8259"/>
      </reference>
      <reference anchor="RFC2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author fullname="S. Bradner" initials="S." surname="Bradner"/>
          <date month="March" year="1997"/>
          <abstract>
            <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
        <seriesInfo name="DOI" value="10.17487/RFC2119"/>
      </reference>
      <reference anchor="RFC8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author fullname="B. Leiba" initials="B." surname="Leiba"/>
          <date month="May" year="2017"/>
          <abstract>
            <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
        <seriesInfo name="DOI" value="10.17487/RFC8174"/>
      </reference>
    </references>
    <?line 255?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO</t>
    </section>
  </back>
  <!-- ##markdown-source:
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

-->

</rfc>
