TRAVISGILBERT.ME/PROJECTS/ANTI-CONSPIRACY THEOREM/TECHNICAL NOTEBOOKSHEET 05 / N
JUN 17, 2026
T. GILBERT
Inventor
ANTI-CONSPIRACY THEOREMTechnical notebook. ACC v2.1.0, extension v0.2.0. Gemma 4 for Good submission.
ACC v2.1.0
EXT v0.2.0
MAY 18, 2026
Thesis

A small Gemma model should not decide what is true.It should generate an inspectable interface from a graph-verifier packet, and let a deterministic scorer carry the load it was never built for. Models hallucinate. Graphs do not. ACT is the working version of that separation.

§ 01

Project snapshot

ACT is the working version of the Anti-Conspiracy Constraint (ACC), a structural-integrity score for claim graphs. It does not ask whether a claim is popular, viral, or written confidently. It asks whether the claim is rooted, independently supported, specific, temporally spread, backed by enough evidence volume, free of collapsed citation loops, falsifiable, and not propped up by rhetorical pressure.

Gemma 4 does the parts a graph cannot: it reads a page, extracts claims and sources, and renders the verifier packet into a human-legible cockpit. Gemma never overwrites the score. This separation is the whole architectural argument.

ACC v2.1.0Extension v0.2.0Gemma 4 E4BWebLLM11-axis graphA2UI scene generationLocal-firstcommit fbb311e
§ 02

The real-world problem

The post-2020 information environment broke a load-bearing assumption: that a citation, by existing, contributes evidence. A single primary source can now be laundered through hundreds of secondary outlets and arrive in a feed looking like consensus. Standard fact-check UX treats each claim as a yes/no verdict, which collapses uncertainty and loses the structural reasons a claim is weak. Readers cannot tell the difference between false, under-evidenced, source-collapsed, and contradicted. All four read as “flagged.”

The cost of this collapse is concrete: people stop reading interfaces that punish them with low-information verdicts, and the readers best positioned to update their priors — undecideds, skeptics, the merely curious — disengage first.

ACT targets that gap with three commitments:

  1. Don’t decide truth. Decide structural integrity. Make the structure visible.
  2. Run on the user’s device.A page-analysis tool that phones home is a tool that won’t be trusted by the audience that most needs it.
  3. Make the small model do small-model work. Extraction, classification, and explanation — not adjudication.
§ 03

How ACT uses Gemma 4

Gemma 4 lives in the browser extension’s inference layer (browser-extension/src/inference/). It runs through WebLLM, with the model artifact served from a hosted /act route and a public WebLLM model as preflight fallback. The runner is a singleton, so a single download per session covers all subsequent page analyses.

Gemma is used in three bounded jobs:

  1. Content-type classification.Before extraction, Gemma decides whether the active page is news, opinion, scientific writeup, social post, or non-content. This routes the extractor’s prompt and prevents the system from treating a recipe page like a press release.
  2. Claim and evidence extraction. Gemma reads paragraphs from the active tab and emits structured claim nodes, source nodes, and evidence snippets that conform to the ACC graph schema. Gemma is the only component that touches raw natural language. Output is JSON-validated before it reaches the scorer.
  3. A2UI scene explanation.Once the deterministic builder has emitted a scene, Gemma may rewrite explanation cells — never scores, never component types, never trait values. A strict validator (schemaValidator.js in the extension, validate_evidence_scene in Python) rejects any Gemma output that drops props, alters ACC scores, or invents component types. The CalibrationBadge’s source field flips from deterministic to model-adjusted the moment Gemma touches a cell, so the reader sees the provenance.

What Gemma is not used for:

  • Deciding whether a claim is true.
  • Computing trait values or weights.
  • Producing the final ACC score.
  • Promoting itself — there is no path by which Gemma’s output can mutate the live threshold or trait weights.

This is the deliberate boundary. The model is a renderer with high-bandwidth I/O. The scorer is the judge.

§ 04

System architecture

pipelineactive page → cockpit

Active browser page
  │
  ▼
Content script: paragraph extraction
  │
  ▼
WebLLM (Gemma 4): content-type classification
  │
  ▼
WebLLM (Gemma 4): claim / evidence / source extraction → claim graph
  │
  ▼  (optional)
