Milestone: the living cybergraph — rendered from real interaction
goal
The Graph world stops showing a synthetic 28-edge demo. It shows a real cybergraph
that grows from what the user does — every terminal command, its output, every
world/cell navigation becomes particles and cyberlinks in an actual Cybergraph
(bbg-backed, in-memory), which mir lays out and renders. Interact → the graph fills
with your session.
the idea
interaction (terminal cmd+output, world/cell nav)
→ emit a cyberlink into a shared live Cybergraph (real bbg state, no proofs)
→ enumerate graph → build mir Csr + ParticleIndex (+ hash→label map)
→ mir lays out (spectral) and renders
Because the store is a real Cybergraph, the same graph is inf-queryable for free
(graph.query("?[cid,energy] := particles{cid,energy}")) — P5 of the cell milestone
lands almost as a side effect.
what exists (verified, file:line)
mirrender:GraphWorldConfig { graph: Arc<Csr> }(mir/src/bevy/resources.rs:20), consumed inon_enter_graph(mir/src/bevy/world.rs:23) which spawns a one-shotEpochWorker(mir/src/epoch/mod.rs:40). CSR is immutable.- mir graph types:
Cyberlink{neuron,from,to,token,amount,valence,block}(mir/src/graph/snapshot.rs:26),ParticleIndexhash→idx (mir/src/graph/vocab.rs),Csr::build(links, index)(mir/src/graph/adjacency.rs:30). - synthetic source:
cyb/shell/src/worlds/graph.rs::build_synthetic_csr()(lines 40-76). - cybergraph store:
Cybergraph::new(),.link(Signal),.query(inf), enumerate viabbg.state.particles / axons_out / axon_edges(cybergraph/src/api.rs,bbg/rs/src/state.rs). - signal build:
cyb_core::SignalBuilder::new(neuron).link(from,to,token,amount,valence).build(); particle id =hemera::hash(bytes). - interaction hooks: terminal
poll_eval_results(terminal/mod.rs:420, has chunks + done_error + command history),process_keyboard_inputEnter (~541); navnav.rs:12,chrome.rs::handle_chrome_input(~360),hotkeys.rs.
what's missing
- a shared live graph resource in the shell.
- an interaction → cyberlink emitter (Bevy Event) + a drain system that applies links.
- a graph → Csr builder over the real cybergraph (replacing the synthetic one) + a hash→label map for node labels.
- live recompute in mir (it lays out once) — for "grows before your eyes".
decisions (recommend)
- Store = real
Cybergraph::new()(bbg-backed, in-memory,proof:None), not a render-only adjacency. Keeps it genuinely "the cybergraph" and inf-queryable. Carry a sideHashMap<Particle,String>for display labels (bbg stores hashes, not text). - Session semantics — which links (small, legible set):
- terminal:
prev-cmd → cmd(temporal chain),cwd → cmd,cmd → output(summary node) - nav:
from-world → to-world,world → cellamount = repetition/conviction (accumulates on repeat); valence = +1.
- terminal:
- G1 before G2. G1 (rebuild-on-enter) needs zero mir changes — every time you switch to the Graph world it rebuilds the CSR from the accumulated cybergraph and re-runs layout, so you see your session graph. G2 adds a recompute channel to mir's EpochWorker so it grows while you watch. Ship G1 first (de-risks the mir surgery).
phases
G1 — session graph, rebuilt on enter (no mir changes)
- Add resource
LiveGraph { graph: Cybergraph, labels: HashMap<Particle,String> }(shell), inserted at Startup with a couple of seed nodes (so it's never empty). - Add
#[derive(Event)] Link { from: String, to: String }(label-addressed). Emit from:poll_eval_results:cmd → output,prev-cmd → cmd,cwd → cmdnav/chrome/hotkeys:from-world → to-world,world → cell
- Drain system: for each
Link, hash labels → particles, record labels, build a Signal,graph.link(signal). - Replace
build_synthetic_csr()withbuild_csr(&LiveGraph): enumerate axon_edges → mirCyberlinks →ParticleIndex+Csr. RebuildGraphWorldConfig.graphatOnEnter(Graph)fromLiveGraphso each entry shows the latest. - Deliverable: run commands + switch worlds, press Cmd+1 → graph shows your session.
G2 — live recompute (grows before your eyes) [mir change]
- Add a recompute channel to
EpochWorker(recompute_tx: Sender<Arc<Csr>>); worker loops on rx and re-runsepoch_pipelineon each new CSR (Procrustes already aligns to the previous epoch, so nodes animate into place). - Debounced shell system: when
LiveGraphchanged, rebuild CSR, send to mir. - Deliverable: type in the terminal, watch nodes/edges appear in the Graph world live.
G3 — labels + polish (optional, after G1/G2)
- Render node labels (hash→label) in mir or as prysm overlays; color by kind (command/output/world/cell); edge weight = repetition. Click a node → inf query.
risks
- mir is one-shot — G2's recompute channel is the one real engine change; keep it
isolated to
EpochWorker. G1 sidesteps it entirely. - graph can grow unbounded — cap/age out nodes for the live view (note any cap).
- bbg Signal ordering — links are per-neuron ordered; use a single synthetic session
neuron and a monotonic step so
graph.linkaccepts them. - labels are not in bbg — must carry the hash→label map ourselves; it is the only source of human-readable node names.
outcome
The graph becomes a mirror of the session: a real, inf-queryable cybergraph built from the user's own terminal and app actions, laid out and rendered by mir.