DEV Community

Akshara A
Akshara A

Posted on Edited on

ARGUS PRISM: The Hundred-Eyed Fact-Checker That Audits AI, Refutes Hallucinations, and Gets Paid for It

Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission 💸

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

ARGUS PRISM checks technical claims in a draft or an AI-generated answer against current, authoritative sources. It scores each claim with deterministic math, corrects what is wrong, and produces a verification report that a freelancer can sell as a service.

Resource Link
Live demo argus-prism-studio.onrender.com
Code github.com/akshara-a/ARGUS-PRISM
Partner categories Render, Gemma, Backboard, ElevenLabs, Sentry Agent Tracing, SerpApi

The Problem in One Example

A team is finalising a migration RFC. The draft says:

"Next.js 15 continues to support React 18 in production, and LegacyAPI v1 is recommended for high-load clusters."

They ask an AI assistant to confirm it, and it answers:

"Yes, absolutely! LegacyAPI v1 is a battle-tested, rock-solid solution. You can safely deploy this to production."

The answer is wrong. The assistant relied on older blog posts that still rank well. The official 2026 changelog says LegacyAPI v1 was removed, so the deployment would fail at runtime.

This example comes from the project's agent walkthrough (docs/AGENT_WALKTHROUGH.md). The library names are fictional test fixtures.

The assistant was not malicious. It sounded confident without checking how current or authoritative its sources were. ARGUS PRISM adds that check.


Summary

ARGUS PRISM is a fact-verification engine for technical writing and AI answers. It decides with deterministic math (source tiers, time decay, contradiction detection, and Bayesian scoring), and when sources disagree it searches for the primary source to settle the dispute.

For open-source AI it uses Gemma 2 locally through Ollama, Llama 3 and Mistral 7B through Backboard, and a TabPFN-style uncertainty model, so no closed API is required. It follows a zero-persistence design: drafts are never written to disk, a database, or logs.

Ghostwriters, docs agencies, DevRel teams, and migration reviewers can use it commercially, and agents can call its 15 MCP tools to verify before they answer. You can try the live Studio or run uv run python backend/demo.py locally with no API keys. All 7 benchmarks and 82 unit tests pass.


How It Handles the Example

flowchart LR
    S["Claim:<br/>LegacyAPI v1 is recommended<br/>for high-load clusters"] --> A["ARGUS PRISM"]
    A --> P1["2022 blog (Tier 3, x0.5)<br/>decayed by e^(-λt)"]
    A --> P2["2026 official changelog (Tier 1, x1.5)<br/>current"]
    P1 & P2 --> X{"Contradiction"}
    X --> T["Tie-breaker search<br/>against primary sources"]
    T --> R["REFUTED"]
    R --> F["Corrected sentence<br/>with citation and diff"]
    R --> D["Dependent claims<br/>downgraded"]

The output includes:

  • a score with ±σ% uncertainty bounds
  • a claim-by-claim ledger with citations
  • a red and green diff of the corrections
  • a client-ready certificate
  • a 60-second spoken briefing

Everything is produced in memory and none of it is stored.


How the Pieces Fit Together

ARGUS PRISM is a single pipeline. Each open-source or partner component has one job.

flowchart LR
    IN["Draft or live URL"] --> EX["Extract claims<br/>Gemma 2 local / regex"]
    EX --> SR["Gather evidence<br/>SerpApi: Web, Scholar, News<br/>or DuckDuckGo"]
    SR --> MATH["Deterministic scoring<br/>tiers x decay x Bayes"]
    EX --> BB["Cross-check<br/>Backboard: Llama 3, Mistral, Gemma 2"]
    BB --> MATH
    MATH --> OUT["Verdict, diff, certificate"]
    OUT --> EL["Spoken debrief<br/>ElevenLabs"]
    MATH -. spans and latency .-> SEN["Sentry agent tracing"]
    OUT --> RND["Hosted on Render<br/>API, Web Studio, Dashboard"]

Gemma 2, run through Ollama, extracts claims locally so private drafts stay on the machine. SerpApi (or DuckDuckGo) returns Google Web, Scholar, and News results for the evidence pool. Backboard reaches Llama 3, Mistral, and Gemma 2 with one key to produce an agreement ratio.

The deterministic kernel then applies source tiers, freshness decay, contradiction detection, and a Bayesian update. ElevenLabs turns the result into a 60-second spoken debrief in one of three voices. Sentry records a span for each pipeline stage with latency and cost visibility, and Render hosts the API, the Web Studio, and the dashboard from one blueprint.


1. What I Built

1.1 The problem

LLMs write fluent text that is often wrong. They state outdated facts, such as an API removed last quarter, with total confidence. Single-pass RAG makes this worse. It retrieves the top-ranked pages, and those are often SEO-heavy 2022 tutorials that contradict the current changelog.

This hurts people who get paid for correctness.

Technical ghostwriters and freelance writers risk their credibility, and sometimes the contract, over a single wrong version number. DevRel and docs agencies ship tutorials that must not break on copy-paste. Due-diligence reviewers and consultants sign off on migration RFCs. AI agent builders need a trustworthy verify-before-you-answer tool.

1.2 The solution

ARGUS PRISM treats search engines as telemetry streams. It does not ask an LLM whether a claim "seems right." It computes a verdict with explicit, reproducible math.

Official registries and docs count 1.5x, community hubs 1.0x, and SEO blogs 0.5x. Evidence ages as e^(-λt), with λ inferred from how fast the domain moves. Opposing claims on the same entity are flagged as contradictions, and a high-severity conflict triggers a tie-breaker search against primary sources.