Tavily or Theseus web-search enrichment for top claims
  │
  ▼
Deterministic ACC v2.1 scorer  ──►  per-claim report
  │                                  (linear_score, geometric_core,
  │                                   penalty_total, rules, penalties,
  │                                   actions, claim_state,
  │                                   support_strength, epistemic_risk,
  │                                   verification_gap, diagnostics)
  ▼
A2UI scene builder  ──►  EvidenceCockpit JSON scene
  │
  ▼
WebLLM (Gemma 4): explanation cells only (validator-gated)
  │
  ▼
Browser cockpit renders the scene

Two implementations of the scorer ship in the repo and produce byte-identical outputs against contract tests:

  • Python reference theseus_acc/ package. NetworkX graphs in, full report out. This is the source of truth for behavior and the basis for benchmarks.
  • JavaScript port— embedded in the extension. Same eleven traits, same weights, same rules and penalties, same diagnostics. Runs entirely in the extension process. Validated against Python-generated fixtures.

The user can also run the extension installer with no model load at all. The deterministic path produces a complete ACC v2.1 report; Gemma’s contribution is restricted to extraction (when input is page text rather than a pre-built graph) and explanation.

Three runtime surfaces inside the extension

The Manifest V3 extension is split into three surfaces, each with a single responsibility. This separation is the reason the “no telemetry, model loads only on user action” guarantee is enforceable rather than a promise:

  • src/background/service-worker.js — coordinates model loading, active-tab analysis, Tavily and Theseus enrichment, deterministic scoring, and federation processing. The service worker owns the singleton MLCRunner; nothing else can spin up a second model instance.
  • src/content/content-script.js — extracts visible page text and renders the claim marker rail in an isolated DOM. Page text never leaves this surface unless the user has explicitly enabled enrichment.
  • src/popup/popup.js— onboarding, model progress, analysis controls, settings, and the result summary. This is the only surface that can issue MSG_START_MODEL_LOAD; the model cannot download without a user gesture in this UI.

The pipeline reads cleanly as a message-passing flow: MSG_START_MODEL_LOAD MLCRunner preflights the configured WebLLM route and falls back to the public model when allowed → MSG_ANALYZE_PAGE collects page text from the content script → WebLLM classifies content type and extracts ACC feature JSON → optional enrichment via tavily-client.js inference/scoring.js computes ACC v2.1 locally → federation processing adds correlation badge data → the content script paints the rail back onto the page.

Federation: aggregation without leakage

The federation processor is opt-in and structurally incapable of leaking page content. When enabled, it transmits only:

  • ACC feature bins (binned trait values, not raw scores)
  • Score components (linear, geometric, penalty totals)
  • Content type from the Gemma classification
  • Cluster metadata
  • Public key plus signature

It explicitly does nottransmit article text, claim text, page URL, or page content. This is the same boundary discipline as the Gemma-output validator and the outcome-layer “propose, never mutate” rule: shared state across users is bounded to the minimum information needed for aggregation, and every share is signed so an aggregator can detect replay or tampering without recovering the originating page.

Federation is the path to a network effect that does not require trusting a central server with reader behavior. It is the version of “this gets smarter as more people use it” that does not silently compromise its own privacy posture.

§ 05

ACC v2.1: the algorithm

The score per claim:

ACC(c) = linear_score(c) + geometric_core(c) − penalty_total(c)

linear_score is a weighted sum over eleven normalized traits. geometric_coreis a nonlinear combination that punishes claims passing on a single dominant trait while failing others — a structurally weak claim cannot ride one strong signal across the line. penalty_total aggregates deterministic symbolic penalties (single-source collapse, citation chain collapse, contradiction load above threshold). Claims with ACC < threshold (default 0.55) are flagged suspect.

The eleven traits

TraitWeightWhat it measures
root_depth0.140Distance from the claim to a verified or canonical root in the graph.
source_independence0.140Diversity of canonical origins among supporting sources.
support_ratio0.105Supporting evidence relative to total evidence, including contradictions.
temporal_spread0.126Distribution of supporting evidence over time vs. single burst.
evidence_volume0.105Raw count of distinct evidence snippets, saturated to prevent gaming.
claim_specificity0.084Specificity of claim language: named entities, dates, units, numbers.
falsifiability0.060Whether the claim admits a structurally defined disproof condition.
rhetorical_pressure0.060Inverse weight on persuasion markers: intensifiers, certainty signaling.
source_quality0.060Domain-list lookup against the bundled domains_v1.json quality table.
contradiction_load0.060Inverse weight on the count and weight of contradicting evidence.
citation_chain_collapse0.060Penalty signal for citation chains terminating in a single canonical origin.

