Inspiration

We kept running into the same uncomfortable idea: an argument doesn't spread because it's right — it spreads because it's shareable, and platforms are very good at rewarding shareability over rigor. We wanted to stop describing that dynamic in the abstract and actually build it: a system where you can dial up what a platform rewards — outrage, simplicity, absurdity, rigor — and watch what kind of population and what kind of ideas that produces. Drift (aka Memetic Drift) is our attempt to make the feedback loop between incentives, content, and people inspectable instead of just something we complain about on Twitter.

What it does

Drift is an agent-based simulation that starts from 200 real tweets, each represented as a normalized 256-dimensional embedding, and lets a small society of simulated agents share, mutate, and reject them over time. Every time someone shares, they either forward an existing variant or generate five candidate mutations that compete against each other under a fitness function blending platform incentives and the sender's own cognitive biases (rigor, outrage-proneness, susceptibility). The winning mutation still has to clear the receiver's bounded-confidence gate and get probabilistically adopted — winning the mutation contest doesn't guarantee it spreads.

Adoption reshapes the agent too: their worldview shifts toward what they accepted, their rigor and susceptibility drift, and their trust in the sender updates retrospectively based on how that content later performed. You can watch all of this live across a semantic "meme cosmos," an agent-space view, and a trust network; inspect any lineage (including ones that went extinct); switch presets like "Conspiratorial cascade" or "Epistemic renaissance"; and export a frozen end-state snapshot — including the raw embedding — as JSON.

How we built it

  • Data layer: 200 source tweets joined by array index to 256D embeddings (C10X/Qwen3-Embedding-TurboX via model2vec, precomputed — not run live), plus four semantic anchor vectors for rigor, outrage, absurdity, and simplicity in the same embedding space.
  • Simulation core: a MemeticEngine driving the tick lifecycle (sharing, transmission, trust updates, conviction decay, archiving) and an EvolutionEngine handling the five-candidate mutation-and-selection step, where each candidate is normalize(parent − Σ alpha[k]·anchor[k] + noise) and fitness is a weighted sum of cosine alignments to the four anchors.
  • State and rendering: Zustand for state and frame publication, Canvas-based views for the cosmos/agent-space/trust-network visualizations, and React for the inspector panels (resizable, keyboard-accessible).
  • Math: a matrix-free power-iteration PCA to project 256D down to 2D for the cosmos view, fit once on the roots so movement stays comparable across a run.
  • Optional interpretation layer: a server-side route that does nearest-neighbor retrieval and, if configured, proposes a Qwen-compatible paraphrase for a mutated vector — explicitly not a claim of exact decoding.

Challenges we ran into

  • Keeping the metaphor honest. "Rationality," "fitness," "R₀" all sound like they carry real-world epistemic weight. We had to be disciplined about labeling every metric for what it actually measures (e.g., Societal rationality is mean agent rigor, not "percent of correct people"; R₀ is a simulation proxy, not an epidemiological estimate) so the tool doesn't quietly overclaim.
  • A genuinely confusing sign convention. The rationality/irrationality field runs 0 (rational) → 1 (irrational) for memes, while an agent's rigor (rho) runs the opposite direction — higher is more rigorous. We caught ourselves flipping this more than once while building the dashboards.
  • Making failure visible. It was tempting to only show what survives. We had to explicitly build out "Extinct / unheld" lineage inspection so the interface doesn't silently discard the (arguably more interesting) content that never found an audience.
  • Decoupling visualization performance from simulation truth. Playback speed depends on machine performance, so we had to make sure comparisons across runs are always tick-based, never wall-clock-based.
  • The interpretation layer's limits. Mutating an embedding doesn't change the displayed tweet text, and there's no guarantee a generated paraphrase re-embeds anywhere near the mutated vector — we had to be careful not to let the optional LLM interpretation feature imply more precision than it has.

Accomplishments that we're proud of

  • A selection mechanism where mutation and adoption are two genuinely separate, inspectable steps — you can see why a candidate won the contest, and separately see why (or whether) it was actually adopted by a receiver.
  • Full lineage archaeology: every variant, including archived and never-adopted ones, stays inspectable within a run, with generation depth, root drift, and selection attribution all exposed.
  • A deterministic, reproducible core — same dataset, code, config, seed, and tick-timed interventions reproduce the same run.
  • An interface that resists over-interpretation on purpose: telemetry captions, trait radars, and polarisation scores are all framed as heuristics and proxies rather than ground truth, with an explicit "what this metric is NOT" alongside what it is.
  • A working end-to-end pipeline from raw embeddings to a live, steerable, exportable simulation — with four adjustable platform-incentive weights that produce visibly different population-level outcomes.

What we learned

  • Small, explicit modeling choices compound fast. A single asymmetric coefficient — rigorous agents pay a larger cognitive-load penalty — has real downstream effects on which content classes survive, and it's exactly the kind of assumption that's easy to bury and important to surface.
  • Evolutionary language is a powerful but risky framing. It's a genuinely useful analogy (variation, selection, differential transmission all show up structurally), but we had to keep reminding ourselves — and now judges and users — that it's an implemented algorithm, not evidence about how culture actually works.
  • Visualization is an argument. Choices like brightness-encodes-rationality or PCA-fit-on-roots-only aren't neutral — they shape what story a viewer walks away with, so they need the same scrutiny as the underlying math.
  • Reproducibility and honest metrics take real engineering effort — deterministic seeding, tick-based comparison, and clearly-scoped telemetry captions were as much work as the simulation logic itself.

What's next for Memetic Drift

  • Validate the tweet metadata and semantic anchors against independently annotated examples rather than relying solely on supplied scores.
  • Re-embed generated paraphrases to actually measure how well an interpreted sentence matches its target mutated vector.
  • Run a mutation-only control against the full selection model across many seeds to isolate what selection is actually contributing.
  • Export full intervention histories (not just end-state snapshots) so entire runs, not just endpoints, are reproducible and shareable.
  • Improve polarisation and distribution diagnostics beyond the current one-dimensional bimodality proxy.
  • Expand the retrieval corpus and explore mutation operators that stay closer to semantically coherent sentence embeddings, narrowing the gap between "moved in embedding space" and "means something different."

Built With

Share this project:

Updates

Submission history