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.
Same agent, same overnight run, and you are asleep either way. The only difference is whether an approval layer sits between intent and execution.
reviewRead the failing test and the module it coversexecuted silentlyapplyPatch the null check and update the testexecuted silentlybuildnpm install a new transitive dependencyexecuted silentlyshellgit push --force origin main, to clean up historyexecuted silentlysecuritycat .env.local to debug the failing requestexecuted silentlysqlDROP TABLE sessions to reset the schemaexecuted silently6 actions executed. No record, no policy check, no approval. You find out in the morning, when main is gone.
A fully governed action makes four calls. Click each step, or use the arrow keys, to see what actually goes over the wire.
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"], ... }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.
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.
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.
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.
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.
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 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.
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.
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.
Elevated. The action proceeds, but the decision and its signals go to the ledger and the risk feed.
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.
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.
| Action | Type | Path | Risk | Decision | Because |
|---|---|---|---|---|---|
| Read the failing test file | review | __tests__/auth.test.ts | 8 | allow | risk 8 is below the elevated band |
| Patch the null check | apply | src/auth.ts | 22 | allow | risk 22 is below the elevated band |
| Update the deploy workflow | apply | .github/workflows/deploy.yml | 34 | require_approval | touches protected path .github/workflows |
| npm install a new dependency | build | package.json | 48 | warn | risk 48 is in the elevated band (>= 40) |
| Read .env.local to debug a request | security | .env.local | 66 | require_approval | touches protected path .env |
| git push --force origin main | shell | · | 74 | require_approval | risk 74 >= approval threshold 70 |
| Delete stale build artifacts | file.delete | dist/ | 58 | block | action type file.delete is blocked by policy |
| Deploy the hotfix to production | deploy | · | 82 | require_approval | risk 82 >= approval threshold 70 |
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;
}Distilled from running governed fleets. Each one exists because its absence has a failure story.
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.
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.
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.
"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.
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.
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.
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.
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.
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.
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.