DashClaw

September 19, 2026 · View on GitHub

Status: CANONICAL. Adopted 2026-07-06 by the maintainer under Wes's full-product-authority mandate (this session's charge: "decide what the perfect product is given everything you know, then make the repo be exactly that product and nothing else"). This is the ONE product-strategy document. Every document in the Superseded documents list below is historical the moment this file lands. The MAINTAINER.md constitution (§1–§5) remains fully binding and is not touched by this thesis.

How this thesis was reached: nine parallel evidence miners (project memory, maintainer log end-to-end, roadmaps v1–v8, RFCs/architecture, market evidence, code-reality survey, the _archive autopsy, session history, positioning), five candidate product definitions from genuinely different lenses, fifteen adversarial judges, two independent cross-candidate comparators. Both comparators converged on the same physical product and disagreed only on framing. This document is that product, committed.


What DashClaw is

Give unattended AI agents useful work while keeping consequential calls subject to policy and remote human approval.

DashClaw's supported enforcement integrations sit between an agent deciding to call a tool and that tool running. They can hold or cancel calls selected by policy. SDK/API integrations remain cooperative outside those seams: the caller must keep the effect inside the governed execution path.

The whole product is one loop:

  1. Intercept — a PreToolUse hook in Claude Code / Codex / Hermes (plus dashclaw_invoke and the OpenClaw gateway) catches an in-scope tool call before it executes.
  2. Decide — the guard engine risk-scores the call against your policies into the decision lattice allow < warn < allow_contained < require_approval < block (join = max; blocks are absolute).
  3. Approverequire_approval freezes the action and pages a human, who approves or denies with one click, from anywhere — the Approvals inbox, a phone, not a terminal. Protocol-1 clients claim an attempt under current policy before execution; operator and plan authority is consumed atomically at that claim. Standing policy grants are separately scoped, leased, and revocable. A plan step without a submitted act is a goal-bound wildcard, not exact-act approval.
  4. Prove — preserve decision and reported-outcome evidence, with Ed25519 receipts where issued and public verification keys. A liveness probe tests the installed seam and reports stale or unavailable evidence honestly. A receipt does not prove external execution; a probe does not establish continuous or tamper-proof enforcement.

One primary human surface: the Approvals inbox — the live stream of what your agent just tried, the items waiting on you, two buttons per item. Support surfaces only: /setup (first run), /policies (a small set of safety switches + calibration review), /decisions (the audit ledger). Nothing else on the front door.

For whom

A solo developer or small team running long, unattended autonomous coding-agent sessions — overnight runs, CI agents, background fleets — against a real repo and real infrastructure. The person who kicks off a 1–6 hour run, cannot watch every tool call, and is one bad run away from an agent that force-pushes over main, wipes a directory, drops a table, or reads a secret.

Where DashClaw fits: local runtime permission prompts serve the operator who is at the keyboard. DashClaw focuses on unattended work and shared, remote governance:

  • remote/async approval — the agent freezes on the dangerous call and you approve from wherever you are, minutes or hours later;
  • one central policy across supported runtimes and recorded sessions, instead of per-session allowlists;
  • an auditable decision trail, with signed evidence where issued, that records what was blocked or approved and the authenticated principal attributed to the resolution;
  • calibrated interruptions — a distribution-free controller (app/lib/guard/calibration.ts, v4.74.0) that tunes the interruption threshold from your approve/deny stream with a proven false-block bound, so governance earns its interruptions instead of nagging you into disabling it;
  • enforcement liveness — a synthetic probe provides time-bounded, client-reported evidence about the installed seam (v4.75.0), with stale and unavailable states instead of silent green.

Not compliance officers. Not enterprise RBAC buyers. Not general tracing or evaluation shoppers. Not a marketplace, not an agent platform.

Why these pieces and not the others

Every line of evidence converges on the enforcement vertical:

  • It is what the code is objectively best at. The guard engine has dedicated policy, risk, approval, and calibration modules and tests; the runtime hooks are the hottest-churned core; the calibration controller is the one section of the theory doc marked "Implemented", with two proven theorems and a golden-vector corpus; the liveness probe is a hard-won answer to a real, named incident.
  • It is the only value the product has ever demonstrably delivered. Every real catch in the record — rm -rf, DROP TABLE, force-push, .env extraction at risk 100 — is this loop firing. The demo is the product.
  • It is what the constitution is built on. "Blocks are absolute", "no self-approval", "precision of interruption is THE product metric" — verbatim MAINTAINER.md, all pointing at this subsystem.
  • Everything else was either scaffolding for this loop or a different product wearing the same name — and that different product (the agent platform) was already tried, archived (app/api/_archive), regrown, and is the reason ~250 of ~290 active routes contradict the repo's own stated identity ("a minimal governance runtime, not an agent platform").

Enforcement honesty (a standing copy rule)

Enforcement is mechanically real where DashClaw sits in the seam between decide and execute: the Claude Code / Codex / Hermes hooks (fail-closed, exit-2 on block), the OpenClaw gateway, and dashclaw_invoke. Everywhere else (bare SDK/API/MCP callers, desktop chat) governance is cooperative — the 2026 enforcement-boundary ruling that killed the universal proxy stands. Outward copy never implies universal hard enforcement. Claims obey claims-proven-live.

