kaldamus entity reference · EventGraph
EventGraph owns no data of its own — it's a full, disposable recomputation of what events.json, event_dependencies.json and event_factors.json already say, plus one structural, falsifiable check: does the market price an effect above its necessary cause?
| Sub-shape | One row per | Holds |
|---|---|---|
| GraphNode | each Event (always) or referenced Factor (optional layer) | id · kind · label / category · event-only: status, probability, resolved_outcome · computed: in/out_degree |
| GraphEdge | each depends_on (event→event) or has_factor (event→factor) | source / target · type · kind (hard/soft) · computed: coherence_violation, precondition_met |
| GraphMetrics | the graph (singleton rollup) | node / edge counts · components · longest_hard_chain · hard_cycle · coherence_violation_count · top_degree |
id="current") holding three co-equal sub-shapes: the nodes, the edges between them, and a rollup of both.graph.json = one rowGraphNode is heterogeneous: event nodes always exist, factor nodes are an optional layer.--no-factors → event-only graphFactor row never appears here at all.
flowchart TD
classDef srcNode fill:#16233b,stroke:#5a8fd4,stroke-width:1.5px,color:#dfe7f5;
classDef factorNode fill:#241d0c,stroke:#c9a84c,stroke-width:1.5px,color:#f3e6bd;
classDef decisionNode fill:#12151f,stroke:#5a6178,stroke-width:1px,color:#c9cbd6;
classDef computeNode fill:#161822,stroke:#e0e0e0,stroke-width:2px,color:#f0f0f0;
classDef deadEnd fill:#12151a,stroke:#3a4058,stroke-width:1px,color:#7a8296,stroke-dasharray:3 3;
A["events.json"]:::srcNode --> D["node per Event"]:::srcNode
B["event_dependencies.json"]:::srcNode --> E["depends_on edges
drop if either endpoint missing"]:::srcNode
D --> E
E --> F{"kind?"}:::decisionNode
F -- "soft" --> H["coherence_violation = false"]:::computeNode
F -- "hard" --> G{"P(source) > P(target)?"}:::decisionNode
G -- "yes" --> I["coherence_violation = true"]:::computeNode
G -- "no" --> H
C["event_factors.json
+ factors.json"]:::factorNode --> K{"--no-factors?"}:::decisionNode
K -- "no (default)" --> L["node per referenced Factor
+ has_factor edges"]:::factorNode
K -- "yes" --> M["factor layer omitted"]:::deadEnd
I --> N["graph-wide metrics:
components, longest_hard_chain,
hard_cycle, coherence_violation_count"]:::computeNode
H --> N
L --> N
M --> N
N --> O["graph.json (id='current')
fully overwritten"]:::factorNode
Every run of update_event_graph.py. Blue = event-side inputs, gold = factor-side inputs and the final write.
depends_on edge with an off-corpus endpoint is dropped, so every rendered edge connects two real event nodes.update-all| graph.json (id="current") | Factor rows it's built from | |
|---|---|---|
| Written by | every run of update-event-graph, unconditionally | the first successful discovery of that canonical_name |
| Update rule | full replace — nodes, edges, metrics all recomputed | first-write-wins on descriptive fields |
| History kept | none — prior snapshot leaves no trace | row persists indefinitely |
| First-write-wins? | no — nothing is asserted more than once | yes — description & category freeze after first write |
stateDiagram-v2
direction LR
classDef computeState fill:#161822,stroke:#e0e0e0,stroke-width:2px,color:#f0f0f0;
[*] --> current: every run of update-event-graph
current --> current: full overwrite —
nodes, edges, metrics all recomputed
class current computeState
The entire lifecycle of graph.json. There is no Stable / Orphaned / Purged here — nothing on this row is ever asserted more than once.
graph.json holds one row and every field changes on every run — there's no first-write-wins group, because nothing here is ever asserted more than once.factors.json deleted → descriptions unrecoverabledepends_on edge is a claim the market's own prices can check: if B must happen before A, A's price should never exceed B's.P(effect) > P(cause) → violationdepends_on edge are excluded, not counted as singletons.hard_cycle: true → flagged as a bug