OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-social commits / 5ede30f

docs: the edge graph — making exchanged data legible
The record graph (observed, discrete) as companion to SOCIAL-GRAPH-NAVIGATION's room graph (MI, statistical). Core value is the four delivery states, which currently all look identical, and rendering bidirectionality as two independent edges so a one-way failure is visible. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
5ede30ff80d1a728d7986db6239f8ef3aa1c4479
by plankatron <fleeky@gmail.com> · 2026-09-05T20:05:04.000Z

Changed files (2) +160 -0

docs/EDGE-GRAPH.md +159 -0
……@@ -0,0 +1,159 @@
1# The Edge Graph — making exchanged data legible
2
3**Status:** design. Nothing built.
4**Date:** 2026-09-05
5**Companion to:** `SOCIAL-GRAPH-NAVIGATION.md`. That document is the **room graph** — nodes are
6rooms, edges are MI, statistical and computed, for navigating. This is the **record graph** — nodes
7are records and actors, edges are actual interaction records, observed and discrete, for seeing what
8was actually exchanged. Same substrate, different graph, and they compose (§7).
9**Depends on:** `SOCIAL-MODEL.md` (the room is the container),
10`favela-markdown/spec/interaction.md` (edges).
11
12---
13
14## 1. Why this exists
15
16hyper-social #30 records the same failure three times in one day and names the shape:
17
18> **every surface we control reported success.** Tests green, RPC ok, log clean, HTTP 2xx. The truth
19> was only visible on the product surface — a Mastodon status, a running process's env, a deploy log
20> that was *quietly empty*.
21
22**The edge layer has no product surface at all.** A like that never projected, an alias that never
23resolved, an inbound claim that never verified, and one that worked perfectly are — from every log,
24test and RPC we have — identical. ap-bridge 0.0.3 shipped `reproject` with green tests, a happy RPC,
25a clean log and a 2xx **and changed nothing**; only reading the actual Mastodon status caught it.
26
27This view is the missing surface. It is a debugging instrument first and a user-facing feature
28second, and §5 keeps those two jobs from being merged into one screen that does neither.
29
30## 2. It costs nothing architecturally
31
32Under `SOCIAL-MODEL.md` a graph view is **a projection** — a pure function from records to a view,
33the same class of thing as a timeline or a notification list. No new storage, no new replication, no
34new state. What makes it different from every other projection is that it renders the **substrate**
35rather than the content.
36
37## 3. What it renders
38
39**Nodes**
40
41| node | is |
42|---|---|
43| record | a post, or any record an edge points at |
44| actor | a user (by `favela://` name; display name resolved for screen only) |
45| room | the container — drawn as the enclosing region, not a node |
46| foreign object | a subject named by an `at://` or `https://` URI we do not hold |
47
48**Edges** — one per interaction record: `like`, `repost`, `follow`, `block`, `reply`, `alias`
49(`interaction.md` §5.4–5.5). Each edge is drawn **inside the room it was written in**, because that
50is what determines its audience (`interaction.md` §4.5). A room boundary on screen is a real
51boundary, not decoration.
52
53## 4. ★ The four states — this is the whole diagnostic value
54
55An edge is not delivered or undelivered. It passes four independent steps, each of which fails
56differently and **all of which currently look identical**:
57
58```
59 ① WRITTEN the pointer is in the author's writer core
60 │ fails: not writable, role missing, admission never granted
61 ▼
62 ② CONVERGED it linearized into the room's view
63 │ fails: no indexer ack, N=2 quorum stall, fork
64 ▼
65 ③ RESOLVED the bytes are locally available (ensureLocal returned)
66 │ fails: no peer served the oid, superseded local copy
67 ▼
68 ④ PROJECTED a bridge emitted it — and for AP, got a 2xx that MEANT something
69 fails: no designated credential, unknown verb, reach excludes,
70 Update without `updated` (silent discard)
71```
72
73**Render the state on the edge itself.** A dashed edge at ② is a quorum problem; a dashed edge at ③
74is a byte-availability problem; a dashed edge at ④ is a bridge problem. Today all three are "the
75like didn't show up."
76
77### 4.1 Bidirectionality is TWO edges, and that is the point
78
79An edge is one-directional. Everything that feels bidirectional — a follow-back, a DM, an `alias`,
80a reply-and-its-acknowledgement — is **a pair of independent edges**, each with its own four states.
81
82**The common bug is one direction landing and the other not**, and a view that draws the pair with
83each direction's state separately makes that visible at a glance. Drawing it as a single
84double-headed arrow would hide exactly the failure the view exists to catch.
85
86### 4.2 `alias` edges are the cross-network truth
87
88`alias` never projects (`interaction.md` §5.5) — it is how a node knows two names denote one thing.
89Rendering alias edges is the only way to see whether cross-network identity actually resolved. A
90foreign object with no alias edge is why `projectLike` returned `null` and the like silently did not
91happen (`ap-bridge/lib/as2-project.js:165-168`).
92
93## 5. Two renderings, opposite requirements
94
95They must not be one screen.
96
97| | **debug view** | **discovery view** |
98|---|---|---|
99| shows | every edge, including failed ones | computed structure |
100| layout | raw, unclustered, ordered by state | force-directed, clustered |
101| labels | verbatim URIs, oids, rkeys | display names |
102| naming | none | ⛔ **never auto-names a cluster** |
103| audience | operator | everyone |
104
105The discovery view is `SOCIAL-GRAPH-NAVIGATION.md`'s Graph View and inherits its rules — in
106particular `COMMUNITY-EMERGENCE.md`'s: *"the observation is an intervention."* The system may surface
107a cluster; **naming it is a political act reserved for humans.**
108
109The debug view has the opposite duty: show the ugly truth, unclustered, including things that failed,
110because a tidy picture is what let six versions of prod run ahead of git for ten days.
111
112## 6. Honesty rules
113
114Inherited from the model, not invented here:
115
1161. **It shows what THIS node knows, not what is true.** Label it as such. Different peers legitimately
117 compute different graphs (`SOCIAL-MODEL.md` §5).
1182. **Never sum local and network counts.** favela-web already refuses to (hyper-social #45 §2); the
119 graph view must not quietly reintroduce a total.
1203. **An absent edge is not a negative.** It means "not replicated to me yet" unless there is a
121 tombstone — the same ambiguity the signer's forward-only gate exists to respect.
1224. **⛔ No aggregation, ever.** No export, no "share your graph", no combining views across peers.
123 `COMMUNITY-EMERGENCE.md` names the aggregation attack and its mitigation is **no mechanism**, not
124 a permission check. A graph view with an export button is that mechanism.
125
126## 7. How it composes with the room graph
127
128```
129SOCIAL-GRAPH-NAVIGATION ←→ EDGE-GRAPH
130room graph ←→ record graph
131MI, statistical ←→ observed, discrete
132map ←→ wiring diagram
133"where am I" ←→ "did that actually land"
134```
135
136Click a room in the map, get its wiring diagram. Click an edge in the wiring diagram, get the record.
137Two projections of one substrate — which is the claim `SOCIAL-MODEL.md` makes about every view.
138
139## 8. Open
140
1411. **Scale.** A busy room's edge count dwarfs its record count. Filtering, and what the default
142 filter is, is unaddressed.
1432. **Where the four states come from.** ① and ② are readable from the autobase; ③ from
144 `ensureLocal`; ④ needs the bridge's **delivery bookkeeping**, which is node-local and not
145 replicated (`identity.md` §6.3). So the debug view is only complete on a node that runs its own
146 bridges.
1473. **Whether ④ can be trusted.** A 2xx from Mastodon is not evidence of anything (#30). The state may
148 need a fifth step — *confirmed on the product surface* — which cannot be derived and must be
149 fetched.
1504. **Where it lives** — favela-web (SSR, no-JS reading path) versus a separate operator tool. A graph
151 is the one thing the no-JS path cannot render.
1525. **Whether the debug view ships to users at all**, or stays an operator surface.
153
154## 9. What this does not claim
155
156- It is not the room graph, and does not compute MI or clusters. That is `SOCIAL-GRAPH-NAVIGATION.md`.
157- It does not make an edge more reliable. It makes its failure visible, which is a different thing.
158- It cannot show what this node has not replicated — an absent edge and an unreplicated one look the
159 same, and §6 #3 says to render that ambiguity rather than resolve it.
docs/README.md +1 -0
……@@ -11,6 +11,7 @@ P2P social layer built on Hypercore Protocol and Keet. A family of interoperable
1111| [NETWORKING.md](NETWORKING.md) | Protocol decisions: WebSocket + JSON-RPC 2.0, why not HTTP/SSE, message format |
1212| [GODOT.md](GODOT.md) | Godot 4 integration: two-tier architecture, keet-social plugin, GDExtension, libudx |
1313| [UDX-GAMING.md](UDX-GAMING.md) | Deep dive: libudx for real-time gaming, packet overhead, NAT holepunching |
14| [EDGE-GRAPH.md](EDGE-GRAPH.md) | The **record** graph — what was actually exchanged via edges, with each edge's four delivery states. A debugging surface for interactivity and bidirectionality. Companion to SOCIAL-GRAPH-NAVIGATION's room graph. |
1415| [SOCIAL-GRAPH-NAVIGATION.md](SOCIAL-GRAPH-NAVIGATION.md) | Graph-based navigation, sheaf theory, parsing social structure like language |
1516| [COMMUNITY-EMERGENCE.md](COMMUNITY-EMERGENCE.md) | How communities form, govern themselves, privacy architecture, Blacksky case study |
1617| [ROADMAP.md](ROADMAP.md) | Evolutionary path from godot-keet to hyper-social — 8 phases, what exists, what to build |