Defaults (the fatigue lesson, encoded)

The only real usage event in the product's history is negative: the reference deployment ran with all policies off for 18 days because the default pack fired an approval roughly every ten seconds. Therefore:

  • The default policy pack is narrowly scoped. Its explicit rules hold protected-target destruction, force pushes, secret-file writes, and classified real-money purchases. A risk score or project cleanup command alone is not a universal hold. The pack source and the instance's active Short List determine the actual interruption set.
  • Calibration ships on, in its constitutional mode. The controller runs from first use; anything that loosens enforcement is a proposal a human ratifies with one click in /policies (constitution §3 — no auto-applied enforcement changes).
  • Fail-closed stays the default at the hook seam, and the liveness probe watches the seam.

Distribution

  • The primary door is the runtime the user already has: one-command plugin install / npx dashclaw up. First protective value lands at install — a working catastrophe pack and a first caught action — no account on the path to first value.
  • The hosted trial (hosted.dashclaw.io) is demoted to the secondary door: "see the Approvals inbox without deploying." It stays alive because the remote-approval wedge needs a reachable server and a zero-infra taste of it is worth operating — but no funnel step points a stranger at a credential before they have seen a block fire. The graduation/export path survives with it.
  • The self-governance story ("an AI maintains this project under its own governance") moves off the front door to an about/proof page. It is supporting evidence, not the pitch.

Explicitly out of scope — what dies

The criterion: if a surface is not on the loop (intercept → decide → approve → prove) or directly supporting it (auth/keys, setup, health), it is not DashClaw.

