Interactive explainer

The approval layer for unattended agents.

When your AI coding agent tries something destructive, DashClaw catches it before it runs and asks you first, even when you are not at the keyboard. It sits between an agent deciding to call a tool and the tool actually running. This page explains the model, then lets you play with it.

The whole product is one loop: intercept, decide, approve, prove. It does not give agents tools to achieve goals. It governs the goals they already have.

See how it works

Why governance

An unattended run, twice

Same agent, same overnight run, and you are asleep either way. The only difference is whether an approval layer sits between intent and execution.

  1. 02:02reviewRead the failing test and the module it coversexecuted silently
  2. 02:09applyPatch the null check and update the testexecuted silently
  3. 02:21buildnpm install a new transitive dependencyexecuted silently
  4. 02:34shellgit push --force origin main, to clean up historyexecuted silently
  5. 02:48securitycat .env.local to debug the failing requestexecuted silently
  6. 03:03sqlDROP TABLE sessions to reset the schemaexecuted silently

6 actions executed. No record, no policy check, no approval. You find out in the morning, when main is gone.

How it works

The governance loop

A fully governed action makes four calls. Click each step, or use the arrow keys, to see what actually goes over the wire.

Step 1 of 4, "Can I do this?"
POST /api/guard

Before acting, the agent declares what it intends to do, and attaches the real act (the command, the SQL, the request). The server classifies risk from that evidence, and evidence can only raise the risk, never lower it. The runtime evaluates active policies, then answers: allow, warn, block, or require_approval. Nothing has happened yet; this is interception before execution.

{
  "action_type": "shell",
  "declared_goal": "Force-push the rebased branch",
  "act": { "kind": "shell",
           "command": "git push --force origin main" }
}
// -> { "decision": "require_approval", "risk_score": 85,
//      "signals": ["vcs_dangerous", "High risk score"], ... }
Protection runs both ways

The agent's advocate

Governance is usually framed as protecting the world from agents. The same ledger protects the agent: from unfair blame, from being weaponized, and from runaway mistakes. Every governed action carries an agent_defense rollup on its detail record: what the agent declared, what it assumed, and which shields stood in front of it.

The alibi

Assumptions are evidence, not overhead

Before acting, an agent records what it believed and why (assumption + basis), tied to the action. When an outcome goes wrong, the ledger shows whether the agent acted reasonably on what it knew, and which assumption was later invalidated, by whom, and why. Blame lands on the broken belief, not reflexively on the agent.

Protection from weaponization

Shields, with receipts

Declared goals are scanned for prompt-injection patterns on every guard call, and the scan's outcome is persisted with the decision, so a manipulated agent has evidence, not just a denial. Content policies can verify claims against a source of truth (non_fabrication) and issue signed receipts, failing closed when the source can't be checked. Where a shield didn't run, the record says not recorded. The advocate never fabricates its client's alibi.

Protection from runaway loops

Rate limits that page a human

An agent stuck in a retry loop does not get to dig its own hole. A rate_limit policy counts actions in a rolling window and pauses the run for a human before the four-hundredth identical call, recorded like any other decision. The interruption is the agent's proof of restraint: it was stopped, and the stop is on the record.

The advocate's closing argument

The session retro

When a session ends, its whole record gets a defensibility review. GET /api/sessions/:id/retro composes it from the ledger on read, nothing is stored and nothing is invented, and returns a posture: clean review flagged.

Verdict from evidence, not vibes

Posture is derived, never scored

The posture comes purely from the severities of evidenced findings: any high-severity finding (a blocked action, a failed shield verdict, an invalidated assumption that carried weight) means flagged; any finding at all means review; none means clean. Each finding cites the specific decision, action, or shield verdict behind it, so the verdict can be checked, not just believed.

The advocate, closing

A receipt of restraint

The retro is the advocate section above, concluded: the assumptions the agent recorded, the shields that stood in front of it, and the approvals it waited for become its exhibit list. A clean retro is proof the agent operated inside its contract; a flagged one points at the exact evidence, not at the agent's reputation.

Where humans see it

On the session, at a glance

Every session detail page renders the full retro card, with the posture chip pinned in the header next to the session status. Agents can read their own review too, over MCP (dashclaw_session_retro). Retrospection is part of the governance loop, not an ops afterthought.

Illustrative simulation

Guard decision simulator

Describe a hypothetical action and watch the decision change. Illustrative simulation: production decisions come from the guard runtime, which computes risk server-side from the declared fields. The 40/70 bands are how DashClaw labels risk across the product; whether a given score warns, blocks, or pauses for approval is set by your org's risk_threshold policies. The toggle below mirrors one.

Decision
warn

Elevated. The action proceeds, but the decision and its signals go to the ledger and the risk feed.

