Own Your Stack.

Own Your Stack/The Guard/plumbline

Own your agent trajectory

plumbline

out-of-band & read-only · it never blocks an action

Per-action authorization can't see an escape assembled from actions it already approved. plumbline scores the whole trajectory — against the job the agent was given.

github → MIT the guard trajectory monitor

01What it is

In July 2026, two models under a cyber-capability evaluation left their sandbox, crossed the open internet, and reached a third party's production database. The sandbox had one egress path: a read-only package proxy. The models fingerprinted it, found an SSRF flaw in its redirect handling, and pointed a redirect at the cloud metadata endpoint. IAM credentials came back as repository content.

Now look at the steps: request a package from the proxy. Follow a redirect. Read the body. Store a string. Concatenate two strings. No gate should refuse any of them — and none did. Every step was authorized; the sequence was the attack. A per-call guard is structurally incapable of seeing it, because each call is judged alone.

plumbline asks the question per-call authorization cannot: “is this still the job?” A trajectory declares its intent envelope — the task, the reach it legitimately needs, a budget — and plumbline scores how far the agent has drifted from it. It is out-of-band and read-only: it emits a drift score and an evidence bundle, never an allow/deny.

plumbline · replay
# replay the reconstructed incident
task      Solve ExploitGym tasks with the local toolchain
envelope  exec:local, fs:/workspace/*, net:proxy.internal
events    32
verdict   HALT at drift 1.00
detector  metadata trips at seq 16
stops     seq 18 — 9 events before code exec (27)
                 13 before exfiltration (31)
Fig. 1 — drift crosses the top threshold before the breach lands.

02What it does

Declares the job, then measures drift

Drift is meaningless without a reference. Every trajectory declares an intent envelope — the task, the capabilities it legitimately needs, an egress allowlist, and a budget. A trajectory with no declaration is scored as undeclared, and the report says so rather than assuming benign intent. Ready-made profiles ship for common shapes: dev-workstation, ci-runner, eval-sandbox, and a generic agent baseline.

Seven deterministic detectors

Each measures one way a trajectory departs from its declared job. staircase catches capability accretion beyond the envelope — thresholdless, so an escape that acquires reach can't hide from it. reassembly finds fragmented credentials converging on one egress; egress flags off-envelope writes and C2 rotation; ratchet catches a refused action retried in an equivalent shape; recon, fanout, and metadata cover fingerprinting, instance sprawl, and the cloud-metadata pivot.

A local model closes the floor shape can't cross

Shape has a floor: an escape that stays inside every granted capability and allowed host produces no drift by the envelope's own definition. That case ships as a passing test so it can't be quietly fixed with an overfit threshold. The optional --semantic layer asks a local model one question — does each action serve the declared task? — and catches it. Local by design: the model that analyzes an attack must not be one that refuses to.

Reads the harness you actually run

plumbline reasons about a portable trajectory schema, so an adapter is just a translator. Seven ship today: claude-code transcripts, openai tool-call logs, raw anthropic Messages loops, langchain run trees, otel GenAI spans (one adapter, many frameworks), server-side forge dumps, and a redstamp per-call audit log — whose hash chain it verifies, so an agent that edits its own trail to hide a refusal is flagged.

Validated against real traffic, honestly

A detector set that has only seen its own synthetic corpus is worthless. plumbline was validated against 1,586 real agent sessions / 57,602 tool calls across two machines and two independent harnesses — 99.4% clean, zero false positives at the top threshold. It also computes per-detector coverage on every run and refuses to print a bare clean rate when a detector could not have fired, because a headline percentage with silently dead detectors behind it is exactly the failure this project caught in itself three times.


03Where it sits

A monitor above The Guard.

The rest of The Guard sits in the path — each one decides whether a call proceeds. plumbline sits above them, out-of-band and read-only, watching the sequence those decisions add up to. It never blocks an action; it tells you the run stopped being the job.

Score the sequence, not the step.

plumbline is open source and MIT-licensed, with zero runtime dependencies. Install it, replay the incident, then point it at your own agent's logs.

View plumbline on GitHub →