# Information System Model — Mutations & Avalanches

## Multi-Context Mutations

The mechanism that governs Context membership and instance propagation is the `propagationConstraint` field embedded in every **Relation** instance. This field defines the "Avalanche Effect"—how the target **Entity** instance behaves when the source **Resource** instance (or the **Relation** instance itself) is added to or removed from a Context.

> **Authorization assumed:** The examples in this chapter illustrate propagation only. Their Contexts (`C1`, `C2`, …) are not placed in a specific tree, and every request is assumed to be issued by a role authorized for the source and the destination (for example an `IS-Manager`, with `bypassHierarchyCheck=true` where the destination lies outside its subtree and siblings). The authorization rules are in [Membership Operations](09-api-instances-and-admin.html#membership-operations-remove-from-current-context-add-to-context).

> **Strict Downstream Propagation:** The "Avalanche Effect" travels strictly **forwards** along directed **Relation** instances (from source to target). 
> - **For `Add to Context`:** the outcome depends on the type of the explicitly added instance.
>   - **Resource instance:** the **Resource** instance is added. Each of its outgoing **IsRelatedTo** and **ConsistsOf** instances is added *if and only if* its constraint is `add: propagate`; since a **Relation** instance cannot exist without its target, it pulls its target **Entity** instance into the target Context as well, and the avalanche continues from there. With `add: unpropagate` the **IsRelatedTo** or **ConsistsOf** instance is left behind (it is NOT added to the target Context), even if its target **Entity** instance happens to already exist in that target Context independently.
>   - **Facet instance:** a **Facet** instance cannot exist in a Context without the **ConsistsOf** instance pointing to it, so that **ConsistsOf** instance is added with it. This is a structural requirement, not upstream propagation: it stops at the **ConsistsOf** instance and never reaches its source. The source **Resource** instance must already be in the target Context; the system never pulls it, and the operation fails with `409 Conflict` otherwise. No avalanche follows, since a **Facet** instance has no outgoing relations.
>   - **IsRelatedTo instance:** its source **Resource** instance must already be in the target Context; the system never pulls it, and the operation fails with `409 Conflict` otherwise. The target **Resource** instance is always added, because an **IsRelatedTo** instance cannot exist without its target: the `add` constraint of the explicitly added **IsRelatedTo** instance is not consulted, since it governs only the avalanche that reaches that **IsRelatedTo** instance from its source. From the target **Resource** instance, the avalanche continues as for a **Resource** instance.
>   - **ConsistsOf instance:** its source **Resource** instance must already be in the target Context; the system never pulls it, and the operation fails with `409 Conflict` otherwise. The target **Facet** instance is always added, because a **ConsistsOf** instance cannot exist without its target, whatever the `add` constraint of the explicitly added **ConsistsOf** instance.
> - **For `Remove from Context`:** This operation acts on a single Context. When evaluating constraints, the avalanche travels exclusively downstream. If a client removes a **Relation** instance, its source **Resource** instance remains completely untouched in that Context. Conversely, if a client removes a **Resource** instance, the system must drop all incoming **Relation** instances pointing to it to preserve graph integrity (a **Relation** instance cannot exist without its target). This drop is a strict *topological cleanup*, not a backwards avalanche: it does not trigger any `remove` constraint evaluations on the sources of those incoming **Relation** instances.

To understand this powerful concept, we will build up the logic through simple didactic examples before demonstrating a comprehensive scenario.

*Note: While the following examples illustrate an `Add to Context` or `Remove from Context` operation starting from a **Resource** instance, the same constraint rules govern the avalanche that continues from an explicitly added or removed **IsRelatedTo** or **ConsistsOf** instance, with one exception for `Add to Context`: the explicitly added **Relation** instance always brings its target, whatever its own `add` constraint, and its source must already be in the destination Context (see the per-type rules above). An operation starting directly on a **Facet** instance triggers no avalanche, since **Facet** instances have no outgoing relations; on `Add to Context` it brings only the **ConsistsOf** instance pointing to it, and its source **Resource** instance must already be in the destination Context.*

## Add Propagation

When an instance (e.g., a **Resource** instance) is added to a new Context (e.g., via an `Add to Context` operation), the system evaluates the `add` propagation constraint on all its visible outgoing **Relation** instances to determine if the target **Entity** instances (**Resource** instance or **Facet** instance) should follow.

The traversal is parameterized by `propagationMode`:

- **`surgical`:** adds the explicitly targeted instance without the recursive traversal described here: the avalanche never continues through **IsRelatedTo** instances. What the targeted instance brings with it depends on its kind (**Resource**, **Facet**, **IsRelatedTo**, or **ConsistsOf**) and is defined in [`propagationMode`](11-api-query-parameters.html#propagationmode).
- **`shallow` (default):** propagation follows eligible `add: propagate` edges, but a path stops when its target **Entity** instance is already present in the destination Context. The existing target is treated as the boundary of that path.
- **`deep`:** propagation continues through eligible outgoing **Relation** instances even when an intermediate target **Entity** is already present, producing the full reachable transitive closure.

The examples below illustrate the propagation-constraint decisions shared by `shallow` and `deep`; where every traversed target is initially absent, both modes produce the same result.

> **Cycle Prevention (Depth-First Search):** To prevent infinite traversal loops in `deep` mode (especially when `propagate` constraints form closed cycles in complex topologies), the model prescribes a Modified Depth-First Search (DFS) traversal equipped with a Visited Set mechanism. The traversal safely halts recursion upon encountering an instance already evaluated in the current avalanche (see [Complex Topology Scenarios](appendix/03-complex-topology-scenarios.md)).

**Initial State:**

The scenario contains the following **Resource** instances:
- **Resource** instance `R1` exists in Context `C1`.

The scenario contains the following **Facet** instances:
- **Facet** instance `F1` exists in Context `C1`.
- **Facet** instance `F2` exists in Context `C1`.

The scenario contains the following **ConsistsOf** instances:
- `R1` is attached to `F1` via **ConsistsOf** instance `CO11`, which exists in Context `C1` and is configured with `add: propagate`.
- `R1` is attached to `F2` via **ConsistsOf** instance `CO12`, which exists in Context `C1` and is configured with `add: unpropagate`.

```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    F1("<b>F1</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet
    F2("<b>F2</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet

    R1 -->|"<b>CO11</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| F1
    R1 -->|"<b>CO12</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| F2

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    classDef facet fill:#9bbb59,stroke:#4f6228,stroke-width:3px,color:#fff;
```

**After `Add` to Context `C2`:**
If a user in Context `C1` adds `R1` into Context `C2`, `CO11` and `F1` follow `R1` into the new Context, while `CO12` and `F2` stay behind. The resulting contextual projection of `R1` in Context `C2` is structurally different from its contextual projection in Context `C1`.
*(Note: If the resulting topology in the target Context violates the **Resource** schema—for example, if an instance of `F2`'s Type was mandatory, or if the propagation would violate a `max` cardinality limit—the entire operation strictly fails and is aborted with a validation error! The system does not attempt partial merges or silent replacements; it strictly propagates the eligible elements and validates the final candidate graph).*

```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>, <i>C2</i>]</sub>"):::resource
    F1("<b>F1</b> <br/> <sub>[<i>C1</i>, <i>C2</i>]</sub>"):::facet
    F2("<b>F2</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet

    R1 -->|"<b>CO11</b> <br/> add: propagate <br/> <sub>[<i>C1</i>, <i>C2</i>]</sub>"| F1
    R1 -->|"<b>CO12</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| F2

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    classDef facet fill:#9bbb59,stroke:#4f6228,stroke-width:3px,color:#fff;
```

## Remove Propagation

> **Visual Disclaimer (Infrastructure Topology Focus):** To avoid unreadable diagrams, the following simplified scenarios focus exclusively on the Infrastructure Topology (the graph of **Resource** instances and **IsRelatedTo** instances). While omitted from these didactic diagrams to reduce noise, it is strictly understood that every valid **Resource** instance must encapsulate its own Descriptive Topology (its attached **Facet** instances).

To understand the difference between `cascade`, `cascadeWhenOrphan`, and `keep` during a removal operation, consider the following scenario strictly contained in Context `C1`.

**Initial State:**

The scenario contains the following **Resource** instances:
- **Resource** instance `R1` exists in Context `C1`.
- **Resource** instance `R2` exists in Context `C1`.
- **Resource** instance `R3` exists in Context `C1`.
- **Resource** instance `R4` exists in Context `C1`.
- **Resource** instance `R5` exists in Context `C1`.
- **Resource** instance `R6` exists in Context `C1`.

The scenario contains the following **IsRelatedTo** instances:
- `R1` is linked to `R2` via **IsRelatedTo** instance `IRT12`, which exists in Context `C1` and is configured with `remove: cascadeWhenOrphan`.
- `R1` is linked to `R3` via **IsRelatedTo** instance `IRT13`, which exists in Context `C1` and is configured with `remove: cascadeWhenOrphan`.
- `R1` is linked to `R4` via **IsRelatedTo** instance `IRT14`, which exists in Context `C1` and is configured with `remove: cascade`.
- `R1` is linked to `R5` via **IsRelatedTo** instance `IRT15`, which exists in Context `C1` and is configured with `remove: keep`.
- `R5` is linked to `R4` via **IsRelatedTo** instance `IRT54`, which exists in Context `C1` and is configured with `remove: keep`.
- `R6` is linked to `R2` via **IsRelatedTo** instance `IRT62`, which exists in Context `C1` and is configured with `remove: keep`.

```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R4("<b>R4</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R5("<b>R5</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource

    R1 -->|"<b>IRT12</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R2
    R1 -->|"<b>IRT13</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    R1 -->|"<b>IRT14</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R4
    R1 -->|"<b>IRT15</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R5

    R6 -->|"<b>IRT62</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT54</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R4

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

**After removing `R1` from Context `C1`:**
When the user explicitly removes `R1` from Context `C1`, the system evaluates the `remove` constraints on the outgoing **IsRelatedTo** instances:
1. **On `R2` (`cascadeWhenOrphan`)**: `IRT12` drops. The system checks `R2` and sees it still has another incoming **IsRelatedTo** instance in Context `C1` (`IRT62` from `R6`). Therefore, `R2` is "saved" and **kept** in Context `C1`.
2. **On `R3` (`cascadeWhenOrphan`)**: `IRT13` drops. The system checks `R3` and sees it has *no other incoming **IsRelatedTo** instances* in Context `C1`. It is officially an orphan, so `R3` is **removed** from Context `C1`.
3. **On `R4` (`cascade`)**: `IRT14` drops. The constraint is a pure, strict `cascade`. The system doesn't care that the **Relation** instance `IRT54` was still pointing to it; `R4` is forcefully **removed** from Context `C1`. As a topological consequence, `IRT54` also disappears. A **Relation** instance cannot exist in a Context if either its source or its target is missing: `IRT15` died because its source (`R1`) was removed, whereas `IRT54` dies because its target (`R4`) was removed. *(Note on Cycles: Because the avalanche drops **Relation** instances from the Context as it progresses, any cycle in the graph is naturally broken when the first relation drops, preventing infinite topological loops).*
4. **On `R5` (`keep`)**: `IRT15` drops (because the source `R1` is gone). The constraint is explicitly `keep`. The system leaves `R5` completely untouched, without even checking if it becomes an orphan. `R5` is **kept** in Context `C1`.

The resulting topology in Context `C1` demonstrates all behaviors at a glance:
```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R5("<b>R5</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource

    R6 -->|"<b>IRT62</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R2
    
    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

## Recursive Avalanche

The removal avalanche is a recursive transaction. `cascadeWhenOrphan` evaluates the *final* state of the Context after the entire wave of deletions, not just the initial snapshot. Consider this advanced topology:

**Initial State:**

The scenario contains the following **Resource** instances:
- **Resource** instance `R1` exists in Context `C1`.
- **Resource** instance `R2` exists in Context `C1`.
- **Resource** instance `R3` exists in Context `C1`.
- **Resource** instance `R4` exists in Context `C1`.

The scenario contains the following **IsRelatedTo** instances:
- `R1` is linked to `R2` via **IsRelatedTo** instance `IRT12`, which exists in Context `C1` and is configured with `remove: cascadeWhenOrphan`.
- `R1` is linked to `R4` via **IsRelatedTo** instance `IRT14`, which exists in Context `C1` and is configured with `remove: cascade`.
- `R4` is linked to `R2` via **IsRelatedTo** instance `IRT42`, which exists in Context `C1` and is configured with `remove: cascadeWhenOrphan`.
- `R4` is linked to `R3` via **IsRelatedTo** instance `IRT43`, which exists in Context `C1` and is configured with `remove: keep`.

```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R4("<b>R4</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource

    R1 -->|"<b>IRT12</b> <br/> remove: cascadeWhenOrphan"| R2
    R1 -->|"<b>IRT14</b> <br/> remove: cascade"| R4
    R4 -->|"<b>IRT42</b> <br/> remove: cascadeWhenOrphan"| R2
    R4 -->|"<b>IRT43</b> <br/> remove: keep"| R3

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

**What happens if we remove `R1` from Context `C1`?**
1. `R1` is removed. Its outgoing **IsRelatedTo** instances drop.
2. `IRT14` drops with `cascade`. `R4` is forcefully removed from Context `C1`.
3. Because `R4` is removed, its outgoing **IsRelatedTo** instances also drop in the same transaction avalanche!
4. `IRT43` drops. The constraint is `keep`, so `R3` safely remains in Context `C1`.
5. Now, look at `R2`. Both `IRT12` and `IRT42` drop (both with `cascadeWhenOrphan`). Because *both* of its incoming **IsRelatedTo** instances are destroyed in this single avalanche, `R2` becomes a true orphan at the end of the transaction. Thus, `R2` is removed from Context `C1`.

**Resulting Graph:**
Only `R3` survives the avalanche.
```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

## Add and Remove Asymmetry

Removing an instance from a Context is **not always the exact inverse of adding it**. Invertibility is strictly not guaranteed. The `remove` constraints dictate what happens to the target **Entity** instances, and depending on how they are paired with `add` constraints, applying an `Add to Context` followed by a `Remove from Context` (or vice versa) will likely **not** return the graph to its initial state. *(Note: in the following visual examples we primarily illustrate propagation using a **Resource** instance, but the same mechanics apply when removing a **Relation** instance, e.g., an **IsRelatedTo** instance).*

**Sequence A: Add first, then Remove**
| Propagation Constraint | `Remove: cascade` <br/> *(or `cascadeWhenOrphan` when orphan)* | `Remove: keep` <br/> *(or `cascadeWhenOrphan` when not orphan)* |
|------------------------|-------------------------------------------------------------------|-----------------------------------------------------------------------|
| **`Add: propagate`**   | Symmetrical Context Add/Remove                                    | Add expands Context, Remove leaves targets in Context                 |
| **`Add: unpropagate`** | Add isolated, Remove cascades to targets                          | Symmetrical isolated Add/Remove                                       |

**Sequence B: Remove first, then Add**
| Propagation Constraint | **`Add: propagate`** | **`Add: unpropagate`** |
|------------------------|----------------------|------------------------|
| **`Remove: cascade`** <br/> *(or `cascadeWhenOrphan` when orphan)* | Symmetrical Context Add/Remove | Add isolated, Remove cascades to targets |
| **`Remove: keep`** <br/> *(or `cascadeWhenOrphan` when not orphan)* | Add expands Context, Remove leaves targets in Context | Symmetrical isolated Add/Remove |

To demonstrate this fundamental asymmetry, let's explore two specular scenarios.

### Scenario 1: `add: propagate` and `remove: keep`

Suppose we have an **IsRelatedTo** instance (`IRT1`) from `R1` to `R2` configured to propagate on add, but keep on remove.

**1. Initial State:** 

The scenario contains the following **Resource** instances:
- **Resource** instance `R1` exists in Context `C1`.
- **Resource** instance `R2` exists in Context `C1`.

The scenario contains the following **IsRelatedTo** instances:
- `R1` is linked to `R2` via **IsRelatedTo** instance `IRT12`, which exists in Context `C1` and is configured with `add: propagate` and `remove: keep`.

```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R2

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

**2. After Add (Add `R1` to Context `C2`):**
Adding `R1` to Context `C2` triggers the `propagate` constraint on `IRT12`. `IRT12` and `R2` are automatically pulled into Context `C2` alongside `R1`.
```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>, <i>C2</i>]</sub>"):::resource
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>, <i>C2</i>]</sub>"):::resource

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> remove: keep <br/> <sub>[<i>C1</i>, <i>C2</i>]</sub>"| R2

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

**3. After Remove (Remove `R1` from Context `C2`):**
We now remove `R1` from Context `C2`, attempting to revert our action. Because the constraint on `IRT12` is `keep`, `R2` is left untouched in Context `C2`. The final state does **not** match the initial state.
```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>, <i>C2</i>]</sub>"):::resource

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R2

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

### Scenario 2: `add: unpropagate` and `remove: cascade`

Suppose we have an **IsRelatedTo** instance (`IRT12`) configured to NOT propagate on add, but forcefully cascade on remove.

**1. Initial State:** 

The scenario contains the following **Resource** instances:
- **Resource** instance `R1` exists in Contexts `C1` and `C2`.
- **Resource** instance `R2` exists in Contexts `C1` and `C2`.

The scenario contains the following **IsRelatedTo** instances:
- `R1` is linked to `R2` via **IsRelatedTo** instance `IRT12`, which exists in Contexts `C1` and `C2` and is configured with `add: unpropagate` and `remove: cascade`.

```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::resource
    R2("<b>R2</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::resource

    R1 -->|"<b>IRT12</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1, C2</i>]</sub>"| R2

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

**2. After Remove (Remove `R1` from Context `C2`):**
Removing `R1` from Context `C2` triggers the strict `cascade` on `IRT12`. `IRT12` drops and `R2` is forcefully removed from Context `C2` as well.
```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource

    R1 -->|"<b>IRT12</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R2

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

**3. After Add (Add `R1` back to Context `C2`):**
We now add `R1` back into Context `C2`, attempting to revert the removal. Because the constraint on `IRT12` is `unpropagate`, `R2` does **not** follow `R1` into Context `C2`. Again, the final state is permanently altered from the initial state.
```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::resource
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource

    R1 -->|"<b>IRT12</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R2

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

## Reference Counting

Removing an instance from a Context simply erases its presence from that specific Venn diagram, but it does not necessarily destroy the instance from the global *Sea of Nodes* of the infrastructure. 

However, an instance has no reason to exist if it doesn't belong to any Context. To prevent the system from filling up with orphaned, invisible instances, the Information System behaves as under a strict **Reference Counting** paradigm, where the Contexts an instance belongs to are its references. The term describes the observable behaviour, not a stored counter. An instance can be removed from a Context either explicitly or implicitly via a removal avalanche. When it no longer belongs to any Context (meaning it no longer exists inside any Venn diagram), it faces true global destruction: the system automatically performs a full "Garbage Collection", permanently deleting the instance. *(Note on Race Conditions: Because every API operation is executed within an ACID transaction using Optimistic Concurrency Control, if two concurrent operations attempt to remove an instance from its last Contexts simultaneously, the database strictly serializes the final state. The winning transaction safely performs the Garbage Collection, while the losing transaction receives a concurrency error and is rolled back).*

> **Authorization Blast Radius in Avalanches:** A common concern is whether a user triggering an avalanche in Context `C1` needs explicit permissions in Context `C2` if their action indirectly causes an instance to be globally Garbage Collected from Context `C2`. The answer is **no**. An administrator operating in Context `C1` only drops their *own* **Relation** instances in Context `C1`. They never modify **Relation** instances in Context `C2`. If an instance happens to lose its last remaining Context presence (which was Context `C1`) and is Garbage Collected, it means by definition it was *already absent* from Context `C2`. The blast radius of any operation is naturally, mathematically contained within the boundaries of the authorized Context.

To see this in action across multiple Contexts, consider the following scenario involving **Resource** instances (the exact same garbage collection mechanism applies equally to **Facet** and **Relation** instances).

**1. Initial State:**
- **Resource** instance `R1` is present across three Contexts: `C1`, `C2`, and `C3`.
- **Resource** instance `R3` is present across Contexts `C1` and `C2`.
- **Resource** instance `R2` exists in Context `C1`.
- `R1` has outgoing **IsRelatedTo** instances: `IRT1` (with `remove: cascade`) pointing to `R2`, and `IRT2` (with `remove: cascade`) pointing to `R3`.

```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1, C2, C3</i>]</sub>"):::resource
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    R3("<b>R3</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::resource

    R1 -->|"<b>IRT1</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R2
    R1 -->|"<b>IRT2</b> <br/> remove: cascade <br/> <sub>[<i>C1, C2</i>]</sub>"| R3

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

**2. First Remove (Remove `R1` from Context `C1`):**
A user removes `R1` from Context `C1`. The `cascade` avalanche evaluates the outgoing **IsRelatedTo** instances in Context `C1`:
- `IRT1` drops. `R2` is removed from Context `C1`. Since Context `C1` was its **only** Context, `R2` reaches a reference count of 0 and is permanently **Garbage Collected**.
- `IRT2` drops from Context `C1`. `R3` is removed from Context `C1`. However, `R3` is still present in Context `C2`, so it safely survives.
- `R1` itself is removed from Context `C1`. It survives because it still exists in Contexts `C2` and `C3`.

```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C2, C3</i>]</sub>"):::resource
    R3("<b>R3</b> <br/> <sub>[<i>C2</i>]</sub>"):::resource

    R1 -->|"<b>IRT2</b> <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| R3

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

**3. Second Remove (Remove `R1` from Context `C2`):**
Later, a user removes `R1` from Context `C2`. The avalanche evaluates the outgoing **IsRelatedTo** instances in Context `C2`:
- `IRT2` drops from Context `C2`. `R3` is removed from Context `C2`. This was its last remaining Context. `R3` hits a reference count of 0 and is **Garbage Collected**.
- `R1` is removed from Context `C2`. It safely survives because it still exists in Context `C3`.

**Final State:**
The graph is not empty, but `R2` and `R3` have been physically destroyed because their respective reference counts dropped to zero. `R1` is the only survivor, resting securely in its last remaining Context `C3`.
```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C3</i>]</sub>"):::resource

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
```

## Comprehensive Scenario

Now that the basic mechanics are clear, we can analyze a complex, real-world topology involving multiple Contexts, differing constraints, and strict schema validation. This scenario demonstrates the full power of the "avalanche effect" combining both **Resource** instances and multiple **Facet** instances.

To provide a comprehensive view, we display the **Global Topology**, showing all instances with their respective Contexts annotated in brackets (e.g., `[C1, C2]`).

### Initial State

The scenario contains the following **Resource** instances:
- **Resource** instance `R1` exists in Contexts `C1` and `C2`.
- **Resource** instance `R2` exists in Context `C1`.
- **Resource** instance `R3` exists in Contexts `C1` and `C2`.
- **Resource** instance `R4` exists in Context `C2`.

The scenario contains the following **Facet** instances:
- **Facet** instance `F1a` exists in Contexts `C1` and `C2`.
- **Facet** instance `F1b` exists in Context `C1`.
- **Facet** instance `F2a` exists in Context `C1`.
- **Facet** instance `F2b` exists in Context `C1`.
- **Facet** instance `F2c` exists in Context `C1`.
- **Facet** instance `F3a` exists in Contexts `C1` and `C2`.
- **Facet** instance `F3b` exists in Context `C1`.
- **Facet** instance `F4a` exists in Context `C2`.
- **Facet** instance `F4b` exists in Context `C2`.

The scenario contains the following **ConsistsOf** instances:
- `R1` is attached to `F1a` via **ConsistsOf** instance `CO11a`, which exists in Contexts `C1` and `C2` and is configured with `add: propagate` and `remove: cascade`.
- `R1` is attached to `F1b` via **ConsistsOf** instance `CO11b`, which exists in Context `C1` and is configured with `add: propagate` and `remove: cascade`.
- `R2` is attached to `F2a` via **ConsistsOf** instance `CO22a`, which exists in Context `C1` and is configured with `add: propagate` and `remove: cascade`.
- `R2` is attached to `F2b` via **ConsistsOf** instance `CO22b`, which exists in Context `C1` and is configured with `add: unpropagate` and `remove: cascade`.
- `R2` is attached to `F2c` via **ConsistsOf** instance `CO22c`, which exists in Context `C1` and is configured with `add: propagate` and `remove: cascade`.
- `R3` is attached to `F3a` via **ConsistsOf** instance `CO33a`, which exists in Contexts `C1` and `C2` and is configured with `add: propagate` and `remove: cascade`.
- `R3` is attached to `F3b` via **ConsistsOf** instance `CO33b`, which exists in Context `C1` and is configured with `add: unpropagate` and `remove: cascade`.
- `R4` is attached to `F4a` via **ConsistsOf** instance `CO44a`, which exists in Context `C2` and is configured with `add: propagate` and `remove: cascade`.
- `R4` is attached to `F4b` via **ConsistsOf** instance `CO44b`, which exists in Context `C2` and is configured with `add: unpropagate` and `remove: cascade`.

The scenario contains the following **IsRelatedTo** instances:
- `R1` is linked to `R2` via **IsRelatedTo** instance `IRT12`, which exists in Context `C1` and is configured with `add: propagate` and `remove: keep`.
- `R1` is linked to `R3` via **IsRelatedTo** instance `IRT13`, which exists in Contexts `C1` and `C2` and is configured with `add: propagate` and `remove: cascadeWhenOrphan`.
- `R4` is linked to `R3` via **IsRelatedTo** instance `IRT43`, which exists in Context `C2` and is configured with `add: unpropagate` and `remove: cascade`.

*(Note: **ConsistsOf** instances must implicitly use `remove: cascade` by definition, as a **Facet** instance cannot be orphaned without its parent **Resource** instance).*

```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::resource
    F1a("<b>F1a</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::facet
    F1b("<b>F1b</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet
    
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    F2a("<b>F2a</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet
    F2b("<b>F2b</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet
    F2c("<b>F2c</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet

    R3("<b>R3</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::resource
    F3a("<b>F3a</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::facet
    F3b("<b>F3b</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet

    R4("<b>R4</b> <br/> <sub>[<i>C2</i>]</sub>"):::resource
    F4a("<b>F4a</b> <br/> <sub>[<i>C2</i>]</sub>"):::facet
    F4b("<b>F4b</b> <br/> <sub>[<i>C2</i>]</sub>"):::facet

    R1 -->|"<b>CO11a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C2</i>]</sub>"| F1a
    R1 -->|"<b>CO11b</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F1b

    R2 -->|"<b>CO22a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F2a
    R2 -->|"<b>CO22b</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F2b
    R2 -->|"<b>CO22c</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F2c

    R3 -->|"<b>CO33a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C2</i>]</sub>"| F3a
    R3 -->|"<b>CO33b</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F3b

    R4 -->|"<b>CO44a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| F4a
    R4 -->|"<b>CO44b</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| F4b

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R2
    R1 -->|"<b>IRT13</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C2</i>]</sub>"| R3
    
    R4 -->|"<b>IRT43</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| R3

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    classDef facet fill:#9bbb59,stroke:#4f6228,stroke-width:3px,color:#fff;
```

### Scenario A: The Add Avalanche

If a manager acting from Context `C2` (starting from the Initial State (Pre-Add)) adds `R1` into a new Context `C3`, the avalanche evaluates only the outgoing **Relation** instances visible from `R1` in Context `C2`. 
`F1b`, `R2` (and its **Facet** instances) are completely invisible to this operation. 
- **For `R1`:** `F1a` is propagated. `R3` is propagated.
- **For `R3` (pulled via `R1`):** Its outgoing **ConsistsOf** instances in Context `C2` are evaluated. `F3a` is pushed to Context `C3` (`propagate`).

The updated Global Topology shows `[C3]` added only to `R1`, `F1a`, `R3`, and `F3a`, and to the **IsRelatedTo** and **ConsistsOf** instances connecting them (`CO11a`, `IRT13`, and `CO33a`):
```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1, C2, C3</i>]</sub>"):::resource
    F1a("<b>F1a</b> <br/> <sub>[<i>C1, C2, C3</i>]</sub>"):::facet
    F1b("<b>F1b</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet
    
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>"):::resource
    F2a("<b>F2a</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet
    F2b("<b>F2b</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet
    F2c("<b>F2c</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet

    R3("<b>R3</b> <br/> <sub>[<i>C1, C2, C3</i>]</sub>"):::resource
    F3a("<b>F3a</b> <br/> <sub>[<i>C1, C2, C3</i>]</sub>"):::facet
    F3b("<b>F3b</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet

    R4("<b>R4</b> <br/> <sub>[<i>C2</i>]</sub>"):::resource
    F4a("<b>F4a</b> <br/> <sub>[<i>C2</i>]</sub>"):::facet
    F4b("<b>F4b</b> <br/> <sub>[<i>C2</i>]</sub>"):::facet

    R1 -->|"<b>CO11a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C2, C3</i>]</sub>"| F1a
    R1 -->|"<b>CO11b</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F1b

    R2 -->|"<b>CO22a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F2a
    R2 -->|"<b>CO22b</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F2b
    R2 -->|"<b>CO22c</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F2c

    R3 -->|"<b>CO33a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C2, C3</i>]</sub>"| F3a
    R3 -->|"<b>CO33b</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F3b

    R4 -->|"<b>CO44a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| F4a
    R4 -->|"<b>CO44b</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| F4b

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R2
    R1 -->|"<b>IRT13</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C2, C3</i>]</sub>"| R3
    
    R4 -->|"<b>IRT43</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| R3

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    classDef facet fill:#9bbb59,stroke:#4f6228,stroke-width:3px,color:#fff;
```

### Scenario B: Alternate Source Context

If, instead of starting from Context `C2`, the exact same add operation originates from Context `C1` (starting from the Initial State (Pre-Add)), the avalanche evaluates the outgoing **Relation** instances visible **only from Context C1**:
- **For `R1`:** Both `F1a` and `F1b` are pushed to Context `C3` (`propagate`). `R2` and `R3` are also pushed to Context `C3` (`propagate`).
- **For `R2` (pulled via `R1`):** Its outgoing **ConsistsOf** instances in Context `C1` are evaluated. `F2a` and `F2c` are pushed to Context `C3` (`propagate`), while `F2b` is left behind (`unpropagate`).
- **For `R3` (pulled via `R1`):** Its outgoing **ConsistsOf** instances in Context `C1` are evaluated. `F3a` is pushed to Context `C3` (`propagate`), while `F3b` is left behind (`unpropagate`).
- `R4` and its **Facet** instances are entirely invisible from Context `C1` and are unaffected.

The updated Global Topology shows `[C3]` added to the propagated elements:
```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1, C2, C3</i>]</sub>"):::resource
    F1a("<b>F1a</b> <br/> <sub>[<i>C1, C2, C3</i>]</sub>"):::facet
    F1b("<b>F1b</b> <br/> <sub>[<i>C1, C3</i>]</sub>"):::facet
    
    R2("<b>R2</b> <br/> <sub>[<i>C1, C3</i>]</sub>"):::resource
    F2a("<b>F2a</b> <br/> <sub>[<i>C1, C3</i>]</sub>"):::facet
    F2b("<b>F2b</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet
    F2c("<b>F2c</b> <br/> <sub>[<i>C1, C3</i>]</sub>"):::facet

    R3("<b>R3</b> <br/> <sub>[<i>C1, C2, C3</i>]</sub>"):::resource
    F3a("<b>F3a</b> <br/> <sub>[<i>C1, C2, C3</i>]</sub>"):::facet
    F3b("<b>F3b</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet

    R4("<b>R4</b> <br/> <sub>[<i>C2</i>]</sub>"):::resource
    F4a("<b>F4a</b> <br/> <sub>[<i>C2</i>]</sub>"):::facet
    F4b("<b>F4b</b> <br/> <sub>[<i>C2</i>]</sub>"):::facet

    R1 -->|"<b>CO11a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C2, C3</i>]</sub>"| F1a
    R1 -->|"<b>CO11b</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C3</i>]</sub>"| F1b

    R2 -->|"<b>CO22a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C3</i>]</sub>"| F2a
    R2 -->|"<b>CO22b</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F2b
    R2 -->|"<b>CO22c</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C3</i>]</sub>"| F2c

    R3 -->|"<b>CO33a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C2, C3</i>]</sub>"| F3a
    R3 -->|"<b>CO33b</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F3b

    R4 -->|"<b>CO44a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| F4a
    R4 -->|"<b>CO44b</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| F4b

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> remove: keep <br/> <sub>[<i>C1, C3</i>]</sub>"| R2
    R1 -->|"<b>IRT13</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C2, C3</i>]</sub>"| R3
    
    R4 -->|"<b>IRT43</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| R3

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    classDef facet fill:#9bbb59,stroke:#4f6228,stroke-width:3px,color:#fff;
```

### Scenario C: The Remove Avalanche

Starting directly from the state established in **Scenario B: Adding R1 from Context C1 to Context C3**, the manager now attempts to remove `R1` from Context `C1`. The avalanche evaluates the `remove` constraints on all outgoing **Relation** instances visible in Context `C1`:
- **For `R1`:** It is removed from Context `C1`. Its outgoing **ConsistsOf** instances `CO11a` and `CO11b` drop (`cascade`):
  - `F1a` is removed from Context `C1` but survives in Contexts `C2, C3`.
  - `F1b` is removed from Context `C1`. Since it existed in Contexts `C1` and `C3`, its Context presence count drops to 1, so it safely remains in `[C3]` and is **not** Garbage Collected. *(Note: if it had been exclusively in Context `C1`, its count would have hit zero and it would be Garbage Collected).*
- **On `R2`:** The **IsRelatedTo** instance `IRT12` drops, but its constraint is `keep`. `R2` safely survives in Context `C1` (retaining all its **Facet** instances in Context `C1`).
- **On `R3`:** The **IsRelatedTo** instance `IRT13` drops, and its constraint is `cascadeWhenOrphan`. `R3` checks for other incoming **IsRelatedTo** instances in Context `C1`. Finding none, it is **removed** from Context `C1`.
  - Because `R3` is removed from Context `C1`, its **Facet** instances must also follow the `cascade`: `F3a` survives in Contexts `C2, C3`, but `F3b` drops to zero Contexts and is permanently **Garbage Collected**.

The final Global Topology perfectly illustrates how `keep`, `cascadeWhenOrphan`, and **Facet** instance Garbage Collection shape the graph through cascading side effects:
```mermaid
---
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C2, C3</i>]</sub>"):::resource
    F1a("<b>F1a</b> <br/> <sub>[<i>C2, C3</i>]</sub>"):::facet
    F1b("<b>F1b</b> <br/> <sub>[<i>C3</i>]</sub>"):::facet
    
    R2("<b>R2</b> <br/> <sub>[<i>C1, C3</i>]</sub>"):::resource
    F2a("<b>F2a</b> <br/> <sub>[<i>C1, C3</i>]</sub>"):::facet
    F2b("<b>F2b</b> <br/> <sub>[<i>C1</i>]</sub>"):::facet
    F2c("<b>F2c</b> <br/> <sub>[<i>C1, C3</i>]</sub>"):::facet

    R3("<b>R3</b> <br/> <sub>[<i>C2, C3</i>]</sub>"):::resource
    F3a("<b>F3a</b> <br/> <sub>[<i>C2, C3</i>]</sub>"):::facet

    R4("<b>R4</b> <br/> <sub>[<i>C2</i>]</sub>"):::resource
    F4a("<b>F4a</b> <br/> <sub>[<i>C2</i>]</sub>"):::facet
    F4b("<b>F4b</b> <br/> <sub>[<i>C2</i>]</sub>"):::facet

    R1 -->|"<b>CO11a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C2, C3</i>]</sub>"| F1a
    R1 -->|"<b>CO11b</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C3</i>]</sub>"| F1b

    R2 -->|"<b>CO22a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C3</i>]</sub>"| F2a
    R2 -->|"<b>CO22b</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| F2b
    R2 -->|"<b>CO22c</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C3</i>]</sub>"| F2c

    R3 -->|"<b>CO33a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C2, C3</i>]</sub>"| F3a

    R4 -->|"<b>CO44a</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| F4a
    R4 -->|"<b>CO44b</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| F4b

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> remove: keep <br/> <sub>[<i>C3</i>]</sub>"| R2
    R1 -->|"<b>IRT13</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C2, C3</i>]</sub>"| R3
    
    R4 -->|"<b>IRT43</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C2</i>]</sub>"| R3

    classDef resource fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    classDef facet fill:#9bbb59,stroke:#4f6228,stroke-width:3px,color:#fff;
```

> **Advanced Scenarios:** The operations detailed above (Scenarios A, B, and C) cover standard tree-like topologies. The model's behavior becomes significantly more complex when dealing with topological cycles (loops) and diamond patterns (especially in conjunction with `cascadeWhenOrphan`). To explore how the system guarantees cycle-breaking and safe Garbage Collection in these advanced topologies, refer to [Complex Topology Scenarios](appendix/03-complex-topology-scenarios.md).
> 
> *(Note: The complex scenarios documented in the appendix are self-contained and fully understandable without prior knowledge of the REST APIs.)*
