The v0.5 series transforms ButterClaw from a reactive threat detector into a full autonomous security operating system. Four pillars — each building on the last — give the Sentinel persistent memory, remote reach, multi-step reasoning, and credential lifecycle management. Here's everything that shipped.
v0.5.0 โ The Nervous System
ShippedApril 14, 2026
The foundational release. ButterClaw gained persistent memory through the Event Ledger and remote reach through SSE transport. The Brain is no longer an amnesiac — it has temporal behavioral tracking. And the Claws can now execute on remote MCP servers without changing a single line of tool logic.
Event Ledger
server.pyPersistent, append-only SQLite audit log for every MCP tool invocation. Every call is logged before dispatch (status: pending) and updated on completion (success / error / timeout). Two new API endpoints for querying the ledger with filters.
SSE Transport
mcp_transport.pyDecoupled I/O layer with StdioTransport and SSETransport. The MCP server is now transport-blind — run the Brain locally on a protected network while remote Claws communicate back via SSE. Zero tool logic changes required.
Memory Injection
server.pyThe Brain now receives a sliding window of the last 5 successful ledger events as timeline_context in every prompt. Temporal behavioral tracking — the Sentinel can spot patterns across multiple invocations instead of evaluating each log entry in isolation.
Ledger UI
routing.htmlFull Event Ledger section in the routing dashboard. Timeline view of recent tool invocations with expand-to-see-result, tool and status filters, and auto-refresh. Every MCP action is visible and auditable from the browser.
server.py), not the child (butterclaw_mcp.py). The child doesn't know it's being audited. This preserves the decoupled sentinel architecture — the Claws execute, the API observes.
v0.5.0.1 โ Patch Stabilization
HotfixApril 14, 2026
A targeted hotfix addressing edge cases discovered immediately after the v0.5.0 launch. No new features — pure reliability hardening for the Event Ledger and SSE transport layer.
Stabilization Fixes
server.py · mcp_transport.pyHardened the SSE reconnection path in the transport layer. Fixed edge cases in ledger timestamp formatting and ensured ledger_log_end() always commits on the same database connection as ledger_log_start(). Tightened error handling in the MCP status endpoint when the transport mode switches between stdio and SSE mid-session.
v0.5.1 โ Tool Chaining
ShippedApril 15, 2026
The Brain learned to think in sequences. Instead of the hardcoded execute_gibson_kill โ rotate_keys response to every CRITICAL verdict, the LLM can now compose custom multi-step tool chains with conditional logic between steps. The hardcoded fallback is preserved for backward compatibility — the chain is an upgrade path, not a replacement.
ChainExecutor
server.pyNew execution engine that intercepts the "chain" array from the Brain's JSON output. Iterates through steps sequentially, evaluates conditions using a safe operator whitelist (no eval()), and routes each tool call through mcp_manager.send(). Safety rails: 10-step maximum, 60-second cumulative timeout.
Condition Evaluator
server.pyWhitelist-based operator dictionary: contains, not_contains, equals, not_equals, starts_with. Case-insensitive, whitespace-stripped. Unknown operators cause the step to be skipped (not crash). Zero use of eval() anywhere in the codebase.
Ledger Chain Grouping
routing.htmlThe Event Ledger UI now visually groups chain events by chain_id. Chain blocks show a consolidated header with step count, aggregated status icons (โ
โโญ๏ธโฑ๏ธ), and individual step-number badges. Standalone events render normally alongside chain groups.
Oopsie Card Chain Links
index.htmlCRITICAL alerts triggered by a chain now render a violet "โ๏ธ Multi-Step Chain" badge in the action field, alongside a "View in Ledger โ" link to trace the full execution path. Detects Chain [ pattern in the action string.
buttervault.butter_keys() is hardcoded outside the chain loop. Even if the LLM forgets to include rotate_keys in its chain, the Vault is always Buttered on CRITICAL. The chain is an optimization — the kill switch is non-negotiable.
ledger_log_start() without a corresponding ledger_log_end(), leaving orphaned "pending" rows in the ledger. Patched in v0.5.2 — failed steps now close out as status="error" with the exception message.
v0.5.2 โ ButterVault OAuth
ShippedApril 16, 2026
The final pillar. The ButterVault evolved from a static key locker into a full credential lifecycle manager. ButterClaw now speaks OAuth 2.0 — it can authenticate with external providers, encrypt and store structured token payloads, silently refresh expired tokens, and atomically destroy everything on panic. Google Cloud (Gemini API) is the first live provider. Zero new dependencies. Zero new files.
Encrypted Token Storage
buttervault.pyOAuth payloads (access token, refresh token, expiry, token type, scope) are serialized to JSON and encrypted using the same Fernet + OS keyring pipeline. Separate oauth_tokens SQLite table — same encryption, clean schema separation. Five new functions: store_oauth_token(), get_oauth_token(), delete_oauth_token(), list_oauth_providers(), refresh_token_if_needed().
OAuth 2.0 Flow
server.pyFull authorization code flow via four new endpoints. CSRF state tokens (secrets.token_urlsafe(32)) with 10-minute TTL. Client credentials stored in the Vault itself (Option C architecture). Self-closing callback popup with postMessage to the opener window. Google-specific: access_type=offline + prompt=consent for refresh token acquisition.
Automatic Token Refresh
buttervault.pyrefresh_token_if_needed() transparently checks expiry with a 60-second safety buffer. If stale, it POSTs the refresh token to the provider, re-encrypts the new access token, and updates the Vault. Handles rotating refresh tokens. The Sentinel never goes blind because a token expired during an attack.
Gibson Destroys Everything
buttervault.pybutter_keys() now atomically destroys both the vault table (static API keys) AND the oauth_tokens table (OAuth payloads). Provider-scoped destruction hits both tables too. The Sovereign Seal holds — OAuth tokens are mathematically annihilated alongside static keys.
| Endpoint | Method | Description |
|---|---|---|
/api/vault/oauth/start/<provider> |
GET | Generate CSRF-protected authorization URL, return to frontend for redirect |
/api/vault/oauth/callback |
GET | Validate state, exchange code for tokens, seal in Vault |
/api/vault/oauth/status |
GET | Connection status of all OAuth-capable providers |
/api/vault/oauth/revoke/<provider> |
POST | Best-effort remote revocation, then unconditional local deletion |
By the Numbers
v0.5.0 โ v0.5.2
| Pillar | Version | What It Does | Files |
|---|---|---|---|
| Event Ledger | v0.5.0 |
Persistent audit trail for every MCP tool call | server.py, routing.html |
| SSE Transport | v0.5.0 |
Remote MCP servers via Server-Sent Events | mcp_transport.py, server.py |
| Tool Chaining | v0.5.1 |
Multi-step conditional tool sequences | server.py, routing.html, index.html |
| ButterVault OAuth | v0.5.2 |
Full OAuth 2.0 lifecycle + token management | buttervault.py, server.py |
| File | v0.5.0 | v0.5.1 | v0.5.2 | Role |
|---|---|---|---|---|
server.py |
Ledger + SSE + Memory | ChainExecutor + Brain prompt | OAuth endpoints + CSRF | Central nervous system |
buttervault.py |
— | — | OAuth storage + Gibson update | Credential lifecycle |
mcp_transport.py |
Stdio + SSE transports | — | — | I/O decoupling |
routing.html |
Ledger UI | Chain grouping | Version bump | Observability dashboard |
index.html |
Ledger nav link | Chain badges | — | Main dashboard |
butterclaw_mcp.py |
No changes across entire v0.5 series | MCP tool server | ||
The Full Stack (Post v0.5)
Safety Rails
| Rail | Implementation | Version |
|---|---|---|
No eval() |
Whitelist-based operator dictionary for chain conditions | v0.5.1 |
| Chain limits | 10-step max, 60-second cumulative timeout | v0.5.1 |
| Sovereign Seal | butter_keys() hardcoded outside chain loop — always fires on CRITICAL |
v0.5.1 |
| CSRF protection | secrets.token_urlsafe(32) with single-use validation + 10-min TTL |
v0.5.2 |
| Client secrets server-side only | Stored in ButterVault, read by Flask — never touch the frontend | v0.5.2 |
| Token refresh buffer | 60-second pre-expiry buffer prevents race conditions | v0.5.2 |
| Gibson destroys OAuth | Both vault + oauth_tokens tables annihilated atomically |
v0.5.2 |
| Audit child is blind | Ledger lives in parent process; MCP child doesn't know it's being audited | v0.5.0 |
What's Next
The v0.5 series is complete. All four pillars are shipped. The Sentinel has memory, remote reach, multi-step reasoning, and credential lifecycle management. The v0.6 chapter opens up new territory:
- Multi-agent coordination — multiple Brain instances sharing a single Event Ledger
- Policy engine — declarative threat response rules beyond LLM reasoning
- Production hardening — TLS, Flask API authentication, deployment packaging
- Provider expansion — GitHub, Anthropic/Claude OAuth integration via the registry
- ButterVault UI modal — OAuth "Connect" buttons with live connection status