On 28 October 2026, Cisco open-sourced Project Quarry, a detection language and engine for AI agent behaviour that only looks wrong when you read several steps together. MoorAI already works with it in both directions. It exports the sessions your coding agents keep on the device as Quarry scan inputs, it imports the Quarry rules it can enforce exactly into signed policy, and an open rule pack carries MoorAI’s detectors into Quarry’s format. Write a detection once, hunt with it in Quarry, and enforce the exact parts of it on the device.
What Quarry is
Quarry rules read an agent conversation in the OpenAI shape: user, assistant and tool messages, the tool calls with their arguments, the tool results and the tools offered to the model. A rule can test text and RE2 regular expressions, structured fields and tool names, and it can test order: a read of a credential file followed, within a window of steps, by a call that reaches the network. Rules can also count, capture, and call a configured model when local checks are not enough. Quarry compiles each rule when it loads and returns the evidence for each match.
Cisco describes three uses: runtime guardrails before and after each model call and tool run, post-hoc evaluation of stored traces, and incident response, running a newly learned pattern against old traces. Its advice on the order is plain: “Move to runtime once you sort through the noise.” The project is Apache-2.0 and in alpha, and its README says the rule syntax may change before v1.0.0.
Where MoorAI fits
MoorAI decides each action of an AI agent on the device before it runs: a command, a file read, a web fetch, a Model Context Protocol (MCP) call. It runs in the agent hosts’ own hooks, such as Claude Code’s PreToolUse hook, under a policy the console signs, and its records carry no prompt, file or code content. Quarry’s strength is the pattern across a whole session. MoorAI’s is the decision at the call site, on every managed device, whether or not anyone is hunting.
The two meet in three places.
1 · Export: your agents’ sessions as Quarry input
Coding agents already keep their sessions on the device. MoorAI’s transcript replay, moorai-ingest, reads Claude Code, Codex and Gemini CLI sessions there, and with --format quarry agent v1.44.0 writes each one as the {"messages": [...]} object Quarry scans, with the tool calls in transcript order under the host’s own tool names (Bash, Read, mcp__<server>__<tool>; Codex shell; Gemini CLI run_shell_command).
# one Quarry scan input per session, in ./traces
node cli/moorai-ingest.mjs --discover --format quarry --out ./traces
# with transcript text, to standard output on this device
node cli/moorai-ingest.mjs --discover --format quarry --content full
The default, --content free, exports no transcript text. Message text is empty; a tool result holds MoorAI’s facts about it, and each call’s arguments hold only what MoorAI knows about the call: its capability tags as the live hook computes them (read-private, network, exec), and for each call the replay judges, MoorAI’s decision, threat ids and findings. That is enough for Quarry’s order and tag rules, for example called_tool("WebFetch") after called_tool("Read"), without moving a line of anyone’s code or prompts off the device.
Text rules need --content full, which adds the prompts, replies, results and each call’s real input. It prints a notice, writes only to the output file or standard output on that device, and cannot be combined with --report, the option that sends replay findings to the console. The export is checked against Quarry 0.1.0 at commit eadc6e3, and since Quarry rejects an input over its limits rather than trimming it, a session past them (10,000 messages, 1,000 tool calls) is cut at the tail, and the export says how much it dropped.
2 · Import: Quarry rules into signed MoorAI policy
In the Management Server (console v0.102.0), the import is in Policy → Custom detection rules: paste or upload Quarry rule files, run the dry run, then apply. The console parses the rules itself and keeps a rule only where MoorAI enforces exactly what it says. Each kept rule becomes a detector in a signed quarry-<name> pack, which the console versions and rolls out like any other policy change. Nothing is approximated.
A rule imports when it is a string test (contains, contains_any, ~, user_said, joined only by or) on one of three surfaces. With agent v1.44.0 or later, each detector’s scope makes it run only at that kind of call site:
| Quarry surface | Where the MoorAI agent runs it |
|---|---|
user_messages, user_said | The prompt a person typed, where the policy scans every prompt (promptScan: "all"); the dry run warns when it does not. The first 64 KiB of a prompt. |
tool_responses | The tool results the hook scans: web fetch and search, shell, sub-agent and MCP results, and a file a read brings into context. |
tool_calls | Only the command argument: a Bash or PowerShell command, before it runs. A command argument of another tool is not scanned. |
Quarry has no threat ids, so each imported rule needs a MoorAI threat id and a mode, chosen by the administrator or carried in the rule’s metadata (moorai_threat, moorai_mode); a rule with neither is refused, never defaulted. From then on a match is a finding like any built-in one: the signed policy’s action for that threat applies, and the alert is content-free.
Everything else is refused with a reason the dry run shows: the flow operators (before, after, within), counts, and, not, all, captures, tool names, model() and the other model functions, and text the model wrote. The parser is bounded (64 KiB of source, 50 rules, and a condition whose variables expand past 5,000 patterns is refused), and every imported pattern passes the same ReDoS guard the agent applies on the device.
That is why few of Cisco’s examples import. Of the 75 example rules in Quarry’s repository, 8 import once a threat id and mode are chosen. Most of the other 67 show what Quarry adds beyond one call, such as event order, counts, tool names and model calls, and they belong in Quarry’s engine.
3 · An open rule pack
The Quarry rule pack in MoorAI’s open benchmark repository (release v0.5.0, Apache-2.0) carries MoorAI’s public detection patterns into Quarry’s format:
- 21 single-surface rules translated from MoorAI agent detectors: credential formats, prompt-injection and exfiltration phrasing, injected tool results, reverse shells, credential file access, untrusted installs, destructive and security-setting commands and outbound messaging. Each names its MITRE ATLAS technique and its MoorAI threat id.
- 3 flow rules for Quarry’s engine: a private read followed by a network call, the order of the lethal trifecta, and poisoned tool descriptions.
- Positive and negative example conversations for every rule, and a benign control. Quarry’s own CLI validated all 24 rules, and its scan agreed with the expected verdict on all 49 example files.
9 of the 21 import into MoorAI policy in warn mode with no choice to make. The other 12 are refused by MoorAI’s import guard, mostly for patterns with more than one unbounded quantifier, which a built-in detector may hold and an imported one may not; they are MoorAI built-in detectors, so every MoorAI agent already runs them. One of the importable rules, with its metadata shortened:
rule "Shadow password file in a command"
metadata:
severity = "high"
atlas = "AML.T0098"
moorai_threat = "55"
moorai_mode = "warn"
strings:
$p = "(^|[\s\"'=])\/etc\/shadow\b" regex
condition:
any call in tool_calls where call.arguments.command contains $p
The pack references Quarry and copies none of its files, and Cisco has not reviewed it.
What a security team gets
- One rule language for hunting and enforcing. A detection your team writes in Quarry runs over every recorded session, and its single-call parts run on every managed device.
- Hunting without moving transcripts. The default export carries the order of the tool calls and MoorAI’s verdicts on them, not code or prompts.
- Enforcement you can read before you apply it. The dry run lists, rule by rule, what will run where and why the rest will not.
- A starting set. 24 rules with test data, checked by Quarry’s own CLI, to hunt with on day one.
Try it in four steps
- 1. Export. On a device with agent v1.44.0, run
node cli/moorai-ingest.mjs --discover --format quarry --out ./traces. - 2. Hunt. Install Quarry (Python 3.11 to 3.13) and, from the benchmark repository’s root, scan the exported traces with the pack:
quarry scan -c quarry/quarry.yaml -t /path/to/traces/. Add rules of your own. - 3. Dry-run the import. In the console, Policy → Custom detection rules, paste the rules you want enforced and read what imports, where it will run, and what is refused.
- 4. Apply and roll out. The signed
quarry-<name>pack reaches devices like any policy change, and the policy’s action for each rule’s threat decides what a match does.
Questions security teams ask
Does MoorAI run Quarry rules itself?
Only the parts it can enforce exactly. The console turns string rules on a user prompt, a tool result or a shell command into detectors in a signed policy, and the agent runs each one at that kind of call site. Flow rules, counts, negation and model calls are refused with a reason and stay in Quarry. The console parses the rules itself and runs no Quarry code.
Do our agents’ transcripts leave the device when we export them?
Not by the export. It writes files, or standard output, on the device. At the default content level it carries no transcript text: the host’s tool names in order and, per call, MoorAI’s capability tags, decision, threat ids and findings. The full level adds the text, prints a notice and still writes only on the device, and it cannot be combined with sending a report to the console.
Why do only 8 of Quarry’s 75 example rules import?
Most of Quarry’s examples show what it does beyond one call: event order, counts, captures, tool names, offered tools and model calls. MoorAI imports a rule only where a decision on one call means exactly what the rule says, so those rules are refused with a reason and stay in Quarry. The 8 that import, once an administrator picks a MoorAI threat id and mode for each, are string rules on one surface.
Sources
- Cisco. A Shared Language for Agent Defense: Introducing Project Quarry, Cisco blog, 28 October 2026; cisco-ai-defense/project-quarry on GitHub, README and licence, at commit
eadc6e3. - SecurityWeek. Cisco Open Sources Quarry to Catch AI Agent Attacks Hidden in Harmless Steps, 29 October 2026.
- MoorAI. MoorAI on GitHub, agent v1.44.0: README sections “Quarry trace export” and “Org detector packs and
scope”; Management Server v0.102.0 documentation, “Quarry rule import”; quarry/ in the agentic security benchmark, v0.5.0.
See also: Agentic apps are attack graphs and agent boundaries mapped to MITRE ATLAS.