An evidence graph downgrades any claim that depends on a refuted one. A Bayesian uncertainty model (TabPFN-style) gives every score calibrated ±σ% bounds. The auto-fixer rewrites refuted claims with primary citations and shows the change as a git-style diff.

1.3 The Side-Hustle Business Model

ARGUS PRISM is built so one person can run a paid verification service. A freelancer runs a client's draft through the engine, reviews the result, and delivers a branded Verification Certificate, a corrected draft, and optional extras. The tool does the slow research. The freelancer supplies judgment and the client relationship.

The service in one line

"I fact-check your technical content against current primary sources, fix what is wrong, and hand you a certificate you can show your readers or your client."

The workflow

flowchart LR
    Client["Client sends draft<br/>or a live docs URL"] --> Run["Freelancer runs<br/>argus validate --file draft.txt<br/>--client 'Client Name'"]
    Run --> Score["Integrity score ±σ%<br/>claim ledger + citations"]
    Score --> Review["Freelancer reviews<br/>contested claims"]
    Review --> Fix["Auto-fix: refuted claims<br/>replaced with primary sources"]
    Fix --> Pack["Package deliverables"]
    Pack --> Invoice["Invoice:<br/>Fact-Check and Verification Audit"]
    Invoice --> Repeat["Retainer or per-article repeat work"]

What the client receives

The Client Verification Certificate is a branded, print-ready HTML report with the integrity score, the claim ledger, and the time-saved figure. It is proof the content was audited and a visible line item on the invoice. The corrected draft replaces refuted claims with grounded text and primary citations, shown as a red and green diff, so the client can apply the fixes without redoing the research.

The evidence dossier adds a summary for each contradiction, the full claim ledger, and the formulas used, which gives editors and compliance teams an audit trail. The verification badge is an embeddable SVG for READMEs, Notion pages, and newsletters. The academic export produces Markdown with numbered footnotes and an IEEE or APA bibliography for Substack, Medium, Ghost, or Obsidian. The spoken debrief is a 60-second audio summary in one of three voices for busy executives and sponsors.

The economics

The CLI estimates the manual work it replaces, so the value shows up on every report. The heuristic in the code is:

estimated_hours = max(0.5, claims × 0.35 + (words ÷ 1000) × 0.5)
billable_value  = estimated_hours × hourly_rate        (default $50/hr)
Enter fullscreen mode Exit fullscreen mode

For example:

A short blog post with 6 claims and 600 words comes out at about 2.4 hours, or $120 at $50 an hour. A technical tutorial with 12 claims and 1,500 words comes out at 4.9 hours, or $245. A long guide or RFC with 25 claims and 3,000 words comes out at 10.2 hours, or $510.

These figures come from the report's built-in heuristic, which assumes roughly 20 to 25 minutes of research per factual claim. They are estimates to anchor a conversation, not measured results or market rates. The hourly rate is configurable.

Why the margins work: the open-source stack keeps the cost of goods close to zero. Local Gemma 2 and DuckDuckGo search are free, the Cost-Guard cache avoids paying twice for the same query, and the offline engine needs no keys. The one metered input is optional live SerpApi search, which the cache is designed to minimise.

Pricing ladder

This is an illustrative starting structure, to be validated with real clients.

A per-article audit (certificate and corrected draft) suits a single post, tutorial, or docs page. A monthly retainer (a fixed number of audits, dossiers, and badges) suits agencies, newsletters, and DevRel teams with regular output. A migration RFC review (dossier, head-to-head stack comparison, and audio debrief) suits engineering managers signing off on an upgrade. The self-hosted MCP and API option gives teams the open-source engine to build "verify before you answer" into their own agents.

Who buys, and what they are really buying

Freelance writers and ghostwriters pay for a documented fact-check on every delivery, because one outdated version number damages credibility. DevRel and docs agencies pay for verification before publication, since tutorials that fail on copy-paste cost trust. Engineering managers and consultants pay for a second opinion backed by current changelogs, because a migration RFC built on stale advice can cause outages. AI agent builders pay for a tool their agent can call before it responds, since agents otherwise answer confidently from stale sources.

Why this beats the alternatives

Manual fact-checking is slow, inconsistent, and hard to document. ARGUS PRISM takes minutes per draft and gives a reproducible score with citations. Asking another LLM to double-check relies on the same stale training data and the same confident tone, whereas ARGUS PRISM uses evidence tiering, time decay, and a tie-breaker against primary sources. Plagiarism and grammar tools check wording, not whether the claims are true.

Trust and privacy as selling points

Clients often share unpublished drafts under NDA. Because the engine can run fully locally with zero persistence, the freelancer can promise that the draft is never stored or sent to a third-party model. That is a concrete reason to choose this service over a hosted one.

1.4 Feature map

ARGUS PRISM is organised into five layers. Each layer feeds the next.

flowchart LR
    A["Verification Core<br/>Decides what is true"] --> B["Open-Weight AI<br/>Extracts and cross-checks"]
    B --> C["Deliverables<br/>What clients receive"]
    C --> D["Interfaces<br/>How people and agents connect"]
    D --> E["Operations<br/>Keeps it fast, safe, and observable"]

Verification Core. A six-state machine enforces one deterministic path from planning to report. Credibility tiering weights sources, freshness decay ages evidence, and a contradiction detector flags opposing claims. A tie-breaker loop resolves conflicts against primary sources, an evidence graph downgrades dependent claims, and a Bayesian posterior updates confidence from corroboration.

Open-Weight AI. Gemma 2 through Ollama handles local, private claim extraction. Backboard provides a tri-model check across Llama 3 8B, Mistral 7B, and Gemma 2 9B. A TabPFN-style oracle returns class probabilities and ±σ% bounds, and a regex fallback works with no model at all.