Dying with this thesis (exhaustive per-surface rationale + last-SHA in the kill ledger, docs/releases/): the agent-platform tier — code sessions/optimal-files/CLAUDE.md generation, capabilities registry (the dashclaw_invoke enforcement seam survives), workflows/work-orders/swarm, prompts library, knowledge/RAG (pgvector), model-strategies/BYOK routing, scoring, reputation/leaderboard, evaluations, learning + behavior learning, drift engine, compliance cockpit (signed receipts/JWKS export folds into the audit layer), messages/threads, handoffs, loops (the 2026-07-09 owner amendment adds a fresh, narrow Team Tasks surface as approval context — it does not revive any of these), launch plans, managed secrets, the status-widget PWA; x402/FinOps/CostClaw surfaces (a separate thesis — spend governance is real but it is not this product; RFC 0002 stays gated on Wes and out of this repo's front door); the MCP server's absorbed provider-tool fork (Stripe/Vercel/Neon/Twilio/Namecheap/Supabase/Sentry — the archived platform re-imported, ~19k lines); the deprecated dashclaw/legacy SDK surface (its removal was already promised for v5); app/api/_archive (48 runtime-dead routes, deleted outright — the fossil taught its lesson); and the process exhaust at the repo root and in docs (superseded specs, logs, media, one-off directories).

The SDKs collapse to the governance core (guard / record / assumptions / approvals / halt / posture and their supporting calls). The MCP server shrinks to the governance toolset. The CLI keeps the install/run/doctor/ approvals path. Plugins keep hook parity across Claude Code / Codex / Hermes.

No destructive database migration ships with the cull (constitution-safe: retired tables stay in place; a documented export-then-drop path can follow separately).

Team/RBAC stays declined (trigger unchanged: a second human governing an org). The TypeScript migration stays declined. Paid tiers stay gated on Wes.

The forward bet stays compatible: the governed-autonomy RFCs (2026-07-06: preflight plan authorization, scoped delegation constraints, containment verdicts) extend this exact loop to plans, delegation, and containment for unattended autonomy. They remain the post-v5 direction.

Owner amendment — 2026-07-09: fleets and teams

Adopted by Wes (owner), full authority. DashClaw's subject is the fleet and the team of agents, not a single agent in isolation — collaboration is a necessity for a great team, and governed collaboration is approval-layer work. "For whom" already said fleets; this amendment makes the multi-agent team a first-class subject of the loop rather than an aggregation of solo sessions.

Concretely: a Team Tasks surface (task + inter-agent event timeline — who leads, who delegated what, which governed actions and approvals each exchange produced) is in scope as approval context and audit, driven by the owner's live Claude Code + OpenClaw two-agent team. It is built fresh and small, on the loop; the cull's kills (work-orders/swarm, messages-threads product, handoffs, loops, routing) stay dead and are not revived. Its surfaces raise the ceilings below in the same commit that adds them, per the brake's own rule. Full reasoning and non-reversals: docs/decisions/2026-07-09-fleets-and-teams.md.

Owner amendment — 2026-09-04: an evolving product, and the next bet

Adopted by Wes (owner), full authority. Three rulings, recorded on the 60-day mark of this thesis.

1. No surface freeze. The maintainer proposed a 30-day freeze on surface growth pending stranger-install data. The owner rejected it: DashClaw is an evolving product and must keep adding capability as AI development improves. The anti-regrowth brake stays exactly as written — every ceiling raise is a recorded, reasoned amendment — but a raise is not a failure of identity when the surface sits on the loop. Falsifier #3 (Regrowth) is re-read accordingly: it watches for un-amended growth and for growth off the loop, not for growth itself.

2. The 60-day regrowth ruling. Between v5.0.0 and today the ceilings moved 117 → 134 routes, 45 → 53 pages, 12 → 17 MCP tools, 28 → 40 Node SDK methods, 14 → 18 policy types. Every step is in the amendment log with a reason, so the brake held mechanically. Read by substance: roughly half of the growth is the governed-autonomy program (plans, delegation, containment, deviation, attestation, role constraints, the approval pause and per-card grants) and is on the loop; the other half is the hosted business layer (usage, claim, team invites, checkout, portal, pricing, Pulse) adopted under docs/decisions/2026-08-09-hosted-paid-tier.md. That layer is named here for what it is — the commercial operation of the control plane, not a governance surface — so that the next reader does not mistake it for the agent-platform regrowth this thesis was written to prevent. Identity held.

3. The next bet: containment beyond files. The forward bet named in "Explicitly out of scope" (the three 2026-07-06 governed-autonomy RFCs) has fully shipped. The thesis now names its successor so the product is not steering by a finished roadmap: extend the containment verdict from the file system to the other effect classes the loop can make reversible, starting with Postgres on Neon (docs/rfcs/2026-09-04-database-containment.md, zero ceiling change). The test for each extension is the same one the original containment RFC set: a cheap, isolated, self-cleaning medium exists for the effect, the operator reviews evidence once, and promotion is a single-use, act-hash-bound grant. Effects with no such medium (payments, message sends, deploys) stay on the require_approval rail.

The 2026-09 outsider review that prompted this amendment also proposed an infrastructure proxy, adversarial self-testing of policy changes, a compliance export, and enterprise-framework wrappers. The proxy stays dead under the enforcement-boundary ADR; the golden-vector corpus already is the self-test; the compliance buyer and the framework wrappers stay outside "For whom". One verification came out of it: the liveness probe already reads a removed PreToolUse entry as unprovablebroken, and a fully stripped hook set as stale within 24h, surfaced as a posture finding — so falsifier #6 holds for the tamper case the review raised.

Falsification — what would prove this thesis wrong

Criteria that fire without strangers (the last eight eras prove stranger cohorts cannot be assumed):

  1. Intrusiveness (7 days, any installs): if >50% of installers disable enforcement within their first week — a repeat of the 18-day incident — the checkpoint cannot be lived with as shipped.
  2. Shippability (continuous): if a factory-fresh machine cannot go from install to first-block-and-one-click-approve in ≤10 minutes (the entry drills, v4.76.0, pin this), the product fails its own legibility bar.
  3. Regrowth (60 days): if the surface budget (below) is raised without a thesis amendment, the identity did not hold and this document failed.

Criteria that need real external use (honest status: demand is un-refuted, not proven — attention remains the owner's lever, per MAINTAINER.md §4):

  1. Value (30 days from ≥10 stranger installs): fewer than 2 reach "agent blocked → I approved → agent continued" → the value prop is wrong, not the friction.
  2. Differentiation: if adopters use only the ledger and never the blocking, observability — not enforcement — is what they wanted, and the axis is wrong.
  3. Provable enforcement: if the liveness probe or an audit surfaces another silent fail-open on a user's machine, "provable enforcement" is false and this is advisory tooling.

The measurement window (July 19–20) — ruling

The v8.1 cohort read (≥2026-07-19) and v8.6 exit read (≥2026-07-20) still run as scheduledscripts/measurement-read.mjs survives, the dates hold, and the verdicts get written. A product built on claims-proven-live does not delete its own instrument days before it fires. But the window is demoted from steering gate to honesty artifact: the v8.5 "branch selected by the read" mechanism is superseded — this thesis IS the branch decision, made on product-definition grounds under the owner's mandate. The read's arithmetic (cohort n, per-channel bySource) gets recorded against the OLD door and becomes the baseline the new falsifiers are judged against.

The anti-regrowth brake

The 2026-03 purge (178→5 SDK methods, 142 routes archived) regrew to full sprawl within four months, and the "Governance Boundary CI check" it promised never shipped. This time the brake is mechanical and shipped: a surface-budget gate in CI (scripts/check-surface-budget.mjs, npm run surface:check, wired into .github/workflows/ci.yml alongside the other contract gates). It counts every governed surface each run — active API routes, pages, MCP tools, MCP resources, Node + Python SDK methods, CLI commands, guard policy types — and fails the build when any exceeds its v5.0.0 ceiling. Exceeding a ceiling fails the build unless the commit also amends this document with a written reason. Sprawl becomes a deliberate, recorded act instead of a drift.

The adopted ceilings — set to the exact live count at v5.0.0, and the machine source of truth for the gate, live in contracts/surface-budget.json:

SurfaceCeilingCounted from
Active API routes136app/api/**/route.{js,ts,tsx} (must export ≥1 HTTP method)
App pages54app/**/page.{js,jsx,ts,tsx}
MCP tools17mcp-server/src/tools.ts
MCP resources3mcp-server/src/resources.ts
Node SDK methods41sdk/dashclaw.js (scripts/count-sdk-methods.mjs)
Python SDK methods61sdk-python/dashclaw/client.py (scripts/count-sdk-methods.mjs)
CLI commands15cli/bin/dashclaw.js (COMMAND_HANDLERS)
Guard policy types20app/lib/guard/policy.ts (KNOWN_POLICY_TYPES)

(This table mirrors contracts/surface-budget.json as of 2026-09-15; it had drifted from the JSON across several amendments — the JSON is the machine source of truth, the amendment log below is the history.)

Raising any ceiling requires amending this section and contracts/surface-budget.json in the same commit with a written reason — the recorded, deliberate act that falsifier #3 (Regrowth) watches for.

Amendment log:

  • 2026-09-15 — Guard policy types 19 → 20 (verification_contract). An LLM verifier catches only what the specification named. Where an obligation was never written down and no convention settles it, the verifier is not failing to reason — it is reasoning correctly over an input that does not contain the answer, and it reports the same confidence it uses when it is right. The measurement this type responds to (Sienkowski, Verifier Reach Is Spec Reach, 2026): a confident false pass on 100% of runs with the edge omitted [94–100], converting to a 98% catch [91–100] once the same edge is written into the spec; model-invariant, and a ~30x spend increase recovers none of it. So the caller attaches the contract its work was specified against, each obligation carrying a verification tier, and this type disposes of the ones that cannot be discharged: a violated item blocks, a test-tier check nobody ran blocks (fail closed — an unrun check is not evidence), and an obligation the spec never settled routes to a human as insufficient_spec rather than collecting a confident green. It does not fold into an existing type. require_evidence escalates when an act arrived without its evidence — a property of the act, not of the spec the act was judged against. non_fabrication compares outbound content to a source of truth — fidelity, not obligation coverage. green_contract reads an observed build level and has no per-obligation tier and no third state. The distinct thing here is that third state: every other type answers pass or fail, and this one can answer "the artifact does not contain the answer," which is the only honest verdict on a blind spot and the one the measurement shows a verifier will otherwise never give. Escalation-only by construction — the validator refuses any disposition other than require_approval or block, so a contract can add a gate and never remove one, and a dishonest client gains at most the verdict it would have had with no contract at all. Off by default: no default pack ships it, and require_contract is false, so an existing install is unchanged until an operator creates the policy. Zero new API routes, zero new pages, zero new tables, zero new migrations, zero new MCP tools, zero new SDK methods, zero new CLI commands.

  • 2026-09-08 — API routes 135 → 136 (POST /api/actions/[actionId]/cancel). The cancellation seam for actions that were approved but should not run. A running or pending action that is unclaimed and unexecuted can be cancelled atomically: the route sets status to cancelled with close_source='direct', writes a "Deliberately not executed…" summary, leaves the outcome pending (no fabricated success/failure), and audits + publishes the update. Once claimed, executed, or terminal the route returns 409. Without it an approved-but-unwanted action has no governed off-ramp — the operator's only choices are letting it run or killing it outside the ledger, which is the ungoverned path the brake exists to close. Requires a trimmed, redacted, capped reason. Zero new policy types, zero new tables, zero new pages, zero new SDK methods, zero new MCP tools.

  • 2026-09-19 — App pages 54 → 55 (/terms). A Terms of Service page. The Meta Muse connector directory (muse.ai/platform) requires a terms URL on every submission, and the hosted trial had none: /privacy says what we store, not what a user agrees to by signing in or authorizing a connector. A legal page, not an agent surface. Zero new API routes, zero new policy types, zero new SDK methods, zero new MCP tools.

  • 2026-09-08 — App pages 53 → 54 (/guides/muse). The Muse (Meta) agent integration guide. Each supported runtime gets its own guide page (precedent: crewai, hermes, langgraph, openclaw); the Muse content cannot fold into an existing guide because the integration is cooperative — no pre-tool-call hook exists in that runtime yet — so the setup, the guard/record/wait/act/outcome loop, plan-first execution, and the stated enforcement boundary are a different document from every mechanical-hook guide. Zero new API routes, zero new policy types, zero new SDK methods, zero new MCP tools: a docs surface only, shipped on PR #233.

  • 2026-09-08 — API routes 134 → 135 (POST /api/calibration/misses). The miss_review tightening channel for the calibration controller. The controller learned only from interruptions — benign approvals loosened θ, denials tightened it — so actions the guard waved through were never labeled at all: allowed false negatives were invisible and θ ratcheted to its ceiling (2026-09-08: θ 101.8, at which point no score could interrupt). A miss files a verdict on a specific allowed action that should have been held: dangerous folds at weight 1 and tightens θ but moves no agent's e-process (agent identity lives in the audit event only); benign is ledger-only. Admin-only; the risk score is server-derived from the persisted action row, never client-supplied; only actions with a persisted allow/warn are missable. Zero new policy types, zero new tables (one additive miss_review source value on approval_adjudications), zero new pages. Ships with a poison-row guard on the proposals path (PostgreSQL 16 pg_input_is_valid gating the context::json cast) so one malformed guard_decisions.context can no longer 500 the whole endpoint.

  • 2026-09-05: Node SDK methods 40 to 41, Python SDK methods 60 to 61 (claimExecution, claim_execution). The audit found that approval selection alone did not bind execution to a single attempt. These methods expose the existing action route's protocol-1 claim: exact act, credential principal, agent, current policy, and atomic authority consumption. The governed helpers call them before the effect callback. No new route or operator surface is added. This strengthens the execution boundary rather than expanding the agent's work capabilities.

  • 2026-09-01 — API routes 133 → 134, Node SDK methods 39 → 40, Python SDK methods 59 → 60 (/api/plans/[planId]/attest, attestPlan, attest_plan). Plan Attestation (v5.28.0), the run-start seam for unattended agents. Preflight Plan Authorization already binds each STEP by act_content_hash, but nothing pinned the plan as a whole and nothing gave a runner a place to ask, at wake, whether the authority it is about to spend is still live. plan_hash is that pin; the attest seam is the question. A runner posts the hash it was authorized under and gets a yes, or one of not_found | not_approved | expired | revoked | hash_mismatch — and fails closed before its first model call. Pins authority by content hash rather than by plan id, so a plan edited or re-approved out from under a paused runner cannot be resumed against silently; every attestation, pass or fail, is journaled on the row. Adapted from memcode's autonomous-agent wake design. Zero new tables (four additive columns on plan_authorizations), zero new policy types, zero new pages, no change to guard evaluation. The route was not foldable into the existing POST /api/plans/[planId]: that path is the OPERATOR verdict behind admin + attributable-principal auth, and this one is the constrained agent asking about its own authority — merging them would put an agent-facing call behind an admin credential or an admin verb behind an agent one.

  • 2026-08-20 — App pages 54 → 53 (/calibration folded into /policies#calibration). The Short List (docs/superpowers/specs/2026-08-20-policies-calibration-onboarding-redesign.md). app/calibration/page.jsx is deleted; next.config.js gains a permanent redirect from /calibration to /policies#calibration, per THESIS's own scoping of that surface as safety switches plus calibration review. Zero routes changed; the section runs on the same /api/calibration/controller pair. First entry in this log that moves a ceiling down.

  • 2026-08-14 — App pages 53 → 54 (/policies/packs). The Pack Gallery (RFC docs/rfcs/2026-08-14-policy-pack-gallery.md, approved by Wes). The pack catalog has existed since v4.x but was buried inside the Import modal on /policies — a capability with no browsable human surface. The gallery is browse/compare across 18 packs with a per-pack "preview against my history" dry run before install; that interaction cannot fold into the ledger without overloading it (the same judgment that folded /policies/rules IN applies here in reverse — the ledger is one rule set, the gallery is a catalog of candidate rule sets). Zero new API routes: the gallery rides the existing /api/policies/templates, /simulate (extended to accept { pack }), and /import.

  • v5.0.0-rc final-fix — Active API routes 117 → 118. Restored a slim, read-only, org-scoped GET /api/agents. The cull removed the full agent-roster route but three live UI callers (the shared agent-filter picker, the identities fleet view, the policy CustomTab agent dropdown) plus the MCP evidence probe still fetched it, so every authenticated page shipped a console 404. The restored route lists distinct agents from action_records via the surviving repository; it does not revive the fleet-observability surface the cull deleted.

  • v5.0.0-rc final-fix — App pages 46 → 45 (ratchet down). Deleted app/actions/[actionId]/page.tsx, a duplicate replay view the cull's own inventory marked KILL but never removed; its two inbound links were repointed to the canonical /decisions/[actionId]. The ceiling ratchets down so regrowth back to the deleted page trips the brake.

  • 2026-07-08 — App pages 45 → 46 (port, not sprawl). The /explain marketing explainer already existed as a hand-authored static file (public/explain/index.html) carrying its own drift-prone mirror of the site navbar — invisible to this counter. It was ported to app/explain/page.tsx sharing PublicNavbar/PublicFooter, and the static file plus its next.config.js rewrite were deleted. The count rises because an existing surface became countable, not because a surface was added.

  • 2026-07-10 — Active API routes 118 → 121 (fleets-and-teams amendment). Three routes for the Team Tasks surface (/api/team-tasks, /[taskId], /[taskId]/events) adopted by the 2026-07-09 owner amendment: the multi-agent task timeline as approval context. Fresh, org-scoped, repository-backed; no culled surface revived.

  • 2026-07-10 — App pages 46 → 47 (fleets-and-teams amendment). Added /team-tasks: the live multi-agent task timeline in the Govern group. One page; its timeline component lives under _components/.

  • 2026-07-10 — MCP tools 12 → 15 (fleets-and-teams amendment). Three dashclaw_task_* tools so both team agents write the Team Tasks timeline through governed, authenticated API calls.

  • 2026-07-10 — Node SDK methods 28 → 31 (fleets-and-teams amendment). Thin wrappers for the three Team Tasks routes. Python SDK deliberately not extended (team agents write via MCP/HTTP).

  • 2026-07-26 — Preflight Plan Authorization (governed-autonomy feature 1). Active API routes 121 → 123, MCP tools 15 → 17, Node SDK methods 31 → 36, Python SDK methods 51 → 56. The thesis's forward bet (governed autonomy) begins shipping: an agent submits its intended plan, the operator reviews one card, approved steps become single-use act-scoped grants — N mid-run interruptions become one upfront review with MORE context, not less. Every new surface sits directly on the loop: plans are intercepted intent, reviewed by a human, provable in the decision ledger (builtin:plan_grant provenance). RFC: docs/rfcs/2026-07-06-preflight-plan-authorization.md.

  • 2026-07-27 — Active API routes 122 → 123 (Containment Verdicts, feature 3; counter methodology aligned to the canonical inventory in the same change). One route, POST /api/actions/[actionId]/containment — the operator's promote/discard verdict on a guard-contained (allow_contained) action. On the thesis loop by construction: a staged file-scoped effect runs unattended, the operator reviews the diff once, and promote raises a single-use act-scoped grant (containment_promote, act-content-hash bound to git merge --no-ff <containment_ref>) provable in the decision ledger — the same intercept → decide → approve → prove shape as plan grants, applied to effects that already ran instead of ones about to run. RFC: docs/superpowers/plans/2026-07-27-containment-verdicts.md. The baseline shown here is 122, not the previously-recorded 123: countApiRoutes() (contracts/surface-budget.json's gate) used to raw-glob every route.{js,ts,tsx} file, while the canonical docs/api-inventory.json generator (discoverApiRoutes()) only counts a file that exports at least one HTTP method — a gap app/api/auth/[...nextauth]/route.ts (no exported method) fell into, pre-dating this branch. The ceiling number changed because the COUNTING METHOD changed to match the canonical source, not because a route was removed; every doc now agrees at 123 live routes.

  • 2026-07-26 — Scoped Delegation Constraints (governed-autonomy feature 2). Guard policy types 14 → 15, Node SDK methods 36 → 37, Python SDK methods 56 → 57. delegation_constraint makes a composed subagent's effective authority a provable subset of its parent's — risk ceiling, action-type allow/block lists, path scope, spawn depth, optional verified-identity requirement — enforced on every guard call from a parent:child identity. That enforcement trusts the identity the caller asserts in agent_id; pair require_verified_parent: true with Phase-2 JWKS identity for a cryptographic claim instead of a self-reported one. No-surface economy: this is a policy type layered on the existing evaluator map, the existing /policies rails, and one convenience wrapper per SDK — no new tables, no new routes, no MCP changes. The evaluator only escalates (require_approval or block); attenuation only tightens, never grants. RFC: docs/rfcs/2026-07-06-scoped-delegation-grants.md.

  • 2026-07-27 — Containment Verdicts SDK parity (feature 3). Node SDK methods 37 → 39, Python SDK methods 57 → 59. resolveContainment/ resolve_containment (operator promote/discard on a contained action) and listContained/list_contained (list by containment_status) — thin wrappers over the one route this feature added (see the apiRoutes 122 → 123 entry above). Neither SDK ever sends client_capabilities, so a bare SDK caller can never receive allow_contained from guard() itself; these methods only manage rows that reached awaiting_promotion some other way. RFC: docs/superpowers/plans/2026-07-27-containment-verdicts.md.

  • 2026-07-27 — CLI commands 13 → 14 (dashclaw contained group). The Containment Verdicts governed-merge CLI: dashclaw contained list|diff|apply — list actions awaiting promotion, print a contained action's captured patch, and (once an operator has promoted from the dashboard) run the governed merge itself. One top-level command housing a runSubcommand group, the same pattern as install/codex, not three separate top-level commands. RFC: docs/superpowers/plans/2026-07-27-containment-verdicts.md.

  • 2026-08-07 — App pages 47 → 48 (/agents, agent-onboarding pass). One public marketing page: the "tell your agent to set DashClaw up" runbook, human-readable twin of the new /llms.txt route (routes under app/llms.txt/ are not pages and do not move this counter). Exists so the zero-human setup path (npx dashclaw up --yes --no-browser) is discoverable by the agents being asked to run it; the hosted-trial door stays deliberately human-gated (Turnstile). Static content, no data access, shares PublicNavbar/PublicFooter. Not a revival of any culled surface.

  • 2026-08-07 — Active API routes 123 → 124 (synthetic-traffic retention sweep). One route, GET /api/cron/synthetic-sweep — a CRON_SECRET-gated daily GC that deletes synthetic-agent (smoke/loadtest/bench/CI) action_records rows older than DASHCLAW_SYNTHETIC_RETENTION_DAYS (default 7). Companion to hiding synthetic agents from listAgentsForOrg by default (same change): without this sweep, test traffic never leaves the ledger and pollutes the agent roster and calibration data indefinitely. Org-scoped (DASHCLAW_SYNTHETIC_SWEEP_ORG, default org_default) deliberately, since test/test-% could name a real hosted-tenant agent elsewhere. Reuses the existing listActionIdsByFilter/deleteActionsByIds repository primitives (same shape as the filtered-delete audit path); no new tables, no MCP/SDK surface.

  • 2026-08-09 — Active API routes 124 → 125 and app pages 48 → 49 (GET /api/usage + /usage, hosted-tier metering G4). The decision record docs/decisions/2026-08-09-hosted-paid-tier.md rules that hosted ceilings and prices are set only after a per-org metering rollup exists and has been run against real usage. This is that rollup's read surface: one caller-org-scoped, read-only route over the new usage_rollups table (governed actions + seats per month), and one read-only dashboard page so a human can see the numbers without curl. Measurement only — no entitlement enforcement reads these counters. Not a revival of the culled FinOps/spend surface: no costs, no budgets, no x402, no billing routes.

  • 2026-08-09 — Active API routes 125 → 127 and app pages 49 → 51 (/api/hosted/claim + /claim, /api/team/invites + /team; hosted-tier accounts G2). The same decision record rules "accounts before billing: you cannot bill an anonymous trial cookie." This is the account layer: claiming binds an anonymous trial org to an authenticated owner without losing its decisions history (the org stops expiring; anonymous cookie access to it ends), and email-matched invites make seats a real, countable thing (a teammate's first sign-in joins the org — no invite emails, no join links, no new auth surface). Not a revival of the culled team/invite routes: no tiers are read, nothing is gated, and the only new table is seat_invites (the legacy token-based invites table stays retired in place on long-lived databases).

  • 2026-08-09 — Active API routes 127 → 130 (/api/billing/checkout, /api/billing/portal, /api/webhooks/stripe; hosted-tier checkout). The decision record's build order put checkout last, after accounts and metering became true; both shipped earlier the same day, so this is that final step. Unlike the culled 2026 billing surface this one is repository-only SQL, carries a webhook idempotency ledger (stripe_webhook_events), and bills only claimed workspaces. Not a revival of plan-quota monetization: nothing reads plan to gate a governance capability — the gating principle ("no tier ever lacks a safety feature") holds by construction until the entitlement work defines capacity ceilings.

  • 2026-08-09 — Active API routes 130 → 131 and app pages 51 → 52 (GET /api/widget/pulse + /widget, DashClaw Pulse). An always-on-top ambient posture surface for the operator who is deliberately NOT watching — the thesis's "ignore your agents safely" made visible: one glyph that is a dim dash when nothing is owed and the pending-approval count when something is, with approval always outranking signals and honesty rules that forbid a dead pipe from rendering as calm. Design chosen by a judged tournament and recorded in docs/decisions/2026-08-09-widget-pulse.md. Not a revival of the culled status-widget PWA (which stays in the kill list): no PWA manifest, no service worker, no prefs/settings, no stat tiles, no action log, no approve/deny (read-only slice 1); one read-only route composed from existing repositories, no new ingestion, no new tables.

  • 2026-08-10 — Guard policy types 15 → 16 (role_constraint, role "workbenches"). A named authority bundle for top-level agents: the policy row is the role, its agent_ids scoping is the membership, and the rules (allowed/blocked action types, risk ceiling, path scope) are the workbench — everything outside the bundle escalates to approval or block instead of running, so an out-of-role attempt lands in the Approvals inbox with what the agent reached for. Structurally delegation_constraint without the composed-id gate: tighten-only, layered on the existing evaluator map and /policies rails. No new tables, routes, pages, MCP tools, or SDK methods. Explicitly NOT a revival of the culled capabilities registry or managed secrets — the credentials half of the original "workbench" concept stays dead. Spec: docs/superpowers/specs/2026-08-10-role-constraints-design.md.

  • 2026-08-13 — Guard policy types 16 → 17 (deviation_response). Per-kind consequence for plan-vs-actual deviation — the follow-on the preflight-plan RFC explicitly deferred, now that the runtime records the diff it always computed and threw away (consumePlanStepGrant's no-match branch). Detection and recording are unconditional and policy-free: a fresh install records and renders deviations with zero behavior change, and no policy row is installed by default. This type only maps a deviation kind (act substitution, scope escape, unplanned action, goal drift…) to warn / require_approval / block — tighten-only, layered on the existing evaluator map and /policies rails, with escalate_action as an explicit ceiling so blocking is an operator's opt-in act. Rejected the zero-budget alternative (folding deviation severity into risk) because it collapses qualitatively different kinds into one dial. No new routes, pages, MCP tools, or SDK methods; one new unbudgeted table (plan_deviations). RFC: docs/rfcs/2026-08-11-plan-deviation-events.md. (Prior: 2026-08-10 15 → 16 role_constraint.)

  • 2026-09-05 — Guard policy types 17 → 18 (assumption_hold). Turns the advisory assumption alert into authority. When an operator invalidated an assumption the agent had recorded, the runtime already told the agent — assumption_alerts rides on the guard response and the pretool hook prints it — but the verdict stayed allow. That is the gap this thesis exists to close: the agent's permission was still valid while its current authority was not, because the evidence it acted on had gone stale, and the agent read the notice and kept going. This type holds the agent family's next action above a risk floor until a human confirms it, with the reason naming the assumption. Hold, never block, by default: escalate_action is require_approval unless the operator opts into block, and relief is the normal path, not an exception — the rule evaluates inside runLocalPolicies, ahead of both grant passes, so approving the held action, a "don't ask again" shape grant, or simply the window elapsing all clear it. It keys on the assumptions table rather than the notification's read state, because the hook acks that message the moment it prints it; client hooks therefore need no change. Rejected the zero-budget alternative (raising risk when an invalidation is recent) because a risk nudge is not an authority statement and cannot name which assumption went stale. No new routes, tables, migrations, pages, MCP tools, or SDK methods. Default packs gain it only under night-shift and evidence-first. (Prior: 2026-08-13 16 → 17 deviation_response.)

  • 2026-08-09 — App pages 52 → 53 (/pricing). Reinstated per docs/decisions/2026-08-09-hosted-paid-tier.md, which reverses the 2026-05-14 "retract the monetization surface entirely" decision (ef8bb678) on the record, loudly and dated, the same standard this thesis holds users' agents to. The rule the retraction set stays intact: self-hosted DashClaw is free, complete, and MIT forever, and the page says so plainly. What changed is that hosted.dashclaw.io, the control plane we operate, now charges for running that plane on someone else's behalf — capacity and operations (seats, action ceilings, retention, support), never a governance capability. Not a revival of the culled MON-01 counter or Pro-tier framing: no live counter, no trigger metric, fixed prices instead.

  • 2026-08-12 — Active API routes 131 → 132 (/api/approval-pause). The bounded, self-expiring approval pause: while it is live a require_approval verdict proceeds instead of waiting for a human. It earns a surface because the alternative is the one MAINTAINER.md already records — "all org policies were turned off for 18 days in June 2026 because of friction". An operator who cannot get relief takes it by deleting their policy set, and gets no expiry, no banner, and no record. This route is that act made bounded (1/4/8/24h windows only), reversible (policy rows are never touched, so expiry restores the exact prior posture), loud (banners on /policies and /approvals), and honest (the decision is stamped "proceeded under an operator pause", never "approved"). It cannot downgrade a block, and it cannot clear a verdict raised by an ungrantable rule, so the control plane still interrupts. No new table — the state is one settings key riding the guard's existing category-general read, so the hot path costs no extra query.

  • 2026-08-12 — Active API routes 132 → 133 (/api/approvals/[actionId]/grant). "Allow, don't ask again" on the approval card. It earns a surface for the same reason the approval pause above does, one step earlier: the repeat interruption is what drives an operator to turn governance off, and until now the only cure for it lived on /policies — a different page from the one being interrupted. The allow_grant engine already existed and was already hardened; what did not exist was a way for a human to reach it from the card that is bothering them. It stays inside the thesis loop rather than widening it. The route mints nothing new: same allow_grant policy type, same shape coordinate system, same F1 unscoped-grant rejection, same ungrantable gate, same lease. It approves nothing either — it returns the ids its grant covers and the client releases them over the existing per-item approval route, so there is exactly one approval path carrying one audit, webhook and calibration chain. It also closes a hole rather than opening one. allow_grant had no risk ceiling, so any grant cleared require_approval at any score for its whole lease. Grants are now born with max_risk: 70, a missing ceiling reads as 70 rather than unlimited, and the card withholds the button above that line instead of selling an authorization the guard would refuse. Net governance strength goes up, not down. No new table, no new policy type, no SDK or MCP change.

Version story

This cull ships as v5.0.0 — the major break the removal list demands, and the version at which the deprecated legacy SDK surface was already promised to disappear. Migration notes accompany the release; every removed surface is recoverable by SHA via the kill ledger.

Superseded documents

Historical as of this file (retained under docs/plans/archive/ where not already archived; superseded ≠ erased):

  • docs/plans/owner-roadmap.md (v8 "the vigil") — v8.1/v8.6 reads carried into this thesis's measurement ruling; v8.4 (health floor) absorbed into ordinary maintenance; v8.5 (branch) superseded by this thesis.
  • docs/plans/archive/owner-roadmap-v1-v3.md, -v4.md, -v5.md, -v6.md, -v7.md (already archived; now closed).
  • docs/plans/2026-04-03-dashclaw-layered-intelligence.md, 2026-06-12-layered-intelligence-rebaselined.md, 2026-06-12-posture-score-rebaseline.md — the platform-convergence era.
  • docs/plans/dashclaw-hardening.md, dashclaw-hardening-report.md, typescript-migration.md (declined a seventh and final time under this thesis: mechanical churn, zero behavior change).
  • docs/plans/platform-convergence.md + status/evidence companions.
  • docs/rfcs/0001-generative-ui-governance.md (three-product company) and docs/rfcs/0002-costclaw-dashclaw-integration.md (open-core paid add-on) — archived as presuming a different product; the CostClaw/x402 money gate (§8, Wes) is unchanged by this thesis.
  • Executed one-off specs in docs/plans/2026-07-* (identity, approvals hygiene, guard deadline/noise, load-harness scope, HX retro audit, explain-claims audit) — their contributions live in the code and this document.
  • The three 2026-07-06 governed-autonomy RFCs are not superseded; they are the forward direction, re-grounded on this thesis.

Relationship to MAINTAINER.md

The constitution (§1–§5) binds this thesis and everything built under it. MAINTAINER.md's introductory thesis paragraph ("protects agents … from being weaponized, blamed unfairly, or bankrupted") is broader than this product: the "blamed unfairly" direction survives here as the signed audit/evidence layer; the "bankrupted" direction (spend governance) is out of scope per this thesis. Per §5, the maintainer does not edit that file unilaterally: a proposed amendment aligning its thesis paragraph with this document is prepared for Wes's ratification and travels with the release notes.