// Five scopes of feedback — 2026-06-07
// "A diagram is worth 10,000 words." — russell@unturf.com
//
// One primitive (feedback) at five nested boundaries. Each row shows what
// crosses, the mechanism that lets it cross, and the implementation
// primitive that makes the mechanism real. The rows stack so a reader
// can run their eye top-to-bottom and see the abstraction widen.
digraph five_scopes {
    rankdir=TB
    splines=true
    nodesep=0.4
    ranksep=0.35
    node [shape=box, style="filled,rounded", fontname="Helvetica", fontsize=11, margin="0.15,0.08"]
    edge [fontname="Helvetica", fontsize=10, arrowsize=0.8]
    label="Five scopes of feedback — one primitive, five boundaries"
    labelloc=t
    fontsize=14
    fontname="Helvetica Bold"

    // Row 1 — within process
    subgraph cluster_1 {
        label="① Within process — call/cc continuation (live)"
        labelloc=b
        style="rounded,filled"
        fillcolor="#e8f4f8"
        color="#0984e3"
        fontname="Helvetica Bold"
        fontsize=11
        fontcolor="#0984e3"
        rank=same
        n1a [label="frame stack" fillcolor="#b3d9e8" color="#0984e3"]
        n1b [label="frame stack" fillcolor="#b3d9e8" color="#0984e3"]
        n1a -> n1b [color="#0984e3" penwidth=1.8]
    }

    // Row 2 — across process
    subgraph cluster_2 {
        label="② Across process — portal (VM state + continuation)"
        labelloc=b
        style="rounded,filled"
        fillcolor="#e8f5e9"
        color="#2e7d32"
        fontname="Helvetica Bold"
        fontsize=11
        fontcolor="#2e7d32"
        rank=same
        n2a [label="process A (any tier)" fillcolor="#a5d6a7" color="#2e7d32"]
        n2b [label="process B (any tier)" fillcolor="#a5d6a7" color="#2e7d32"]
        n2a -> n2b [color="#2e7d32" penwidth=1.8]
    }

    // Row 3 — across impl
    subgraph cluster_3 {
        label="③ Across impl — source-as-data (the reader)"
        labelloc=b
        style="rounded,filled"
        fillcolor="#fff8e1"
        color="#f57f17"
        fontname="Helvetica Bold"
        fontsize=11
        fontcolor="#f57f17"
        rank=same
        n3a [label="Python tier" fillcolor="#ffe082" color="#f57f17"]
        n3b [label="C / asm tier" fillcolor="#ffe082" color="#f57f17"]
        n3a -> n3b [color="#f57f17" penwidth=1.8]
    }

    // Row 4 — across machine
    subgraph cluster_4 {
        label="④ Across machine — TCP socket (request / response bytes)"
        labelloc=b
        style="rounded,filled"
        fillcolor="#fce4ec"
        color="#c2185b"
        fontname="Helvetica Bold"
        fontsize=11
        fontcolor="#c2185b"
        rank=same
        n4a [label="machine M1" fillcolor="#f8bbd0" color="#c2185b"]
        n4b [label="machine M2" fillcolor="#f8bbd0" color="#c2185b"]
        n4a -> n4b [color="#c2185b" penwidth=1.8]
    }

    // Row 5 — across compute
    subgraph cluster_5 {
        label="⑤ Across compute — (bend …) form (S-exp or BSHK binary)"
        labelloc=b
        style="rounded,filled"
        fillcolor="#f3e5f5"
        color="#7b1fa2"
        fontname="Helvetica Bold"
        fontsize=11
        fontcolor="#7b1fa2"
        rank=same
        n5a [label="host CPU (any tier)" fillcolor="#ce93d8" color="#7b1fa2"]
        n5b [label="CUDA worker + kernel" fillcolor="#ce93d8" color="#7b1fa2"]
        n5a -> n5b [color="#7b1fa2" penwidth=1.8]
    }

    // Invisible chain forces vertical stacking of clusters.
    n1a -> n2a [style=invis]
    n2a -> n3a [style=invis]
    n3a -> n4a [style=invis]
    n4a -> n5a [style=invis]
}