Deliverables. Clients receive a certificate, an evidence dossier, an embeddable badge, an academic export with IEEE or APA references, a 60-second spoken debrief, and a git-style auto-fix diff.

Interfaces. The engine is available as an MCP server (15 tools, 4 resources, 3 prompts), a REST API with 12 endpoints, a Next.js 16 Web Studio, a Streamlit dashboard, and a CLI.

Operations. The Cost-Guard cache combines an in-memory LRU with SQLite, Sentry provides tracing, and the zero-persistence design stores no draft. Security hardening covers SSRF, XSS, and CSP, and delivery uses Docker, Render, and GitHub Actions.


2. Demo

2.1 Links

Try the Studio in under a minute:

  1. Open the Studio.
  2. Click one of the six enterprise presets: FastAPI Concurrency, Kafka KRaft Consensus, PyTorch 2.5 Inductor, OAuth 2.1 Security, LegacyAPI v1 Stale Spec, or the QuantumReactJS Trap.
  3. Pick a provider (DuckDuckGo, SerpApi, or the offline Mock Engine), a search engine (Web, Scholar, or News), and an extractor (regex, Gemma 2, or tri-model).
  4. Press Run Deterministic Factual Audit.

The free-tier host sleeps when idle, so the first request can take a short while to wake. The Studio also has a Mock Engine for deterministic offline runs, and the presets are meant to show the range from verified to hallucinated.

2.2 Five-second quickstart

No API keys needed. The offline path uses the mock provider and the regex extractor.

git clone https://github.com/akshara-a/ARGUS-PRISM
cd "ARGUS-PRISM"
uv venv && uv pip install -e .
uv run python backend/demo.py     # hallucination trap, contradiction catch,
                                  # cost-guard economics, comparison, HTML dossier
uv run python backend/evaluate.py # 7/7 benchmark checks
Enter fullscreen mode Exit fullscreen mode

2.3 Demo storyline

sequenceDiagram
    autonumber
    actor W as Freelance writer
    participant UI as Web Studio (Next.js)
    participant API as FastAPI
    participant ENG as ARGUS Engine
    participant WEB as Search provider
    participant AI as Open models

    W->>UI: Paste draft or a live docs URL
    UI->>API: POST /api/validate
    API->>ENG: run 6-state pipeline
    ENG->>WEB: optimistic, skeptical, temporal queries
    WEB-->>ENG: raw documents (cached by Cost-Guard)
    ENG->>AI: extract claims, triangulate models, uncertainty
    ENG->>ENG: tier, decay, detect conflict, tie-break
    ENG-->>API: score ±σ%, claim ledger, DAG
    API-->>UI: report + audio (base64, in-RAM)
    UI-->>W: gauge, claim cards, red/green diff
    W->>UI: Apply Fixes, then Download Certificate

2.4 What you will see

The hallucination trap feeds in a made-up library (QuantumReactJS), which scores 0.0% with an empty claim ledger. The contradiction catch shows a stale 2022 tutorial saying LegacyAPI v1 is fine while a 2026 changelog says it was removed. ARGUS decays the tutorial, runs a tie-breaker query, elevates the changelog, and marks the old claim REFUTED.

The auto-fix diff shows the false claim in red and the grounded replacement in green, and one click applies it to the editor. The certificate modal previews the HTML report in a sandboxed iframe, ready to download. The voice persona switch lets Rachel, Adam, or Drew read the 60-second debrief.


3. Code

3.1 Repository

ARGUS PRISM

Deterministic Evidence Intelligence Layer via Model Context Protocol (MCP)
Autonomous Hallucination Elimination & Deterministic Evidence Intelligence Engine

CI Benchmark Unit Tests Next.js 16 CI Workflow Docker Python MCP License


🎯 Executive Summary

Modern AI agents suffer from an over-reliance on single-pass retrieval, leading to hallucination disguised as confidence. ARGUS PRISM solves this by treating live search APIs (SerpApi) as pluggable telemetry streams to mathematically validate, contradict, and score AI claims.

Instead of subjective LLM summaries, ARGUS PRISM evaluates assertions with deterministic mathematics, source credibility tiering, temporal exponential decay, multi-hop entailment graph topology, and autonomous self-correcting tie-breaker search loops.

The full architecture specification and developer documentation are located in docs/.


🌐 Next.js 16 Web Studio & Autonomous Remediation

ARGUS PRISM delivers both an open-standard MCP 2.x server for autonomous agents and an executive zero-login Next.js 16 Web Studio for human creators, technical ghostwriters, and due-diligence reviewers:

  • 🔬 100% Zero-Persistence Architecture (TabPFN + Backboard): Evaluates drafts strictly in volatile…

Link: github.com/akshara-a/ARGUS-PRISM

The code is organised by responsibility. backend/src/argus/engine/ holds the state machine, scoring, contradiction detector, graph engine, auto-fixer, and exporters. llm/ contains the Gemma and Backboard clients, providers/ holds the search interface, the DuckDuckGo, SerpApi, and mock providers, and the cache, and mcp/ is the MCP server. api/ is the FastAPI server, and audio/ and observability/ hold the ElevenLabs client and the Sentry tracer.

The frontend/ folder is the Next.js 16 Web Studio, and tests/ holds the 82 pytest tests. docs/ and learnings.md contain the API reference, the connector SDK guide, deployment notes, and the full architecture write-up. The Dockerfile, render.yaml, and .github/workflows/ci.yml cover the container, the Render blueprint, and CI.

3.2 Quality gates

The benchmark harness (backend/evaluate.py) passes 7 of 7 checks in about 0.21 seconds, and all 82 pytest unit tests pass. CI runs on GitHub Actions, and the full suite runs offline with no API keys.


4. How I Built It

