Complex Topology Scenarios — Cyclic Graphs

This scenario introduces a complex topology containing structural cycles (loops) and diamond patterns. It demonstrates two critical administrative safety mechanisms of the IS-Model:

  1. Orphan Evaluation: How the system guarantees deterministic and safe garbage collection during a Remove from Context avalanche when cascadeWhenOrphan is used in diamond topologies.

  2. Cycle Breaking: How the system prevents infinite loops during an Add to Context avalanche when propagate constraints form a closed circuit.

Authorization assumed: The scenarios illustrate propagation only. The Contexts C1…C4 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.

Visual Disclaimer (Infrastructure Topology Focus): To avoid unreadable diagrams, this scenario visually focuses exclusively on the Infrastructure Topology (the graph of Resource instances and IsRelatedTo instances). While omitted from the diagrams to reduce noise, it is strictly understood that every Resource instance encapsulates its own Descriptive Topology (its attached Facet instances via ConsistsOf instances). During any propagation avalanche, whenever a Resource instance is added or removed from a Context, its Descriptive Topology strictly follows its parent Resource instance according to standard propagation rules.

The scenario contains the following Resource instances:

  • Resource instance R1 exists in Contexts C1 and C4.

  • Resource instance R2 exists in Contexts C1 and C4.

  • Resource instance R3 exists in Contexts C1 and C4.

  • Resource instance R4 exists in Contexts C1 and C3.

  • Resource instance R5 exists in Contexts C1, C2, C3 and C4.

  • Resource instance R6 exists in Contexts C1, C3 and C4.

  • Resource instance R7 exists in Contexts C1 and C3.

The scenario contains the following IsRelatedTo instances:

  • R1 is linked to R2 via IsRelatedTo instance IRT12, which exists in Contexts C1 and C4.

  • R2 is linked to R3 via IsRelatedTo instance IRT23, which exists in Contexts C1 and C4.

  • R2 is linked to R5 via IsRelatedTo instance IRT25, which exists in Contexts C1 and C4.

  • R3 is linked to R1 via IsRelatedTo instance IRT31, which exists in Context C1.

  • R3 is linked to R5 via IsRelatedTo instance IRT35, which exists in Contexts C1 and C4.

  • R3 is linked to R7 via IsRelatedTo instance IRT37, which exists in Context C1.

  • R4 is linked to R2 via IsRelatedTo instance IRT42, which exists in Context C1.

  • R5 is linked to R6 via IsRelatedTo instance IRT56, which exists in Contexts C1, C3 and C4.

  • R6 is linked to R3 via IsRelatedTo instance IRT63, which exists in Contexts C1 and C4.

  • R6 is linked to R7 via IsRelatedTo instance IRT67, which exists in Context C3.

