<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc [
<!ENTITY nbsp "&#160;">
<!ENTITY zwsp "&#8203;">
<!ENTITY nbhy "&#8209;">
<!ENTITY wj "&#8288;">
]>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ietf-calext-jscontact-profiles-01" submissionType="IETF" consensus="true" category="std" xml:lang="en" obsoletes="" updates="" tocInclude="true" symRefs="true" sortRefs="true" version="3">
  <front>
    <title abbrev="JSContact Profiles">Protocol-Specific Profiles for JSContact</title>
    <seriesInfo name="RFC" value="draft-ietf-calext-jscontact-profiles-01"/>
    <author initials="R." surname="Stepanek" fullname="Robert Stepanek">
      <organization>Fastmail</organization>
      <address>
        <postal>
          <extaddr>PO Box 234</extaddr>
          <street>Collins St. West</street>
          <city>Melbourne</city>
          <region>VIC</region>
          <code>8007</code>
          <country>Australia</country>
          <region/>
        </postal>
        <email>rsto@fastmailteam.com</email>
      </address>
    </author>
    <author initials="M." surname="Loffredo" fullname="Mario Loffredo">
      <organization>IIT-CNR</organization>
      <address>
        <postal>
          <street>Via Moruzzi, 1</street>
          <city>Pisa</city>
          <code>56124</code>
          <country>Italy</country>
          <region/>
        </postal>
        <email>mario.loffredo@iit.cnr.it</email>
      </address>
    </author>
    <date year="2025" month="June" day="4"/>
    <area>art</area>
    <workgroup>calext</workgroup>
    <keyword>JSContact</keyword>
    <abstract>
      <t>This document defines JSContact profiles, a named subsets of JSContact elements that are supported in context of a contact data exchange protocol or other use case. It aims to facilitate using JSContact in contexts where supporting all of JSContact semantics is not appropriate.</t>
    </abstract>
  </front>
  <middle>
    <section anchor="notational-conventions" numbered="true" toc="default">
      <name>Notational Conventions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14> SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14> RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as described in BCP 14 <xref target="RFC2119" format="default" sectionFormat="of" derivedContent="RFC2119"/> <xref target="RFC8174" format="default" sectionFormat="of" derivedContent="RFC8174"/> when, and only when, they appear in all capitals, as shown here.</t>
      <t>The ABNF definitions in this document use the notations of <xref target="RFC5234"/>. ABNF rules not defined in this document are defined in either <xref target="RFC5234"/> (such as the ABNF for CRLF, WSP, DQUOTE, VCHAR, ALPHA, and DIGIT) or <xref target="RFC6350"/>.</t>
    </section>
    <section anchor="introduction" numbered="true" toc="default">
      <name>Introduction</name>
      <t>The <xref target="RFC9553">JSContact</xref> contact card data model and format is designed for use in address book applications and directory services. Intended as an alternative to the prevalent <xref target="RFC6350">vCard</xref> data format, it covers vCard core semantics and extensions, and provides a rich model for personal names, postal addresses and localization. All JSContact elements are relevant for some contact card use case and, similar to vCard, implementations are expected to support these elements when exchanging contact card information using protocols such as <xref target="RFC6352">CardDAV</xref> and <xref target="RFC9610">JMAP for Contacts</xref>.</t>
      <t>In contrast, other protocols and internet standards might require to exchange <em>some</em> contact card information, but not need all of what JSContact provides. <xref target="RFC9553" section="1.7.4"/> outlines how JSContact implementations may ignore unknown JSContact elements, but this only applies to future extensions of <xref target="RFC9553"/>; they are still expected to implement all elements of the core specification. Also, the extensibility of JSContact and the requirement to preserve arbitrary contact elements might not be adequate for some protocols.</t>
      <t>To make use of JSContact under these circumstances, this document defines a new IANA registry for JSContact that allows to register named subsets of JSContact elements. These subsets are referred to as "JSContact profiles" and are meant to bring the following benefits:</t>
      <ul>
        <li>Protocol designers might be encouraged to use JSContact, rather than coming up with their own contacts format. This facilitates cross-protocol data exchange and migration.</li>
        <li>Different protocols use the same IANA registry to express which JSContact elements they support. This facilitates understanding their commonalities and reusing existing profiles.</li>
        <li>A central registry provides implementors of JSContact libraries with a consistent format documenting which profile supports what elements, rather than having to look up that information from possibly distinctly organized internet drafts.</li>
      </ul>
      <t>This document is organized as follows: <xref target="jscontact-profiles"/> defines JSContact profiles, <xref target="example"/> illustrates JSContact profiles by example, <xref target="iana-considerations"/> summarizes the relevant information for IANA to establish the JSContact Profiles registry.</t>
    </section>
    <section anchor="jscontact-profiles">
      <name>JSContact Profiles</name>
      <t>A JSContact profile is a named subset of JSContact properties. The JSContact properties <bcp14>MUST</bcp14> be registered in the IANA JSContact registry. A JSContact extension <bcp14>MAY</bcp14> define both a new profile and new properties, as long as they are registered at the same time.</t>
      <t>A JSContact object conforms to a profile if all its properties are in the subset of properties defined by that profile and its property values comply with the profile restrictions.</t>
      <t>A JSContact profile <bcp14>MUST</bcp14> be registered at IANA (see <xref target="iana-considerations"/>).</t>
      <section anchor="name">
        <name>Profile Name</name>
        <t>A JSContact profile <bcp14>MUST</bcp14> have a unique name. The name <bcp14>MUST</bcp14> only contain ASCII lowercase alphabetic and numeric characters, optionally separated by a hyphen. Formally, it <bcp14>MUST</bcp14> be a valid "profile-name" defined in the appendix section in <xref target="profile-name-abnf"/>.</t>
      </section>
      <section anchor="version">
        <name>Profile Version</name>
        <t>A JSContact profile <bcp14>MUST</bcp14> define its current version. That version identifier <bcp14>MUST</bcp14> be a valid "jsversion" value as defined in <xref target="RFC9553" section="1.9.1"/>. Any addition to the list of <xref target="properties">JSContact properties supported by that profile</xref> <bcp14>MUST</bcp14> update the current version.</t>
        <t>Should the semantic versioning scheme not be adequate for protocol designers making use of JSContact profiles, then an alternative approach is to register a new JSContact profile for each new version.</t>
      </section>
      <section anchor="properties">
        <name>Supported Properties</name>
        <t>The subset of JSContact object properties supported by a profile is defined by a list of object properties. A JSContact property of an object type is part of this subset if one of the following conditions apply:</t>
        <ol>
          <li>It explicitly is listed as supported for that object type in that profile.</li>
          <li>It is defined for an object type which is the value type of an explicitly listed property and no properties are listed explicitly for this object type.</li>
          <li>It is defined for the Card object and no properties are listed explicitly for the Card object type.</li>
        </ol>
        <t>A profile <bcp14>MUST</bcp14> explicitly list at least one property.</t>
        <t>If at least one property is listed explicitly for an object type, then all mandatory properties of that object type <bcp14>MUST</bcp14> be listed (this is to allow a profile restrict an object type to only its mandatory properties).</t>
        <t>The following properties need not be listed, they are always supported:</t>
        <ul>
          <li>The "@type" of any object type that is supported by this profile.</li>
          <li>The "version" property of the Card object.</li>
        </ul>
        <t>In contrast, a profile <bcp14>MUST NOT</bcp14> define mandatory properties to be optional. It also <bcp14>MUST NOT</bcp14> fully replace or expand the value type signature of a property, or change the default type of a multi-typed property.</t>
      </section>
      <section anchor="patchobject">
        <name>PatchObject Keys</name>
        <t>The JSContact <xref target="RFC9553" section="1.4.3" sectionFormat="parens">PatchObject value type</xref> allows to patch both top-level properties and nested properties in a Card object. This results in a compact representation, as only the actually changed property values are included in the patch. Notably, the <xref target="RFC9553" section="2.7.1" sectionFormat="parens">"localizations" property</xref> of the Card object uses PatchObject values to localize Card properties.</t>
        <t>Yet, protocol designers might prefer not to support patching nested properties, typically the goal being to simplify the processing of JSContact data. For this, a JSContact profile <bcp14>MAY</bcp14> define nested PatchObject keys to not be supported. Each JSON Pointer key in a PatchObject then <bcp14>MUST</bcp14> consist of exactly one <xref target="RFC6901" section="3" sectionFormat="parens">JSON Pointer reference token</xref>. In context of the "localizations" property, this means that a localized Card replaces one or more top-level properties entirely.</t>
      </section>
    </section>
    <section anchor="example">
      <name>Example Profile</name>
      <t>This section provides an example for a JSContact profile. This profile is just for illustration, it is not registered at IANA.</t>
      <dl newline="true">
        <dt>Name:</dt>
        <dd>jscontact-simple</dd>
        <dt>Profile Version:</dt>
        <dd>1.0</dd>
        <dt>Nested PatchObject Keys:</dt>
        <dd>Not Supported</dd>
        <dt>Property Registry:</dt>
        <dd>
          <table>
            <name>Properties of the "jscontact-simple" profile</name>
            <thead>
              <tr>
                <th>Property Name</th>
                <th>Property Context</th>
                <th>Restricted to be Mandatory</th>
                <th>Restricted Property Type</th>
                <th>Since Profile Version</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>addresses</td>
                <td>Card</td>
                <td/>
                <td/>
                <td>1.0</td>
              </tr>
              <tr>
                <td>emails</td>
                <td>Card</td>
                <td/>
                <td/>
                <td>1.0</td>
              </tr>
              <tr>
                <td>kind</td>
                <td>Card</td>
                <td/>
                <td/>
                <td>1.0</td>
              </tr>
              <tr>
                <td>localizations</td>
                <td>Card</td>
                <td/>
                <td/>
                <td>1.0</td>
              </tr>
              <tr>
                <td>name</td>
                <td>Card</td>
                <td/>
                <td/>
                <td>1.0</td>
              </tr>
              <tr>
                <td>full</td>
                <td>Address</td>
                <td>Mandatory</td>
                <td/>
                <td>1.0</td>
              </tr>
              <tr>
                <td>components</td>
                <td>Name</td>
                <td/>
                <td/>
                <td>1.0</td>
              </tr>
              <tr>
                <td>full</td>
                <td>Name</td>
                <td/>
                <td/>
                <td>1.0</td>
              </tr>
              <tr>
                <td>kind</td>
                <td>NameComponent</td>
                <td/>
                <td/>
                <td>1.0</td>
              </tr>
              <tr>
                <td>value</td>
                <td>NameComponent</td>
                <td/>
                <td/>
                <td>1.0</td>
              </tr>
            </tbody>
          </table>
        </dd>
      </dl>
      <t>This profile describes contact cards that can only contain:</t>
      <ul>
        <li>Full postal address lines, but no address components or any other property of the Address object type.</li>
        <li>Full names and distinct name components, but no other properties of the Name object type.</li>
        <li>Email addresses, where all properties of the EmailAddress object are supported.</li>
        <li>Localizations, with the restriction that PatchObject keys must not patch nested properties.</li>
      </ul>
      <t>The following Card object conforms to that profile:</t>
      <sourcecode type=""><![CDATA[
{
  "@type": "Card",
  "version": "1.0",
  "name": {
     "components": [
      { "kind": "given", "value": "Akiyo" },
      { "kind": "surname", "value": "Murakami" }
    ]
  },
  "addresses": {
    "a1": {
      "full": "71 Cherry Court, Somewhere, 123SO, UK"
    }
  },
  "emails": {
    "e1": {
      "address": "akiyo@example.com"
    }
  },
  "localizations": {
    "jp": {
      "name": {
        "components": [
         { "kind": "surname", "value": "村上" },
         { "kind": "given", "value": "啓代" }
        ]
      }
    }
  }
}
]]></sourcecode>
    </section>
    <section anchor="iana-considerations" numbered="true" toc="default">
      <name>IANA Considerations</name>
      <t>TBD</t>
    </section>
    <section anchor="security-considerations" numbered="true" toc="default">
      <name>Security Considerations</name>
      <t>This document does not provide new security considerations. The security considerations of <xref target="RFC9553" section="4" sectionFormat="of"/> apply.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5234.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6350.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6352.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6901.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9553.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9610.xml"/>
      </references>
    </references>
    <section>
      <name>ABNF definition for JSContact Profile Name</name>
      <figure anchor="profile-name-abnf">
        <name>ABNF Rule for JSContact Profile Name</name>
        <sourcecode name="" type="abnf"><![CDATA[
profile-name = LALPHA *[ ["-"] LALPHA ]

LALPHA       = %x61-7A | DIGIT  ; a-z or 0-9
]]></sourcecode>
      </figure>
    </section>
  </back>
</rfc>