The build is described in seven parts: architecture, scoring math, reasoning, the open-weight AI layer, platform services, interfaces, and hardening and delivery.


Part A: Architecture

4.1 System architecture

flowchart TB
    subgraph Clients["Clients"]
        WEB["Next.js 16 Web Studio"]
        ST["Streamlit Explorer"]
        CLI["CLI"]
        AGENT["AI Agents<br/>Claude Desktop, Cursor, any MCP client"]
    end

    subgraph Surface["Interface layer"]
        REST["FastAPI REST"]
        MCP["MCP 2.x Server<br/>15 tools, 4 resources, 3 prompts"]
    end

    subgraph Core["ARGUS Deterministic Kernel"]
        SM["GoF State Machine<br/>(6 master states)"]
        EXT["Claim Extractor"]
        SC["Scoring: tiers x decay x Bayes"]
        CON["Contradiction Detector"]
        GR["Evidence DAG Engine"]
        FIX["Auto-Fixer"]
        EXP["Exporters<br/>dossier, certificate, badge, academic"]
    end

    subgraph Providers["Pluggable connectors (open interfaces)"]
        DDG["DuckDuckGo (free, no key)"]
        SERP["SerpApi: Web, Scholar, News"]
        MOCK["Mock (offline, CI)"]
        CACHE[("Cost-Guard cache<br/>LRU RAM + SQLite")]
    end

    subgraph AI["Open-weight AI connectors"]
        GEM["Gemma 2 local (Ollama)"]
        BB["Backboard: Llama 3, Mistral, Gemma 2"]
        TAB["TabPFN-style<br/>Bayesian oracle"]
        RX["Regex fallback"]
    end

    subgraph Side["Side channels"]
        EL["ElevenLabs TTS<br/>(ephemeral base64)"]
        SEN["Sentry tracing"]
    end

    WEB & ST & CLI --> REST
    AGENT --> MCP
    REST & MCP --> SM
    SM --> EXT --> SC --> CON --> GR --> FIX
    GR --> EXP
    SM <--> CACHE
    CACHE <--> DDG & SERP & MOCK
    EXT -.-> GEM & RX
    SC -.-> TAB
    CON -.-> BB
    REST -.-> EL
    SM -.-> SEN

4.2 The six master states (GoF State pattern)

Every run walks the same deterministic path. Transitions are explicit, and there is exactly one tie-breaker recursion. This is why identical inputs produce bit-identical scores.

stateDiagram-v2
    [*] --> STATE_INITIALIZED
    STATE_INITIALIZED --> STATE_PLANNING: configure(topic, domain, lambda)

    state STATE_PLANNING {
        [*] --> OptimisticVector
        OptimisticVector --> SkepticVector
        SkepticVector --> TemporalVector
        TemporalVector --> [*]
    }
    STATE_PLANNING --> STATE_GATHERING: vectors_ready

    state STATE_GATHERING {
        [*] --> ProviderDispatch
        ProviderDispatch --> Normalize
        Normalize --> Dedupe
        Dedupe --> [*]
    }
    STATE_GATHERING --> STATE_EVALUATING: documents_normalized

    state STATE_EVALUATING {
        [*] --> ExtractClaims
        ExtractClaims --> CredibilityTiering
        CredibilityTiering --> FreshnessDecay
        FreshnessDecay --> DetectContradictions
        DetectContradictions --> [*]
    }
    STATE_EVALUATING --> STATE_CONFLICT_RESOLUTION: high_severity_conflict [depth < 1]
    STATE_EVALUATING --> STATE_REPORTING: no_conflicts

    state STATE_CONFLICT_RESOLUTION {
        [*] --> TieBreakerQuery
        TieBreakerQuery --> TargetedSearch
        TargetedSearch --> ReEvaluate
        ReEvaluate --> ReconcileOrFlag
        ReconcileOrFlag --> [*]
    }
    STATE_CONFLICT_RESOLUTION --> STATE_REPORTING: depth == 1

    state STATE_REPORTING {
        [*] --> BuildDAG
        BuildDAG --> Synthesize
        Synthesize --> GlobalConfidence
        GlobalConfidence --> EvidenceReport
        EvidenceReport --> [*]
    }
    STATE_REPORTING --> STATE_COMPLETED: payload_validated
    STATE_COMPLETED --> [*]

STATE_INITIALIZED receives the topic, domain, and decay constant. STATE_PLANNING builds the optimistic, skeptical, and temporal query vectors. STATE_GATHERING dispatches to the provider, normalises documents, and deduplicates them. STATE_EVALUATING extracts claims, tiers sources, applies decay, and detects contradictions.

STATE_CONFLICT_RESOLUTION runs one bounded tie-breaker round against primary sources. STATE_REPORTING builds the graph, synthesises the result, computes global confidence, and emits the report.

4.3 Claim lifecycle

stateDiagram-v2
    [*] --> WEAK: extracted, uncorroborated or stale (score < 50)
    WEAK --> VERIFIED: multi-domain corroboration, score >= 70, no conflict
    WEAK --> CONTESTED: opposing polarity found
    VERIFIED --> CONTESTED: fresher conflicting source
    CONTESTED --> VERIFIED: tie-breaker confirms
    CONTESTED --> REFUTED: Tier 1 doc overrules
    REFUTED --> [*]
    VERIFIED --> [*]

A claim is VERIFIED when its score is at least 70, it has multi-domain corroboration, and no conflict is active. It is CONTESTED when sources oppose each other and the conflict is under tie-breaker evaluation or flagged as unresolved. It is WEAK when its score is below 50 because it is stale, uncorroborated, or from an unverified origin. It is REFUTED when fresher Tier 1 documentation overrules it.


Part B: The scoring math

4.4 Credibility tier weight W(d)

