No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

xep-0366.xml 25KB

  1. <?xml version='1.0' encoding='UTF-8'?>
  2. <!DOCTYPE xep SYSTEM 'xep.dtd' [
  3. <!ENTITY % ents SYSTEM 'xep.ent'>
  4. %ents;
  5. ]>
  6. <?xml-stylesheet type='text/xsl' href='xep.xsl'?>
  7. <xep>
  8. <header>
  9. <title>Entity Versioning</title>
  10. <abstract>
  11. A method by which lists of items may be versioned so that servers will not
  12. need to send the entire list if it has not been modified, saving bandwidth
  13. and time with minimal state being stored by the server and client.
  14. </abstract>
  16. <number>0366</number>
  17. <status>Deferred</status>
  18. <type>Standards Track</type>
  19. <sig>Standards</sig>
  20. <approver>Council</approver>
  21. <dependencies>
  22. <spec>RFC 6120</spec>
  23. <spec>RFC 6121</spec>
  24. </dependencies>
  25. <supersedes />
  26. <supersededby />
  27. <shortname>EV</shortname>
  28. &sam;
  29. <revision>
  30. <version>0.1.2</version>
  31. <date>2016-12-21</date>
  32. <initials>ssw</initials>
  33. <remark><p>Spelling, tone, and grammar.</p></remark>
  34. </revision>
  35. <revision>
  36. <version>0.1.1</version>
  37. <date>2016-07-11</date>
  38. <initials>ssw</initials>
  39. <remark><p>Typo fixes.</p></remark>
  40. </revision>
  41. <revision>
  42. <version>0.1</version>
  43. <date>2015-12-15</date>
  44. <initials>XEP Editor (mam)</initials>
  45. <remark><p>Initial published version approved by the XMPP Council.</p></remark>
  46. </revision>
  47. <revision>
  48. <version>0.0.2</version>
  49. <date>2015-09-17</date>
  50. <initials>ssw</initials>
  51. <remark><p>Add profiles / partial sync.</p></remark>
  52. </revision>
  53. <revision>
  54. <version>0.0.1</version>
  55. <date>2015-08-25</date>
  56. <initials>ssw</initials>
  57. <remark><p>First draft</p></remark>
  58. </revision>
  59. </header>
  60. <section1 topic='Introduction' anchor='intro'>
  61. <p>
  62. This problem of "downloading the world" (downloading the entire roster
  63. every time a session is initialized, or receiving an entire disco items
  64. response every time a MUC list is queried, etc.) was partially addressed by
  65. &xep0237; which was later merged into &rfc6121; §2.6. While this solved
  66. the problem for the roster, it did not account for other entities.
  67. Furthermore, roster versioning requires that the server maintain a great
  68. deal of state (roster items which should be pushed for each entity on
  69. reconnect, monotonically increasing counters, etc.) which can be difficult
  70. to store or synchronize in a large, distributed system.
  71. This XEP defines a method by which generic entity lists can be versioned and
  72. cached which is optimized for distributed systems with large entity lists,
  73. but which works equally well on small, single server deployments.
  74. </p>
  75. </section1>
  76. <section1 topic='Requirements' anchor='reqs'>
  77. <ul>
  78. <li>
  79. An extra round trip MUST NOT be required to initiate entity versioning.
  80. </li>
  81. <li>
  82. Clients that do not implement this protocol (but which use servers that
  83. do) MUST still be able to request and receive entities normally.
  84. </li>
  85. <li>
  86. Servers which implement this protocol MUST NOT be required to store
  87. multiple versions of an entity list or maintain other redundant state.
  88. </li>
  89. <li>
  90. Inconsistent state between servers in a cluster should not cause cache
  91. invalidation for the entire entity list.
  92. </li>
  93. <li>
  94. Large changes SHOULD NOT be required for existing servers / clients.
  95. </li>
  96. </ul>
  97. </section1>
  98. <section1 topic='Glossary' anchor='glossary'>
  99. <dl>
  100. <di>
  101. <dt>Aggregate Token</dt>
  102. <dd>
  103. A hash which represents the state of a list of entities, and changes if
  104. any of the entities change.
  105. </dd>
  106. </di>
  107. <di>
  108. <dt>Versioned Entity</dt>
  109. <dd>Any object which may be versioned (eg. rooms, users).</dd>
  110. </di>
  111. <di>
  112. <dt>Version Token</dt>
  113. <dd>
  114. A short, case sensitive string which represents an entity and changes if
  115. that entity changes.
  116. </dd>
  117. </di>
  118. </dl>
  119. </section1>
  120. <section1 topic='Use Cases' anchor='use_cases'>
  121. <section2 topic='Clients' anchor='client_use_cases'>
  122. <ul>
  123. <li>
  124. A client on a mobile device where bandwidth and throughput are limited
  125. has a very large roster which cause connecting to take an unacceptable
  126. amount of time.
  127. With entity versioning, subsequent connections after the first do not
  128. take as long, and use less bandwidth.
  129. </li>
  130. <li>
  131. A client often wants to view the list of multi-user chat rooms
  132. available on a servers MUC service. However, the list is very long and
  133. takes a long time to download. After enabling entity versioning the
  134. client can fetch the list, and then poll for changes at a later date
  135. without re-requesting the entire list.
  136. </li>
  137. <li>
  138. A client wishes to cache the features supported by servers of the
  139. contacts in their roster since their disco items is not likely to
  140. change often.
  141. </li>
  142. </ul>
  143. </section2>
  144. <section2 topic='Servers' anchor='server_use_cases'>
  145. <ul>
  146. <li>
  147. A server is running in an environment where storing multiple versions
  148. of each users roster may put too much pressure on the storage backend.
  149. After enabling entity versioning, they only have to store a small token
  150. per user and can calculate the diffs to send to the client afterwards.
  151. </li>
  152. <li>
  153. A server maintains an out-of-band HTTP API for fetching information
  154. about MUC rooms to display on their web page. They wish to use a
  155. reverse proxy to cache API requests based on etags. Instead of
  156. attempting to check if the backend page has changed and generate etags,
  157. the room's entity version token is used as a weakly-validated ETag.
  158. </li>
  159. </ul>
  160. </section2>
  161. </section1>
  162. <section1 topic='Entity Versioning Profiles' anchor='profiles'>
  163. <p>
  164. Because entity versioning is designed to be a generic system for syncing
  165. any sort of list in XMPP, and the format and requirements of various entity
  166. lists may vary greatly, no specific wire format is defined in this
  167. specification. Instead, the specifics for various lists will be left up to
  168. separate XEPs which will define entity versioning "profiles" which must be
  169. registered with the XMPP registrar. These profiles will define exactly how
  170. version tokens are represented in the specific list format for which they
  171. wish to use entity versioning. The rest of this document will provide
  172. details about entity versioning which will be common to all entity
  173. versioning profiles and do not need to be redefined in EV profile XEPs. It
  174. will also define an EV profile for fetching the roster.
  175. </p>
  176. <p>
  177. The roster entity versioning profile which is used as an example throughout
  178. this document will use the namespace 'urn:xmpp:entityver:profile:roster:0'
  179. as described in the <link url="#registrar">XMPP Registrar
  180. Considerations</link> section of this document.
  181. </p>
  182. </section1>
  183. <section1 topic='Discovering Support' anchor='disco'>
  184. <p>
  185. If a server supports entity versioning, it MUST inform the connecting
  186. client when returning stream features during the stream negotiation
  187. process. This is done by including a &lt;ver/&gt; element, qualified by the
  188. 'urn:xmpp:entityver:0' namespace with child &lt;profile&gt; nodes for each
  189. supported entity versioning profile. At the latest, this SHOULD be done
  190. when informing a client that resource binding is required. For example if
  191. the server only supports versioning of rosters it might return:
  192. </p>
  193. <example caption="Stream Features"><![CDATA[
  194. <stream:features>
  195. <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
  196. <required/>
  197. </bind>
  198. <ver xmlns='urn:xmpp:entityver:0'>
  199. <profile xmlns='urn:xmpp:entityver:profile:roster:0'/>
  200. </ver>
  201. </stream:features>
  202. ]]></example>
  203. <p>
  204. The entity versioning stream feature is merely informative and therefore
  205. is never mandatory-to-negotiate.
  206. </p>
  207. <p>
  208. Clients, servers, and other entities that support &xep0030; and entity
  209. versioning must respond to service discovery requests with a feature of
  210. 'urn:xmpp:entityver:0' and with a feature for each EV profile supported by
  211. the responding entity as described in the relavant specifications. Eg. a
  212. response from a server that supports roster versioning for the requesting
  213. entity might look like the following:
  214. </p>
  215. <example caption="Service discovery information response"><![CDATA[
  216. <iq from='shakespeare.lit'
  217. id='ku6e51v3'
  218. to='kingclaudius@shakespeare.lit/castle'
  219. type='result'>
  220. <query xmlns=''>
  221. <feature var='urn:xmpp:entityver:0'/>
  222. <feature var='urn:xmpp:entityver:profile:roster:0'/>
  223. </query>
  224. </iq>]]></example>
  225. </section1>
  226. <section1 topic='Entity Sync' anchor='entity_sync'>
  227. <section2 topic='Version Tokens' anchor='version_tokens'>
  228. <p>
  229. Version tokens are short case-sensitive strings which are generated by
  230. the server. Their format is not defined in this spec, but a
  231. recommendation may be found in the <link url="#impl">Implementation
  232. Notes</link>. Version tokens are akin to a weakly-validated etag for the
  233. entity in question.
  234. </p>
  235. <p>
  236. Servers that implement this protocol must assign such a version token to
  237. each entity that is controlled by the server.
  238. The server SHOULD then update this version every time any mutable property
  239. of the entity changes (eg. when the subscription status of a user
  240. changes).
  241. The server MAY choose to update this token at any time (to force the
  242. clients to invalidate their cached representation of the object).
  243. This version token MUST then be included with every object representation
  244. of that entity transmitted in the stream.
  245. This is done by including a sub-node called "version" qualified by the
  246. entity versioning XML namespace defined in this document.
  247. Similarly, clients MAY also add version nodes for each version token they
  248. possess to the request for a list (not specifying a version token will
  249. force the server to send information on that entity to the client).
  250. If a client sends up a list of version tokens, the server MUST then check
  251. to see if those tokens correspond to any entity which it knows about, and
  252. not send down any entities with matching version tokens in the response.
  253. </p>
  254. <p>
  255. For example, a versioned roster request might look like this:
  256. </p>
  257. <example caption="Roster Request"><![CDATA[
  258. <!-- Client -->
  259. <iq from='romeo@montague.lit/home' id='56' to='romeo@montague.lit' type='get'>
  260. <query xmlns='jabber:iq:roster'>
  261. <item jid='bill@shakespeare.lit'>
  262. <version xmlns='urn:xmpp:entityver:0'>25P2A7H8</version>
  263. </item>
  264. <item jid='anne@shakespeare.lit'>
  265. <version xmlns='urn:xmpp:entityver:0'>VIZSVF0D</version>
  266. </item>
  267. </query>
  268. </iq>
  269. <!-- Server -->
  270. <iq from='romeo@montague.lit' id='56' to='romeo@montague.lit/home' type='result>
  271. <query xmlns='jabber:iq:roster'>
  272. <item subscription='both' jid='bill@shakespeare.lit'>
  273. <version xmlns='urn:xmpp:entityver:0'>9ZFZXVP9</version>
  274. </item>
  275. </query>
  276. </iq>]]></example>
  277. <p>
  278. Note that in this case there may be three roster items total (and the
  279. client only knows about two of them), or there may be two total roster
  280. items and the server is informing the client about a change to
  281. "bill@shakespeare.lit". Version tokens MUST also be present in roster
  282. pushes:
  283. </p>
  284. <example caption="Roster Push"><![CDATA[
  285. <iq from='romeo@montague.lit' id='ah382g678jka7' to='romeo@montague.lit/home' type='set'>
  286. <query xmlns='jabber:iq:roster' ver='ver34'>
  287. <item jid='tybalt@shakespeare.lit' subscription='remove'>
  288. <version xmlns='urn:xmpp:entityver:0'>XWE4MUUP</version>
  289. </item>
  290. </query>
  291. </iq>
  292. ]]></example>
  293. </section2>
  294. <section2 topic='Cache Invalidation' anchor='deletes'>
  295. <p>
  296. When a client syncs with the server and indicates that it has a version
  297. token in its cache that does not match any entity on the server (or when
  298. the server wants to remove an entity from the clients cache for any other
  299. reason), the server MUST reply with an empty &lt;version/&gt; node. When
  300. the client receives such an empty version node it SHOULD purge the entity
  301. from its cache. For example, the following would remove the roster item
  302. 'bill@shakespeare.lit' from the cache:
  303. </p>
  304. <example caption="Cache invalidation"><![CDATA[
  305. <iq from='romeo@montague.lit' id='56' to='romeo@montague.lit/home' type='result>
  306. <query xmlns='jabber:iq:roster'>
  307. <item subscription='both' jid='bill@shakespeare.lit'>
  308. <version xmlns='urn:xmpp:entityver:0'/>
  309. </item>
  310. </query>
  311. </iq>]]></example>
  312. <p>
  313. Roster pushes that indicate a deleted item MUST also remove the version
  314. from the cache (and need not contain an empty &lt;version/&gt; element).
  315. </p>
  316. </section2>
  317. <section2 topic='Partial sync'>
  318. <p>
  319. For very large groups fetching an entire list may not be practical or
  320. necessary. For example, one might imagine a large corporation with a
  321. shared roster that is too large for its version tokens to be sent up to
  322. the server on every sync, or even to download fully the first time. To
  323. solve this, servers MAY choose to send down only a part of an entity list
  324. in response to a query (unless the individual EV profile forbids partial
  325. list sync). How servers choose what items to return is an implementation
  326. detail that is out of the scope of this document. Some suggestions may be
  327. found in the <link url="#impl">Implementation Notes</link>. On subsequent
  328. requests for the entity list, the server MAY choose to return more
  329. entities (eg. based on changes in its internal selection criteria),
  330. however it MUST NOT invalidate cached entities unless they have actually
  331. been removed from the list.
  332. </p>
  333. <p>
  334. XEPs defining entity versioning profiles MUST include a section to
  335. indicate if partial sync is supported, and if so, how it will be
  336. indicated to the client (and how the client can request a full list). If
  337. no mechanism is specified, this is done by adding a boolean "full_list"
  338. attribute to the request, eg. a roster request for a partial list looks
  339. like:
  340. </p>
  341. <example caption="Roster Request"><![CDATA[
  342. <!-- Client -->
  343. <iq from='romeo@montague.lit/home'
  344. id='56'
  345. to='romeo@montague.lit'
  346. type='get'>
  347. <query xmlns='jabber:iq:roster' full_list='false'>
  348. <item jid='bill@shakespeare.lit'>
  349. <version xmlns='urn:xmpp:entityver:0'>25P2A7H8</version>
  350. </item>
  351. <item jid='anne@shakespeare.lit'>
  352. <version xmlns='urn:xmpp:entityver:0'>VIZSVF0D</version>
  353. </item>
  354. </query>
  355. </iq>
  356. <!-- Server -->
  357. <iq from='romeo@montague.lit' id='56' to='romeo@montague.lit/home' type='result'>
  358. <query xmlns='jabber:iq:roster' full_list='false'>
  359. <item subscription='both' jid='bill@shakespeare.lit'>
  360. <version xmlns='urn:xmpp:entityver:0'>9ZFZXVP9</version>
  361. </item>
  362. </query>
  363. </iq>]]></example>
  364. <p>
  365. When making a request for a partial list, clients do not need to send up
  366. every entity in their cache. Instead they MAY send up just those entities
  367. for which they wish to check for updates. The server MUST then respond
  368. with any updates for those entities, and MAY also add other entities to
  369. the list if desired. If the client requests a partial list but does not
  370. indicate that it has anything in its cache, what entities to return (if
  371. any) is left up to the server implementation.
  372. </p>
  373. </section2>
  374. <section2 topic='List search'>
  375. <p>
  376. When a client has an incomplete versioned list, it may be beneficial to
  377. download more of the list without requesting the full list. To do this,
  378. servers which support entity versioning MUST supply a "search" IQ which
  379. can be used to discover list items matching a certain criteria. What data
  380. to match on (JID, metadata, associated vcards, etc.), and what type of
  381. search are left up to the server implementation and MAY be different
  382. between profiles.
  383. </p>
  384. <p>
  385. Search queries are qualified by the 'urn:xmpp:entityver:0:search'
  386. namespace and MUST have a 'profile' attribute set to the namespace for
  387. which the search is being performed. For instance, searching the roster
  388. looks like the following:
  389. </p>
  390. <example caption="Roster search"><![CDATA[
  391. <!-- Client -->
  392. <iq from='romeo@montague.lit/home'
  393. id='564'
  394. to='romeo@montague.lit'
  395. type='get'>
  396. <query xmlns="urn:xmpp:entityver:0:search" profile='urn:xmpp:entityver:profile:roster:0'>
  397. Search term
  398. </query>
  399. </iq>
  400. <!-- Server -->
  401. <iq from='romeo@montague.lit' id='564' to='romeo@montague.lit/home' type='result'>
  402. <query xmlns="urn:xmpp:entityver:0:search" profile='urn:xmpp:entityver:profile:roster:0' type='result'>
  403. <item subscription='both' jid='matching_search@term.lit'>
  404. <version xmlns='urn:xmpp:entityver:0'>4YAZ7Y38</version>
  405. </item>
  406. </query>
  407. </iq>]]></example>
  408. <p>
  409. Search results SHOULD be added to the given list's cache. In this way,
  410. the full list does not need to be known.
  411. </p>
  412. </section2>
  413. <section2 topic='Aggregate Tokens' anchor='agg_tokens'>
  414. <p>
  415. While the version token approach to caching does not require a great deal
  416. of state to be stored on the client or the server, it does require a lot
  417. more information to be sent by the client when requesting a list of
  418. entities. For a very large list which is not likely to have changed, it
  419. may be useful know in advance if the roster has changed or not (so that
  420. we can avoid sending the large request entirely). To do this, we can
  421. request an aggregate version token from the server. This aggregate token
  422. is calculated by constructing a string of comma separated "ID:version"
  423. pairs sorted in byte-wise order (because the ID:version pair is
  424. constructed before sorting, if two items in the list have the same ID
  425. they can still be sorted by the version token), and taking the MD5 hash
  426. of the constructed string. The ID in the pair is any ID or key that
  427. identifies the entity as defined in its profile (eg. a JID for roster
  428. items and most other entities). For example, if the server is calculating
  429. the aggregate version token for a roster, it might end up with the
  430. following string:
  431. </p>
  432. <example caption="Aggregate token list"><![CDATA[
  433. anne@shakespeare.lit:VIZSVF0D,bill@shakespeare.lit:25P2A7H8
  434. ]]></example>
  435. <p>
  436. Which results in the aggregate token:
  437. </p>
  438. <example caption="Aggregate token"><![CDATA[
  439. 0514fc90e6c7981b06bbb2173bb8ef03
  440. ]]></example>
  441. <p>
  442. The actual request is an IQ sent to the server, or entity handling the
  443. versioned list which contains a query that specifies the namespace of the
  444. list we want to fetch. Eg. to fetch the aggregate token for the roster
  445. one would query the server with the query's XMLNS set to
  446. 'urn:xmpp:entityver:profile:roster:0':
  447. </p>
  448. <example caption="Roster aggregate token request"><![CDATA[
  449. <!-- Client -->
  450. <iq to='bill@shakespeare.lit' type='get' id='bill1'>
  451. <query xmlns='urn:xmpp:entityver:profile:roster:0'/>
  452. </iq>
  453. <!-- Server -->
  454. <iq to='bill@shakespeare.lit/home' type='result' id='bill1'>
  455. <query xmlns='urn:xmpp:entityver:profile:roster:0'>
  456. 0514fc90e6c7981b06bbb2173bb8ef03
  457. </query>
  458. </iq>
  459. ]]></example>
  460. <p>
  461. Because aggregate tokens are OPTIONAL to implement, clients MUST fall
  462. back to making a normal list request if any error is returned in response
  463. to an aggregate token IQ.
  464. </p>
  465. <p>
  466. If an aggregate token is requested for a list that may contain more than
  467. one type of entity (eg. MUC rooms and pubsub nodes that live on the same
  468. component), then the server MUST return the aggregate token constructed
  469. with the entire list (rooms and pubsub nodes).
  470. </p>
  471. <p>
  472. Because aggregate tokens are calculated for the entire list as seen by
  473. the client or server, they will never match if partial lists have been
  474. downloaded by the client.
  475. </p>
  476. <p>
  477. Clients are also NOT REQUIRED to check aggregate tokens. However, clients
  478. MAY wish to check aggregate tokens before making a roster or MUC request
  479. when the cached roster or MUC list is very large. When to check aggregate
  480. tokens (if at all) is left up to the implementation.
  481. </p>
  482. </section2>
  483. </section1>
  484. <section1 topic='Implementation Notes' anchor='impl'>
  485. <p>
  486. Version tokens may not provide enough collision resistance across versioned
  487. entities (hereafter simply called "entities"), and may vary from server to
  488. server, and therefore they MUST NOT be used as an entity identifier.
  489. </p>
  490. <p>
  491. Version tokens SHOULD always be considered opaque to the client (eg. even
  492. if the version token is a derivable and consistent hash on the server side,
  493. clients should not need to know how the server is calculating the token).
  494. </p>
  495. <p>
  496. The author RECOMMENDS using 8 character (32-bit) random alphanumeric ASCII
  497. strings (eg. AABd7z9T) for version tokens.
  498. </p>
  499. <p>
  500. If a server which supports this XEP provides an HTTP API which can be used
  501. to fetch information about entities (eg. for listing information about MUC
  502. rooms that a server provides on the providers web page), the entities
  503. version token MAY be used as a weakly validated ETag for any API requests
  504. for that entity.
  505. </p>
  506. <p>
  507. Servers following this specification may choose to send down partial entity
  508. lists in response to queries. For the case of rosters one or more of the
  509. following may be returned to the requesting entity during the initial
  510. roster sync:
  511. </p>
  512. <ul>
  513. <li>
  514. Users that are grouped with the requester in some way.
  515. Eg. for a company with a large shared roster which places the requesting
  516. client in the "Marketing Department" group, the server may wish to return
  517. roster items that also share that group.
  518. </li>
  519. <li>Users whom the requester has contacted recently or frequently.</li>
  520. <li>Users that should always be returned as part of server policy.</li>
  521. </ul>
  522. </section1>
  523. <section1 topic='Security Considerations' anchor='security'>
  524. <p>
  525. Client-side caching of entity information across sessions (rather than
  526. holding them in memory only for the life of a session) could pose a privacy
  527. risk, especially on shared systems. Implementations SHOULD protect cached
  528. entity data with strong encryption or other appropriate means.
  529. </p>
  530. </section1>
  531. <section1 topic='IANA Considerations' anchor='iana'>
  532. <p>This document requires no interaction with &IANA;.</p>
  533. </section1>
  534. <section1 topic='XMPP Registrar Considerations' anchor='registrar'>
  535. <section2 topic='Protocol Namespaces' anchor='registrar-ns'>
  536. <p>This specification defines the following XML namespace:</p>
  537. <ul>
  538. <li>urn:xmpp:entityver:0</li>
  539. <li>urn:xmpp:entityver:0:search</li>
  540. </ul>
  541. <p>
  542. Upon advancement of this specification from a status of Experimental to a
  543. status of Draft, the &REGISTRAR; shall add the foregoing namespace to the
  544. registry located at &STREAMFEATURES;, as described in Section 4 of
  545. &xep0053;.
  546. </p>
  547. </section2>
  548. <section2 topic='Namespace Versioning' anchor='registrar-versioning'>
  549. &NSVER;
  550. </section2>
  551. <section2 topic='Entity Versioning Profiles Registry' anchor='registrar-ev'>
  552. <p>
  553. The XMPP Registrar shall maintain a registry of entity versioning
  554. profiles. All EV profile registrations shall be defined in separate
  555. specifications (not in this document). Application types defined within
  556. the XEP series MUST be registered with the XMPP Registrar, resulting in
  557. protocol URNs of the form "urn:xmpp:entityver:profile:name:X" (where
  558. "name" is the registered name of the profile and "X" is a non-negative
  559. integer).
  560. </p>
  562. <code><![CDATA[
  563. <profile>
  564. <name>The name of the entity versioning profile.</name>
  565. <desc>A natural-language summary of the profile.</desc>
  566. <listdef>
  567. The document in which the original list definition is specified.
  568. </listdef>
  569. <doc>
  570. The document in which the EV profile for the list is specified (may be the
  571. same as <listdev/>).
  572. </doc>
  573. </profile>]]></code>
  574. </section2>
  575. <section2 topic='Entity Versioning Profiles' anchor='registrar-evprofile'>
  576. <p>This specification defines the following entity versioning profile:</p>
  577. <ul>
  578. <li>urn:xmpp:entityver:profile:roster:0</li>
  579. </ul>
  580. <p>
  581. Upon advancement of this specification from a status of Experimental to a
  582. status of Draft, the &REGISTRAR; shall add the following definition to
  583. the entity versioning profiles registry, as described in this document:
  584. </p>
  585. <code><![CDATA[
  586. <profile>
  587. <name>Roster entity versioning</name>
  588. <desc>Allows versioning of entities in an XMPP roster.</desc>
  589. <listdef>RFC 6121</listdef>
  590. <doc>TODO: Insert this document once it is assigned a number</doc>
  591. </profile>]]></code>
  592. </section2>
  593. </section1>
  594. <section1 topic='XML Schema' anchor='schema'>
  595. <p>TODO</p>
  596. </section1>
  597. <section1 topic='Acknowledgements' anchor='ack'>
  598. <p>
  599. The original entity versioning proposal was engineered and written by
  600. HipChat's Doug Keen.
  601. </p>
  602. </section1>
  603. </xep>