Real-time threat intelligence for coordinated misinformation campaigns. Paste in a WhatsApp forward, an image, or any real social handle β ShadowTrace ingests it into a live Neo4j graph, runs 10 specialised AI agents across it, and hands back the campaign: which accounts coordinated, how tightly, in what language, and how dangerous.
This is not a fixture. Type your own Bluesky handle into the live demo β a handle we could never have pre-seeded. It gets fetched from the public API, written into the graph, and analysed inside that request. We show you how to falsify it below.
π΄ Live Mission Control Β· π¬ Demo Video Β· Pitch Deck Β· Run Locally Β· Technical Docs
A coordinated misinformation campaign β a fabricated EVM-hacking claim, a fake health advisory, deepfake audio attributed to a doctor β reaches millions in India within minutes. The infrastructure behind it is not one bad post. It is hundreds of accounts pushing the same narrative inside the same 60-second window, seeded from a handful of coordination hubs.
Today's defence is fact-checking, and fact-checking is post-level and retrospective. By the time a claim is verified and debunked, the network that pushed it has already moved 10,000 shares and started on the next narrative. Fact-checking scales linearly; the attack scales exponentially. Nobody is watching the network.
Our thesis: coordination is a graph problem, not a text problem. A bot's real tell isn't what it said β it's that it said it twelve seconds after forty other accounts did. That's a relationship, not a property of a sentence. So we stopped classifying posts and started reconstructing networks β which is why the whole system is built on a graph database, and why the network signal outweighs the content signal in our own scoring.
Themes Selected:
- Trust, Identity & Security β
PRIMARYCoordinated inauthentic behaviour detection, bot-network attribution, synthetic-media forensics. Every agent in the pipeline exists to answer a trust question: is this account real, is this image real, is this coordination real? - Media, Social & Interactive Platforms β
SECONDARYLive ingestion and forensic analysis of social propagation across Bluesky, WhatsApp forwards, and Indian fact-checker feeds. - Public Systems, Governance and Civic Tech β
TERTIARYElection integrity and public-health information defence β built for newsrooms, election commissions, and public-health information cells.
The target users Newsroom fact-checkers (Alt News, BOOM, The Quint), election-commission and public-health information cells, and platform trust-and-safety teams.
The pain point Existing tools answer "is this post false?" β a question that arrives too late and scales linearly with the flood. Nobody can answer the question that actually matters: "Which accounts are pushing this together, since when, how tightly are they synchronised, and who is the hub?" β not without a data-science team and weeks of manual work.
The value we provide ShadowTrace turns a single suspicious message, image, or account handle into a complete campaign dossier in under a minute:
| You give it | It gives you back |
|---|---|
| A WhatsApp forward | Misinformation score, forward-chain markers, Hindi/Hinglish language ID, live fact-checker cross-reference, threat class |
| A real Bluesky handle | Live-ingested post graph, 60-second coordination windows, stylometric cluster peers, LLM-authorship signals |
| An image URL | ELA heatmap of edited regions, EXIF anomalies, two-model AI-generation verdict |
| A claim or narrative | The bot cluster amplifying it, campaign attribution, severity, and an exportable evidence package |
The difference is the difference between debunking one post and dismantling the network responsible for it.
Most hackathon demos are fixtures with a loading spinner. Here is how to prove ours isn't, in under a minute, on the live deployment:
| # | Do this | Why it can't be faked |
|---|---|---|
| 1 | Open Account Intel and type in your own Bluesky handle β or any handle you invent on the spot | We can't have pre-seeded a handle we've never seen. It is fetched from the Bluesky public API, MERGEd into Neo4j, and analysed by the same Cypher our seeded campaigns use |
| 2 | Open Live Feed | Those are today's debunked claims, pulled live from Alt News / BOOM / FactChecker.in / The Quint RSS. Cross-check any headline against their site |
| 3 | Open Agent Monitor, then go run an analysis and come back | Task counts go up. They're read from an in-process counter (agent_stats.py), not a hardcoded array |
| 4 | Paste a real photograph into Image Forensics | It should not be flagged as AI-generated. Getting this right cost us a rebuild β see below |
Or skip the UI entirely and hit production directly. Pick any Bluesky handle β one we could not possibly have seeded:
curl -X POST https://shadowtrace-backend-g6uy.onrender.com/account-intel/analyze \
-H "Content-Type: application/json" \
-d '{"handles": ["bsky.app"]}'"source": "bluesky" means that handle was not in our graph β it was pulled from the Bluesky API, written into Neo4j, and analysed back out of it, in that request. Swap in your own handle and watch it happen. The LIKELY_HUMAN verdict on a real account is the point too: a detector that flags everything is worthless.
(Render free tier cold-starts β the first request after idle can take up to a minute to wake the backend.)
Trace Matrix
- Uttampreet Kaur β GitHub @uttampreet-dev
- Aditya Bhandari β GitHub @Neverask1121
Why we chose this problem. Every hackathon builds a fake-news classifier. We asked a harder question: a classifier tells you a post is false β so what? The post is already viral. The real adversary is an operation: coordinated, funded, multi-account, and completely invisible to post-level tooling. Nobody was building the counter-tool for that, so we did.
Key challenges we addressed.
-
Coordination is a graph problem, not a text problem. A bot's giveaway isn't what it says β it's that it said it 12 seconds after 40 other accounts did. We modelled accounts, posts, campaigns and
COORDINATES_WITHedges in Neo4j AuraDB, so synchronisation becomes a first-class, queryable relationship instead of something we recompute in memory on every request. -
"AI-generated" is a verdict you cannot get wrong. Our first image-forensics build flagged real photographs as AI-generated on a single model's say-so. We rebuilt it to require two independent classifiers to agree before making that call β and made the AI-generation verdict unable to veto the ELA editing evidence, so a real-but-doctored photo still gets caught. Being loudly wrong is worse than being quiet.
-
India doesn't post in English. A WhatsApp forward is Hindi, Hinglish, or Devanagari-script code-mixing. We wired in Sarvam AI's language ID and built the forward-chain detector around Indian-language urgency and share-bait patterns rather than translated English heuristics.
-
Demos lie; we wanted live wires. Anyone can hardcode a graph. ShadowTrace ingests real Bluesky accounts and real debunked claims from live Indian fact-checker RSS feeds β so a judge can type in their own handle, or any handle, and watch the pipeline actually run.
-
A 512MB box made the system better. Our host's free tier caps at 512MB, and
torch+transformersOOM on load. Rather than pay for a bigger box, we deleted local model weights entirely: content scoring became a Groq LLaMA-3.3-70B call with a deterministic lexical fallback, andsentence-transformersis lazily imported behind anlru_cacheso it never loads at startup. The backend now runs in under 100MB β and a 70B model comfortably outperforms the fine-tuned BERT-tiny it replaced. The constraint made it lighter and more accurate.
Pivots, iterations, breakthroughs. We started with a BERT classifier and a pretty graph. The breakthrough was inverting the pipeline β making the network the subject and the text merely evidence. That reframing is what turned a fake-news demo into a threat-intelligence platform: it's why temporal coordination, stylometric fingerprinting, and LLM-operation detection run as peers to content analysis, not as decoration around it.
- Frontend: Next.js 16 (App Router) Β· React 19 Β· TypeScript Β· Tailwind CSS v4 Β· D3.js force-directed network graph
- Backend: Python 3.11 Β· FastAPI + Uvicorn Β· LangGraph multi-agent orchestration Β· NetworkX Β· scikit-learn (DBSCAN)
- Database: Neo4j AuraDB (primary β accounts, posts, campaigns, coordination edges) Β· Supabase Postgres
- APIs: Groq (LLaMA-3.3-70B) Β· Sarvam AI (Indian-language ID) Β· Hugging Face Inference (AI-image classifiers) Β· Bluesky public API Β· Fact-checker RSS (Alt News, BOOM, FactChecker.in, The Quint)
- Hosting: Vercel (frontend) Β· Render (FastAPI agent backend) Β· Neo4j AuraDB (managed graph)
- AI / ML β LLaMA-3.3-70B scoring & threat classification, LangGraph agent graph, DBSCAN stylometric clustering, bigram-perplexity/burstiness LLM-authorship detection, ELA + Hugging Face image forensics
- Web3 / Blockchain
- Cyber Security β coordinated inauthentic behaviour detection, bot-network attribution, synthetic-media forensics, evidence packaging
- Cloud β Vercel, Render, Neo4j AuraDB, Groq & Sarvam inference
- Neo4j Track β AuraDB is our primary database
- Sarvam AI Track β Indian-language identification, live in the analysis pipeline
- Expo Track β not applicable (ShadowTrace is an analyst web console, not a mobile app)
- Base44 Track β not applicable (built from scratch; retrofitting Base44 would be cosmetic)
How we used the partner technology:
π¦ Neo4j AuraDB β Coordination is a graph, so AuraDB is the substrate, not a store. We model
(:Account)-[:SHARED]->(:Post)-[:PART_OF]->(:Campaign)plus aCOORDINATES_WITHedge that we compute at ingest for any two accounts posting within 60 seconds of each other. Bot scoring and cluster detection run as Cypher inside AuraDB and persist back onto the nodes. Live Bluesky accounts areMERGEd straight into the graph, and the dashboard's D3 network is a direct projection ofGET /campaignsβ not a fixture.π§ Sarvam AI β Our highest-value input is a WhatsApp forward, and real Indian forwards are Hindi/Hinglish, not English.
SarvamLanguageDetectoris a first-class agent calling Sarvam'stext-lid, running as step 3 of the live 5-agent/investigatechain and exposed standalone atPOST /language/detect. Language ID feeds the scoring; it doesn't decorate it.
π Verify it β queries, files, and failure modes
(:Account)-[:SHARED]->(:Post)-[:PART_OF]->(:Campaign)
(:Account)-[:PART_OF]->(:Campaign)
(:Account)-[:INTERACTS {relation}]->(:Account) // retweet Β· mention Β· reply
(:Account)-[:COORDINATES_WITH {delay_seconds}]->(:Account) // β the money edgeBot scoring executes inside the database and writes the result onto the node:
MATCH (a:Account)-[:PART_OF]->(c:Campaign {id: $campaign_id})
SET a.bot_score = (
CASE WHEN a.post_count > 50 THEN 0.25 ELSE 0 END +
CASE WHEN a.age_days < 30 THEN 0.20 ELSE 0 END +
CASE WHEN a.following > a.followers*10 THEN 0.20 ELSE 0 END
)
RETURN a.handle, a.bot_score ORDER BY a.bot_score DESCCOORDINATES_WITHis computed, not seeded β synchronised amplification becomes a one-hop traversal instead of an O(nΒ²) rescan per request.- Clusters are community detection over that edge set β we don't guess campaign membership, we find the densely-coordinating component.
- Degradation: if AuraDB is unreachable,
seed_database()fails soft to a JSON fallback so the API stays up β but coordination traversal and cluster attribution are AuraDB-native. - Code:
backend/db/neo4j_client.pyΒ·backend/db/seed.pyΒ·backend/graph/bot_detection.py
- Patterns matched are native Hinglish, not translated English β
turant,sabko dikhao,sarkar chupa rahi. - Submit Hindi in the WhatsApp panel and the step trace shows Sarvam's real measured latency, live.
- Degradation: without
SARVAM_API_KEY, falls back to a Devanagari-character + Hinglish function-word heuristic β the demo never dies, but the real call is what ships. - Code:
backend/agents/sarvam_language_detector.py
The first four are the ones that make ShadowTrace something other tools aren't.
The flagship. Type in any real Bluesky handle β yours, ours, one you invent on the spot. Its posts are fetched live from the Bluesky API, MERGEd into Neo4j, and analysed by three forensic agents running against the same Cypher our seeded campaigns use.
| Agent | What it catches |
|---|---|
| TemporalCoordinator | Accounts posting inside the same 60-second window β the signature of a synchronised burst |
| LinguisticFingerprinter | DBSCAN stylometric clustering β accounts that write like each other, i.e. one operator behind many handles |
| AIOperationDetector | Bigram perplexity, burstiness, topic drift β posts authored by an LLM rather than a person |
Nothing here is pre-computed. Ingestion happens inside the request.
A D3.js force-directed rendering that is a direct projection of AuraDB β nodes, edges and campaign membership all served from Cypher, not a fixture file. Origin nodes, bot clusters and amplifier accounts are draggable, hoverable and clickable, with animated campaign switching.
Forward-chain detection across English / Hindi / Hinglish (turant, sabko dikhao, sarkar chupa rahi β not translated English heuristics), blended with a Groq LLaMA-3.3-70B judgment.
Then one click runs a 5-agent investigation, each stage reporting its own measured latency:
WhatsAppAnalyzer β ContentAnalyzer β SarvamLanguageDetector β FactCheckCrossRef β ThreatClassifier
patterns Groq 70B Indian-language ID live debunk match severity
Error Level Analysis heatmaps + EXIF anomaly detection, blended with a three-model Hugging Face classifier ensemble.
Two models must independently agree before we will call an image AI-generated β we take the second-highest score, so no single false positive can flag an image alone. And that verdict can never overrule the ELA evidence beneath it, because "not AI-generated" and "not manipulated" are different claims. A real photo edited in Photoshop still gets caught.
- β Mission Control Dashboard β dense, data-first console. No decorative UI; every element carries operational data.
- β Live Fact-Checker Feed β real debunked claims streamed from Alt News, BOOM, FactChecker.in and The Quint RSS, each re-scored through our own content pipeline.
- β Severity-Classified Alert Feed β CRITICAL / HIGH / MED / LOW with campaign attribution and one-click pivot into the network graph.
- β Agent Status Monitor β genuine per-agent task counts read from the running backend process, not a hardcoded array. Run an analysis and watch them increment.
- β Evidence Export β one-click JSON export of campaign data, alerts and network summaries, formatted for handoff to trust-and-safety teams.
Everything flows through the graph. Neo4j AuraDB is not a store the agents write to afterwards β it's the substrate they run on.
flowchart TD
subgraph SRC["π‘ DATA SOURCES"]
BS["π¦ Bluesky<br/>LIVE β any real handle"]
RSS["π° Fact-Checker RSS<br/>LIVE β AltNews Β· BOOM Β· Quint"]
WA["π¬ WhatsApp Forwards<br/>EN / HI / Hinglish"]
IMG["πΌ Image URLs"]
end
GRAPH[("πΈ Neo4j AuraDB<br/>Account Β· Post Β· Campaign<br/>COORDINATES_WITH Β· INTERACTS")]
subgraph CORE["π€ CORE DETECTION"]
CA["ContentAnalyzer<br/>Groq LLaMA-3.3-70B"]
NM["NetworkMapper<br/>Cypher bot scoring"]
CD["CampaignDetector<br/>LangGraph"]
TC["ThreatClassifier<br/>Groq LLaMA-3.3-70B"]
end
subgraph ACCT["π ACCOUNT INTELLIGENCE"]
TCO["TemporalCoordinator<br/>60s windows"]
LF["LinguisticFingerprinter<br/>DBSCAN stylometry"]
AIO["AIOperationDetector<br/>Perplexity Β· Burstiness"]
end
subgraph MEDIA["πΌ MEDIA & LANGUAGE"]
DD["DeepfakeDetector<br/>ELA + 2-of-3 HF ensemble"]
WAA["WhatsAppAnalyzer<br/>Forward chains"]
SLD["SarvamLanguageDetector<br/>Indian-language ID"]
end
DASH["π₯ MISSION CONTROL<br/>Network Β· Account Intel Β· Forensics Β· Alerts"]
BS & RSS & WA & IMG --> GRAPH
GRAPH --> CORE
GRAPH --> ACCT
WA & IMG --> MEDIA
CORE & ACCT & MEDIA --> DASH
classDef src fill:#1e3a5f,stroke:#3b82f6,color:#e2e8f0
classDef agent fill:#2e1065,stroke:#a855f7,color:#e2e8f0
classDef db fill:#052e16,stroke:#22c55e,color:#a7f3d0
classDef dash fill:#1c1917,stroke:#f59e0b,color:#e2e8f0
class BS,RSS,WA,IMG src
class CA,NM,CD,TC,TCO,LF,AIO,DD,WAA,SLD agent
class GRAPH db
class DASH dash
Bot scoring β 8 weighted signals, four from metadata and four from graph topology:
account age Γ0.22 Β· posting frequency Γ0.18 Β· connectivity Γ0.14 Β· follower/following imbalance Γ0.12 Β· betweenness centrality Γ0.10 Β· clustering coefficient Γ0.10 Β· PageRank Γ0.08 Β· unverified penalty
The topology signals are the ones that matter. Betweenness finds the bridge accounts wiring separate clusters together β which is exactly where a campaign's coordination hubs sit.
π Deeper diagrams β graph data model, live-ingestion sequence, the 5-agent chain, the image-forensics decision tree, and the LangGraph state machine all live in docs/Architecture_Diagram.md, with full agent reference in docs/Technical_Documentation.md.
- Demo Video Link (Mandatory): Watch the demo
- Deployment Link: https://shadowtrace-bay.vercel.app
- Pitch Deck / PPT: View the deck
- Technical Documentation: docs/Technical_Documentation.md Β· Architecture Diagrams
- Live API:
shadowtrace-backend-g6uy.onrender.comβ interactive OpenAPI docs
- All team members completed the mandatory social task
- Bonus Task 1 β Badge sharing
- Bonus Task 2 β Blog/article
- Node.js 20+ (required by Next.js 16)
- Python 3.11+
- Neo4j AuraDB instance β free at neo4j.com/cloud/aura
- Groq API key β free at console.groq.com
- (Optional) Sarvam AI key (Indian-language ID), Hugging Face token (AI-image classifiers), Supabase project
# 1. Clone
git clone https://github.com/uttampreet-dev/ShadowTrace.git
cd ShadowTrace
# 2. Frontend dependencies
npm install
# 3. Backend dependencies
pip install -r backend/requirements.txt4. Environment variables
.env.local in the project root:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
GROQ_API_KEY=your_groq_api_key
BACKEND_API_URL=http://localhost:8000
NEXT_PUBLIC_API_URL=http://localhost:8000backend/.env:
GROQ_API_KEY=your_groq_api_key
# Neo4j AuraDB β the graph substrate
NEO4J_URI=neo4j+s://xxxxxxxx.databases.neo4j.io
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=your_aura_password
# Optional β omit and the system degrades gracefully (see table below)
SARVAM_API_KEY=your_sarvam_key
HF_API_KEY=your_huggingface_token5. Run β two terminals:
# Terminal 1 β AI agent backend (seeds AuraDB on startup)
uvicorn backend.main:app --reload --port 8000
# Terminal 2 β Mission Control frontend
npm run devOpen http://localhost:3000 β Launch Mission Control.
Try it in 30 seconds: open Account Intel, drop in any real Bluesky handle, and watch it get ingested into the graph and scored for coordination live.
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Health check |
GET |
/campaigns |
All campaigns + node/edge data (Cypher β AuraDB) |
POST |
/analyze-text |
Groq LLaMA-3.3-70B misinformation scoring |
POST |
/analyze-network |
8-signal bot scoring over the account graph |
POST |
/detect-campaign |
LangGraph campaign-detection pipeline |
POST |
/generate-alert |
Groq threat classification |
POST |
/investigate |
Full 5-agent investigation of one message |
POST |
/whatsapp/analyze |
WhatsApp forward analysis (patterns + LLM) |
POST |
/account-intel/analyze |
Temporal + stylometric + AI-operation analysis (live Bluesky ingestion β Neo4j) |
POST |
/deepfake/analyze |
ELA forensics + two-model AI-image verdict |
POST |
/language/detect |
Sarvam Indian-language identification |
GET |
/live-feed |
Live debunked claims from fact-checker RSS |
GET |
/agents/status |
Real per-agent task counts from the running process |
curl -X POST http://localhost:8000/analyze-text \
-H "Content-Type: application/json" \
-d '{"text": "BREAKING: EVMs hacked β share before this gets deleted"}'{
"misinformation_score": 87,
"confidence": 0.87,
"signals": { "lexical_score": 0.34, "model_score": 0.95, "score_blend": 0.87 }
}The score is a deliberate blend β 0.85 Γ LLaMA-3.3-70B + 0.15 Γ deterministic lexical. The lexical half is not decoration: it is the offline fallback, so the endpoint keeps returning a defensible score when Groq is down.
Every external dependency has a defined failure mode. Pull any plug and the system stays up, just quieter:
| Pull this plug | What happens |
|---|---|
| Neo4j unreachable | JSON campaign fallback β in-memory NetworkX pipeline |
| Groq down | Deterministic lexical scorer + rule-based threat classifier |
No HF_API_KEY |
ELA + EXIF forensics still run; AI-generation verdict omitted |
No SARVAM_API_KEY |
Regex EN/HI/Hinglish heuristic takes over |
| A fact-checker feed is down | Skipped silently; the other three still serve |
| Only one HF model responds | Score clamped to 0.49 β it cannot flag an image alone |
ShadowTrace/
β
βββ app/ # Next.js 16 App Router
β βββ page.tsx # Landing β scroll-journey globe
β βββ layout.tsx
β βββ globals.css
β β
β βββ dashboard/ # ββ MISSION CONTROL ββ
β β βββ page.tsx # Overview
β β βββ layout.tsx
β β βββ account-intel/page.tsx # β
Live Bluesky β Neo4j intel
β β βββ network/page.tsx # β
D3 propagation graph
β β βββ whatsapp/page.tsx # β
Forward analyzer + 5-agent run
β β βββ image-forensics/page.tsx # β
ELA + AI-image ensemble
β β βββ alerts/page.tsx # Severity-classified alert feed
β β βββ agents/page.tsx # Live agent task counts
β β βββ reports/page.tsx # Campaign intelligence reports
β β βββ _components/
β β βββ NetworkGraph.tsx # D3 force simulation
β β βββ NetworkGraphPanel.tsx
β β βββ AnalyzePanel.tsx
β β βββ AlertFeed.tsx
β β βββ LiveClaimsCell.tsx
β β βββ Sidebar.tsx
β β βββ Topbar.tsx
β β
β βββ api/ # Next.js β FastAPI proxy layer
β βββ account-intel/route.ts
β βββ investigate/route.ts
β βββ deepfake/route.ts
β βββ whatsapp/route.ts
β βββ campaigns/route.ts
β βββ live-feed/route.ts
β βββ analyze/route.ts
β βββ alert/route.ts
β βββ agents/route.ts
β
βββ components/
β βββ account-intel/
β β βββ TemporalHeatmap.tsx # 60s coordination windows
β β βββ FingerprintCluster.tsx # DBSCAN stylometric clusters
β β βββ AIOperationScores.tsx # Perplexity Β· burstiness Β· drift
β β βββ VerdictPanel.tsx
β βββ landing/OutbreakCanvas.tsx # Live outbreak simulation
β βββ WhatsAppAnalyzer.tsx
β βββ DeepfakeAnalyzer.tsx
β βββ LiveFeedPanel.tsx
β
βββ backend/ # ββ FastAPI AI BACKEND (Render) ββ
β βββ main.py # Entry point; seeds AuraDB on startup
β β
β βββ agents/ # ββ THE 10-AGENT ROSTER ββ
β β βββ content_analyzer.py # Groq LLaMA-3.3-70B + lexical blend
β β βββ network_mapper.py # Cypher bot scoring Β· PageRank
β β βββ campaign_detector.py # LangGraph state machine
β β βββ threat_classifier.py # Groq severity + rationale
β β βββ temporal_coordinator.py # 60s coordination windows
β β βββ linguistic_fingerprinter.py # DBSCAN stylometry
β β βββ ai_operation_detector.py # LLM-authorship signals
β β βββ deepfake_detector.py # ELA + EXIF forensics
β β βββ ai_image_detector.py # 3-model HF ensemble (2-of-N rule)
β β βββ whatsapp_analyzer.py # EN/HI/Hinglish forward chains
β β βββ sarvam_language_detector.py # Sarvam text-lid
β β βββ bluesky_ingestion.py # Live account β Neo4j
β β βββ fact_checker_ingestion.py # Alt News Β· BOOM Β· Quint RSS
β β βββ agent_stats.py # Real in-process task counters
β β
β βββ db/ # ββ NEO4J AURADB ββ
β β βββ neo4j_client.py # Driver + Cypher runner
β β βββ seed.py # Campaign seeding Β· COORDINATES_WITH
β β βββ seed_demo.py # Demo account timelines
β β
β βββ graph/
β β βββ bot_detection.py # 8-signal composite + Cypher scoring
β β βββ community_detection.py # Label propagation Β· greedy modularity
β β
β βββ api/
β β βββ routes.py # All endpoints
β β βββ schemas.py # Pydantic request/response models
β β
β βββ data/ # Synthetic campaign datasets
β β βββ campaign_1.json # Operation Pulse
β β βββ campaign_2.json # MedFear
β β βββ campaign_3.json # ReviewStorm
β β
β βββ requirements.txt
β
βββ lib/
β βββ groq.ts
β βββ supabase.ts
β βββ mockData.ts
β
βββ docs/
β βββ Technical_Documentation.md # Full agent + graph reference
β βββ Architecture_Diagram.md # Mermaid system diagrams
β
βββ render.yaml # Backend deploy blueprint
βββ vercel.json # Frontend deploy config
βββ package.json
β
marks the four flagship surfaces.
- π‘ Live Telegram ingestion β Telethon connector for public channels, feeding straight into the agent pipeline
- π¦ Twitter/X & Mastodon connectors β extend the live Bluesky ingestion path across platforms
- β‘ Real-time WebSocket alerts β sub-second push from detection to analyst, replacing today's polling model
- π° Journalist & government API β public REST endpoint for newsrooms and election commissions to submit content and receive structured threat reports
- π Evidence packages β signed PDF + JSON bundles per campaign, formatted for platform trust-and-safety submission
- π‘οΈ Purpose-trained deepfake model β replace hosted classifiers with a detector fine-tuned on Indian misinformation imagery
- π Broader Indian-language coverage β extend Sarvam ID into full multilingual narrative clustering across the 22 scheduled languages
- Neo4j AuraDB β the graph substrate for accounts, posts, campaigns and coordination edges
- Groq β LLaMA-3.3-70B inference for content scoring and threat classification
- Sarvam AI β Indian-language identification (
text-lid) - Hugging Face Inference API β AI-generated-image classifiers
- Bluesky (AT Protocol) public API β live account and post ingestion
- Alt News, BOOM, FactChecker.in, The Quint β live debunked-claim RSS feeds; thank you for doing the hard work this project is built to support
- Open source: FastAPI Β· LangGraph Β· NetworkX Β· scikit-learn Β· Pillow Β· D3.js Β· Next.js Β· Tailwind CSS
- Campaign seed datasets are synthetic, designed to emulate coordinated inauthentic behaviour patterns documented in public research. We label this explicitly rather than pass synthetic data off as live intelligence.
We came in planning to build a fake-news detector. We threw it away on day one, because a detector that tells you a viral lie is a lie after it has gone viral isn't a defence β it's an obituary.
The hardest night was image forensics. We had a working build, and it confidently flagged a perfectly real photograph as AI-generated. In a tool whose entire value is being trusted about what's fake, that is the worst failure available to us. So we tore it up: two independent models must now agree before ShadowTrace will say those words, and that verdict can never bulldoze the ELA evidence underneath it. Shipping less certainty, more honestly was the most useful thing we learned all hackathon β and it's why the score caps at 97, never 100.
The moment it clicked: pasting a stranger's real Bluesky handle into Account Intel, watching their posts flow into Neo4j, and seeing coordination edges light up against accounts already in the graph. Not a mock. Not a fixture. A real network, traced in real time.
Huge thanks to NAMESPACE, HACKHAZARDS '26 and Neo4j β for the platform, and for the graph that made this possible. π
Detect. Trace. Neutralize.
{ "sources": { "bsky.app": "bluesky" }, // β fetched live, MERGEd into AuraDB "temporal": { "score": 0, "flagged_pairs": 0, "timeline": [ /* 20 real posts */ ] }, "ai_operation": { "score": 17.8, "verdict": "LIKELY_HUMAN" } }