Tier 1 (1.5x, authoritative) covers primary sources such as github.com, gitlab.com, docs.* sites, learn.microsoft.com, python.org, pypi.org, npmjs.com, kubernetes.io, ietf.org, w3.org, and .gov and .edu domains. Tier 2 (1.0x, community) covers stackoverflow.com, stackexchange.com, lwn.net, dev.to, news.ycombinator.com, arxiv.org, infoq.com, and engineering blogs. Tier 3 (0.5x, unverified) covers Medium, SEO listicles, and the rest of the general web.

4.5 Freshness decay

DecayMultiplier(t) = e^(−λ · t)        t = document age in months
Enter fullscreen mode Exit fullscreen mode
Domain velocity λ Approx. half-life Typical examples
Fast: AI and web frameworks 0.35 about 2 months LLM tooling, JS frameworks
Cloud and orchestration 0.22 about 3 months Docker, Kubernetes, cloud APIs
Core systems and protocols 0.05 about 14 months POSIX, Linux syscalls, RFCs
xychart-beta
    title "Evidence weight vs. document age (decay multiplier)"
    x-axis "Age in months" [0, 3, 6, 12, 18, 24]
    y-axis "Multiplier" 0 --> 1
    line [1.0, 0.35, 0.12, 0.015, 0.002, 0.0002]
    line [1.0, 0.52, 0.27, 0.07, 0.02, 0.005]
    line [1.0, 0.86, 0.74, 0.55, 0.41, 0.30]

Lines, top to bottom at 3 months: systems λ=0.05, cloud λ=0.22, fast λ=0.35. These values are computed from the formula, not measured.

4.6 Conflict discount and Bayesian update

Proportional conflict discount (instead of zeroing a claim on the first dispute):

DiscountedScore = RawScore × max(0.40, 1.0 − 0.15 × n_conflicts)
Enter fullscreen mode Exit fullscreen mode

Bayesian update:

P(H|E) = P(E|H) · P(H) / P(E)
Enter fullscreen mode Exit fullscreen mode

4.7 Score pipeline per claim

flowchart LR
    D["Retrieved document"] --> T["Tier weight W(d)<br/>1.5 / 1.0 / 0.5"]
    D --> A["Age t (months)"]
    A --> E["Decay e^(−λt)"]
    T --> M(("×"))
    E --> M
    M --> C["Corroboration<br/>(independent domains)"]
    C --> B["Bayesian posterior<br/>P(H|E)"]
    B --> X["Conflict discount<br/>max(0.40, 1 − 0.15n)"]
    X --> TP["Bayesian oracle: P(VER), P(CON), P(REF)<br/>and ±σ%"]
    TP --> S["Claim score 0–100<br/>+ state"]

Part C: Reasoning and self-correction

4.8 Self-correcting tie-breaker loop

This is the core anti-hallucination idea. When sources disagree, ARGUS does not average them. It goes and finds a primary-source answer.

flowchart TD
    S["Claim extracted"] --> V1["Optimistic query<br/>(general web)"]
    S --> V2["Skeptic query<br/>(issues, PRs, deprecations)"]
    S --> V3["Temporal query<br/>(release notes, changelog)"]
    V1 & V2 & V3 --> POOL["Document pool"]
    POOL --> SCORE["Tier x decay scoring"]
    SCORE --> Q{"High-severity<br/>contradiction?"}
    Q -- No --> REP["Report"]
    Q -- Yes --> DEPTH{"depth &lt; 1 ?"}
    DEPTH -- No --> FLAG["Flag as CONTESTED / unresolved"]
    DEPTH -- Yes --> TB["Generate tie-breaker query<br/>aimed at Tier 1 primary docs"]
    TB --> RS["Targeted search"]
    RS --> RE["Re-evaluate claims"]
    RE --> WIN{"Fresher Tier 1<br/>overrules?"}
    WIN -- Yes --> REF["Loser → REFUTED<br/>winner elevated"]
    WIN -- No --> FLAG
    REF --> REP
    FLAG --> REP

4.9 Evidence DAG and transitive invalidation

flowchart LR
    A["Claim A (2026 changelog):<br/>'LegacyAPI v1 removed Mar 2026'<br/>VERIFIED"]
    B["Claim B (2022 blog):<br/>'LegacyAPI v1 is production-ready'<br/>REFUTED"]
    C["Claim C:<br/>'High-load clusters should use v1'<br/>depends on B"]
    D["Claim D:<br/>'Migrate to UnifiedAPI v2'<br/>ENTAILS from A"]

    A -- CONTRADICTS --> B
    C -- REQUIRES --> B
    A -- TRANSITIVELY_CONTRADICTS --> C
    A -- ENTAILS --> D

    classDef good fill:#d1fae5,stroke:#047857,color:#064e3b
    classDef bad fill:#fee2e2,stroke:#b91c1c,color:#7f1d1d
    classDef warn fill:#fef3c7,stroke:#b45309,color:#78350f
    class A,D good
    class B bad
    class C warn

The graph uses four edge types. CONTRADICTS links direct opposing claims about the same entity. REQUIRES marks a prerequisite dependency. ENTAILS marks a logical consequence. TRANSITIVELY_CONTRADICTS applies when claim A refutes claim B and claim C depends on B, so C is downgraded with a transitive-risk rationale.

Graph-level metrics:

  • Contradiction density = conflicting pairs ÷ total claim pairs (0.0 to 1.0).
  • Consensus centrality = corroboration weighted by node degree (0 to 100).

Part D: The open-weight AI layer

4.10 Model layer