---
title: "Graph D: Initial Global Topology"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1, C4</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1, C4</i>]</sub>")
    R3("<b>R3</b> <br/> <sub>[<i>C1, C4</i>]</sub>")
    R4("<b>R4</b> <br/> <sub>[<i>C1, C3</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1, C2, C3, C4</i>]</sub>")
    R6("<b>R6</b> <br/> <sub>[<i>C1, C3, C4</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1, C3</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C4</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C4</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C4</i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> add: unpropagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C4</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> add: propagate <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C3, C4</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C4</i>]</sub>"| R3
    R6 -->|"<b>IRT67</b> <br/> add: unpropagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C3</i>]</sub>"| R7

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

Part 1: The Remove Avalanche (Orphan Evaluation)

Visual Legend: Remove Avalanche

To trace the avalanche mechanisms clearly, the diagrams in this section use the following visual language:

---
title: "Visual Legend: Remove Avalanche"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    B("<b>Resource</b> <br/> (Dropping/Evaluating)"):::fading
    A1("<b>Resource</b> <br/> (Active/Surviving)")
    A2("<b>Resource</b> <br/> (Active/Surviving)")
    
    B -.->|"<b>IsRelatedTo</b> <br/> (Dropping/Evaluating)"| A1
    A1 -->|"<b>IsRelatedTo</b> <br/> (Active)"| A2

    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef fading fill:#d9d9d9,stroke:#808080,stroke-width:3px,color:#666666,stroke-dasharray: 5 5;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 0 stroke:#aaaaaa,stroke-width:3px,stroke-dasharray: 5 5;

An authorized user executes a Remove from Current Context operation (DELETE /instances/{type}/{R4-uuid}) on Resource instance R4 from Context C1, using the default propagationMode=shallow.

To accurately trace the avalanche, we temporarily isolate our view strictly to Context C1. Any IsRelatedTo instances or Resource instances that do not exist in C1 are unaffected by this local removal and can be safely ignored.

Visual Trace Disclaimer: Because an avalanche is evaluated strictly within the scope of the targeted Context, this trace projects the graph down to C1 only. When a node or edge visually vanishes from these intermediate diagrams, it exclusively means its C1 membership has been revoked. Whether the instance is physically Garbage Collected from the global database depends entirely on Reference Counting (as explained in Scenario C), which we will assess in the Final Global Topology.

The C1 sub-graph appears as follows:

---
title: "Graph D1.0: Isolated C1 Sub-graph"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>")
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R4("<b>R4</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1</i>]</sub>")
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;

Step 1: The Initial Trigger

The operation directly targets R4. The system schedules Resource instance R4 to be removed from Context C1. (In the following diagrams, nodes and edges turning grey and dashed indicate they are currently under evaluation for dropping from C1).

---
title: "Graph D1.1: Initial Trigger"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>")
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R4("<b>R4</b>"):::fading
    R5("<b>R5</b> <br/> <sub>[<i>C1</i>]</sub>")
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef fading fill:#d9d9d9,stroke:#808080,stroke-width:3px,color:#666666,stroke-dasharray: 5 5;
    linkStyle default stroke:#385d8a,stroke-width:3px;

Step 2: Topological Cleanup of IRT42 and Cascading to R2

Because Resource instance R4 is scheduled for removal from C1, any IsRelatedTo instance in C1 connected to it must also be dropped to maintain topological integrity. Consequently, the outgoing IsRelatedTo instance IRT42 drops from C1 (its line turns dashed). At this exact moment, its remove cascading constraints have not been evaluated yet.

---
title: "Graph D1.2: Topological Cleanup of IRT42"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>")
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1</i>]</sub>")
    R4("<b>R4</b>"):::fading
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    R4 -.->|"<b>IRT42</b> <br/> remove: cascade"| R2
    R5 -->|"<b>IRT56</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef fading fill:#d9d9d9,stroke:#808080,stroke-width:3px,color:#666666,stroke-dasharray: 5 5;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 6 stroke:#aaaaaa,stroke-width:3px,stroke-dasharray: 5 5;

At this junction, the behavior diverges based on the propagationMode:

  • If propagationMode=surgical (Safe Undo): The avalanche is intentionally halted here. The system physically drops R4 (along with all its attached Facet instances and the ConsistsOf instances attaching them) and the IsRelatedTo instance IRT42 from C1 to maintain topological integrity, but it explicitly ignores the remove propagation constraint of IRT42. R2 is completely spared, and the transaction ends securely.

  • If propagationMode=shallow (the standard cascading behavior): The system proceeds to evaluate the propagation constraint. IRT42 is configured with remove: cascade. Therefore, its target Resource instance R2 is inextricably pulled into the avalanche and is scheduled for removal from C1.

(In the following diagram, both R4 and IRT42 have fully vanished from C1, while R2 is now marked for removal).

---
title: "Graph D1.3: Cascading to R2"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b>"):::fading
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1</i>]</sub>")
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    R5 -->|"<b>IRT56</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef fading fill:#d9d9d9,stroke:#808080,stroke-width:3px,color:#666666,stroke-dasharray: 5 5;
    linkStyle default stroke:#385d8a,stroke-width:3px;

Step 3: Removing R2 and Evaluating its Outgoing Relations

With R2 scheduled for removal from C1, all its connected IsRelatedTo instances in C1 must drop due to topological integrity. This includes the incoming IRT12 (whose remove constraint is ignored because we are removing its target, not its source) and the outgoing IRT23 and IRT25.

(In the following diagram, the dropping relations are stripped of their C1 formatting).

---
title: "Graph D1.4: Connected Relations of R2 Drop"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b>"):::fading
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1</i>]</sub>")
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R1 -.->|"<b>IRT12</b>"| R2
    R2 -.->|"<b>IRT23</b> <br/> remove: cascadeWhenOrphan"| R3
    R2 -.->|"<b>IRT25</b> <br/> remove: cascade"| R5
    R3 -->|"<b>IRT31</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    R5 -->|"<b>IRT56</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef fading fill:#d9d9d9,stroke:#808080,stroke-width:3px,color:#666666,stroke-dasharray: 5 5;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 0,1,2 stroke:#aaaaaa,stroke-width:3px,stroke-dasharray: 5 5;

