ServicesRumor

The Propagation Model

What actually happens to a fact between injection and belief. The graph here has 1 s edge latency, 0.7 edge fidelity, and a deterministic seed.

Hops are scheduled events

Injection records the origin's belief immediately, then schedules one hop per outgoing edge at now + latency_seconds. A background scheduler (every RUMOR_SCHEDULER_TICK_MS, 1 s by default) delivers hops as they come due; each delivery records a belief at the receiving node and schedules that node's own outgoing hops in turn, up to RUMOR_MAX_HOPS (32) from the origin. There is no global tick - a rumor crossing a three-day edge simply surfaces three days later.

snug rumor tick <graph> drains due hops on demand and reports hops_processed / beliefs_recorded / hops_scheduled. With the scheduler running it usually finds nothing; it exists for deployments that disable the scheduler and for deterministic tests.

Fidelity decay and distortion

Each hop carries a fidelity: the product of every edge fidelity along its path. With 0.7 edges, the first hop arrives at 0.7 and the second at 0.49. While carried fidelity stays at or above 0.6 the payload is copied verbatim; below that threshold it mutates. The origin injected {"claim": "the king is wounded", "severity": 2}, one hop out the innkeeper held it intact at 0.7, and two hops out the guard held {"claim": "the king is slain"} at 0.49.

Mutation is a built-in table applied to an object payload's claim (string) and severity (integer, clamped 0-5) fields; payloads without those fields pass through unchanged even below the threshold. The table does case-insensitive substring replacement - wounded becomes slain, ill becomes dying, delayed becomes lost, seen becomes vanished, missing becomes dead, rumored becomes confirmed - and a claim matching none of these gets an allegedly prefix or a (distorted) suffix. Substring matching is literal: a claim about "the mill" mutated to "the mdying" in live testing, because mill contains ill. severity drifts upward on roughly half of mutating hops.

The graph's distortion config accepts a table_id and an arbiter_paraphrase mode, but the current engine always applies the built-in table; treat those fields as reserved.

Deterministic mode

Creating a graph with --seed enables seeded mode: every mutation draw is keyed to the seed plus the fact id, sending node, receiving node, and hop number. Replaying the same injection over the same topology reproduces byte-identical distortion, which is what makes spread experiments and QA comparisons meaningful. Without a seed, draws are keyed to the clock.

Confidence and trust

A belief's confidence is its carried fidelity times the receiving node's trust in the network. Nodes without a trust_source trust fully (1.0), so by default confidence equals fidelity - the 0.49-fidelity guard belief above arrived with confidence 0.49. A node created with a trust_source of the form {"reputation_index": "domain:kind:id"} instead looks up that Reputation score at delivery time and maps it linearly (score -100 to +100 onto trust 0.0 to 1.0, with 0.5 when the score is unavailable). See Reputation.

Saturation and cycle blocking

A rumor never echoes. A hop is dropped when its receiver already knows the fact, and a node never fans out toward any node already on the hop's provenance path. Verified on a diamond graph (a to b and c, both to d): d ended up with exactly one belief, one provenance path (["a", "b", "d"]), and an unreinforced confidence of 0.49 - the second delivery via c was discarded. Repeat deliveries do not boost confidence or extend memory; only corrections punch through.

Forgetting

Every belief expires default_ttl_seconds (7 days by default) after it arrives, per the graph's forgetting config. Expiry is enforced lazily: reads purge expired entries, so beliefs, trace, and prevalence counts only ever reflect live memory. There is no resurrection - once forgotten, a node treats a re-arriving rumor as news.

Corrections

A correction re-seeds an existing fact_id from an origin node and chases it through the same edges at the same speed. It differs from a plain rumor in three ways:

  • It never mutates - every node receives the corrected payload verbatim, regardless of fidelity.
  • It overwrites - a node already holding the rumor keeps its provenance and fidelity_remaining but takes the corrected form, is marked corrected: true, gets a fresh expiry (when reinforcement_extends is on, the default), and gains confidence (the guard's 0.49 rose to 0.735).
  • It counts separately - trace prevalence moves nodes from true_form or distorted into corrected, and the correction response reports the original_footprint it must cover.

A correction follows edges, so it only reaches nodes reachable from its origin; seed it from a well-connected node or the rumor's own origin.

Quarantine

Quarantining a node makes it inert on the receiving side: incoming hops are consumed and dropped - no belief, no onward fanout, and no replay after release. Its existing beliefs are untouched and it can still be read. Quarantining a high-traffic hub is the built-in way to cut a spread off mid-flight before a correction lands.

On this page