flowchart TB
    IN["Draft text"] --> CHOOSE{"LLM mode"}
    CHOOSE -->|"--llm gemma"| G["Gemma 2 2B<br/>local via Ollama<br/>0 cost, 0 data leaves machine"]
    CHOOSE -->|"Backboard key set"| B["Backboard gateway<br/>one key, three open models"]
    CHOOSE -->|"default / offline"| R["Regex extractor<br/>deterministic, 0.2s"]

    B --> L["Llama 3 8B"]
    B --> M["Mistral 7B"]
    B --> GG["Gemma 2 9B"]
    L & M & GG --> AGR{"Agreement ratio"}
    AGR -->|"3 of 3"| OK["3/3 Models Concur"]
    AGR -->|"2 of 3"| MID["2/3 Concur: review"]
    AGR -->|"dissent"| HI["High Hallucination Risk"]

    G --> CL["Structured JSON claims"]
    R --> CL
    OK & MID & HI --> CL
    CL --> ENGINE["Deterministic scoring kernel"]

There are three extraction paths. Gemma 2 2B through Ollama runs with --llm gemma. It is free, local, and private, but it is a small model and can miss subtle claims. The Backboard tri-model check runs when BACKBOARD_API_KEY is set. It gives a real cross-model agreement signal from Llama 3, Mistral, and Gemma 2, but needs a key and network access. Without a key it falls back to a deterministic offline simulation so demos and tests still run. The regex extractor is the default and works offline. It is instant and fully deterministic but coarse.

Design principle: open models extract and cross-examine. They never decide the score. The math does. If every model is unavailable, the regex path still works end to end, which keeps CI and the benchmark deterministic.

4.11 Bayesian uncertainty oracle (TabPFN-style)

Each claim becomes a 4-feature vector [W(d), age, corroboration_count, conflict_count] plus its deterministic base score. The oracle turns that into [P(VERIFIED), P(CONTESTED), P(REFUTED)] and an uncertainty interval, shown on the gauge as, for example, 94.5% (±2.4%).

How it works: it is a hand-written, closed-form calibrated model. It computes a logit for each class from the features, applies a softmax, and derives ±σ from the entropy of the resulting distribution (bounded between 1.2% and 8.5%). It runs entirely in memory with no download and no GPU.

What it is not: it does not load the pretrained TabPFN network. It is named for the idea, which is a prior-fitted, tabular, in-memory probabilistic classifier. Swapping in the real TabPFN behind the same evaluate_claim interface is a natural next step.


Part E: Platform services

4.12 Zero-persistence data flow

flowchart LR
    U["User draft"] -->|HTTPS| API["FastAPI process RAM"]
    API --> ENG["Engine: transient objects"]
    ENG --> OUT["Report + base64 audio"]
    OUT -->|HTTPS| U
    ENG -. "X no disk write" .-> DISK[("Disk / DB")]
    ENG -. "X no draft logging" .-> LOG[("Logs")]
    CACHE[("Cost-Guard cache<br/>search results ONLY")] <--> ENG
    note1["Cache stores search-query to results,<br/>never user drafts or claims text"] -.-> CACHE

Guarantees:

  • Drafts and extracted claims live only in process memory for the life of the request.
  • No draft is written to disk, SQLite, or logs.
  • Audio is streamed as base64 in the HTTP response, with no server-side files.
  • The SQLite tier of the cache holds public search results keyed by query. It never holds user drafts.

4.13 Cost-Guard two-tier cache

flowchart LR
    Q["Search query"] --> T1{"Tier 1: in-memory LRU"}
    T1 -- hit --> R["Return, sub-millisecond"]
    T1 -- miss --> T2{"Tier 2: SQLite<br/>.cache/serpapi_cache.sqlite"}
    T2 -- hit --> P["Promote to LRU, return"]
    T2 -- miss --> API["Live provider call"]
    API --> W["Write both tiers"] --> R
    R --> TEL["Telemetry: hit rate, calls,<br/>USD saved ($0.01/query est.), avg latency"]

Benchmark result: 12 repeated requests gave 7 hits, a 58.3% hit rate, and an estimated $0.07 saved. The score stayed identical.

4.14 Deliverables pipeline

flowchart LR
    REP["Evidence report"] --> DOS["Evidence Dossier<br/>contradiction summaries, claim ledger, formulas"]
    REP --> CERT["Client Certificate<br/>(HTML, billable time saved)"]
    REP --> BADGE["SVG badge<br/>GET /api/badge"]
    REP --> ACAD["Academic export<br/>[^1] footnotes + IEEE/APA"]
    REP --> FIXD["Auto-fixed Markdown<br/>+ git-style diff"]
    REP --> AUD["60s audio debrief<br/>Rachel / Adam / Drew"]
    BADGE --> SNIP["Markdown / HTML snippet<br/>GitHub, Notion, Substack"]
    ACAD --> PUB["Notion, Substack, Medium,<br/>Ghost, Obsidian"]

Part F: Interfaces and integrations

4.15 MCP integration (15 tools)

flowchart LR
    AG["Agent (Claude Desktop / Cursor / Inspector)"] -->|stdio or SSE| MCPS["ARGUS MCP Server"]
    subgraph Tools["15 Tools"]
        T1["validate_response"]
        T2["execute_research"]
        T3["execute_targeted_search"]
        T4["inspect_evidence"]
        T5["inspect_confidence"]
        T6["inspect_conflicts"]
        T7["compare_technologies"]
        T8["inspect_telemetry"]
        T9["generate_dossier"]
        T10["auto_repair_draft"]
        T11["crawl_and_audit_url"]
        T12["export_academic_markdown"]
        T13["generate_verification_badge"]
        T14["backboard_compare_models"]
        T15["tabpfn_bayesian_uncertainty"]
    end
    subgraph Res["4 Resources"]
        R1["argus://reports/latest"]
        R2["argus://conflicts/active"]
        R3["argus://reports/dossier"]
        R4["argus://graph/dot"]
    end
    subgraph Pr["3 Prompts"]
        P1["validate_response"]
        P2["adversarial_fact_check"]
        P3["migration_risk_audit"]
    end
    MCPS --> Tools & Res & Pr

