figdown 0.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,54 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 527 596" width="527" height="596" font-family="system-ui,sans-serif"><defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker><pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" stroke="#bbb" stroke-width="2"/></pattern></defs><g transform="translate(18,6)"><line data-edge="22" x1="157.16" y1="56" x2="96.44000000000003" y2="100" stroke="#555" stroke-width="1.6"/><line data-edge="23" x1="197.12" y1="56" x2="234.08000000000004" y2="100" stroke="#555" stroke-width="1.6"/><line data-edge="24" x1="221.2" y1="50.810457516339866" x2="371.72" y2="100" stroke="#555" stroke-width="1.6"/><line data-edge="25" x1="277.20000000000005" y1="50.810457516339866" x2="126.68000000000004" y2="100" stroke="#555" stroke-width="1.6"/><line data-edge="26" x1="301.28000000000003" y1="56" x2="264.32000000000005" y2="100" stroke="#555" stroke-width="1.6"/><line data-edge="27" x1="341.24000000000007" y1="56" x2="401.96000000000004" y2="100" stroke="#555" stroke-width="1.6"/><line data-edge="28" x1="69.98000000000002" y1="136" x2="66.02000000000001" y2="180" stroke="#555" stroke-width="1.6"/><line data-edge="29" x1="249.20000000000005" y1="136" x2="249.20000000000002" y2="180" stroke="#555" stroke-width="1.6"/><line data-edge="30" x1="428.4200000000001" y1="136" x2="432.38" y2="180" stroke="#555" stroke-width="1.6"/><line data-edge="34" x1="132.40000000000003" y1="118" x2="188.40000000000003" y2="118" stroke="#dc2626" stroke-width="1.6" stroke-dasharray="6 4"/><g data-node="sp1" data-x="142.8" data-y="20" style="cursor:move"><rect x="142.8" y="20" width="78.4" height="36" rx="14" fill="#e0e7ff" stroke="#8a8880" stroke-width="1.8"/><text x="182" y="42.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Spine-1</text></g><g data-node="sp2" data-x="277.20000000000005" data-y="20" style="cursor:move"><rect x="277.20000000000005" y="20" width="78.4" height="36" rx="14" fill="#e0e7ff" stroke="#8a8880" stroke-width="1.8"/><text x="316.40000000000003" y="42.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Spine-2</text></g><g data-node="lf1" data-x="10.800000000000011" data-y="100" style="cursor:move"><rect x="10.800000000000011" y="100" width="121.60000000000001" height="36" rx="14" fill="#fff" stroke="#8a8880" stroke-width="1.8"/><text x="71.60000000000002" y="122.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Leaf-1 (VTEP)</text></g><g data-node="lf2" data-x="188.40000000000003" data-y="100" style="cursor:move"><rect x="188.40000000000003" y="100" width="121.60000000000001" height="36" rx="14" fill="#fff" stroke="#8a8880" stroke-width="1.8"/><text x="249.20000000000005" y="122.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Leaf-2 (VTEP)</text></g><g data-node="lf3" data-x="366.00000000000006" data-y="100" style="cursor:move"><rect x="366.00000000000006" y="100" width="121.60000000000001" height="36" rx="14" fill="#fff" stroke="#8a8880" stroke-width="1.8"/><text x="426.80000000000007" y="122.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Leaf-3 (VTEP)</text></g><g data-node="h1" data-x="0" data-y="180" style="cursor:move"><rect x="0" y="180" width="128.8" height="36" fill="#fff" stroke="#8a8880"/><text x="64.4" y="202.55" font-size="13" text-anchor="middle" fill="#1d1d1b">VM-A (VLAN 10)</text></g><g data-node="h2" data-x="184.8" data-y="180" style="cursor:move"><rect x="184.8" y="180" width="128.8" height="36" fill="#fff" stroke="#8a8880"/><text x="249.20000000000002" y="202.55" font-size="13" text-anchor="middle" fill="#1d1d1b">VM-B (VLAN 10)</text></g><g data-node="h3" data-x="369.6" data-y="180" style="cursor:move"><rect x="369.6" y="180" width="128.8" height="36" fill="#fff" stroke="#8a8880"/><text x="434" y="202.55" font-size="13" text-anchor="middle" fill="#1d1d1b">VM-C (VLAN 20)</text></g><text x="126.80000000000001" y="72.25" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">eBGP</text><text x="126.80000000000001" y="72.25" font-size="11" text-anchor="middle" fill="#555">eBGP</text><text x="160.40000000000003" y="112.25" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">VXLAN VNI 10010</text><text x="160.40000000000003" y="112.25" font-size="11" text-anchor="middle" fill="#dc2626">VXLAN VNI 10010</text><path d="M132.40000000000003 118 L142.48000000000005 112.4 L142.48000000000005 123.6 z" fill="#dc2626" stroke="none"/><path d="M188.40000000000003 118 L178.32000000000002 123.6 L178.32000000000002 112.4 z" fill="#dc2626" stroke="none"/><text x="0" y="240" font-size="13" font-weight="600">VNI mapping</text><rect x="0" y="248" width="71.2" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="vni:0:1" style="cursor:pointer"/><text x="35.6" y="265.3" font-size="12" text-anchor="middle" font-weight="600">Leaf</text><rect x="71.2" y="248" width="56.8" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="vni:0:2" style="cursor:pointer"/><text x="99.6" y="265.3" font-size="12" text-anchor="middle" font-weight="600">VLAN</text><rect x="128" y="248" width="64" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="vni:0:3" style="cursor:pointer"/><text x="160" y="265.3" font-size="12" text-anchor="middle" font-weight="600">VNI</text><rect x="192" y="248" width="56.8" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="vni:0:4" style="cursor:pointer"/><text x="220.4" y="265.3" font-size="12" text-anchor="middle" font-weight="600">Type</text><rect x="0" y="274" width="71.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:1:1" style="cursor:pointer"/><text x="7" y="291.3" font-size="12" text-anchor="start">Leaf-1</text><rect x="71.2" y="274" width="56.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:1:2" style="cursor:pointer"/><text x="99.6" y="291.3" font-size="12" text-anchor="middle">10</text><rect x="128" y="274" width="64" height="26" fill="#fee2e2" stroke="#c9c7bf" data-cell="vni:1:3" style="cursor:pointer"/><text x="135" y="291.3" font-size="12" text-anchor="start">10010</text><rect x="192" y="274" width="56.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:1:4" style="cursor:pointer"/><text x="199" y="291.3" font-size="12" text-anchor="start">L2</text><rect x="0" y="300" width="71.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:2:1" style="cursor:pointer"/><text x="7" y="317.3" font-size="12" text-anchor="start">Leaf-2</text><rect x="71.2" y="300" width="56.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:2:2" style="cursor:pointer"/><text x="99.6" y="317.3" font-size="12" text-anchor="middle">10</text><rect x="128" y="300" width="64" height="26" fill="#fee2e2" stroke="#c9c7bf" data-cell="vni:2:3" style="cursor:pointer"/><text x="135" y="317.3" font-size="12" text-anchor="start">10010</text><rect x="192" y="300" width="56.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:2:4" style="cursor:pointer"/><text x="199" y="317.3" font-size="12" text-anchor="start">L2</text><rect x="0" y="326" width="71.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:3:1" style="cursor:pointer"/><text x="7" y="343.3" font-size="12" text-anchor="start">Leaf-3</text><rect x="71.2" y="326" width="56.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:3:2" style="cursor:pointer"/><text x="99.6" y="343.3" font-size="12" text-anchor="middle">20</text><rect x="128" y="326" width="64" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:3:3" style="cursor:pointer"/><text x="135" y="343.3" font-size="12" text-anchor="start">10020</text><rect x="192" y="326" width="56.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:3:4" style="cursor:pointer"/><text x="199" y="343.3" font-size="12" text-anchor="start">L2</text><text x="0" y="396" font-size="13" font-weight="600">Fabric planes</text><rect x="0" y="404" width="136" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="planes:0:1" style="cursor:pointer"/><text x="68" y="421.3" font-size="12" text-anchor="middle" font-weight="600">Plane</text><rect x="136" y="404" width="143.2" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="planes:0:2" style="cursor:pointer"/><text x="207.6" y="421.3" font-size="12" text-anchor="middle" font-weight="600">Protocol</text><rect x="279.2" y="404" width="208" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="planes:0:3" style="cursor:pointer"/><text x="383.2" y="421.3" font-size="12" text-anchor="middle" font-weight="600">Role</text><rect x="0" y="430" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:1:1" style="cursor:pointer"/><text x="7" y="447.3" font-size="12" text-anchor="start">Underlay</text><rect x="136" y="430" width="143.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:1:2" style="cursor:pointer"/><text x="143" y="447.3" font-size="12" text-anchor="start">eBGP</text><rect x="279.2" y="430" width="208" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:1:3" style="cursor:pointer"/><text x="286.2" y="447.3" font-size="12" text-anchor="start">loopback reachability</text><rect x="0" y="456" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:2:1" style="cursor:pointer"/><text x="7" y="473.3" font-size="12" text-anchor="start">Overlay control</text><rect x="136" y="456" width="143.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:2:2" style="cursor:pointer"/><text x="143" y="473.3" font-size="12" text-anchor="start">MP-BGP EVPN</text><rect x="279.2" y="456" width="208" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:2:3" style="cursor:pointer"/><text x="286.2" y="473.3" font-size="12" text-anchor="start">MAC/IP route distribution</text><rect x="0" y="482" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:3:1" style="cursor:pointer"/><text x="7" y="499.3" font-size="12" text-anchor="start">Overlay data</text><rect x="136" y="482" width="143.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:3:2" style="cursor:pointer"/><text x="143" y="499.3" font-size="12" text-anchor="start">VXLAN (UDP 4789)</text><rect x="279.2" y="482" width="208" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:3:3" style="cursor:pointer"/><text x="286.2" y="499.3" font-size="12" text-anchor="start">L2-in-L3 encapsulation</text><rect x="0" y="549" width="16" height="11" fill="#fff" stroke="#555"/><text x="21" y="558.5" font-size="11" fill="#1d1d1b">Physical underlay link — eBGP/L3 transport between leaf and spine</text><rect x="0" y="569" width="16" height="11" fill="#dc2626" stroke="#555" stroke-dasharray="6 4"/><text x="21" y="578.5" font-size="11" fill="#1d1d1b">Logical VXLAN overlay tunnel — rides on the physical underlay</text></g><metadata id="figdown-source" data-sha256="a4518bb370358dede9dc83a015667587b74d738a1d5b1112547d14c0eff955d8"><![CDATA[
2
+ figdown 0.1 topology
3
+ title "VXLAN/EVPN Leaf-Spine Fabric — topology with plane notes"
4
+
5
+ # ── Semantic classes ─────────────────────────────────────────────────
6
+ class underlay "Physical underlay link — eBGP/L3 transport between leaf and spine"
7
+ class overlay "Logical VXLAN overlay tunnel — rides on the physical underlay" style=dashed color=#dc2626
8
+
9
+ # ── Topology ────────────────────────────────────────────────────────
10
+ node sp1 "Spine-1" shape=rounded color=#e0e7ff
11
+ node sp2 "Spine-2" shape=rounded color=#e0e7ff
12
+ node lf1 "Leaf-1 (VTEP)" shape=rounded
13
+ node lf2 "Leaf-2 (VTEP)" shape=rounded
14
+ node lf3 "Leaf-3 (VTEP)" shape=rounded
15
+ node h1 "VM-A (VLAN 10)"
16
+ node h2 "VM-B (VLAN 10)"
17
+ node h3 "VM-C (VLAN 20)"
18
+ flow down
19
+ rank sp1 sp2
20
+ rank lf1 lf2 lf3
21
+
22
+ # underlay: every leaf peers with every spine
23
+ edge sp1 -[eBGP]- lf1 class=underlay
24
+ edge sp1 -- lf2 class=underlay
25
+ edge sp1 -- lf3 class=underlay
26
+ edge sp2 -- lf1 class=underlay
27
+ edge sp2 -- lf2 class=underlay
28
+ edge sp2 -- lf3 class=underlay
29
+ edge lf1 -- h1 class=underlay
30
+ edge lf2 -- h2 class=underlay
31
+ edge lf3 -- h3 class=underlay
32
+
33
+ # overlay: VXLAN tunnel between the two VTEPs sharing VNI 10010
34
+ layer overlay "VXLAN tunnels" z=2
35
+ edge lf1 <-[VXLAN VNI 10010]-> lf2 class=overlay layer=overlay
36
+
37
+ # ── Supplementary knowledge ─────────────────────────────────────────
38
+ table vni "VNI mapping"
39
+ | Leaf | VLAN | VNI | Type |
40
+ |--------|:----:|-------|------|
41
+ | Leaf-1 | 10 | 10010 | L2 |
42
+ | Leaf-2 | 10 | 10010 | L2 |
43
+ | Leaf-3 | 20 | 10020 | L2 |
44
+ cell 1,3 color=#fee2e2
45
+ cell 2,3 color=#fee2e2
46
+
47
+ table planes "Fabric planes"
48
+ | Plane | Protocol | Role |
49
+ |-----------------|-------------------|---------------------------|
50
+ | Underlay | eBGP | loopback reachability |
51
+ | Overlay control | MP-BGP EVPN | MAC/IP route distribution |
52
+ | Overlay data | VXLAN (UDP 4789) | L2-in-L3 encapsulation |
53
+
54
+ ]]></metadata></svg>
@@ -0,0 +1,51 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 559 370" width="559" height="370" font-family="system-ui,sans-serif"><defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker><pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" stroke="#bbb" stroke-width="2"/></pattern></defs><g transform="translate(18,6)"><line data-edge="32" x1="172" y1="74.86640581330352" x2="365" y2="54.36892118501956" stroke="#dc2626" stroke-width="1.6" stroke-dasharray="6 4"/><line data-edge="33" x1="172" y1="95.46666666666667" x2="365" y2="121.2" stroke="#dc2626" stroke-width="1.6" stroke-dasharray="6 4"/><path data-edge="37" d="M443.8 72 L443.8 146 Q443.8 156 433.8 156 L96 156 Q86 156 86 146 L86 110" fill="none" stroke="#16a34a" stroke-width="1.6"/><g data-node="a" data-x="0" data-y="58" style="cursor:move"><rect x="0" y="58" width="172" height="52" fill="#fff" stroke="#8a8880"/><text x="86" y="80.1" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="86" dy="0">Host A</tspan><tspan x="86" dy="16.900000000000002">wants MAC for B's IP</tspan></text></g><g data-node="b" data-x="365" data-y="20" style="cursor:move"><rect x="365" y="20" width="157.6" height="52" fill="#fff" stroke="#8a8880"/><text x="443.8" y="42.099999999999994" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="443.8" dy="0">Host B</tspan><tspan x="443.8" dy="16.900000000000002">owns the target IP</tspan></text></g><text x="268.5" y="58.86766349916154" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">1: who-has B? (broadcast)</text><text x="268.5" y="58.86766349916154" font-size="11" text-anchor="middle" fill="#dc2626">1: who-has B? (broadcast)</text><path d="M365 54.36892118501956 L355.5677913970842 61.00215877092595 L354.38495222174663 49.864794114720844 z" fill="#dc2626" stroke="none"/><text x="268.5" y="102.58333333333334" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">1: heard, ignored</text><text x="268.5" y="102.58333333333334" font-size="11" text-anchor="middle" fill="#dc2626">1: heard, ignored</text><path d="M365 121.2 L354.2683059286093 125.41866594530529 L355.7485395936288 114.31691345765978 z" fill="#dc2626" stroke="none"/><text x="264.9" y="150.25" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">2: B is at aa:bb:cc:... A caches it</text><text x="264.9" y="150.25" font-size="11" text-anchor="middle" fill="#16a34a">2: B is at aa:bb:cc:... A caches it</text><path d="M86 110 L91.6 120.08 L80.4 120.08 z" fill="#16a34a" stroke="none"/><text x="381" y="119" font-size="10" text-anchor="start" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round"><tspan x="381" dy="0">rest of the LAN</tspan><tspan x="381" dy="13">(hosts C, D, ...)</tspan></text><text x="381" y="119" font-size="10" text-anchor="start" fill="#555"><tspan x="381" dy="0">rest of the LAN</tspan><tspan x="381" dy="13">(hosts C, D, ...)</tspan></text><text x="0" y="196" font-size="13" font-weight="600">Host A's ARP cache — before and after the exchange</text><rect x="0" y="204" width="164.8" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="cache:0:1" style="cursor:pointer"/><text x="82.4" y="221.3" font-size="12" text-anchor="middle" font-weight="600">Moment</text><rect x="164.8" y="204" width="359.2" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="cache:0:2" style="cursor:pointer"/><text x="344.4" y="221.3" font-size="12" text-anchor="middle" font-weight="600">Entry</text><rect x="0" y="230" width="164.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="cache:1:1" style="cursor:pointer"/><text x="7" y="247.3" font-size="12" text-anchor="start">before the exchange</text><rect x="164.8" y="230" width="359.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="cache:1:2" style="cursor:pointer"/><text x="171.8" y="247.3" font-size="12" text-anchor="start">(no entry for B's IP)</text><rect x="0" y="256" width="164.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="cache:2:1" style="cursor:pointer"/><text x="7" y="273.3" font-size="12" text-anchor="start">after segment 2</text><rect x="164.8" y="256" width="359.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="cache:2:2" style="cursor:pointer"/><text x="171.8" y="273.3" font-size="12" text-anchor="start">B's IP → aa:bb:cc:... , learned from the reply</text><rect x="0" y="323" width="16" height="11" fill="#dc2626" stroke="#555" stroke-dasharray="6 4"/><text x="21" y="332.5" font-size="11" fill="#1d1d1b">Broadcast — delivered to every host on the LAN (dst MAC ff:ff:ff:ff:ff:ff)</text><rect x="0" y="343" width="16" height="11" fill="#16a34a" stroke="#555"/><text x="21" y="352.5" font-size="11" fill="#1d1d1b">Unicast — delivered only to the requester (dst MAC = A's MAC)</text></g><metadata id="figdown-source" data-sha256="caa9e13ac4274b5a645a657feb74d396938d4457af8b4350c93ee3d48120e77f"><![CDATA[
2
+ figdown 0.1 topology
3
+ # ARP address resolution (RFC 826): Host A needs the MAC for B's IP.
4
+ # A broadcasts "who-has", B replies unicast, A caches the mapping.
5
+ # The broadcast vs unicast distinction is a CLASS (meaning in the label,
6
+ # dashed is only its presentation, R57) — presentation is never the sole
7
+ # carrier. "The rest of the LAN" is a boundary, not an invented node.
8
+ #
9
+ # HONEST LIMIT (EXPRESSING "strict message ordering"): step order rides on
10
+ # the 1/2 label ordinals, a naming convention; the sequence genre
11
+ # (OQ-S18, v0.2) will make it first-class. The cache update is a local
12
+ # action on A, not a message — it rides on the reply label and the prose
13
+ # (mode 3: figure + prose are one deliverable), not on a self-edge.
14
+ title ARP Resolution
15
+
16
+ # Semantic classes: delivery scope. Label = MEANING; dashed = presentation
17
+ # only; the legend derives automatically (spec §2.7, R57).
18
+ class bcast "Broadcast — delivered to every host on the LAN (dst MAC ff:ff:ff:ff:ff:ff)" color=#dc2626 style=dashed
19
+ class ucast "Unicast — delivered only to the requester (dst MAC = A's MAC)" color=#16a34a
20
+
21
+ node a "Host A\nwants MAC for B's IP"
22
+ node b "Host B\nowns the target IP"
23
+
24
+ # Every other station on the segment hears the broadcast but is outside the
25
+ # resolution proper: a boundary, drawn as an open edge end (spec §2.8).
26
+ boundary lan "rest of the LAN\n(hosts C, D, ...)"
27
+
28
+ flow right
29
+
30
+ # Step 1: A broadcasts the request to the whole segment. The same broadcast
31
+ # reaches every other station too; they ignore it (short label — detail here
32
+ # and in the showcase prose).
33
+ edge a -[1: who-has B? (broadcast)]-> b class=bcast
34
+ edge a -[1: heard, ignored]-> lan class=bcast
35
+
36
+ # Step 2: B replies to A directly (unicast); on receipt A caches the
37
+ # IP -> MAC binding — a local action on A, stated on the label, not a message.
38
+ edge b -[2: B is at aa:bb:cc:... A caches it]-> a class=ucast
39
+
40
+ # COMPOSITION (spec §8, OQ-S5 resolved): a second typed block below the
41
+ # scene, composed in document order. The cache TRANSITION is the figure's
42
+ # actual outcome, but it is a local state change on A, not a message — so
43
+ # this table carries the before/after cache state machine-readably, which
44
+ # the edge label alone can only gesture at.
45
+ table cache "Host A's ARP cache — before and after the exchange"
46
+ | Moment | Entry |
47
+ |--------------------|-----------------------------------------|
48
+ | before the exchange| (no entry for B's IP) |
49
+ | after segment 2 | B's IP → aa:bb:cc:... , learned from the reply |
50
+
51
+ ]]></metadata></svg>
@@ -0,0 +1,37 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 884 194" width="884" height="194" font-family="system-ui,sans-serif"><defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker><pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" stroke="#bbb" stroke-width="2"/></pattern></defs><g transform="translate(18,6)"><text x="0" y="14" font-size="13" font-weight="600">Ethernet II frame — column order = wire order (byte counts in the second header tier)</text><rect x="0" y="22" width="90" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="45" y="39.3" font-size="12" text-anchor="middle" font-weight="600">Variant</text><rect x="90" y="22" width="136" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="158" y="39.3" font-size="12" text-anchor="middle" font-weight="600">Destination MAC</text><rect x="226" y="22" width="100" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="276" y="39.3" font-size="12" text-anchor="middle" font-weight="600">Source MAC</text><rect x="326" y="22" width="208" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="430" y="39.3" font-size="12" text-anchor="middle" font-weight="600">802.1Q Tag</text><rect x="534" y="22" width="92.8" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="580.4" y="39.3" font-size="12" text-anchor="middle" font-weight="600">EtherType</text><rect x="626.8" y="22" width="136" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="694.8" y="39.3" font-size="12" text-anchor="middle" font-weight="600">Payload</text><rect x="762.8" y="22" width="92.8" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="809.1999999999999" y="39.3" font-size="12" text-anchor="middle" font-weight="600">FCS</text><rect x="0" y="48" width="90" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:1" style="cursor:pointer"/><text x="45" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(frame)</text><rect x="90" y="48" width="136" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:2" style="cursor:pointer"/><text x="158" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(6 bytes)</text><rect x="226" y="48" width="100" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:3" style="cursor:pointer"/><text x="276" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(6 bytes)</text><rect x="326" y="48" width="208" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:4" style="cursor:pointer"/><text x="430" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(4 bytes)</text><rect x="534" y="48" width="92.8" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:5" style="cursor:pointer"/><text x="580.4" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(2 bytes)</text><rect x="626.8" y="48" width="136" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:6" style="cursor:pointer"/><text x="694.8" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(46-1500 bytes)</text><rect x="762.8" y="48" width="92.8" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:7" style="cursor:pointer"/><text x="809.1999999999999" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(4 bytes)</text><rect x="0" y="74" width="90" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:1:1" style="cursor:pointer"/><text x="7" y="91.3" font-size="12" text-anchor="start">Untagged</text><rect x="90" y="74" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:1:2" style="cursor:pointer"/><text x="97" y="91.3" font-size="12" text-anchor="start">DA</text><rect x="226" y="74" width="100" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:1:3" style="cursor:pointer"/><text x="233" y="91.3" font-size="12" text-anchor="start">SA</text><rect x="326" y="74" width="208" height="26" fill="#dbeafe" stroke="#c9c7bf" data-cell="eth:1:4" style="cursor:pointer"/><text x="333" y="91.3" font-size="12" text-anchor="start">(none)</text><rect x="534" y="74" width="92.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:1:5" style="cursor:pointer"/><text x="541" y="91.3" font-size="12" text-anchor="start">Type</text><rect x="626.8" y="74" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:1:6" style="cursor:pointer"/><text x="633.8" y="91.3" font-size="12" text-anchor="start">Data</text><rect x="762.8" y="74" width="92.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:1:7" style="cursor:pointer"/><text x="769.8" y="91.3" font-size="12" text-anchor="start">CRC-32</text><rect x="0" y="100" width="90" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:2:1" style="cursor:pointer"/><text x="7" y="117.3" font-size="12" text-anchor="start">Tagged</text><rect x="90" y="100" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:2:2" style="cursor:pointer"/><text x="97" y="117.3" font-size="12" text-anchor="start">DA</text><rect x="226" y="100" width="100" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:2:3" style="cursor:pointer"/><text x="233" y="117.3" font-size="12" text-anchor="start">SA</text><rect x="326" y="100" width="208" height="26" fill="#dbeafe" stroke="#c9c7bf" data-cell="eth:2:4" style="cursor:pointer"/><text x="333" y="117.3" font-size="12" text-anchor="start">TPID 0x8100 + PCP/DEI/VID</text><rect x="534" y="100" width="92.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:2:5" style="cursor:pointer"/><text x="541" y="117.3" font-size="12" text-anchor="start">Type</text><rect x="626.8" y="100" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:2:6" style="cursor:pointer"/><text x="633.8" y="117.3" font-size="12" text-anchor="start">Data</text><rect x="762.8" y="100" width="92.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:2:7" style="cursor:pointer"/><text x="769.8" y="117.3" font-size="12" text-anchor="start">CRC-32</text><rect x="0" y="167" width="16" height="11" fill="#dbeafe" stroke="#555"/><text x="21" y="176.5" font-size="11" fill="#1d1d1b">802.1Q VLAN tag (4 bytes), inserted after Source MAC; absent in an untagged frame</text></g><metadata id="figdown-source" data-sha256="c6b2c8047c1e15cb7c0a62bf7820ed3bfbbfd3f95aff8e5e3cf16470319b4f61"><![CDATA[
2
+ figdown 0.1 table
3
+ # Ethernet II frame, byte-order-on-the-wire carried by CELL ORDER (the
4
+ # OQ-S24 sanctioned pattern: a byte-unit packet is a single-row table, not
5
+ # a bitfield — no misleading bit ruler). Left-to-right cell order IS the
6
+ # order bytes appear on the wire; the strip test survives because that
7
+ # order lives in the syntax, never in geometry.
8
+ #
9
+ # Two data rows = two frame variants: untagged (Ethernet II) and 802.1Q
10
+ # tagged. The tag is INSERTED between Source MAC and EtherType — the class
11
+ # marks exactly which column is the insertion point, so a reader sees it
12
+ # without pixels.
13
+ title Ethernet II Frame — Untagged vs 802.1Q Tagged
14
+
15
+ # Semantic class: the 802.1Q tag and its insertion point. The label states
16
+ # the MEANING; the legend derives from this line (spec §2.7).
17
+ class tag "802.1Q VLAN tag (4 bytes), inserted after Source MAC; absent in an untagged frame" color=#dbeafe
18
+
19
+ table eth "Ethernet II frame — column order = wire order (byte counts in the second header tier)"
20
+ | Variant | Destination MAC | Source MAC | 802.1Q Tag | EtherType | Payload | FCS |
21
+ | (frame) | (6 bytes) | (6 bytes) | (4 bytes) | (2 bytes) | (46-1500 bytes) | (4 bytes) |
22
+ |----------|-----------------|------------|-------------|-----------|-----------------|-----------|
23
+ | Untagged | DA | SA | (none) | Type | Data | CRC-32 |
24
+ | Tagged | DA | SA | TPID 0x8100 + PCP/DEI/VID | Type | Data | CRC-32 |
25
+ colw 90 auto auto auto auto auto auto
26
+ cell 1,4 class=tag
27
+ cell 2,4 class=tag
28
+
29
+ # HONEST LIMIT (OQ-S16, span/coverage annotation): the FCS (CRC-32) is
30
+ # computed over DA through Payload inclusive — a coverage span across a
31
+ # CONTIGUOUS run of columns. FigDown has no construct to draw or annotate
32
+ # such a span (curly-brace grouping over a contiguous field/cell range is
33
+ # OQ-S16, v0.2; a `cell` note is not available in the table genre). Until it
34
+ # lands, this fact rides on a source comment and the SHOWCASE prose, never on
35
+ # geometry — stated here so a reader recovers it from the text, not pixels.
36
+
37
+ ]]></metadata></svg>
@@ -0,0 +1,42 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 544 651" width="544" height="651" font-family="system-ui,sans-serif"><defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker><pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" stroke="#bbb" stroke-width="2"/></pattern></defs><g transform="translate(18,6)"><line data-edge="31" x1="290.37307692307695" y1="32" x2="290.37307692307695" y2="76" stroke="#555" stroke-width="1.6"/><line data-edge="32" x1="290.37307692307695" y1="144" x2="290.37307692307695" y2="188" stroke="#555" stroke-width="1.6"/><line data-edge="33" x1="290.37307692307695" y1="240" x2="290.37307692307695" y2="284" stroke="#555" stroke-width="1.6"/><line data-edge="35" x1="316.80398475528494" y1="333.30324720278287" x2="387.66843676737295" y2="386.74285714285713" stroke="#555" stroke-width="1.6"/><line data-edge="36" x1="266.24256332978035" y1="334.1248165738226" x2="191.637909323235" y2="398.2883630891489" stroke="#555" stroke-width="1.6"/><line data-edge="38" x1="186.46826779078154" y1="456.9233011944657" x2="236.0239383938394" y2="510.66221198156677" stroke="#555" stroke-width="1.6"/><line data-edge="39" x1="130.7317322092185" y1="456.9233011944657" x2="81.17606160616063" y2="510.66221198156677" stroke="#555" stroke-width="1.6"/><g data-node="learn" data-x="204.37307692307695" data-y="76" style="cursor:move"><rect x="204.37307692307695" y="76" width="172" height="68" fill="#fff" stroke="#8a8880"/><text x="290.37307692307695" y="97.64999999999999" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="290.37307692307695" dy="0">Learn source MAC:</tspan><tspan x="290.37307692307695" dy="16.900000000000002">update MAC table</tspan><tspan x="290.37307692307695" dy="16.900000000000002">(SA -&gt; ingress port)</tspan></text></g><g data-node="lookup" data-x="193.57307692307694" data-y="188" style="cursor:move"><rect x="193.57307692307694" y="188" width="193.6" height="52" fill="#fff" stroke="#8a8880"/><text x="290.37307692307695" y="210.10000000000002" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="290.37307692307695" dy="0">Look up destination MAC</tspan><tspan x="290.37307692307695" dy="16.900000000000002">in MAC table</tspan></text></g><g data-node="hit" data-x="208.13307692307694" data-y="284" style="cursor:move"><polygon points="290.37307692307695,284 372.61307692307696,313.37142857142857 290.37307692307695,342.74285714285713 208.13307692307694,313.37142857142857" fill="#fff" stroke="#8a8880"/><text x="290.37307692307695" y="317.9214285714286" font-size="13" text-anchor="middle" fill="#1d1d1b">Entry found?</text></g><g data-node="same" data-x="44.253846153846155" data-y="386.74285714285713" style="cursor:move"><polygon points="158.60000000000002,386.74285714285713 272.94615384615383,426.70253456221195 158.60000000000002,466.66221198156677 44.253846153846155,426.70253456221195" fill="#fff" stroke="#8a8880"/><text x="158.60000000000002" y="422.802534562212" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="158.60000000000002" dy="0">Egress port ==</tspan><tspan x="158.60000000000002" dy="16.900000000000002">ingress port?</tspan></text></g><g data-node="fwd" data-x="0" data-y="510.66221198156677" style="cursor:move"><rect x="0" y="510.66221198156677" width="114.4" height="52" rx="14" fill="#16a34a" stroke="#8a8880" stroke-width="1.8"/><text x="57.2" y="532.7622119815667" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="57.2" dy="0">Forward out</tspan><tspan x="57.2" dy="16.900000000000002">learned port</tspan></text></g><g data-node="fld" data-x="328.9461538461539" data-y="386.74285714285713" style="cursor:move"><rect x="328.9461538461539" y="386.74285714285713" width="186.4" height="52" rx="14" fill="#2563eb" stroke="#8a8880" stroke-width="1.8"/><text x="422.1461538461539" y="408.84285714285716" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="422.1461538461539" dy="0">Flood to all ports</tspan><tspan x="422.1461538461539" dy="16.900000000000002">in VLAN except ingress</tspan></text></g><g data-node="flt" data-x="170.4" data-y="510.66221198156677" style="cursor:move"><rect x="170.4" y="510.66221198156677" width="179.20000000000002" height="52" rx="14" fill="#dc2626" stroke="#8a8880" stroke-width="1.8"/><text x="260" y="532.7622119815667" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="260" dy="0">Filter (drop):</tspan><tspan x="260" dy="16.900000000000002">same-port destination</tspan></text></g><path d="M290.37307692307695 76 L284.7730769230769 65.92 L295.973076923077 65.92 z" fill="#555" stroke="none"/><path d="M290.37307692307695 188 L284.7730769230769 177.92 L295.973076923077 177.92 z" fill="#555" stroke="none"/><path d="M290.37307692307695 284 L284.7730769230769 273.92 L295.973076923077 273.92 z" fill="#555" stroke="none"/><text x="332.3941641979443" y="357.40996138959923" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">no</text><text x="332.3941641979443" y="357.40996138959923" font-size="11" text-anchor="middle" fill="#555">no</text><path d="M387.66843676737295 386.74285714285713 L376.2485927245621 385.1448702724861 L382.99209291771245 376.2025436655576 z" fill="#555" stroke="none"/><text x="249.82953944834037" y="360.5907968071944" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">yes</text><text x="249.82953944834037" y="360.5907968071944" font-size="11" text-anchor="middle" fill="#555">yes</text><path d="M191.637909323235 398.2883630891489 L195.62870077540882 387.46986117875224 L202.93177246717303 395.96133595436993 z" fill="#555" stroke="none"/><text x="207.33496897169888" y="476.34497443059604" font-size="11" text-anchor="start" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">yes</text><text x="207.33496897169888" y="476.34497443059604" font-size="11" text-anchor="start" fill="#555">yes</text><path d="M236.0239383938394 510.66221198156677 L225.07377169049153 507.04831530776835 L233.30734750001278 499.4556721982269 z" fill="#555" stroke="none"/><text x="121.86503102830115" y="476.34497443059604" font-size="11" text-anchor="start" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">no</text><text x="121.86503102830115" y="476.34497443059604" font-size="11" text-anchor="start" fill="#555">no</text><path d="M81.17606160616063 510.66221198156677 L83.89265249998722 499.4556721982269 L92.1262283095085 507.04831530776835 z" fill="#555" stroke="none"/><text x="290.37307692307695" y="16" font-size="10" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">from ingress port</text><text x="290.37307692307695" y="16" font-size="10" text-anchor="middle" fill="#555">from ingress port</text><rect x="0" y="583.6622119815668" width="16" height="11" fill="#16a34a" stroke="#555"/><text x="21" y="593.1622119815668" font-size="11" fill="#1d1d1b">Forward — send the frame out the single learned egress port</text><rect x="0" y="603.6622119815668" width="16" height="11" fill="#2563eb" stroke="#555"/><text x="21" y="613.1622119815668" font-size="11" fill="#1d1d1b">Flood — send out every port in the VLAN except the ingress port</text><rect x="0" y="623.6622119815668" width="16" height="11" fill="#dc2626" stroke="#555"/><text x="21" y="633.1622119815668" font-size="11" fill="#1d1d1b">Filter — discard; destination is out the same port it arrived on</text></g><metadata id="figdown-source" data-sha256="4ee81fee8c81e33d2509064df822874cb7cad6da03f39df44cc6c69fca4f04db"><![CDATA[
2
+ figdown 0.1 flowchart
3
+ # The classic learning-bridge / L2 switch forwarding decision (IEEE 802.1D).
4
+ # A frame arrives; the switch learns the source, looks up the destination,
5
+ # and takes one of three actions. The LOGIC is machine-readable: a reader
6
+ # answers "when does a switch flood?" by tracing the Y/N edges — no pixels.
7
+ title L2 Switch Forwarding Decision
8
+
9
+ # Semantic classes: the three terminal OUTCOMES. Each label states the
10
+ # MEANING; the legend derives from these lines (spec §2.7).
11
+ class forward "Forward — send the frame out the single learned egress port" color=#16a34a
12
+ class flood "Flood — send out every port in the VLAN except the ingress port" color=#2563eb
13
+ class filter "Filter — discard; destination is out the same port it arrived on" color=#dc2626
14
+
15
+ # The wire is external to the decision logic: the frame enters from outside
16
+ # the figure (spec §2.8 boundary — never drawn as a shape, edge ends open).
17
+ boundary wire "from ingress port"
18
+
19
+ # Actions are boxes; ONLY decisions get shape=diamond (branch semantics by
20
+ # convention). The lookup is an action — the decision is "Entry found?".
21
+ node learn "Learn source MAC:\nupdate MAC table\n(SA -> ingress port)"
22
+ node lookup "Look up destination MAC\nin MAC table"
23
+ node hit "Entry found?" shape=diamond
24
+ node same "Egress port ==\ningress port?" shape=diamond
25
+ node fwd "Forward out\nlearned port" shape=rounded class=forward
26
+ node fld "Flood to all ports\nin VLAN except ingress" shape=rounded class=flood
27
+ node flt "Filter (drop):\nsame-port destination" shape=rounded class=filter
28
+
29
+ # top-to-bottom reading order for the decision process.
30
+ flow down
31
+
32
+ edge wire -> learn
33
+ edge learn -> lookup
34
+ edge lookup -> hit
35
+ # Miss (unknown unicast, or broadcast/multicast) -> flood.
36
+ edge hit -[no]-> fld
37
+ edge hit -[yes]-> same
38
+ # Hit, but destination is behind the ingress port -> filter; else forward.
39
+ edge same -[yes]-> flt
40
+ edge same -[no]-> fwd
41
+
42
+ ]]></metadata></svg>
@@ -0,0 +1,56 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 624 350" width="624" height="350" font-family="system-ui,sans-serif"><defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker><pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" stroke="#bbb" stroke-width="2"/></pattern></defs><g transform="translate(18,6)"><line data-edge="31" x1="172" y1="34.5" x2="358.5" y2="34.5" stroke="#2563eb" stroke-width="1.6"/><path data-edge="34" d="M476.9 56 L476.9 74 Q476.9 84 466.9 84 L96 84 Q86 84 86 74 L86 56" fill="none" stroke="#2563eb" stroke-width="1.6"/><line data-edge="39" x1="172" y1="41.5" x2="358.5" y2="41.5" stroke="#16a34a" stroke-width="1.6"/><g data-node="client" data-x="0" data-y="20" style="cursor:move"><rect x="0" y="20" width="172" height="36" fill="#fff" stroke="#8a8880"/><text x="86" y="42.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Client (active open)</text></g><g data-node="server" data-x="358.5" data-y="20" style="cursor:move"><rect x="358.5" y="20" width="236.8" height="36" fill="#fff" stroke="#8a8880"/><text x="476.9" y="42.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Server (passive open, LISTEN)</text></g><text x="265.25" y="28.75" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">1: SYN seq=x</text><text x="265.25" y="28.75" font-size="11" text-anchor="middle" fill="#2563eb">1: SYN seq=x</text><path d="M358.5 34.5 L348.42 40.1 L348.42 28.9 z" fill="#2563eb" stroke="none"/><text x="281.45" y="78.25" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">2: SYN,ACK seq=y ack=x+1</text><text x="281.45" y="78.25" font-size="11" text-anchor="middle" fill="#2563eb">2: SYN,ACK seq=y ack=x+1</text><path d="M86 56 L91.6 66.08 L80.4 66.08 z" fill="#2563eb" stroke="none"/><text x="265.25" y="53.85" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">3: ACK ack=y+1 (+ data)</text><text x="265.25" y="53.85" font-size="11" text-anchor="middle" fill="#16a34a">3: ACK ack=y+1 (+ data)</text><path d="M358.5 41.5 L348.42 47.1 L348.42 35.9 z" fill="#16a34a" stroke="none"/><text x="0" y="124" font-size="13" font-weight="600">Endpoint state after each segment (RFC 9293 §3.3.2 state names)</text><rect x="0" y="132" width="114.4" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="state:0:1" style="cursor:pointer"/><text x="57.2" y="149.3" font-size="12" text-anchor="middle" font-weight="600">Segment</text><rect x="114.4" y="132" width="186.4" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="state:0:2" style="cursor:pointer"/><text x="207.60000000000002" y="149.3" font-size="12" text-anchor="middle" font-weight="600">Client state</text><rect x="300.8" y="132" width="193.6" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="state:0:3" style="cursor:pointer"/><text x="397.6" y="149.3" font-size="12" text-anchor="middle" font-weight="600">Server state</text><rect x="0" y="158" width="114.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:1:1" style="cursor:pointer"/><text x="7" y="175.3" font-size="12" text-anchor="start">start</text><rect x="114.4" y="158" width="186.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:1:2" style="cursor:pointer"/><text x="121.4" y="175.3" font-size="12" text-anchor="start">CLOSED</text><rect x="300.8" y="158" width="193.6" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:1:3" style="cursor:pointer"/><text x="307.8" y="175.3" font-size="12" text-anchor="start">LISTEN</text><rect x="0" y="184" width="114.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:2:1" style="cursor:pointer"/><text x="7" y="201.3" font-size="12" text-anchor="start">1: SYN →</text><rect x="114.4" y="184" width="186.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:2:2" style="cursor:pointer"/><text x="121.4" y="201.3" font-size="12" text-anchor="start">SYN-SENT</text><rect x="300.8" y="184" width="193.6" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:2:3" style="cursor:pointer"/><text x="307.8" y="201.3" font-size="12" text-anchor="start">SYN-RECEIVED on receipt</text><rect x="0" y="210" width="114.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:3:1" style="cursor:pointer"/><text x="7" y="227.3" font-size="12" text-anchor="start">2: SYN,ACK ←</text><rect x="114.4" y="210" width="186.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:3:2" style="cursor:pointer"/><text x="121.4" y="227.3" font-size="12" text-anchor="start">ESTABLISHED on receipt</text><rect x="300.8" y="210" width="193.6" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:3:3" style="cursor:pointer"/><text x="307.8" y="227.3" font-size="12" text-anchor="start">SYN-RECEIVED</text><rect x="0" y="236" width="114.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:4:1" style="cursor:pointer"/><text x="7" y="253.3" font-size="12" text-anchor="start">3: ACK →</text><rect x="114.4" y="236" width="186.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:4:2" style="cursor:pointer"/><text x="121.4" y="253.3" font-size="12" text-anchor="start">ESTABLISHED</text><rect x="300.8" y="236" width="193.6" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:4:3" style="cursor:pointer"/><text x="307.8" y="253.3" font-size="12" text-anchor="start">ESTABLISHED on receipt</text><rect x="0" y="303" width="16" height="11" fill="#2563eb" stroke="#555"/><text x="21" y="312.5" font-size="11" fill="#1d1d1b">Connection-setup segment — carries SYN and/or ACK control flags</text><rect x="0" y="323" width="16" height="11" fill="#16a34a" stroke="#555"/><text x="21" y="332.5" font-size="11" fill="#1d1d1b">Segment that also carries application data (piggybacked on the ACK)</text></g><metadata id="figdown-source" data-sha256="6064267340e45c25cdb009cb0c6f96edf34f15baacf2b50773eb6785a07e3e98"><![CDATA[
2
+ figdown 0.1 topology
3
+ # TCP three-way handshake + data on the third segment (RFC 9293 §3.5).
4
+ # Two endpoints, three directed segments carrying the connection-setup
5
+ # exchange. Each segment's ordinal (1/2/3) is in its edge label.
6
+ #
7
+ # HONEST LIMIT (EXPRESSING known limits — "strict message ordering"):
8
+ # message ORDER is carried only by the 1/2/3 numbering convention in the
9
+ # labels, a naming convention that R37 does not treat as first-class order.
10
+ # The sequence genre (OQ-S18, v0.2) will make order first-class semantics;
11
+ # until then a reader must trust the ordinal prefixes below.
12
+ # Likewise, the canonical RFC 9293 figure carries the per-endpoint TCP
13
+ # STATE (LISTEN, SYN-SENT, …) on the lifelines; the topology genre has no
14
+ # lifeline-state construct, so the companion `table` block below carries
15
+ # those states machine-readably — composition (multiple typed blocks in one
16
+ # document, in document order) is the ruled interim until sequence lands.
17
+ title TCP Three-Way Handshake
18
+
19
+ # Semantic classes: the label states the MEANING; colour merely renders it,
20
+ # and the legend derives automatically (spec §2.7). Each segment is classed
21
+ # by what it does — a reader queries the class, not the arrow colour.
22
+ class setup "Connection-setup segment — carries SYN and/or ACK control flags" color=#2563eb
23
+ class data "Segment that also carries application data (piggybacked on the ACK)" color=#16a34a
24
+
25
+ node client "Client (active open)"
26
+ node server "Server (passive open, LISTEN)"
27
+
28
+ # left-to-right reading: client on the left issues the active open.
29
+ flow right
30
+
31
+ # Segment 1: client -> server, SYN, seq=x (flags: SYN)
32
+ edge client -[1: SYN seq=x]-> server class=setup
33
+
34
+ # Segment 2: server -> client, SYN+ACK, seq=y ack=x+1 (flags: SYN, ACK)
35
+ edge server -[2: SYN,ACK seq=y ack=x+1]-> client class=setup
36
+
37
+ # Segment 3: client -> server, ACK ack=y+1, carrying piggybacked data
38
+ # (flags: ACK). One segment, so ONE edge; it is both an ACK and a data
39
+ # carrier, so it is classed as data (the stronger claim). Detail in prose.
40
+ edge client -[3: ACK ack=y+1 (+ data)]-> server class=data
41
+
42
+ # COMPOSITION (spec §8, OQ-S5 resolved): a second typed block in the same
43
+ # document, composed in document order below the scene. The canonical RFC
44
+ # 9293 figure carries the TCP state names on the two lifelines; the topology
45
+ # genre has no lifeline-state construct, so this table carries them
46
+ # machine-readably. State names are the RFC 9293 §3.3.2 constants
47
+ # (CLOSED, LISTEN, SYN-SENT, SYN-RECEIVED, ESTABLISHED) verbatim.
48
+ table state "Endpoint state after each segment (RFC 9293 §3.3.2 state names)"
49
+ | Segment | Client state | Server state |
50
+ |--------------------|-----------------------|---------------------------|
51
+ | start | CLOSED | LISTEN |
52
+ | 1: SYN → | SYN-SENT | SYN-RECEIVED on receipt |
53
+ | 2: SYN,ACK ← | ESTABLISHED on receipt| SYN-RECEIVED |
54
+ | 3: ACK → | ESTABLISHED | ESTABLISHED on receipt |
55
+
56
+ ]]></metadata></svg>
@@ -0,0 +1,47 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 764 284" width="764" height="284" font-family="system-ui,sans-serif"><defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker><pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" stroke="#bbb" stroke-width="2"/></pattern></defs><g transform="translate(18,6)"><text x="0" y="14" font-size="13" font-weight="600">TCP Header (RFC 9293)</text><text x="11.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">0</text><text x="34.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">1</text><text x="57.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">2</text><text x="80.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">3</text><text x="103.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">4</text><text x="126.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">5</text><text x="149.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">6</text><text x="172.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">7</text><text x="195.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">8</text><text x="218.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">9</text><text x="241.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">10</text><text x="264.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">11</text><text x="287.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">12</text><text x="310.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">13</text><text x="333.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">14</text><text x="356.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">15</text><text x="379.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">16</text><text x="402.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">17</text><text x="425.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">18</text><text x="448.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">19</text><text x="471.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">20</text><text x="494.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">21</text><text x="517.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">22</text><text x="540.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">23</text><text x="563.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">24</text><text x="586.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">25</text><text x="609.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">26</text><text x="632.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">27</text><text x="655.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">28</text><text x="678.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">29</text><text x="701.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">30</text><text x="724.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">31</text><rect x="0" y="34" width="368" height="30" fill="#fff" stroke="#555"/><text x="184" y="52.85" font-size="11" text-anchor="middle">Source Port</text><rect x="368" y="34" width="368" height="30" fill="#fff" stroke="#555"/><text x="552" y="52.85" font-size="11" text-anchor="middle">Destination Port</text><rect x="0" y="64" width="736" height="30" fill="#fff" stroke="#555"/><text x="368" y="82.85" font-size="11" text-anchor="middle">Sequence Number</text><rect x="0" y="94" width="736" height="30" fill="#fff" stroke="#555"/><text x="368" y="112.85" font-size="11" text-anchor="middle">Acknowledgment Number</text><rect x="0" y="124" width="92" height="30" fill="#fff" stroke="#555"/><text x="46" y="142.85" font-size="11" text-anchor="middle">Data Offset</text><title>header length in 32-bit words; min 5 (=20 bytes), max 15 (=60 bytes)</title><rect x="92" y="124" width="92" height="30" fill="#fff" stroke="#555"/><text x="138" y="142.85" font-size="11" text-anchor="middle">Reserved</text><title>must be zero</title><rect x="184" y="124" width="23" height="30" fill="#fff" stroke="#555"/><text x="195.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">CWR</text><rect x="207" y="124" width="23" height="30" fill="#fff" stroke="#555"/><text x="218.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">ECE</text><rect x="230" y="124" width="23" height="30" fill="#fff" stroke="#555"/><text x="241.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">URG</text><rect x="253" y="124" width="23" height="30" fill="#fff" stroke="#555"/><text x="264.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">ACK</text><rect x="276" y="124" width="23" height="30" fill="#fff" stroke="#555"/><text x="287.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">PSH</text><rect x="299" y="124" width="23" height="30" fill="#fff" stroke="#555"/><text x="310.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">RST</text><rect x="322" y="124" width="23" height="30" fill="#fee2e2" stroke="#555"/><text x="333.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">SYN</text><rect x="345" y="124" width="23" height="30" fill="#fee2e2" stroke="#555"/><text x="356.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">FIN</text><rect x="368" y="124" width="368" height="30" fill="#fff" stroke="#555"/><text x="552" y="142.85" font-size="11" text-anchor="middle">Window</text><title>receive window size in bytes (subject to window scaling option)</title><rect x="0" y="154" width="368" height="30" fill="#fff" stroke="#555"/><text x="184" y="172.85" font-size="11" text-anchor="middle">Checksum</text><rect x="368" y="154" width="368" height="30" fill="#fff" stroke="#555"/><text x="552" y="172.85" font-size="11" text-anchor="middle">Urgent Pointer</text><rect x="0" y="184" width="736" height="30" fill="#fff" stroke="#555" stroke-dasharray="5 3"/><text x="368" y="202.85" font-size="11" text-anchor="middle">Options</text><title>present iff Data Offset &gt; 5; padded to a 32-bit boundary</title><rect x="0" y="214" width="736" height="30" fill="#fff" stroke="#555"/><text x="368" y="232.85" font-size="11" text-anchor="middle">Data</text><title>variable-length payload; length derived from the IP datagram, not carried in the TCP header</title></g><metadata id="figdown-source" data-sha256="f1ce5b6b0b129a760a826f9bc81e4fa8417a571929d9e3b0adc5480e3fb1445f"><![CDATA[
2
+ figdown 0.1 bitfield
3
+ # TCP Header — RFC 9293 §3.1, IETF MSB-0 bit numbering (bit 0 = leftmost).
4
+ # The .fd is the machine-readable truth: field ORDER + WIDTH give every
5
+ # bit its absolute offset, so a reader answers "which bits carry X?" from
6
+ # text alone — no pixels, no OCR.
7
+ title TCP Header
8
+
9
+ bitfield tcp "TCP Header (RFC 9293)" unit=32 numbering=msb0
10
+
11
+ # Row 1: Source Port (16) + Destination Port (16) = 32 bits
12
+ field "Source Port" 16
13
+ field "Destination Port" 16
14
+
15
+ # Row 2: Sequence Number = 32 bits
16
+ field "Sequence Number" 32
17
+
18
+ # Row 3: Acknowledgment Number = 32 bits
19
+ field "Acknowledgment Number" 32
20
+
21
+ # Row 4: Data Offset (4) + Reserved (4) + 8 control flags (1 bit each) + Window (16)
22
+ field "Data Offset" 4 note="header length in 32-bit words; min 5 (=20 bytes), max 15 (=60 bytes)"
23
+ field Reserved 4 note="must be zero"
24
+ # The eight control bits are declared as individual 1-bit fields so a reader
25
+ # can address each flag's exact bit position, not just the byte that holds them.
26
+ field CWR 1
27
+ field ECE 1
28
+ field URG 1
29
+ field ACK 1
30
+ field PSH 1
31
+ field RST 1
32
+ field SYN 1 color=#fee2e2
33
+ field FIN 1 color=#fee2e2
34
+ field Window 16 note="receive window size in bytes (subject to window scaling option)"
35
+
36
+ # Row 5: Checksum (16) + Urgent Pointer (16) = 32 bits
37
+ field Checksum 16
38
+ field "Urgent Pointer" 16
39
+
40
+ # Row 6+: Options — present only when Data Offset > 5 (dashed border marks
41
+ # conditional presence; a reader computing offsets past here MUST branch, R48)
42
+ field Options 32 optional note="present iff Data Offset > 5; padded to a 32-bit boundary"
43
+
44
+ # Payload — variable length, inferred from the IP total length, not a TCP field
45
+ field Data * note="variable-length payload; length derived from the IP datagram, not carried in the TCP header"
46
+
47
+ ]]></metadata></svg>