Weights sum to 1.000. The geometric core uses the same trait vector but with a stricter aggregation that prevents single-dimension dominance.

Per-claim report shape

Every claim emits a structured report:

linear_score · geometric_core · penalty_total
rules        · penalties      · actions
support_strength · epistemic_risk
claim_state  · verification_gap
diagnostics

claim_state is one of: well_supported, source_collapsed, contradicted, under_evidenced, rootless, vague, suspect, unresolved. This is the field that does the UI work the old yes/no fact-check could not do.

The outcome layer

theseus_acc.outcomes records every deterministic ACC decision alongside any later outcome label (editor verdict, retraction, correction). From replayed outcomes it can propose a calibrated threshold — but it cannot rewrite weights, mutate the live threshold, or promote itself automatically. Recalibration is a reviewable PR, not a runtime side effect. This is the same safety boundary as the Gemma-output validator: nothing model-adjacent gets to touch the scorer behind the user’s back.

§ 06

A2UI: the verifier packet as an interface

docs/a2ui-scene-schema.md defines the EvidenceCockpit scene contract. The deterministic builder theseus_acc.a2ui.build_evidence_scene produces a JSON envelope:

EvidenceCockpit envelopev0.1.0

{
  "scene": "EvidenceCockpit",
  "version": "0.1.0",
  "acc_version": "2.1.0",
  "claim_count": N,
  "threshold": 0.55,
  "summary": "",
  "components": [ ... ]
}

Each claim contributes a ClaimCard, TraitRadar, RuleChecklist, NextChecks, and CalibrationBadge. SourceCollapsePanel, PenaltyList, and ContradictionPanel are conditional — they only appear when the underlying signal is non-trivial, which keeps the cockpit from screaming about penalties that did not fire.

Component IDs follow <Type>.<claim_id> so the renderer can recover ownership without walking props. The validator is the security boundary: it rejects unknown component types, missing required props, wrong scene name, claim-count mismatches, and any CalibrationBadge.source value other than deterministic or model-adjusted. Tests in tests/test_a2ui_scene.py enumerate every rejection condition.

This is the architectural payoff. The score lives in deterministic Python and JavaScript. The scene lives in JSON. Gemma renders the explanation, and only the explanation, against a schema that knows exactly what it is allowed to change.

§ 07

Engineering decisions and trade-offs

On-device by default. WebLLM was chosen over a hosted inference endpoint because the audience that most needs ACT is the audience that least trusts a server-side fact-checker. The cost is a one-time model download per session; the benefit is that no page text ever leaves the browser unless the user explicitly enables Tavily or Theseus enrichment with their own credentials.

Two implementations, one contract. The Python package is the source of truth for behavior; the JavaScript port is the deployment target. Both score the same fixtures to identical output. Contract tests run in CI. This is more code to maintain, but it means the browser extension can ship without any server dependency for the core scoring path.

Geometric core, not just a weighted sum.A linear-only score lets a single dominant trait carry a structurally weak claim across the threshold. The geometric core punishes that. The cost is interpretive: explaining “this claim scored 0.71 linearly but 0.43 geometrically” requires the cockpit to actually show both. The A2UI scene’s TraitRadar and CalibrationBadge are how that explanation gets carried.

Eleven traits, not five. ACC v2 had six traits. v2.1 added falsifiability, rhetorical_pressure, source_quality, contradiction_load, and citation_chain_collapse after the synthetic adversarial family in the benchmarks revealed that the v2 vector could be gamed by stacking specificity and temporal spread on a claim with no real evidence backbone. The new traits close those holes. The cost is more annotation surface in the graph schema; the synthetic generator was extended to match.

No automatic threshold mutation.The outcome layer can propose a calibration but never apply one. Reviewable calibration is slower than runtime self-adjustment. It is also the only version of “learning from outcomes” that is safe to ship to an audience that does not trust the people running the system.