The system now evaluates the propagation constraints of the two outgoing IsRelatedTo instances:

  1. IRT23 (remove: cascadeWhenOrphan): The target is R3. The system checks if R3 has any other incoming IsRelatedTo instances remaining in C1. Since IRT63 is still active and pointing to R3, R3 is not an orphan. Therefore, R3 safely survives in C1.

---
title: "Graph D1.5: Evaluating IRT23"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b>"):::fading
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1</i>]</sub>")
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R2 -.->|"<b>IRT25</b> <br/> remove: cascade"| R5
    R3 -->|"<b>IRT31</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    R5 -->|"<b>IRT56</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef fading fill:#d9d9d9,stroke:#808080,stroke-width:3px,color:#666666,stroke-dasharray: 5 5;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 0 stroke:#aaaaaa,stroke-width:3px,stroke-dasharray: 5 5;
  1. IRT25 (remove: cascade): The target is R5. Because the constraint is a strict cascade, R5 is unconditionally pulled into the avalanche and scheduled for removal from C1.

---
title: "Graph D1.6: Cascading to R5"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b>"):::fading
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R3 -->|"<b>IRT31</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    R5 -->|"<b>IRT56</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef fading fill:#d9d9d9,stroke:#808080,stroke-width:3px,color:#666666,stroke-dasharray: 5 5;
    linkStyle default stroke:#385d8a,stroke-width:3px;

Step 4: Removing R5 and Evaluating IRT56

With R5 scheduled for removal from C1, its connected IsRelatedTo instances drop for topological integrity: the incoming IRT35 (whose remove constraint is ignored) and the outgoing IRT56.

---
title: "Graph D1.7: Connected Relations of R5 Drop"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b>"):::fading
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R3 -->|"<b>IRT31</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -.->|"<b>IRT35</b>"| R5
    R3 -->|"<b>IRT37</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    R5 -.->|"<b>IRT56</b> <br/> remove: cascadeWhenOrphan"| R6
    R6 -->|"<b>IRT63</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef fading fill:#d9d9d9,stroke:#808080,stroke-width:3px,color:#666666,stroke-dasharray: 5 5;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 1,3 stroke:#aaaaaa,stroke-width:3px,stroke-dasharray: 5 5;

The system evaluates the outgoing IRT56 (remove: cascadeWhenOrphan), which targets R6. It checks if R6 has any other incoming IsRelatedTo instances in C1. Since IRT56 was the only incoming link to R6 in this Context, R6 is an orphan. Consequently, R6 is scheduled for removal from C1.

---
title: "Graph D1.8: Cascading to R6"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R6("<b>R6</b>"):::fading
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R3 -->|"<b>IRT31</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT37</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    R6 -->|"<b>IRT63</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef fading fill:#d9d9d9,stroke:#808080,stroke-width:3px,color:#666666,stroke-dasharray: 5 5;
    linkStyle default stroke:#385d8a,stroke-width:3px;

Step 5: Removing R6, Evaluating IRT63, and the Post-State Orphan Check

With R6 scheduled for removal, its outgoing IsRelatedTo instance IRT63 drops. (Note: R6 also has an outgoing IRT67 in the global graph, but since IRT67 exists only in C3, it is completely unaffected by this C1 avalanche and is not evaluated).

---
title: "Graph D1.9: Post-State Orphan Check on R3"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R3 -->|"<b>IRT31</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT37</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    R6("<b>R6</b>"):::fading -.->|"<b>IRT63</b> <br/> remove: cascadeWhenOrphan"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef fading fill:#d9d9d9,stroke:#808080,stroke-width:3px,color:#666666,stroke-dasharray: 5 5;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 2 stroke:#aaaaaa,stroke-width:3px,stroke-dasharray: 5 5;

IRT63 has remove: cascadeWhenOrphan and targets R3. The system evaluates whether R3 is an orphan. Earlier in Step 3, R3 survived because IRT63 was acting as its protector. However, the IS-Model evaluates orphans based on the final post-state of the transaction (i.e., the set of relations that will survive the avalanche), not the real-time intermediate state. Because both IRT23 and IRT63 are scheduled for deletion within this same avalanche, R3 will have 0 incoming IsRelatedTo instances remaining in C1. Therefore, R3 is now correctly identified as an orphan and is scheduled for removal from C1.

