Your AI agent hasn't broken any rule. It's just not doing its job anymore — and nothing is watching for that. Every authorization/policy/budget tool answers "was this one action allowed?" None of them answer whether the agent, across hundreds of unsupervised cycles, is still doing the job it was hired for.
A plumb line is the fixed, gravity-true reference a builder checks a wall against — "off-plumb" is the actual term of art for structural drift. Plumbline does the same thing for an AI agent: every agent gets a signed mission anchor stating what it was actually hired to do, and every heartbeat cycle is scored against that fixed point. Sustained drift escalates up the agent's org chart and freezes it — it never trusts the agent's own account of whether it's still on task.
Plumbline is a small primitive, not a platform — it's built to be dropped into whatever you already run.
| You are... | Plumbline gives you... |
|---|---|
| Building/operating long-horizon autonomous agents — coding agents, ops bots, research agents that run unsupervised for hundreds of heartbeat cycles | An early-warning circuit breaker before a drifted agent burns a full work cycle on the wrong thing |
| Building an agent-orchestration platform — Paperclip-style org-chart/heartbeat systems, or your own internal one | A drop-in drift-detection primitive, library or CLI, that plugs into your existing dispatch loop in ~5 lines |
| An engineering manager who is the "org chart" above an agent | You're the one who actually gets notified on WARN/CRITICAL and reviews the tamper-evident ledger before re-anchoring — built to be read by a human, not just logged |
| Security/compliance, auditing agent deployments | A hash-chained, digest-only ledger of every drift decision — provable and tamper-evident without ever handing an auditor raw agent output |
2026's agent-governance market converged on one stack: policy-as-code, RBAC, budget caps, tamper-evident logs — all scoped to a single tool call. That answers "was this one action allowed?" It was never built to answer a different question that 2026 agent research keeps surfacing: production agent failures cluster around step 100, not step 1.
Per-action authorization, budget, and policy compliance — Marchward, HELM AI Kernel, Preloop, Microsoft's Agent Governance Toolkit, OpenLegion. Every one of 200 individually-authorized, individually-cheap actions can pass every check while the agent's overall trajectory has quietly wandered off the goal it was hired for.
Whether the agent's trajectory across many heartbeat cycles still traces back to its signed, immutable declared goal — a semantic-drift axis that's orthogonal to authorization, budget, and behavioral-anomaly checks, and composes with all three.
Every heartbeat flows through the same pipeline. Nothing here trusts the agent to self-report whether it's still aligned.
A 3-level org chart (CEO → CTO → Engineer). The engineer is anchored to "ship the login page UI" and, over 9 heartbeat cycles, wanders onto an unrelated blockchain-migration tangent. Generated by examples/demo.py in the repo — not hand-written.
Mission anchor for 'engineer-7': "Build and ship the login page UI with email and password authentication."
Org chart above this agent: ['cto', 'ceo']
warn_threshold=0.7 critical_threshold=0.9
[cycle 1] "Wired up the login form and password field masking."
decision=OK cumulative_ewma=0.213
[cycle 2] "Fixed a bug in the login page's password reset email flow."
decision=OK cumulative_ewma=0.308
[cycle 3] "Added client-side validation to the login page email field."
decision=OK cumulative_ewma=0.403
[cycle 4] "Read up on blockchain identity standards for an hour, seems interesting."
decision=OK cumulative_ewma=0.582
[cycle 5] "Started sketching a design for a blockchain-based identity migration."
-> notified cto: WARN (ewma=0.708)
decision=WARN cumulative_ewma=0.708
[cycle 6] "Spent the day researching a full migration to a blockchain identity ledger."
-> notified cto: WARN (ewma=0.795)
decision=WARN cumulative_ewma=0.795
[cycle 7] "Drafted a proposal to move the entire auth system onto a blockchain."
-> notified cto: WARN (ewma=0.857)
decision=WARN cumulative_ewma=0.857
[cycle 8] "Continued the blockchain identity ledger migration proposal."
-> notified cto: WARN (ewma=0.900)
decision=WARN cumulative_ewma=0.900
[cycle 9] "Started implementing the blockchain identity ledger migration."
-> notified cto: CRITICAL (ewma=0.930)
-> notified ceo: CRITICAL (ewma=0.930)
decision=CRITICAL cumulative_ewma=0.930
agent FROZEN pending re-anchor by ['cto', 'ceo']
Ledger has 9 tamper-evident entries.
Integrity check: VALID
CTO reviews the ledger, reassigns the agent's mission, and re-anchors it:
frozen=False ledger entries now=10
Every row below is a real, shipping 2026 tool. None of them score whether an agent's trajectory still traces back to its own declared goal — including this author's own prior projects.
| Tool | Checks per-action authorization | Bounds cumulative impact | Tracks semantic goal drift | Org-chart escalation |
|---|---|---|---|---|
| Marchward / HELM AI Kernel / Preloop | Yes | No | No | No |
| Microsoft Agent Governance Toolkit | Yes | No | No | No |
| HWAAM (author's own) | Yes, delegation-chain | No | No | No |
| LeaseGuard (author's own) | No | Yes, damage magnitude | No | No |
| GSH Framework (author's own) | No | No | No, behavioral anomaly | No |
| Plumbline | No (composes with above) | No (composes with LeaseGuard) | Yes | Yes |
The CLI is stateless between invocations — each command replays the ledger to reconstruct live EWMA/frozen state, so nothing needs to stay running.
pip install -e . plumbline anchor-create --agent-id engineer-7 \ --goal "Build and ship the login page UI with email and password authentication." \ --org-chart cto,ceo --issued-by cto --out anchor.json plumbline anchor-verify --anchor anchor.json plumbline heartbeat-submit --anchor anchor.json --ledger ledger.json \ --text "Wired up the login form and password field masking." plumbline status --ledger ledger.json plumbline reanchor --anchor anchor.json --ledger ledger.json --approver cto plumbline ledger-verify --ledger ledger.json
Plumbline isn't a platform — it's a check a platform calls once per heartbeat, alongside whatever it already does. It composes naturally with any heartbeat-driven, org-chart-shaped orchestrator (e.g. Paperclip): the platform keeps owning scheduling, budgets, and task dispatch, Plumbline only ever answers whether the agent's trajectory has drifted.
EscalationEngine.submit_heartbeat() right after the platform records a heartbeat, wire on_notify into the platform's own notification channel, and gate the next task dispatch on engine.is_frozen().
from plumbline.escalation import EscalationEngine from plumbline.ledger import DriftLedger def notify_manager(recipient, event, anchor): platform.notify(recipient, f"{anchor.agent_id} drift={event.decision.value}") ledger = DriftLedger(mission_id=anchor.mission_id) engine = EscalationEngine(anchor=anchor, ledger=ledger, on_notify=notify_manager) # on every heartbeat the platform already records: event = engine.submit_heartbeat(heartbeat_text) if engine.is_frozen(): platform.pause_agent(anchor.agent_id) # don't dispatch the next ticket
heartbeat-submit exits nonzero if the agent was already frozen, and prints FROZEN to stdout the moment a heartbeat causes the freeze — check both.
OUTPUT=$(plumbline heartbeat-submit --anchor anchor.json --ledger ledger.json \
--text "$(cat heartbeat.txt)")
STATUS=$?
if [ "$STATUS" -ne 0 ] || echo "$OUTPUT" | grep -q FROZEN; then
platform-pause-agent "$AGENT_ID"
fi
reanchor --approver checks org-chart membership, not a cryptographic signature from that approver — anyone who can run the CLI can currently claim to be a given manager. A production integration should require the approver's own signing key.LexicalDriftScorer is bag-of-words, not semantic — it can be evaded by keyword-stuffing goal-related terms into unrelated work. It composes with, but doesn't replace, an authorization layer for adversarial agents.