§ 08

Challenges and mitigations

Model output drift. Early Gemma extraction runs produced JSON that was usually valid but occasionally invented sources or merged claims. The mitigation is a hard validator at the boundary: extraction output is parsed against a schema, and any failure rejects the entire packet and falls back to a deterministic chunked-paragraph heuristic. The system always produces some graph; the worst case is a thinner one.

WebLLM cold start.Loading the model the first time a user opens the popup is a noticeable wait. The mitigation is a deterministic-first analysis path — the user can analyze pages with no model load at all, and the model load is gated behind an explicit user action with progress feedback.

Chrome Web Store policy on remote WebAssembly. Manifest V3 disallows remotely hosted executable logic. The WebLLM runtime itself is bundled with the extension, but the configured model .wasm library currently loads from a remote host — which means it must be treated as policy-sensitive executable code until proven otherwise. browser-extension/docs/CHROME_WEB_STORE.md documents two acceptable paths to public store submission: (1) package the WebLLM .wasm library inside the extension ZIP and reference it with an extension-local URL, or (2) ship a store-specific build that disables WebLLM and exposes only the deterministic local scorer plus optional user-enabled search enrichment. The deterministic path produces a complete ACC v2.1 report on its own, so option (2) is a fully functional fallback. The judging artifact in this submission is the unpacked extension loaded via Developer mode, which has no such restriction.

Adversarial benchmarks.The synthetic generator produces four families: clean, suspect, mixed, and adversarial. The adversarial family specifically targets claims that look strong on a single dimension. ACC v2.1’s penalty system was redesigned around what the adversarial family kept getting past v2.

§ 09

Why these design choices fit the problem

The problem is not “we need a better truth oracle.” The problem is that the audience that needs evidence-literacy tooling does not trust opaque verdicts, server-side processing, or anything that looks like the existing fact-check apparatus. ACT’s design is shaped almost entirely by that constraint:

  • Deterministic scoring means the score is auditable and reproducible.
  • Local-first inference means the user keeps control of their page text.
  • A small Gemma model in a narrow role means inference is feasible on consumer hardware.
  • The A2UI cockpit means the user sees why a claim got the score it did, not just the verdict.
  • The reviewable outcome layer means the system can improve without quietly retraining itself behind users.

The Gemma 4 for Good framing is the right one because the win here is not raw capability — it is what becomes possible when a small model is constrained to honest, bounded work and a deterministic system carries the responsibility for adjudication.

§ 10

How to run

Python referencetheseus_acc

python -m pip install -e ".[dev]"
python -m theseus_acc.benchmarks.synthetic --full
python -m pytest

Browser extension (judges)npx installer

npx act-theorem install --out ./anti-conspirarcy-theorem-extension
# Then chrome://extensions → Developer mode → Load unpacked

Browser extension (local checkout)repo build

cd browser-extension
npm ci
npm run package
# load browser-extension/release/anti-conspirarcy-theorem-extension.zip

Once loaded, click the extension icon, run analysis on the active tab, and (optionally) start the WebLLM model load to enable Gemma-driven extraction and explanation.

§ 11

What is public and what is not

Public, MIT-licensed

  • ACC v2.1 Python reference implementation (theseus_acc/)
  • JavaScript scorer port (browser-extension/src/)
  • Manifest V3 browser extension (three runtime surfaces: service worker, content script, popup)
  • NPX installer (act-theorem)
  • A2UI scene schema, builder, and validator (Python + JavaScript mirror)
  • Privacy-preserving federation processor
  • Synthetic benchmark generator and four-family eval harness
  • Outcome layer and threshold calibration tooling
  • Eleven-trait domain list lookup data
  • Contract tests across Python ↔ JavaScript
  • Chrome Web Store readiness documentation

Not public

  • The full Theseus research backplane that produced the ACC trait vector.

The split is intentional. The theorem is the contribution. The research that produced the theorem stays in its own repo.

§ 12

Acknowledgements

ACC v2.1 owes its structure to the Theseus epistemic engine work that preceded it. The adversarial benchmark family is what forced the move from six traits to eleven. Every reader who told me a fact-check verdict felt useless is in some small way responsible for the cockpit existing at all.