-
-
Sources → poller → Gemini scoring → evidence gate → ClickHouse → Grafana ratio alert → agent over read-only MCP → WhatsApp page
-
The feed: every mention with source, sentiment and evidence quote. Unproven rows are labeled UNVERIFIED; untraceable scores flagged.
-
Pulse: reception score, positive or negative split, top topics and a publish-date timeline with what was excluded stated up front.
-
Incidents: when a spike fires, the investigator agent's verdict lands here real, noise or duplicate with its reasoning.
-
Settings: the WhatsApp number that gets paged and the spike-ratio threshold, tuned by the producer — no engineer required.
Inspiration
You shouldn't wait until Release Week begins to start paying attention to what the Internet thinks of your film. Review bombing, leaked scenes, and some trailer backlash all become socially-destructive viral events, and sometimes the whole world finds out about them at the same time, which translates into hours of trending. We'd arrive on set on Monday morning to find trending 16-hour-old tweets about a secret scene that was leaked by a PTA member, and a room full of executives would try to rationalize away the problem until they realized the only way to convince themselves that nothing was going on was to stop looking at the social information altogether. Studios invariably run dashboards that track a set of pre-curated web sources, but when you add up the hundreds of hours normally spent watching dashboards, you start to realize that there's not just the risk of missing some trend, but that executives don't have the time and discipline to be the ones watching them. The goal was to build a dashboard that could self-watch and page only when the evidence on the dashboard as a whole gets interesting.
What it does
At a high level, the system is smart about ingestion (Aggregate mentions of a filmed-and-released movie from across the web, YouTube, and from the studio's own inbox); it performs scoring with Gemini (run a sentiment analysis with a closed feedback-optimized vocabulary to produce its reception score, and a few topic tags); and it implements a deterministic evidence gate (use a purpose-built deterministic knowledge base to recognize that it is in fact the studio's film and exclude games and other movies), resolving each unproven item with a recorded reason: confirmed, unresolved, or rejected, and labeling such unproven items as UNVERIFIED. When mention volume spikes versus what the dashboard shows to be its same-hour weekly median, Grafana fires an alert webhook, and an investigator agent reads mentions of the film with the past hour's window from read-only Grafana MCP (to avoid reading from the same underlying database as the main dashboard) and from a read-only ClickHouse MCP (to compute metrics), classifies the spike cause as real, noise, or duplicate, then annotates the dashboard's incident panel and pages the on-duty producer on WhatsApp with the evidence they need to know it's real and want to see a deeper look. The War Room is shaped as a per-film workspace, with a live feed panel supporting filters (sentiment, topic, source, media), a ticket drill-down into full mention citations, a Pulse view into all-current sentiment, positive-negativity split, topic tags, a publish-date timeline with what people are saying quotes, an Incidents tab, the ability to export the current dash as a CSV file, producer-tunable alert thresholds, and a read-only MCP server that a Gemini CLI or an MCP host can talk to without corrupting the main dashboard for other viewers.
How we built it
Ingestion is built from a Cloud Run Job continually polling a Parallel Search aggregation (see: release-war-room-aggregation), the YouTube Data API v3 (search, video stats, comment threads), and optionally Gmail and Calendar, with a generous day-long daily search budget. Scoring runs on Vertex AI, running google-genai with sentiment and a closed 14-topic vocabulary, which stores the model, prompt version, and input hash on each row, so nothing changes without a new provenance version ever being introduced into a row.
The deterministic evidence gate runs over the knowledge base, producing a stamp: confirmed, unresolved, or rejected along with a recorded reason. This ensures that even if the model ever changes its mind about what counts as evidence, it never gets a say in what is a film fact on this dashboard. This information gets stored in the events table along with the event, and the verdict in a verdicts table, which in turn is used to compute the unchanging daily pulse snapshots in the dashboard's Pulse view. Every event and pulse row passes through PII-sanitization and validation before insert.
Grafana Cloud alert rules compare confirmed mentions for the current hour against the same clock-hour seven-day median, with an absolute floor, and fire a webhook. A FastAPI service runs the Google ADK investigator in a separate environment over official Grafana and ClickHouse MCP servers, with a code-level guard that rejects any rule-mutating tool call, so while prompt injection can try to read and annotate, it can't change rules. A Twilio WhatsApp service then pings the on-duty producer, with deterministic cooldown so a spike pages once. The UI has no build, uses vanilla ES modules, renders untrusted fields as text nodes, and is generally truth-telling even in empty states, explaining when nothing has been polled yet, no incidents are open, or mentions are being reported but are mixed with no clear lean yet.
Challenges we ran into
A key challenge we had to fix was the evidence decision, which was initially made by a non-deterministic model opinion. We moved this decision inside deterministic knowledge-based evidence gating, demoting the model verdict to a diagnostic. Separating honest numbers from honest reasoning by exposing unverified and not this film as separate claims was another important challenge. Exposure of honest numbers at all forced us to find a way that a single number could not satisfy both claims, which we did by using not this film for all unconfirmed mentions of other movies and games. Charts and alerts window on publish date instead of ingest time to avoid spikes due to cold imports of old comments, and day-precision dates are never rendered at all as a fake clock time. We improved our alert logic: instead of trying to find any film with a spike above a scalar threshold, we compute the ratio against its own seven-day baseline and use that as the evidence quantity that fires the alert. This change avoids many alerts on every small film's normal Friday. Comparing trending to a real-world baseline was just a coincidence. We previously applied the absolute floor against the same-hour median, but we found it was better to base the absolute floor on the same-hour median of the past 24 hours, which kept the naive floor from being a persisting wedge.
Accomplishments that we're proud of
We were proud that our agent runs inside a hard boundary that prevents it from altering Grafana's rule set or the ClickHouse data it reads. The agent is only able to view events using a read-only API that doesn't write back to the source database. Alerting actions and dashboard annotations cannot be changed. Model output is conveniently labeled with provenance. We wanted to maintain the PII-sanitized field with both the unaltered original and the sanitized value, so we can later attempt to re-sanitize once a photo or ID-number is released. We put an Unaudited score badge on items which we cannot trace back to their original metasource. We ran 1,347 online tests with real event passes under mock flags, plus five plain-Node browser self-checks that can be run standalone and that enable us to evaluate this dashboard without any Google credentials. UI never lies, not even in empty states.
What we learned
Lessons learned: keep the deterministic core and use AI only at the edges, because the model is good at scoring and summarizing but unreliable as the gate, and make sure disclosures count the same rows as the omission it discloses, since late bugs were numbers that were technically true about the wrong set.
What's next for Release War Room
Next steps are to add multi-title live polling as soon as scheduler changes allow pipeline fan-out; a review queue for tier-correction suggestions; fan out YouTube search per-alias when quota allows; and add the studio's own social accounts once we have the capability to review the platform.
Built With
- clickhouse
- cloud-functions
- cloud-run
- cloud-scheduler
- docker
- fastapi
- firestore
- gmail-api
- google-adk
- google-calendar-api
- google-cloud
- google-gemini
- grafana
- javascript
- mcp
- parallel
- pytest
- python
- secret-manager
- svg
- twilio
- vertex-ai
- youtube-data-api
Log in or sign up for Devpost to join the conversation.