---
title: "Graph D1.10: Cascading to R3"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R3("<b>R3</b>"):::fading
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R3 -->|"<b>IRT31</b> <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT37</b> <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef fading fill:#d9d9d9,stroke:#808080,stroke-width:3px,color:#666666,stroke-dasharray: 5 5;
    linkStyle default stroke:#385d8a,stroke-width:3px;

Step 6: Removing R3 and Evaluating IRT31 and IRT37

With R3 dropping, its outgoing IsRelatedTo instances IRT31 and IRT37 drop for topological integrity.

---
title: "Graph D1.11: Connected Relations of R3 Drop"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R3("<b>R3</b>"):::fading -.->|"<b>IRT31</b> <br/> remove: cascadeWhenOrphan"| R1
    R3 -.->|"<b>IRT37</b> <br/> remove: keep"| R7
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef fading fill:#d9d9d9,stroke:#808080,stroke-width:3px,color:#666666,stroke-dasharray: 5 5;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 0,1 stroke:#aaaaaa,stroke-width:3px,stroke-dasharray: 5 5;

Evaluating the constraints:

  • IRT31 (remove: cascadeWhenOrphan): Targets R1. Since IRT31 was the only incoming link to R1 in C1, R1 is an orphan and drops.

  • IRT37 (remove: keep): Targets R7. Because the constraint is keep, R7 survives safely in C1.

Final Local Topology in C1

The avalanche concludes. The only original Resource instance that survived the removal chain in C1 is R7.

---
title: "Graph D1.12: Final Surviving Instances in C1"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;

Final Global Topology

Zooming back out to the global perspective, the initial graph D1 has transformed. The Context C1 has been stripped from all Resource instances except R7. Furthermore, the IsRelatedTo instances IRT31, IRT37, and IRT42 (which existed exclusively in C1) have been completely physically Garbage Collected.

---
title: "Graph D1.13: Final Global Topology"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C4</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C4</i>]</sub>")
    R3("<b>R3</b> <br/> <sub>[<i>C4</i>]</sub>")
    R4("<b>R4</b> <br/> <sub>[<i>C3</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C2, C3, C4</i>]</sub>")
    R6("<b>R6</b> <br/> <sub>[<i>C3, C4</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1, C3</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C4</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C4</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C4</i>]</sub>"| R5
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C4</i>]</sub>"| R5
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C3, C4</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C4</i>]</sub>"| R3
    R6 -->|"<b>IRT67</b> <br/> add: unpropagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C3</i>]</sub>"| R7

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

Part 2: The Add Avalanche (Cycle Breaking)

Visual Legend: Add Avalanche

For the addition scenarios, we use a distinct visual language to represent instances that are being injected into a new Context:

---
title: "Visual Legend: Add Avalanche"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "transparent"
---
graph LR
    A("<b>Resource</b> <br/> (Visited / Added)"):::spawning
    B("<b>Resource</b> <br/> (Under Evaluation)"):::evaluating
    C("<b>Resource</b> <br/> (Unprocessed / Existing in Source)")
    
    A -->|"<div style='border:1px solid #8faadc; padding:2px 4px; background-color:#ffffff;'><b>IsRelatedTo</b> <br/> (Visited / Added)</div>"| B
    B -->|"<div style='border:2px solid #ed7d31; padding:2px 4px; background-color:#ffffff;'><b>IsRelatedTo</b> <br/> (Under Evaluation)</div>"| C

    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef spawning fill:#b4c6e7,stroke:#8faadc,stroke-width:3px,color:#333;
    classDef evaluating fill:#b4c6e7,stroke:#ed7d31,stroke-width:4px,color:#333;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 0 stroke:#8faadc,stroke-width:3px;
    linkStyle 1 stroke:#ed7d31,stroke-width:4px;

To demonstrate the Add to Context avalanche, the different propagationMode behaviors (surgical, shallow, deep), and the cycle-breaking mechanism:

---
title: "Graph D: Initial Global Topology (Repeated)"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1, C4</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1, C4</i>]</sub>")
    R3("<b>R3</b> <br/> <sub>[<i>C1, C4</i>]</sub>")
    R4("<b>R4</b> <br/> <sub>[<i>C1, C3</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1, C2, C3, C4</i>]</sub>")
    R6("<b>R6</b> <br/> <sub>[<i>C1, C3, C4</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1, C3</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C4</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C4</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C4</i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> add: unpropagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C4</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> add: propagate <br/> remove: keep <br/> <sub>[<i>C1</i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C3, C4</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C4</i>]</sub>"| R3
    R6 -->|"<b>IRT67</b> <br/> add: unpropagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C3</i>]</sub>"| R7

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

Step 1: The Initial Trigger and the Visited Set

An authorized user (e.g., an IS-Admin) executes an Add to Context operation (PUT /instances/{type}/{R2-uuid}/contexts/{C2}) on Resource instance R2 from Context C1 into Context C2.

To accurately trace the avalanche and reduce visual noise, we temporarily isolate our view strictly to Context C1 (the source Context) and Context C2 (the target Context). Any instances or relations that do not exist in either C1 or C2 are safely ignored.

---
title: "Graph D2.0: Isolated C1/C2 Sub-graph"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1</i>]</sub>")
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R4("<b>R4</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1, C2</i>]</sub>")
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    linkStyle default stroke:#385d8a,stroke-width:3px;

To prevent infinite loops during propagation avalanches, the system maintains a Visited Set tracking the instances that have already been evaluated. At the start of the operation, R2 is immediately added to the Visited Set. Only Resource instances (vertices) are tracked in the Visited Set; relations are implicitly bound by the status of their source vertices.

If the operation is executed using propagationMode=surgical, the avalanche is intentionally halted here. The system adds R2 to C2, together with each of its ConsistsOf instances whose add constraint is propagate and the Facet instance it points to, and stops. No outgoing IsRelatedTo instances are processed. The resulting topology isolates R2 within C2 without pushing it down the graph (we highlight the newly added Context C2 in bold):

---
title: "Graph D2.1: Surgical Addition of R2 to C2 | Visited Set: {R2}"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::evaluating
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R4("<b>R4</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1, C2</i>]</sub>")
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef spawning fill:#b4c6e7,stroke:#8faadc,stroke-width:3px,color:#333;
    classDef evaluating fill:#b4c6e7,stroke:#ed7d31,stroke-width:4px,color:#333;
    linkStyle default stroke:#385d8a,stroke-width:3px;

Step 2: Evaluating Outgoing Relations (shallow vs deep)

If the operation is instead executed using propagationMode=shallow (the default) or propagationMode=deep, the system proceeds to evaluate the outgoing IsRelatedTo instances from R2 visible in the source Context C1. These are IRT25 and IRT23. (Their evaluation order is undefined, but for this trace we will analyze IRT25 first).

The IsRelatedTo instance IRT25 has an add: propagate constraint and targets R5. Because R5 is already physically present in the destination Context C2 (as seen by its initial [C1, C2] tags), the Add to Context operation on R5 acts as a no-op update. However, the IsRelatedTo instance IRT25 itself successfully propagates and is added to C2.

At this junction, the behavior diverges based on the propagationMode:

  • If propagationMode=shallow: Because R5 was already present in C2 prior to this operation, the avalanche HALTS its downward traversal along this branch immediately. (Effectively, R5 is treated as if it were added to the Visited Set without exploring its children).

  • If propagationMode=deep: The system ignores the fact that R5 was already present and forcefully continues the avalanche. The system begins evaluating R5, adding it to the Visited Set.

(For the remainder of this scenario, we will assume propagationMode=deep to trace the full cycle-breaking logic).

