<?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"
     category="info"
     docName="draft-kashyap-calext-ical-property-deps-00"
     submissionType="IETF"
     consensus="true"
     xml:lang="en"
     version="3">

  <front>
    <title abbrev="iCalendar Property Dependencies">Machine-Readable Property Dependencies for iCalendar (RFC 5545)</title>

    <seriesInfo name="Internet-Draft" value="draft-kashyap-calext-ical-property-deps-00"/>

    <author initials="R." surname="Kashyap" fullname="Ravi Kashyap">
      <organization>iCalDAV Project</organization>
      <address>
        <uri>https://github.com/iCalDAV/ical-dependency-graph</uri>
      </address>
    </author>

    <date year="2026" month="March" day="28"/>

    <area>art</area>
    <workgroup>calext</workgroup>

    <keyword>iCalendar</keyword>
    <keyword>CalDAV</keyword>
    <keyword>property dependencies</keyword>
    <keyword>merge safety</keyword>
    <keyword>VEVENT</keyword>
    <keyword>RFC 5545</keyword>

    <abstract>
      <t>
        RFC 5545 defines inter-property interaction rules for iCalendar
        components in prose scattered across multiple RFC sections.  No
        published, standalone representation of these rules exists in a
        form suitable for machine consumption.  This document specifies
        a formal dependency graph for VEVENT components with 27
        properties and 20 edges spanning six edge types.  It classifies
        properties into five merge safety categories that determine
        whether concurrent edits can be combined without user
        intervention.  The specification is published as YAML and JSON
        artifacts for cross-language consumption.
      </t>
    </abstract>

  </front>

  <middle>

    <!-- ============================================================ -->
    <section anchor="introduction">
      <name>Introduction</name>
      <t>
        CalDAV <xref target="RFC4791"/> treats calendar resources as
        opaque blobs.  Clients PUT entire iCalendar objects; servers
        use ETags for conflict detection.  When two clients modify the
        same event, the only options are whole-event replacement or
        manual resolution.  Property-level merge is not part of the
        protocol.
      </t>
      <t>
        The barrier to property-level merge is not algorithmic.
        Three-way merge for structured data is well understood.  The
        barrier is that <xref target="RFC5545"/> property dependencies
        are implicit: changing DTSTART can invalidate RRULE expansion,
        EXDATE membership, and VALARM trigger offsets, but this is
        expressed only in prose across separate RFC sections.  Without
        a formal model of which properties depend on which, a merge
        engine cannot determine whether two concurrent edits are safe
        to combine.
      </t>
      <t>
        This document extracts these implicit dependencies into a
        formal graph for VEVENT components and classifies each property
        by merge safety.
      </t>

      <section anchor="scope">
        <name>Scope</name>
        <t>
          This specification covers VEVENT properties only.  VTODO and
          VJOURNAL have different dependency structures (e.g., the Tasks
          draft removes the VTODO DURATION-to-DTSTART requirement).
          Extension to other component types is future work.
        </t>
        <t>
          The graph includes all VEVENT properties with non-trivial
          inter-property dependencies, plus commonly-edited safe
          properties.  <xref target="RFC5545"/> Section 3.6.1 defines
          additional VEVENT properties with no inter-property
          dependencies that are omitted for brevity: ATTACH, COMMENT,
          CONTACT, RELATED-TO, and RESOURCES.  All are safe with set
          cardinality and union merge semantics.
        </t>
        <t>
          Single-property cardinality constraints (e.g., DTSTART is
          REQUIRED) and value-level constraints (e.g., DTEND datetime
          MUST be greater than or equal to DTSTART datetime) are not
          modeled.  This graph captures structural and type-level
          dependencies only.
        </t>
      </section>

      <section anchor="merge-unit">
        <name>Merge Unit</name>
        <t>
          CalDAV resources can contain multiple VEVENTs sharing a UID:
          one master and zero or more exception VEVENTs (each identified
          by RECURRENCE-ID).  This graph models properties within a
          single VEVENT, but three edges cross VEVENT boundaries.  A
          merge engine consuming this graph MUST operate on the full UID
          group (all VEVENTs sharing a UID), not individual VEVENTs in
          isolation.  Edges marked "cross_vevent" in the machine-readable
          artifact require this UID-group scope.
        </t>
      </section>
    </section>

    <!-- ============================================================ -->
    <section anchor="terminology">
      <name>Terminology</name>
      <t>
        The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
        NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED",
        "MAY", and "OPTIONAL" in this document are to be interpreted as
        described in BCP 14 <xref target="RFC2119"/>
        <xref target="RFC8174"/> when, and only when, they appear in
        all capitals, as shown here.
      </t>
      <t>
        The following terms are used throughout this document:
      </t>
      <dl>
        <dt>Edge:</dt>
        <dd>A directed relationship between two properties in the
        dependency graph.  Each edge has a type and a strength.</dd>

        <dt>Merge safety:</dt>
        <dd>A classification of whether a property can be independently
        merged when two clients concurrently edit the same event.</dd>

        <dt>UID group:</dt>
        <dd>The set of all VEVENTs sharing the same UID value within a
        calendar resource.  Consists of one master VEVENT and zero or
        more exception VEVENTs identified by RECURRENCE-ID.</dd>

        <dt>Significant change:</dt>
        <dd>A change to a property classified as "dependent" or
        "scheduling" in the merge safety classification.  Significant
        changes require SEQUENCE to be incremented per
        <xref target="RFC5546"/> Section 2.1.4.</dd>
      </dl>
    </section>

    <!-- ============================================================ -->
    <section anchor="edge-types">
      <name>Edge Type Definitions</name>
      <t>
        The graph uses six edge types with the following semantics:
      </t>

      <dl>
        <dt>depends_on:</dt>
        <dd>The source property's interpretation requires the target
        property's value.  Changing the target makes the source's
        cached result stale, but the source's stored value remains
        syntactically valid.  Example: RRULE depends_on DTSTART
        (<xref target="RFC5545"/> Section 3.8.5.3) because recurrence
        expansion uses DTSTART's day-of-week, month, etc. for BY*
        rules.</dd>

        <dt>derived_from:</dt>
        <dd>The source property's value was computed from the target
        at creation time.  The target can change afterward without
        requiring the source to update.  Example: RECURRENCE-ID
        derived_from DTSTART.</dd>

        <dt>requires:</dt>
        <dd>The source property requires the target to be present.
        The source without the target is a protocol violation.
        Example: ATTENDEE requires ORGANIZER (<xref target="RFC5545"/>
        Section 3.8.4.1).</dd>

        <dt>mutually_exclusive_with:</dt>
        <dd>The source and target MUST NOT both be present on the same
        VEVENT.  This relationship is symmetric.  Example: DTEND
        mutually_exclusive_with DURATION (<xref target="RFC5545"/>
        Section 3.6.1).</dd>

        <dt>type_consistency:</dt>
        <dd>The source and target must use the same value type (DATE
        or DATE-TIME).  This relationship is symmetric.  Example:
        EXDATE type_consistency DTSTART (<xref target="RFC5545"/>
        Section 3.8.5.1).</dd>

        <dt>computes_with:</dt>
        <dd>The source and target are used together in computation.
        Neither needs updating when the other changes.  Example:
        DTSTART computes_with DURATION to produce the implied end
        time.</dd>
      </dl>
    </section>

    <!-- ============================================================ -->
    <section anchor="edge-strength">
      <name>Edge Strength</name>
      <t>
        Each edge carries a strength indicating the RFC conformance
        level of the constraint it represents:
      </t>

      <dl>
        <dt>must:</dt>
        <dd>An RFC MUST or MUST NOT requirement.  Violation is a
        protocol error.</dd>

        <dt>should:</dt>
        <dd>An RFC SHOULD or SHOULD NOT recommendation.  Violation is
        suboptimal but conformant.</dd>

        <dt>advisory:</dt>
        <dd>Not a conformance requirement.  Useful for generating
        warnings (e.g., an EXDATE for a date not in the recurrence
        set is a no-op, not a violation).</dd>

        <dt>informational:</dt>
        <dd>Annotation only.  Documents a computational relationship
        with no conformance or warning implication.  Used for
        computes_with and derived_from edges.</dd>
      </dl>
    </section>

    <!-- ============================================================ -->
    <section anchor="property-deps">
      <name>Property Dependencies</name>
      <t>
        The following table lists the 20 inter-property edges.  All
        edges derive from <xref target="RFC5545"/>.  Additional RFCs
        (<xref target="RFC7986"/>, <xref target="RFC5546"/>,
        <xref target="RFC6047"/>, <xref target="RFC6638"/>) contribute
        property definitions and scheduling semantics used in the merge
        safety classification (<xref target="merge-safety"/>), but no
        edges in this table originate from those documents.  Symmetric
        edges (type_consistency, mutually_exclusive_with) are listed on
        both participating properties, yielding 20 entries for 16
        unique relationships.
      </t>

      <table anchor="tab-edges">
        <name>Inter-Property Dependency Edges for VEVENT</name>
        <thead>
          <tr>
            <th>Source</th>
            <th>Target</th>
            <th>Type</th>
            <th>Str.</th>
            <th>Ref</th>
          </tr>
        </thead>
        <tbody>
          <tr><td>RRULE</td><td>DTSTART</td><td>depends_on</td><td>must</td><td>S3.8.5.3</td></tr>
          <tr><td>EXDATE</td><td>DTSTART</td><td>type_cons.</td><td>must</td><td>S3.8.5.1</td></tr>
          <tr><td>EXDATE</td><td>RRULE</td><td>depends_on</td><td>adv.</td><td>S3.8.5.1</td></tr>
          <tr><td>RDATE</td><td>DTSTART</td><td>type_cons.</td><td>must</td><td>S3.8.5.2</td></tr>
          <tr><td>VALARM</td><td>DTSTART</td><td>depends_on</td><td>must</td><td>S3.8.6.3</td></tr>
          <tr><td>VALARM</td><td>DTEND</td><td>depends_on</td><td>must</td><td>S3.8.6.3</td></tr>
          <tr><td>VALARM</td><td>DURATION</td><td>depends_on</td><td>must</td><td>S3.8.6.3</td></tr>
          <tr><td>REC-ID</td><td>DTSTART</td><td>derived_from</td><td>info.</td><td>S3.8.4.4</td></tr>
          <tr><td>REC-ID</td><td>RRULE</td><td>depends_on</td><td>must</td><td>S3.8.4.4</td></tr>
          <tr><td>REC-ID</td><td>RDATE</td><td>depends_on</td><td>must</td><td>S3.8.4.4</td></tr>
          <tr><td>ATTENDEE</td><td>ORGANIZER</td><td>requires</td><td>must</td><td>S3.8.4.1</td></tr>
          <tr><td>DTEND</td><td>DURATION</td><td>mut_excl.</td><td>must</td><td>S3.6.1</td></tr>
          <tr><td>DTSTART</td><td>DURATION</td><td>computes_w.</td><td>info.</td><td>S3.8.2.5</td></tr>
          <tr><td>DURATION</td><td>DTSTART</td><td>depends_on</td><td>must</td><td>S3.8.2.5</td></tr>
          <tr><td>DTSTART</td><td>DTEND</td><td>type_cons.</td><td>must</td><td>S3.6.1</td></tr>
          <tr><td>DTSTART</td><td>EXDATE</td><td>type_cons.</td><td>must</td><td>S3.8.5.1</td></tr>
          <tr><td>DTSTART</td><td>RDATE</td><td>type_cons.</td><td>must</td><td>S3.8.5.2</td></tr>
          <tr><td>DTSTART</td><td>UNTIL</td><td>type_cons.</td><td>must</td><td>S3.3.10</td></tr>
          <tr><td>DTEND</td><td>DTSTART</td><td>type_cons.</td><td>must</td><td>S3.6.1</td></tr>
          <tr><td>DURATION</td><td>DTEND</td><td>mut_excl.</td><td>must</td><td>S3.6.1</td></tr>
        </tbody>
      </table>

      <t>
        Abbreviations: REC-ID = RECURRENCE-ID; type_cons. =
        type_consistency; mut_excl. = mutually_exclusive_with;
        computes_w. = computes_with; adv. = advisory;
        info. = informational.  All references are to
        <xref target="RFC5545"/> sections.
      </t>

      <t>
        VALARM is a sub-component nested inside VEVENT, not a VEVENT
        property.  Its edges are modeled at the VEVENT level for merge
        safety purposes.  A complete VALARM merge requires set-level
        comparison of sub-components, not scalar property diffing.
        The VALARM depends_on edges are conditional on each alarm's
        TRIGGER RELATED parameter: RELATED=START (the default) depends
        on DTSTART; RELATED=END depends on DTEND or, when DTEND is
        absent, on DURATION.  A merge engine that unconditionally flags
        all VALARMs when DTEND changes will produce false positive
        conflicts for RELATED=START alarms.
      </t>
      <t>
        The DURATION depends_on DTSTART edge
        (<xref target="RFC5545"/> Section 3.8.2.5) captures a
        non-obvious format constraint: if DTSTART uses the DATE value
        type (all-day event), DURATION MUST use dur-day or dur-week
        format (e.g., P1D, P2W), not time granularity (e.g., PT1H).
        Changing DTSTART from DATE-TIME to DATE requires validating
        the DURATION format.
      </t>

      <section anchor="cross-vevent">
        <name>Cross-VEVENT Edges</name>
        <t>
          RECURRENCE-ID lives on an exception VEVENT; its targets
          (RRULE, RDATE, DTSTART) live on the master VEVENT.  These
          edges are marked "cross_vevent: true" in the machine-readable
          artifact.  A merge engine MUST resolve these edges across the
          full set of VEVENTs sharing a UID.
        </t>
      </section>

      <section anchor="internal-constraints">
        <name>RRULE Internal Constraints</name>
        <t>
          COUNT and UNTIL are mutually exclusive within an RRULE value
          (<xref target="RFC5545"/> Section 3.3.10).  This is captured
          as an internal constraint rather than an inter-property edge,
          because both are parameters of the RRULE value, not separate
          VEVENT properties.
        </t>
      </section>
    </section>

    <!-- ============================================================ -->
    <section anchor="merge-safety">
      <name>Merge Safety Classification</name>
      <t>
        Given two concurrent edits to the same event (local and remote),
        can a property be independently merged?  This section classifies
        all 27 VEVENT properties into five categories.
      </t>

      <section anchor="merge-safe">
        <name>Safe</name>
        <t>
          Properties: SUMMARY, DESCRIPTION, LOCATION, URL, GEO,
          PRIORITY, CATEGORIES, COLOR (<xref target="RFC7986"/>),
          CLASS, TRANSP, STATUS.
        </t>
        <t>
          No cross-property dependencies.  Independent merge is always
          valid.  If local changes SUMMARY and remote changes LOCATION,
          both edits can be kept without conflict.
        </t>
        <t>
          STATUS is structurally safe but semantically hazardous.
          Auto-merging STATUS:CANCELLED with a concurrent SUMMARY edit
          produces a cancelled event with a new title.  A merge engine
          SHOULD surface STATUS:CANCELLED as a manual-resolution
          candidate.
        </t>
      </section>

      <section anchor="merge-dependent">
        <name>Dependent</name>
        <t>
          Properties: DTSTART, DTEND, DURATION, RRULE, EXDATE, RDATE,
          VALARM.
        </t>
        <t>
          Can be merged if graph validation passes.  For example, if
          local changes DTSTART and remote adds an EXDATE, the merge
          engine MUST verify that the EXDATE value type still matches
          the new DTSTART type.
        </t>
      </section>

      <section anchor="merge-scheduling">
        <name>Scheduling</name>
        <t>
          Properties: ATTENDEE, ORGANIZER, REQUEST-STATUS.
        </t>
        <t>
          When CalDAV Scheduling <xref target="RFC6638"/> is active,
          modifying these properties triggers scheduling messages per
          <xref target="RFC6047"/>.  They MUST NOT be auto-merged.
        </t>
        <t>
          On servers without <xref target="RFC6638"/> (e.g., Radicale,
          Baikal), ATTENDEE is dependent (requires ORGANIZER) and
          ORGANIZER is also dependent (removing ORGANIZER while
          ATTENDEEs are present violates the "requires" edge regardless
          of scheduling support).  REQUEST-STATUS falls back to safe.
          The machine-readable artifact captures this via a
          "scheduling_fallback" field.
        </t>
      </section>

      <section anchor="merge-immutable">
        <name>Immutable</name>
        <t>
          Properties: UID, CREATED, RECURRENCE-ID.
        </t>
        <t>
          Set once within a VEVENT instance.  MUST NOT be changed after
          initial creation.  UID identifies the event
          (<xref target="RFC5545"/> Section 3.8.4.7).  CREATED records
          creation time (<xref target="RFC5545"/> Section 3.8.7.1).
          RECURRENCE-ID identifies which occurrence of a recurrence
          series was modified (<xref target="RFC5545"/>
          Section 3.8.4.4).
        </t>
      </section>

      <section anchor="merge-always-update">
        <name>Always-Update</name>
        <t>
          Properties: SEQUENCE, DTSTAMP, LAST-MODIFIED.
        </t>
        <t>
          Automatically set on any edit.  DTSTAMP and LAST-MODIFIED
          are set to the current UTC time.
        </t>
        <t>
          SEQUENCE has a non-trivial merge rule.  If only one side
          changed significant properties, the merge engine SHOULD
          preserve that side's SEQUENCE.  If both sides changed
          significant properties, the merge engine SHOULD use
          max(local, remote) + 1.  If neither changed significant
          properties, the merge engine SHOULD use max(local, remote).
          A blind max + 1 on every merge causes the escalation loop
          documented in existing CalDAV client implementations.
        </t>
      </section>

      <section anchor="set-valued">
        <name>Set-Valued Properties</name>
        <t>
          Properties with cardinality "set" (EXDATE, RDATE, CATEGORIES,
          ATTENDEE, VALARM) hold multiple values.  The merge safety
          classification determines whether a property can be
          independently merged with edits to other properties but does
          not specify how to merge concurrent edits to the same
          multi-valued property.
        </t>
        <t>
          The machine-readable artifact includes a "merge_op" field for
          set properties: "union" (EXDATE, RDATE, CATEGORIES) for
          additive merge, or "conflict" (ATTENDEE, VALARM) for
          set-level comparison requiring manual resolution.
        </t>
        <t>
          EXDATE union requires checking for corresponding exception
          VEVENTs on the same date before applying.  Adding an EXDATE
          for a date that has an exception VEVENT produces conflicting
          signals (the occurrence is both excluded and replaced).
        </t>
      </section>
    </section>

    <!-- ============================================================ -->
    <section anchor="machine-readable">
      <name>Machine-Readable Artifact</name>
      <t>
        The dependency graph is published as structurally equivalent
        YAML and JSON files at
        &lt;https://github.com/iCalDAV/ical-dependency-graph&gt;.
        The YAML includes inline commentary; the JSON uses fields
        prefixed with underscore ("_note", "_schema") for annotations.
        Underscore-prefixed fields are non-normative.
      </t>

      <section anchor="schema-fields">
        <name>Schema Fields</name>
        <t>Each property object contains:</t>
        <dl>
          <dt>cardinality:</dt>
          <dd>"scalar" (single value) or "set" (multiple values).</dd>

          <dt>merge_safety:</dt>
          <dd>One of: "safe", "dependent", "scheduling", "immutable",
          "always_update".</dd>

          <dt>Edge lists:</dt>
          <dd>Zero or more of: "depends_on", "derived_from",
          "requires", "mutually_exclusive_with", "type_consistency",
          "computes_with".  Each entry is an object with "target"
          (property name) and "strength" (must/should/advisory/
          informational).</dd>

          <dt>merge_op:</dt>
          <dd>(Set properties only.) "union" or "conflict".</dd>

          <dt>scheduling_fallback:</dt>
          <dd>(Scheduling properties only.) The merge safety category
          to use on servers without <xref target="RFC6638"/>.</dd>

          <dt>merge_rule:</dt>
          <dd>(SEQUENCE only.) Three conditions:
          "one_side_changed" (PRESERVE), "both_sides_changed"
          (MAX_PLUS_ONE), "neither_changed" (MAX).</dd>

          <dt>cross_vevent:</dt>
          <dd>(Optional, boolean.) True when the edge crosses VEVENT
          boundaries within a UID group.</dd>
        </dl>
      </section>

      <section anchor="versioning">
        <name>Versioning</name>
        <t>
          The "version" field uses semantic versioning:
        </t>
        <ul>
          <li>Patch (1.0.x): Corrects an incorrect edge.  No new
          properties or edge types.</li>
          <li>Minor (1.x.0): Adds new properties, edge types, or
          schema fields.  Existing edges unchanged.</li>
          <li>Major (x.0.0): Changes existing edge semantics or
          restructures the schema.</li>
        </ul>
      </section>
    </section>

    <!-- ============================================================ -->
    <section anchor="evidence">
      <name>Implementation Evidence</name>
      <t>
        25 bugs were identified across 17 distinct open-source projects
        spanning 8 programming languages (JavaScript, Python, C, Java,
        PHP, Kotlin, C#, Vala) where the root cause is a violated
        property dependency.  The bugs fall into three categories:
      </t>
      <ul>
        <li>Expansion/interpretation (13 bugs): The dependency rule was
        not correctly implemented in RRULE expansion, EXDATE filtering,
        or property interpretation.</li>
        <li>Validation/serialization (10 bugs): Invalid property
        combinations were accepted or produced.</li>
        <li>Merge/sync (2 bugs): Concurrent edits or sync operations
        produced invalid state due to missing property-level
        awareness.</li>
      </ul>
      <t>
        The EXDATE-type-must-match-DTSTART rule
        (<xref target="RFC5545"/> Section 3.8.5.1) alone accounts for
        7 separate bugs across independent implementations.  The
        RRULE-DTSTART interaction has bugs dating back to 2013.
        13 of 25 bugs involve these same two rules across independent
        implementations.
      </t>
      <t>
        Additionally, 7 major calendar libraries across 6 languages
        have documented cross-property validation gaps: ical4j (Java),
        ical.js (JavaScript), libical (C), Python icalendar (Python),
        sabre/vobject (PHP), rrule.js (JavaScript), and ical4android
        (Kotlin).
      </t>
      <t>
        The full bug catalog with links to individual issues is
        available in the companion preprint
        <xref target="ICAL-DEP-GRAPH"/> and at the repository listed
        in <xref target="machine-readable"/>.
      </t>
    </section>

    <!-- ============================================================ -->
    <section anchor="security">
      <name>Security Considerations</name>
      <t>
        This document formalizes existing constraints from
        <xref target="RFC5545"/> and related specifications.  It does
        not introduce new protocol elements or modify existing ones.
      </t>
      <t>
        Implementations that consume the dependency graph for automated
        merge operations SHOULD validate the graph artifact's integrity
        before use (e.g., by verifying a checksum or fetching from a
        trusted source).  A modified graph could cause a merge engine
        to incorrectly classify unsafe merges as safe, producing
        invalid iCalendar objects.
      </t>
      <t>
        The scheduling properties (ATTENDEE, ORGANIZER, REQUEST-STATUS)
        have side effects beyond the local event when CalDAV Scheduling
        <xref target="RFC6638"/> is active.  A merge engine MUST NOT
        auto-merge scheduling properties without the user's explicit
        consent, as this could result in unintended scheduling messages
        being sent to other participants.
      </t>
    </section>

    <!-- ============================================================ -->
    <section anchor="iana">
      <name>IANA Considerations</name>
      <t>
        This document has no IANA actions.
      </t>
    </section>

  </middle>

  <back>
    <references>
      <name>References</name>

      <references>
        <name>Normative References</name>

        <reference anchor="RFC5545" target="https://www.rfc-editor.org/info/rfc5545">
          <front>
            <title>Internet Calendaring and Scheduling Core Object Specification (iCalendar)</title>
            <author fullname="B. Desruisseaux" initials="B." role="editor" surname="Desruisseaux"/>
            <date month="September" year="2009"/>
          </front>
          <seriesInfo name="RFC" value="5545"/>
          <seriesInfo name="DOI" value="10.17487/RFC5545"/>
        </reference>

        <reference anchor="RFC7986" target="https://www.rfc-editor.org/info/rfc7986">
          <front>
            <title>New Properties for iCalendar</title>
            <author fullname="C. Daboo" initials="C." surname="Daboo"/>
            <date month="October" year="2016"/>
          </front>
          <seriesInfo name="RFC" value="7986"/>
          <seriesInfo name="DOI" value="10.17487/RFC7986"/>
        </reference>

        <reference anchor="RFC5546" target="https://www.rfc-editor.org/info/rfc5546">
          <front>
            <title>iCalendar Transport-Independent Interoperability Protocol (iTIP)</title>
            <author fullname="C. Daboo" initials="C." role="editor" surname="Daboo"/>
            <date month="December" year="2009"/>
          </front>
          <seriesInfo name="RFC" value="5546"/>
          <seriesInfo name="DOI" value="10.17487/RFC5546"/>
        </reference>

        <reference anchor="RFC6047" target="https://www.rfc-editor.org/info/rfc6047">
          <front>
            <title>iCalendar Message-Based Interoperability Protocol (iMIP)</title>
            <author fullname="A. Melnikov" initials="A." role="editor" surname="Melnikov"/>
            <date month="December" year="2010"/>
          </front>
          <seriesInfo name="RFC" value="6047"/>
          <seriesInfo name="DOI" value="10.17487/RFC6047"/>
        </reference>

        <reference anchor="RFC6638" target="https://www.rfc-editor.org/info/rfc6638">
          <front>
            <title>Scheduling Extensions to CalDAV</title>
            <author fullname="C. Daboo" initials="C." surname="Daboo"/>
            <author fullname="B. Desruisseaux" initials="B." surname="Desruisseaux"/>
            <date month="June" year="2012"/>
          </front>
          <seriesInfo name="RFC" value="6638"/>
          <seriesInfo name="DOI" value="10.17487/RFC6638"/>
        </reference>

        <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/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"/>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>

        <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/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"/>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>

      </references>

      <references>
        <name>Informative References</name>

        <reference anchor="ICAL-DEP-GRAPH" target="https://doi.org/10.5281/zenodo.19299690">
          <front>
            <title>Formalizing Implicit Property Dependencies in RFC 5545: Toward Safe Property-Level Calendar Synchronization</title>
            <author fullname="R. Kashyap" initials="R." surname="Kashyap"/>
            <date month="March" year="2026"/>
          </front>
          <seriesInfo name="DOI" value="10.5281/zenodo.19299690"/>
        </reference>

        <reference anchor="RFC4791" target="https://www.rfc-editor.org/info/rfc4791">
          <front>
            <title>Calendaring Extensions to WebDAV (CalDAV)</title>
            <author fullname="C. Daboo" initials="C." surname="Daboo"/>
            <author fullname="B. Desruisseaux" initials="B." surname="Desruisseaux"/>
            <author fullname="L. Dusseault" initials="L." surname="Dusseault"/>
            <date month="March" year="2007"/>
          </front>
          <seriesInfo name="RFC" value="4791"/>
          <seriesInfo name="DOI" value="10.17487/RFC4791"/>
        </reference>

      </references>
    </references>

    <!-- ============================================================ -->
    <section anchor="acknowledgements" numbered="false">
      <name>Acknowledgements</name>
      <t>
        The dependency rules formalized in this document were validated
        against 295+ tests across three codebases and six CalDAV
        servers (iCloud, Nextcloud, Radicale, Baikal, Stalwart, Zoho).
        The bug catalog was compiled from public GitHub issues across
        17 open-source calendar projects.
      </t>
    </section>

  </back>
</rfc>