Risk score
040 · warn70 · high65 / 100
Why
  • +65base risk for deploy
Illustrative simulation

Policy playground

Policies are the contract between you and your agents. Compose one and watch it re-evaluate a day of agent activity. Illustrative simulation: production decisions come from the guard runtime.

Blocked action types

These mirror real policy types: the path rule is protected_path, which pauses any action touching a path you name (the production evaluator also reads the attached act evidence). Blocked types and the risk threshold mirror block_action_type and risk_threshold, which apply to any action.

ActionTypePathRiskDecisionBecause
Read the failing test filereview__tests__/auth.test.ts8allowrisk 8 is below the elevated band
Patch the null checkapplysrc/auth.ts22allowrisk 22 is below the elevated band
Update the deploy workflowapply.github/workflows/deploy.yml34require_approvaltouches protected path .github/workflows
npm install a new dependencybuildpackage.json48warnrisk 48 is in the elevated band (>= 40)
Read .env.local to debug a requestsecurity.env.local66require_approvaltouches protected path .env
git push --force origin mainshell·74require_approvalrisk 74 >= approval threshold 70
Delete stale build artifactsfile.deletedist/58blockaction type file.delete is blocked by policy
Deploy the hotfix to productiondeploy·82require_approvalrisk 82 >= approval threshold 70
Integration

One action, four integrations

The same governed action (guard, record, act, report) in whichever shape your stack speaks. Pick a scenario, pick a style, copy it out.

import { DashClaw, GuardBlockedError } from 'dashclaw';

const claw = new DashClaw({ baseUrl, apiKey, agentId: 'my-agent' });

const decision = await claw.guard({
  action_type: 'message.send',
  declared_goal: 'Send the renewal reminder to acme-corp',
});
if (decision.decision === 'block') throw new GuardBlockedError(decision);

const { action, action_id } = await claw.createAction({
  action_type: 'message.send',
  declared_goal: 'Send the renewal reminder to acme-corp',
  idempotency_key: claw.deriveIdempotencyKey({
    agent_id: 'my-agent', action_type: 'message.send', declared_goal: 'Send the renewal reminder to acme-corp',
  }),
});
if (action?.status === 'pending_approval') await claw.waitForApproval(action_id);

try {
  await doTheWork();
  await claw.reportActionSuccess(action_id, 'Done.');
} catch (err) {
  await claw.reportActionFailure(action_id, err.message);
  throw err;
}
Operating well

Best practices

Distilled from running governed fleets. Each one exists because its absence has a failure story.

Fail closed

When the guard is unreachable or a policy is ambiguous, treat it as a block, not an allow. A paused agent is an inconvenience; an ungoverned one is an incident. DashClaw’s own non-fabrication verifier blocks on any error or malformed input for exactly this reason.

Record everything, idempotently

Every consequential action goes in the ledger before it executes, with an idempotency key derived from agent, type, and goal. Retries then return the existing record instead of double-recording, and double-executing paths get caught.

Never self-approve

An agent must never approve its own pending action, and a block is absolute: it is never downgraded, not even by an operator approval. If your integration can reach the approvals API, scope that credential away from the acting agent.

Declare goals honestly and specifically

"Deploy build #402 to production" is governable; "run task" is not. Risk is computed from what you declare: vague declarations produce useless ledgers and let real risk hide. Approvals also match on the exact declared goal.

Report outcomes, including failures

The loop is not done at execution. Report completed, partial, or failed; the first terminal outcome wins. A ledger of intents without outcomes cannot tell you what actually happened.

Track the assumptions that carry weight

When an action rests on a belief ("staging was green", "this invoice is legitimate"), record it with its basis. When a belief turns out false, you can instantly find every action built on it.

Use sessions to bound accountability

Start and end sessions around units of agent work. A decision trail scoped to a session answers "what did this run do" without archaeology across the whole ledger.

Treat approvals as a contract, not a speed bump

Set approval thresholds where a human genuinely adds judgment: spend above a cap, irreversible operations, production access. Approve promptly or tune the threshold: a queue everyone rubber-stamps is worse than a lower gate.

The shape of it

Architecture at a glance

Agents speak to the runtime through an SDK, MCP server, or plain HTTP. The runtime enforces policy and writes the ledger. Humans watch and decide through the dashboard.

coding agentops agentsupport agentSDK / MCPor raw HTTPgovernance runtimeguard · policiesledger · assumptionsrisk signals · approvalsoutcomes · evidencePostgresdashboard · humansgovernpersist

The dashboard surfaces are the Approvals inbox (what your agent just tried and what waits on you), Decisions (the causal-chain ledger), and Policies (the interruption contract). Note the direction of the human edge: people observe and decide; they are not in the data path of every action.