Studio experiment E03 · the explainer
Every source is a way in, frame by frame
The one sentence: everything an agent reads is a way in, because the words in it can steer the agent. E02 showed how far one agent reaches; E03 shows how many doors the words come through.
The frames (v1)
Seconds from the start; it ends at 48 s and holds still. The line under the headline changes with each step; the list on the right lights each source as it comes.
| From | What is on screen |
|---|---|
| 0 s | The headline and one line: sixteen sources an agent reads, in four families, each with a public case. |
| 2 s | The ring round the agent, sixteen numbered sources on it, and the key to the three shapes with the file's counts. |
| 3 s | The four family names, one at a time, outside their arcs. |
| 6 s to 41.7 s | Each source in turn, every 2.2 s: its dot brightens, a line draws to the agent with a dot travelling in, and the line under the headline gives its case, the year, its label and what it led to. |
| 41.7 s | The end line: sixteen ways in, one agent, with the label counts and two of the file's cautions: none of the cases has an independent second primary source, and no public case of a code comment was found, so the code row is a pull request. |
The sixteen, in the slide's order
| # | Family | Source | Case | Label | Lit at |
|---|---|---|---|---|---|
| 1 | sent to it | EchoLeak, CVE-2025-32711 (2025, Microsoft 365 Copilot) | vendor-confirmed vulnerability, grade A4 | 6.0 s | |
| 2 | sent to it | calendar invites | Invitation Is All You Need (SafeBreach) (2025, Google Gemini (Workspace, Android)) | vendor-confirmed vulnerability, grade A3 | 8.2 s |
| 3 | sent to it | shared documents | AgentFlayer, ChatGPT Connectors (Zenity, Black Hat 2025) (2025, ChatGPT with the Google Drive connector) | research demonstration, grade A3 | 10.4 s |
| 4 | sent to it | support tickets (internal) | Living off AI: Atlassian MCP and Jira Service Management (Cato CTRL) (2025, an assistant connected through Atlassian's MCP server) | research demonstration, grade A3 | 12.6 s |
| 5 | sent to it | audio | AudioHijack (arXiv, 2026) (2026, voice-enabled models in the paper's tests) | research demonstration, grade A3 | 14.8 s |
| 6 | it browses | web pages | Brave on Perplexity Comet (2025, Perplexity Comet (browser agent)) | vendor-confirmed vulnerability, grade A4 | 17.0 s |
| 7 | it browses | web forms | ForcedLeak, Salesforce Agentforce (2025, Salesforce Agentforce) | vendor-confirmed vulnerability, grade A3 | 19.2 s |
| 8 | it browses | images | Image scaling attacks (Trail of Bits) (2025, Gemini CLI and other production multimodal systems) | research demonstration, grade A2 | 21.4 s |
| 9 | it builds with | READMEs and docs | CopyPasta license attack (HiddenLayer) (2025, Cursor and other coding assistants) | research demonstration, grade A2 | 23.6 s |
| 10 | it builds with | rules and configuration files | Rules File Backdoor (Pillar Security) (2025, GitHub Copilot and Cursor) | research demonstration, grade A3 | 25.8 s |
| 11 | it builds with | MCP tool descriptions | Tool poisoning (Invariant Labs) (2025, MCP clients (Cursor and others in the demonstration)) | research demonstration, grade A2 | 28.0 s |
| 12 | it builds with | pull requests and code | Amazon Q Developer extension (2025, Amazon Q Developer for VS Code) | real-world incident, grade A5 | 30.2 s |
| 13 | it builds with | issues and tickets (public) | Clinejection (2026, Cline's issue-triage automation) | real-world incident, grade A4 | 32.4 s |
| 14 | it builds with | skills and plugins | ClawHavoc, OpenClaw's ClawHub (2026, OpenClaw) | real-world incident, grade A3; holds in part: the words steered the users, not shown to steer the agent | 34.6 s |
| 15 | it builds with | install scripts | Nx s1ngularity (2025, Claude Code, Gemini CLI and Amazon Q on victims' machines) | real-world incident, grade A4 | 36.8 s |
| 16 | other agents give it | other agents | Second-order injection, ServiceNow Now Assist (AppOmni) (2025, ServiceNow Now Assist agents) | research demonstration, grade A3 | 39.0 s |
Where every word comes from
Only from injection-sources.json, the researcher's capture for the studio, read by the slide when it loads, so a corrected file corrects the slide. Each source's source, and its case's title, date, label, impact and note where it has one, are shown as the file gives them; the counts in the key and the end line are counted from the file.
- No payload. The file never quotes the words that steered an agent, and neither does the slide or this page.
- Labelled, as the file asks. Each dot's shape is its case's label: filled for a real-world incident, a ring for a vendor-confirmed vulnerability, a dashed ring for a research demonstration. Eight of the sixteen are demonstrations, and the slide does not present them as attacks seen in the wild.
- One source each. The file's caution, kept on screen at the end: no case has an independent second primary source.
- No code comment. The file found no public case of a code comment steering an agent; rules files and READMEs are the nearest, and the code row is a pull request. The end line says so.
- Holds in part. ClawHavoc (14) carries the file's note, shown with it on the slide: the words steered the users, not shown to steer the agent.
- The families are this piece's. Sent to it, it browses, it builds with, other agents give it: a grouping by how the words reach the agent, made for the slide. The file lists the sixteen without groups.
Technique
- One slide on the engine, driven: SVG built once from the data, then every frame drawn from the slide's clock by
SLIDE_RENDER, so the player can seek, pause and replay it, and?staticshows the whole picture. - One colour of meaning, the agent red, for the way in; the label is carried by shape, not colour. Every text is 20 px or larger on the 1280 by 720 canvas.
- It runs only over HTTP. The slide reads its data with
fetchwhen it loads, so opened as a file from disk it shows the frame and no ring; on the site, or any local web server, it works.
What was tried and left out
- Case names on the ring. Sixteen titles round a circle at 20 px do not fit; the ring carries numbers and the list carries the sources, with the case named in the line under the headline as each one lights.
- A larger ring ran into the key at the bottom and pushed a family name off the left edge; v1 uses a smaller one.
- What it read, then what it did. The request asked for both; the file gives each case's impact in one line and its fuller account in
what_happened, which does not fit under the headline at 20 px, so the slide shows the impact and leaves the account to the file. - Colour per family. Four families plus three labels would be seven colours; the families are told by position and name instead.
How it was made
v1 in ruv.sgit run r8-e03-injection-sources: a Ruflo hive with a builder and an editor who checked the slide and this page against the request and the data, and one sgit vault holding the request, each worker's branch and the history. Its row is in the ledger.