A map of all 37 lessons: the core data flow (build + consume), the four deeper strands (at_risk · discovery · self-checking · billing), the coordination primitives beneath it all, the cross-cutting invariants, where the code lives, and what to watch. The compressed essence — keep it; print it.
It watches the blockchain in real time and turns on-chain events into a risk graph in Memgraph — nodes are addresses, typed edges are relationships — then computes who's at risk if something fails, and fires customer alerts when risk crosses a threshold. Self-seeds once from the chain, then maintains incrementally forever (no batch runs).
Genesis: the graph is born by self-seeding (factory walks around focus tokens), then the loop above runs forever. L10
Transfer log), caches RPC, XADDs to blocks:{chain}.XREADGROUPs it; the transferDecoder (topic0 match) emits a typed TransferEvent.UNWIND…MERGE (token)-[:HOLDS]->(holder); new nodes get pending_enrichment=true.node_risk_score, admin_risk_usd) for the affected nodes. (L6·L13)AlertEvent. (L12)BlockCursor=N = pure function of blocks 0..N. ⇒ recovery is re-derivation, not repair. L8MERGE + monotonic updated_block guard ⇒ at-least-once redelivery is safe. L4·L7MERGE / graphwrite IdemKey / alert doc-id = msg-id) ⇒ replays are no-ops. L4·L9·L15| # | Lesson | The one idea |
|---|---|---|
| L1 | Three-binary pipeline | Events in → graph edges out; 3 binaries + the monitored-set filter. |
| L2 | Graph data model | :Entity nodes, graph_id partition, 19 edges in 8 categories; query rules. |
| L3 | Event decoder path | topic0 → registry map → LogDecoder → typed event. |
| L4 | Write path | Accumulate → coalesce → UNWIND/MERGE → atomic commit w/ cursor. |
| L5 | Enrichment worker | Poll → claim → classify → structural edges → discovery feedback loop. |
| L6 | Risk engine | AT_RISK cells (failure-source → victim token) + exposure BFS, incremental. |
| L7 | Streaming backbone | Durable log + consumer groups + at-least-once + backpressure. |
| L8 | Failure & recovery | Determinism + truth-vs-cache ⇒ reorg/crash/flush/divergence all recover. |
| L9 | Single-writer | OCC disaster → serialize via one leased graph-writer; explains recorder + 2 cursors. |
| L10 | Bootstrap | Self-seed from the chain (factory walks); resumable locked task DAG. |
| L11 | Observability | Metrics/traces/logs; trace context hops through the stream; the signal map. |
| L12 | Rule engine | Customer rules over risk fields; scope resolution; firing state machine → alerts. |
| L13 | Risk math | Severity weights; USD = max over attack channels; score = noisy-OR; HHI. |
| L14 | Read surface | query-api scaffold; never full-scan; pre-computed fields; read/write (CQRS) asymmetry. |
| L15 | Alert processor | AlertStream (L7 idiom) → dedup-by-msg-id → OpenSearch + notify; fail-loud ops. |
| L16 | Exposure-BFS | Weight 1.0 decays ×edge-weight per hop; max over paths; minDelta prune; Bardoscia. |
| L17 | Admin panel | Operator console: auth0 identity + RBAC guard + audit log; Cypher-backed views. |
| L18 | Delivery boundary | Resilient HTTP adapter to an external notifier; know where the system ends. |
| Strand A · the at_risk engine, end to end | ||
| L19 | at_risk aggregation | Cells → number: value_pool collapse, max-in/sum-across, 3 caps. at_stake vs extractable. |
| L20 | Oracle attack path | One target_role, two attacks: DeFi-borrow (other-asset) + NAV-redemption. Honest-zero. |
| L21 | Exit liquidity v2 | The drainable ceiling: 4 mechanisms, counter-token apportionment, the $2.85B LTV bug. |
| L22 | Multisig expansion | Anchor → signer cells at at_stake/threshold; where the partial flag is born. |
| L23 | at_risk lifecycle | Trigger (periodic full recompute) · HOLDS/vault paths · parity diff + 4 invariants. |
| Strand B · discovery — how the graph grows itself | ||
| L24 | Discovery flywheel | Bare node → RPC classify → RelatedAddrs → monitored set → repeat. Seeders vs refreshers. |
| L25 | Admin-role discovery | 17-probe battery (no admin standard); OZ ladder; severity stamped at source (feeds L13). |
| L26 | Oracle/NAV discovery | Registry symbol-binding → value_defining_oracle + ORACLE_DEP; cross-source net. |
| L27 | Oracle bridger | Transitive ORACLE_DEP (pure Cypher): markets/vaults inherit their assets' oracles. |
| L28 | Project inference | Contract → protocol via label precedence cascade + canonical-slug parity. A good-enough heuristic. |
| Strand C · self-checking — does the graph stay correct? | ||
| L29 | Chainref harness | Re-read chain: C vs G → gap/excess/drift; streak → ticket/heal. Chain-truth vs parity. |
| L30 | Healer subsystem | Auto-fix drift; 5 guards; heal-freely/prune-fearfully; shadow mode first. |
| L31 | Reconcile transport | Shared safe-apply: budget + 2s deadline + single-writer; secondary writes never stall primary. |
| L32 | Balance conservation | ΣHOLDS≈totalSupply; asymmetric band = coverage policy; big.Int sum, float ratio. |
| L33 | Linear promoter | File each finding once: create-then-mark, owned window, loud-dupe-over-silent-miss. |
| L34 | Validation suite | Self-consistency monitor; fast/slow tiers; per-check isolation; monitor not control loop. |
| Strand D · billing + corners | ||
| L35 | Cost allocation | Allocation, not measurement: blended-share of signals × sales-chosen pool; co_users split. |
| L36 | Balance-cache gateway | One un-bypassable plausibility invariant contains sticky cache corruption. |
| L37 | Coordination primitives | Lease + writer-epoch fencing (the "how" of L9); genesis self-heal; immutable-truth-heals-live. |
Companion refs: Glossary (nodes/edges/terms + Cypher · incl. at_risk terms) · Add-a-Decoder card.
| Subsystem | Key files |
|---|---|
| Block producer | cmd/block-ingest/main.go, pkg/feed/rpc.go |
| Stream / queue | pkg/queue/queue.go (XAdd/XReadGroup/XAck/XAutoClaim, backpressure) |
| Decoders | pkg/decoder/topics.go (topic0s), decoder.go (registry + decoders) |
| Graph vocabulary | pkg/types/schema.go (NodeType, EdgeType, EdgeCategory) |
| Write path | pkg/indexer/batch_writer.go (accumulate/coalesce/flush), indexer.go |
| Enrichment | pkg/enrichment/{worker,classify,enricher}.go; docs/enrichment-pipeline.md |
| Risk engine | pkg/risk/{at_risk_*,bfs,exposure}.go; PARITY_NOTE.md |
| Single-writer | pkg/graphwrite/, pkg/indexer/tx_recorder.go; docs/single-writer.md |
| Failure/recovery | cmd/indexer/cursor_watchdog.go, main.go (self-heal), pkg/genesis/balance_rebuild.go |
| Bootstrap | internal/freshstart/, pkg/bootstrap/, pkg/enrichment/v*_pool_seeder.go |
| Observability | pkg/telemetry/, otel-collector-config.yaml, grafana/*.json |
| Rule engine | pkg/rules/{engine,types,scope,firing}.go, docs/rule-fields.json (field catalog) |
| Risk math | pkg/risk/{admin_risk,node_risk_score,vault_concentration}.go, pkg/types/role_severity.go |
| Exposure BFS | pkg/risk/bfs.go (computeNodeExposure), exposure.go (incremental) |
| Admin panel | cmd/admin-panel/{auth.go, main.go}, auth0/xpapi_audit.go; docs in cmd/admin-panel/docs/ |
| Read surface | cmd/query-api/main.go (scaffold), cmd/admin-panel/ (auth0), pkg/rules/node_lookup.go |
| Alert delivery | pkg/alertprocessor/{processor,opensearchstore}.go, cmd/alert-processor/main.go, pkg/notification/ |
| at_risk engine (L19–23) | pkg/risk/at_risk_{cells,aggregate,extractable,exit_liquidity,value_pool,multisig,edges,scheduler,diff}.go |
| Discovery (L24–28) | pkg/enrichment/{enricher,discovery,oracle_bridger,navlink_*,admin_roles,focus_token_admin_probes,project}.go |
| Self-checking (L29–34) | pkg/quality/chainref/{verifier,runner,findings,linear_promoter,runner_healer,verify_*}.go, pkg/reconcile/, pkg/validation/ |
| Billing (L35) | pkg/pricing/allocate.go, cmd/cost-tool/; docs/pricing-model.md |
| Balance cache (L36) | pkg/balancecache/balancecache.go (typed gateway + plausibility invariant) |
| Coordination (L37) | pkg/statetracker/{lease,writer_epoch,transient,cursor}.go, pkg/genesis/balance_rebuild.go, pkg/reconcile/vaultheal/ |
| Concept | Metric |
|---|---|
| Backpressure (L7) | block_ingest.backpressure.blocked |
| Writer backlog (L9) | graphwrite_stream_backlog |
| Reconcile heal (L8) | chainref_reconcile.heal.total |
| Concept | Metric |
|---|---|
| Risk cycle (L6) | at_risk.cycle.duration |
| Enrich APIs (L5) | blockscout.api.{calls,errors,duration} |
| Bootstrap (L10) | bootstrap.task.attempts |
| Alerts (L15) | OpenSearch risk-alerts index · Delivered flag |
| Quality findings (L29) | OpenSearch quality-findings · streak; chainref_verifier.skip |
| Self-test (L34) | validation.{errors,warnings,findings} per check_id |
Scope every Cypher by graph_id; never full-scan (MATCH (n)); query both edge directions. |
Read a node's kind via coalesce(n.type, n.subcategory, n.category). Memgraph has no APOC. |
| Single position > $1T = bug (overflow), not a number. |
Bulk writes go through the graph-writer (a forbidigo lint guard enforces it); don't add raw ExecuteWrite. |
| Risk engine has strict parity-vs-Python — read the parity test before touching a cell path. Not a first-PR area. |
🎓 Deep-understanding tour: L1–L37 — COMPLETE, every major package opened. The build/maintain pipeline (L1–L11), the consumer/product side (rules L12 · read surface L14 · alerts L15 · boundary L18 · admin-panel L17), and the four deeper strands: at_risk end to end (cells/aggregation L6·L19, oracle attack L20, exit liquidity L21, multisig L22, lifecycle L23, field math L13, exposure L16); discovery, how the graph grows itself (flywheel L24, admin/oracle discovery L25·L26, bridger L27, project inference L28); self-checking, how it stays correct (chainref L29 · healers/transport L30·L31 · a verifier L32 · promoter L33 · validation L34); and billing (cost allocation L35); under it all sit the coordination primitives — balance-cache gateway (L36) and the lease + writer-epoch fencing, genesis self-heal, and immutable-truth healers (L37). This map is the index to your collection — every box links to the lesson that explains it. Print it (⌘P → Save as PDF) and keep it beside the glossary. When phase 2 (contributing) begins, start from the Add-a-Decoder card + L3/L4.