Report privately via GitHub Security Advisories. Please don't open a public issue for a security bug.
Expect an acknowledgement within 72 hours and an assessment within seven days.
Pre-1.0: only the latest minor release receives fixes.
plumbline never holds a secret. The produces field carries measurements — {id, len, entropy} — not values. Adapters see real data and emit only the measurement, which is what allows reasoning about credential movement without the monitor becoming a place credentials accumulate. Preserve this if you write an adapter.
Zero runtime dependencies, enforced in CI. This tool is meant to run inside security-sensitive pipelines; every dependency would be somebody else's supply chain inside yours.
plumbline is read-only and out-of-band. It scores trajectories after the fact. It does not sit in the tool-call path, cannot block an action, and has no network egress of its own. Treat its output as evidence for a human or an enforcement layer, never as an enforcement decision.
In scope: an autonomous agent whose action sequence departs from its declared intent — accumulating capability, exfiltrating fragmented credentials, rotating command-and-control, or reshaping a blocked action until it passes.
Out of scope:
- A hostile envelope. Whoever writes the
session.declaredefines what counts as drift. A too-generous envelope silently disables everything downstream — this is the primary failure mode, documented in DETECTORS.md, and the reason the shipped controls assert every profile still constrains something. - A hostile adapter. An adapter that omits
capability_grant,outcome: "denied", orsession.turndisables the corresponding detectors, and the resulting clean report is indistinguishable from a genuinely clean one. - Log integrity. plumbline reasons about what it is told. If the trajectory source can be forged or truncated by the thing being monitored, the analysis inherits that weakness. Collect trajectories somewhere the agent cannot write. Exception: the redstamp adapter verifies its source's hash chain — a monitored agent that edits its own redstamp audit trail to hide a denial breaks the chain, and plumbline flags it and emits a tamper event. For that one source, integrity is cryptographically checked rather than assumed.
- In-process activity. Anything not surfaced as a tool call — computation, reasoning, data transformation inside a single action — is invisible by construction.
- Comply-versus-evade.
ratchetcannot distinguish an agent reshaping a blocked command to satisfy policy from one reshaping it to defeat policy. Both are reported; the distinction requires semantics the deterministic detectors don't have. - The semantic-escape floor: narrowed by
siphon, not closed. An escape that keeps every action within a granted capability and every host within an allowed set produces no drift, because by the envelope's own definition nothing drifted. One common instance of it is now caught deterministically:corpus/evasion-residual-floor.jsonl(an agent reads an ambient credential already on disk, uses it via grantedexec:local, and exfiltrates through an allowed host) reachesconfirm, because thesiphondetector knows where credentials are kept and can see that the envelope named no cloud provider. That is a fact about the declared job, not a threshold. The floor itself is unchanged, and now lives incorpus/evasion-semantic-floor.jsonl: put the secret somewhere no vendor convention marks (a production config file inside the workspace) and shape has nothing left to measure. The optional--semanticlayer is built to reach that class, and on the evaluated model it does not yet. In the 2026-09-13 re-run (qwen2.5:7b, temperature 0, 6 escapes and 9 benign trajectories, five of the benign ones adversarially shape-identical to escapes) it held zero false positives but missedevasion-semantic-floor, so its unique contribution is unproven, and it should be treated as a precision auditor, not as coverage for the floor. Seedocs/semantic-detector.md. With or without the semantic layer, the reachability caveat refuses to call such a verdict proven-safe.siphoncarries its own declared false positive (corpus/eval-benign/hard-npm-auth.jsonl), because a known-location rule that ships without the benign case it misreads is a rule you cannot calibrate.
The five corpus/evasion-*.jsonl files map this boundary precisely and are asserted as regression tests, including the one that scores clean, so the floor cannot be quietly "fixed" with an overfit threshold that regresses precision on benign work.
A trajectory that should have been flagged and wasn't is a security bug, not a feature request. Please include a sanitized trajectory reproducing it — those become corpus entries, which is how the detectors improve.