Agent before and after:

sequenceDiagram
    actor Dev
    participant LLM as Naive LLM
    participant AG as ARGUS-equipped agent
    participant AR as ARGUS MCP

    Dev->>LLM: "Next.js 15 supports React 18 and LegacyAPI v1 is production-ready?"
    LLM-->>Dev: "Yes, absolutely!" (stale blog bias, WRONG)

    Dev->>AG: same question
    AG->>AR: auto_repair_draft(draft, domain)
    AR->>AR: tier, decay, tie-break to the changelog
    AR-->>AG: refuted claims + diff + ±σ confidence
    AG-->>Dev: "Not accurate. v1 was removed (source, date). Corrected text attached."

4.16 REST API (12 endpoints)

Method Path Purpose
GET /api/health Liveness and readiness probe
POST /api/fetch-url SSRF-safe crawl of a live page
POST /api/validate Full audit of a draft
GET /api/badge Embeddable SVG verification badge
POST /api/compare-models Backboard tri-model comparison
POST /api/bayesian-evaluate Class probabilities and uncertainty interval
POST /api/export-footnotes Footnoted Markdown with IEEE/APA references
POST /api/auto-fix Grounded rewrite plus diff
POST /api/research Adversarial multi-vector research
POST /api/compare Head-to-head technology comparison
POST /api/chat Documentation-anchored assistant
GET /api/telemetry Cache and cost telemetry

4.17 Head-to-head comparator

compare FastAPI Django runs two research pipelines and scores each on four dimensions.

The four dimensions are global evidence confidence (a deterministic score across all sources), authoritative verified claims (the count of Tier 1 verified claims), operational stability (the inverse of conflict and weak-claim density), and ecosystem freshness (exponentially decayed recency).

quadrantChart
    title Illustrative comparator output (example shape, not real data)
    x-axis "Low freshness" --> "High freshness"
    y-axis "Low evidence confidence" --> "High evidence confidence"
    quadrant-1 "Strong and current"
    quadrant-2 "Well-evidenced but aging"
    quadrant-3 "Weak and stale"
    quadrant-4 "Fresh but thinly evidenced"
    "Tech A": [0.78, 0.82]
    "Tech B": [0.55, 0.88]

4.18 Pluggable connector design

Every external dependency sits behind an interface, so contributors can add engines without touching the kernel:

classDiagram
    class ISearchProvider {
        <<interface>>
        +provider_name str
        +search(query, ...) list~RawDocument~
    }
    class DuckDuckGoSearchStrategy
    class WebSearchStrategy
    class MockSearchStrategy
    class CustomEnterpriseProvider
    ISearchProvider <|.. DuckDuckGoSearchStrategy
    ISearchProvider <|.. WebSearchStrategy
    ISearchProvider <|.. MockSearchStrategy
    ISearchProvider <|.. CustomEnterpriseProvider

    class CredibilityDecorator {
        +evaluate_source_tier(url)
    }
    class SerpApiCache {
        +get() +put() +telemetry()
    }
    class ClaimGraphEngine {
        +add_claim() +relate() +transitive_invalidate()
    }
    class ArgusStateMachine
    ArgusStateMachine --> ISearchProvider
    ArgusStateMachine --> CredibilityDecorator
    ArgusStateMachine --> SerpApiCache
    ArgusStateMachine --> ClaimGraphEngine

The design uses the State pattern for the six-state pipeline, the Decorator pattern for credibility tiers, the Strategy pattern for swappable search providers, the Observer pattern for the traceability drawer, and the Adapter pattern for the SerpApi engines.


Part G: Hardening, delivery, and proof

4.19 Security hardening

flowchart TB
    subgraph Threats
        T1["SSRF via URL auditor"]
        T2["XSS in generated HTML"]
        T3["Malicious certificate preview"]
        T4["Wildcard CORS"]
        T5["SVG stored XSS"]
        T6["Regex backreference injection"]
    end
    subgraph Mitigations
        M1["is_safe_public_url: DNS pre-resolve,<br/>block loopback, 169.254.169.254, RFC1918,<br/>redirects disabled"]
        M2["http/https scheme allow-list,<br/>html.escape on every href and content"]
        M3["iframe sandbox=''"]
        M4["Origin whitelist + onrender.com regex"]
        M5["CSP default-src 'none'<br/>+ nosniff on badge"]
        M6["pattern.sub(lambda _: repl, text)"]
    end
    T1 --> M1
    T2 --> M2
    T3 --> M3
    T4 --> M4
    T5 --> M5
    T6 --> M6

4.20 Tech stack

The backend is Python 3.11 to 3.13 with Pydantic v2, FastAPI, and Uvicorn, and it exposes the Model Context Protocol (MCP 2.x) over stdio and SSE. The frontend is Next.js 16 with Turbopack, React 19, Tailwind CSS v4, TypeScript, and Bun, and the dashboard uses Streamlit, PyVis, and NetworkX. Open-weight models are Gemma 2 through Ollama and Llama 3 8B, Mistral 7B, and Gemma 2 9B through Backboard.

Uncertainty comes from an in-memory Bayesian oracle modelled on the TabPFN idea (a closed-form softmax with no model download). Search uses DuckDuckGo, SerpApi (Google, Scholar, News), or an offline mock. ElevenLabs provides voice and Sentry provides observability. The cache is an in-memory LRU plus SQLite, and packaging and delivery use uv, pytest, Docker, GitHub Actions, and a Render Blueprint.