---
title: "Graph D2.2: Evaluating IRT25 | Visited Set: {R2, R5}"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R4("<b>R4</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::evaluating
    R6("<b>R6</b> <br/> <sub>[<i>C1</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef spawning fill:#b4c6e7,stroke:#8faadc,stroke-width:3px,color:#333;
    classDef evaluating fill:#b4c6e7,stroke:#ed7d31,stroke-width:4px,color:#333;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 2 stroke:#ed7d31,stroke-width:4px;

Step 3: Propagating from R5 to R6

The system evaluates the outgoing IsRelatedTo instances from R5 visible in C1. The only relation is IRT56 (add: propagate), which targets R6. R6 is not present in C2, so it is injected into C2 along with the IsRelatedTo instance IRT56. R6 is added to the Visited Set.

---
title: "Graph D2.4: Propagating IRT56 to R6 | Visited Set: {R2, R5, R6}"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R3("<b>R3</b> <br/> <sub>[<i>C1</i>]</sub>")
    R4("<b>R4</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::spawning
    R6("<b>R6</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::evaluating
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef spawning fill:#b4c6e7,stroke:#8faadc,stroke-width:3px,color:#333;
    classDef evaluating fill:#b4c6e7,stroke:#ed7d31,stroke-width:4px,color:#333;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 2 stroke:#8faadc,stroke-width:3px;
    linkStyle 7 stroke:#ed7d31,stroke-width:4px;

Step 4: Propagating from R6 to R3

The system evaluates the outgoing IsRelatedTo instances from R6 visible in C1. (Note: R6 possesses another outgoing IsRelatedTo instance IRT67 in the global graph, but since IRT67 exists only in Context C3, it is completely invisible to this avalanche sourced from C1 and is ignored).

The visible relation IRT63 (add: propagate) targets R3. R3 is injected into C2 along with the IsRelatedTo instance IRT63, and R3 is added to the Visited Set.

---
title: "Graph D2.5: Propagating IRT63 to R3 | Visited Set: {R2, R5, R6, R3}"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R3("<b>R3</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::evaluating
    R4("<b>R4</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::spawning
    R6("<b>R6</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef spawning fill:#b4c6e7,stroke:#8faadc,stroke-width:3px,color:#333;
    classDef evaluating fill:#b4c6e7,stroke:#ed7d31,stroke-width:4px,color:#333;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 2,7 stroke:#8faadc,stroke-width:3px;
    linkStyle 8 stroke:#ed7d31,stroke-width:4px;

Step 5: Cycle Breaking on IRT35

The system evaluates the outgoing IsRelatedTo instances from R3 visible in C1. We begin with IRT35 (add: propagate), which targets R5.

The system checks the Visited Set and discovers that R5 has already been evaluated in this transaction (Visited Set: {R2, R5, R6, R3}). Following the rules of a Modified Depth-First Search (DFS), the system successfully processes the edge but avoids infinite recursion: the IsRelatedTo instance IRT35 itself is added to C2 (as a direct consequence of its add: propagate constraint; had it been unpropagate, it would have been left behind), but the avalanche halts along this specific branch without re-evaluating R5 or its downstream linked Resource instances. This safely breaks the topological cycle (R5 -> R6 -> R3 -> R5).

---
title: "Graph D2.6: Cycle Break on IRT35 | Visited Set: {R2, R5, R6, R3}"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R3("<b>R3</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R4("<b>R4</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::spawning
    R6("<b>R6</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R7("<b>R7</b> <br/> <sub>[<i>C1</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef spawning fill:#b4c6e7,stroke:#8faadc,stroke-width:3px,color:#333;
    classDef evaluating fill:#b4c6e7,stroke:#ed7d31,stroke-width:4px,color:#333;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 2,7,8 stroke:#8faadc,stroke-width:3px;
    linkStyle 4 stroke:#ed7d31,stroke-width:4px;

Step 6: Propagating IRT37

The system evaluates the next outgoing IsRelatedTo instance from R3: IRT37 (add: propagate), targeting R7. R7 is injected into C2 and added to the Visited Set ({R2, R5, R6, R3, R7}). Since R7 has no outgoing IsRelatedTo instances in C1, this branch concludes.

---
title: "Graph D2.7: Propagating IRT37 to R7 | Visited Set: {R2, R5, R6, R3, R7}"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R3("<b>R3</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R4("<b>R4</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::spawning
    R6("<b>R6</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R7("<b>R7</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::evaluating

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef spawning fill:#b4c6e7,stroke:#8faadc,stroke-width:3px,color:#333;
    classDef evaluating fill:#b4c6e7,stroke:#ed7d31,stroke-width:4px,color:#333;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 2,4,7,8 stroke:#8faadc,stroke-width:3px;
    linkStyle 5 stroke:#ed7d31,stroke-width:4px;

Step 7: Halting on IRT31

The system evaluates the final outgoing IsRelatedTo instance from R3: IRT31. It has the constraint add: unpropagate. Regardless of the target’s status, the avalanche stops here. The IsRelatedTo instance IRT31 and its target R1 are not added to C2.

---
title: "Graph D2.8: Unpropagate Halt on IRT31 | Visited Set: {R2, R5, R6, R3, R7}"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R3("<b>R3</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R4("<b>R4</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1, C2</i>]</sub>"):::spawning
    R6("<b>R6</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R7("<b>R7</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef spawning fill:#b4c6e7,stroke:#8faadc,stroke-width:3px,color:#333;
    classDef evaluating fill:#b4c6e7,stroke:#ed7d31,stroke-width:4px,color:#333;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 2,4,5,7,8 stroke:#8faadc,stroke-width:3px;
    linkStyle 3 stroke:#ed7d31,stroke-width:4px;

Step 8: Final Cycle Break on IRT23

The depth-first traversal of the IRT25 branch is fully resolved. The system returns to the original root node R2 to evaluate its remaining outgoing IsRelatedTo instance IRT23 (add: propagate).

IRT23 targets R3. The system checks the Visited Set ({R2, R5, R6, R3, R7}) and discovers that R3 has already been fully evaluated through the other loop. The avalanche halts immediately. IRT23 is added to C2, but no further traversal occurs.

---
title: "Graph D2.9: Cycle Break on IRT23 | Visited Set: {R2, R5, R6, R3, R7}"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R3("<b>R3</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R4("<b>R4</b> <br/> <sub>[<i>C1</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R6("<b>R6</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning
    R7("<b>R7</b> <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"):::spawning

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> add: unpropagate <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> <sub>[<i>C1, <b>C2</b></i>]</sub>"| R3
    
    classDef default fill:#4f81bd,stroke:#385d8a,stroke-width:3px,color:#fff;
    classDef spawning fill:#b4c6e7,stroke:#8faadc,stroke-width:3px,color:#333;
    classDef evaluating fill:#b4c6e7,stroke:#ed7d31,stroke-width:4px,color:#333;
    linkStyle default stroke:#385d8a,stroke-width:3px;
    linkStyle 2,4,5,7,8 stroke:#8faadc,stroke-width:3px;
    linkStyle 1 stroke:#ed7d31,stroke-width:4px;

The entire transaction concludes safely.

Final Global Topology

Zooming back out to the global perspective (reintroducing C3 and C4), the avalanche initiated in C1 has successfully replicated the cyclic propagated cluster into C2 without getting trapped in infinite loops. R1 and R4 were shielded by unpropagate or directional constraints, while the R2->R5->R6->R3 cluster was perfectly synchronized.

---
title: "Graph D2.10: Final Global Topology"
config:
  theme: neutral
  flowchart:
    edgeLabelBackground: "#ffffff"
---
graph LR
    R1("<b>R1</b> <br/> <sub>[<i>C1, C4</i>]</sub>")
    R2("<b>R2</b> <br/> <sub>[<i>C1, C2, C4</i>]</sub>")
    R3("<b>R3</b> <br/> <sub>[<i>C1, C2, C4</i>]</sub>")
    R4("<b>R4</b> <br/> <sub>[<i>C1, C3</i>]</sub>")
    R5("<b>R5</b> <br/> <sub>[<i>C1, C2, C3, C4</i>]</sub>")
    R6("<b>R6</b> <br/> <sub>[<i>C1, C2, C3, C4</i>]</sub>")
    R7("<b>R7</b> <br/> <sub>[<i>C1, C2, C3</i>]</sub>")

    R1 -->|"<b>IRT12</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C4</i>]</sub>"| R2
    R2 -->|"<b>IRT23</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C2, C4</i>]</sub>"| R3
    R2 -->|"<b>IRT25</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C2, C4</i>]</sub>"| R5
    R3 -->|"<b>IRT31</b> <br/> add: unpropagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1</i>]</sub>"| R1
    R3 -->|"<b>IRT35</b> <br/> add: propagate <br/> remove: cascade <br/> <sub>[<i>C1, C2, C4</i>]</sub>"| R5
    R3 -->|"<b>IRT37</b> <br/> add: propagate <br/> remove: keep <br/> <sub>[<i>C1, C2</i>]</sub>"| R7
    R4 -->|"<b>IRT42</b> <br/> add: unpropagate <br/> remove: cascade <br/> <sub>[<i>C1</i>]</sub>"| R2
    R5 -->|"<b>IRT56</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C2, C3, C4</i>]</sub>"| R6
    R6 -->|"<b>IRT63</b> <br/> add: propagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C1, C2, C4</i>]</sub>"| R3
    R6 -->|"<b>IRT67</b> <br/> add: unpropagate <br/> remove: cascadeWhenOrphan <br/> <sub>[<i>C3</i>]</sub>"| R7

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