4.21 Deployment topology

flowchart LR
    GH["GitHub repo"] --> CI["GitHub Actions<br/>pytest + benchmark"]
    GH --> RND["Render Blueprint (render.yaml)"]
    RND --> APIsvc["argus-prism-api<br/>FastAPI + MCP core<br/>health: /api/health"]
    RND --> FEsvc["Web Studio (Next.js)"]
    FEsvc -->|REST| APIsvc
    APIsvc --> EXT1["DuckDuckGo / SerpApi"]
    APIsvc --> EXT2["Backboard / ElevenLabs"]
    APIsvc --> EXT3["Sentry"]
    DK["Dockerfile"] --> GH
    LOC["Local: Ollama + Gemma 2"] -.optional.-> APIsvc

4.22 Benchmarks

# Test What it proves Result
1 Hallucination trap A fabricated library scores 0.0 with an empty ledger Pass
2 Contradiction catch A 2026 changelog elevates over a decayed 2022 blog via tie-breaker Pass
3 Traceability 100% of claims map to a URL, snippet, and tier Pass
4 Reproducibility Bit-identical float scores across runs Pass
5 Adaptive λ and Bayes λ is 0.35 for web and 0.05 for systems, and P(H|E) ∈ [0,1] Pass
6 Cost-Guard Hit rate ≥ 50%, savings > 0, scores unchanged Pass
7 Multi-hop DAG A dependent claim is penalized when its prerequisite is refuted Pass

Suite runtime is about 0.21 s, with 82/82 unit tests passing.

4.23 Run it yourself

CLI audit with client deliverables:

python -m argus.cli validate --file article_draft.txt \
  --client "Acme Ghostwriting" \
  --export-report client_audit.html \
  --markdown-report client_briefing.md \
  --audio briefing.wav \
  --llm gemma --provider duckduckgo
Enter fullscreen mode Exit fullscreen mode

Other commands:

python -m argus.cli research "Pydantic v2 migration" --domain "Python Architecture"
python -m argus.cli compare "FastAPI" "Django"
python -m argus.cli dossier "PostgreSQL JSONB indexing" --output dossier.html
python -m argus.cli telemetry
python -m argus.cli mcp --transport stdio
Enter fullscreen mode Exit fullscreen mode

Local open model:

ollama pull gemma2:2b
Enter fullscreen mode Exit fullscreen mode

Claude Desktop or Cursor config:

{
  "mcpServers": {
    "argus-prism": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/ARGUS PRISM", "python", "-m", "argus.cli", "mcp"],
      "env": { "PYTHONUNBUFFERED": "1" }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

5. Why Does Open Innovation Matter?

5.1 What open made possible

A hosted, closed fact-checking API would not suit this product. Open components make several things possible.

Privacy you can verify. Ghostwriters handle unpublished client drafts, and some are under NDA. With Gemma 2 running locally through Ollama, nothing leaves the machine, and with open code a client can audit the zero-persistence claim instead of trusting a vendor policy.

Cross-model checking needs model diversity. Backboard lets one key query Llama 3, Mistral, and Gemma 2 side by side. Agreement and dissent between independently trained open models is a real hallucination signal that a single closed model cannot provide.

Determinism and reproducibility. The kernel is open math (tiers, decay, Bayes) and open models are used only for extraction. Anyone can re-run an audit and get the same score, so a Verified badge can be checked, not just trusted.

Pluggable connectors. ISearchProvider lets a contributor add a search source, such as an internal wiki, without forking the kernel. This is the same open-kernel idea used by Airbyte and OpenTelemetry.

Offline testing and zero-cost onboarding. The mock provider and the regex fallback let 82 tests and 7 benchmarks run in under a second with no keys, and the free DuckDuckGo path lets a new user try live verification at no cost.

Open standards for agents. Because ARGUS speaks MCP, it works with Claude Desktop, Cursor, and any other MCP-compatible agent without a custom integration.

5.2 Limitations

The regex fallback is fast and deterministic but coarse, and Gemma 2 2B is small enough to miss subtle claims. Freshness depends on publication dates from search results, which are sometimes missing or wrong. The tier lists are heuristics, so a Tier 1 domain can still be wrong and a Tier 3 source can be right.

The benchmarks use the mock provider, and live-web results vary with the search engine. The uncertainty oracle is TabPFN-style rather than the pretrained TabPFN network, and without a Backboard API key the three-model consensus is a deterministic stand-in rather than real model output. The $0.01-per-query savings and $50 per hour figures are configurable estimates, not billing data.


6. Prize Categories

ARGUS PRISM is entered in the partner categories below. Each entry below describes how ARGUS PRISM uses the technology.

Best Use of Render. A blueprint deploys three services: the FastAPI and MCP API, the Next.js Web Studio, and the Streamlit dashboard. The API exposes /api/health.

Best Use of Gemma. Gemma 2 2B runs locally through Ollama for private claim extraction (--llm gemma), and Gemma 2 9B is the third voter in the tri-model check.

Best Use of Backboard. One key queries Llama 3 8B, Mistral 7B, and Gemma 2 9B and reports an agreement ratio (3/3 Concur, 2/3 Concur, or High Hallucination Risk).

Best Use of ElevenLabs. A 60-second spoken debrief with three personas (Rachel, Adam, and Drew) is streamed as base64, with nothing stored on the server.

Best Use of Sentry Agent Tracing. Each pipeline stage is a span with latency visibility, and the Cost-Guard and Telemetry panel includes a flamegraph view.

Best Use of SerpApi. A SerpApi provider with Google Web, Google Scholar, and Google News engines supplies the evidence pool, behind a cache that tracks credits saved.


Top comments (0)