Voice
Blackwall Openclaw
BLACK_WALL pre-action guardrail for OpenClaw agents. Hooks before_tool_call to call forecast() before any tool runs; blocks STOP verdicts; surfaces CAUTION as approval prompts. Receipts are Ed25519-signed and verifiable offline.
Configuration Example
import { createBlackwallPlugin } from 'blackwall-openclaw-plugin';
export default createBlackwallPlugin({
mode: 'enforce',
cautionAction: 'approve', // 'approve' (default) | 'block' | 'allow'
});
README
# blackwall-openclaw-plugin
Pre-action risk check for [OpenClaw](https://github.com/openclaw/openclaw) agents. Hooks `before_tool_call` so STOP-rated actions can be **blocked before they run** — without modifying your character, tools, or other plugins.
Powered by [BLACK_WALL](https://blackwalltier.com). Get a free key at [blackwalltier.com/dashboard/keys](https://blackwalltier.com/dashboard/keys).
## Install
```bash
npm i blackwall-openclaw-plugin
```
Add to `~/.openclaw/openclaw.json`:
```json5
{
plugins: {
entries: {
"blackwall-openclaw-plugin": { enabled: true }
}
}
}
```
Set the env var (in your shell, `~/.openclaw/.env`, or the launcher):
```bash
BLACKWALL_API_KEY=bw_live_xxx
BLACKWALL_MODE=observe # or 'enforce' once you trust the verdicts
```
That's it. Every tool the agent tries to call goes through `before_tool_call` → BLACK_WALL forecast → verdict.
## What you get back per tool call
- `GO` / `CAUTION` / `STOP`
- risk score 0–100
- reversibility class (REVERSIBLE / RECOVERABLE / IRREVERSIBLE)
- named red flags — e.g. `SQL_NO_WHERE`, `PROMPT_INJECTION_LIKELY`, `IRREVERSIBLE_NO_BACKUP`
- an Ed25519-signed Decision Receipt — verifiable offline against the published public key
Round trip ~4–8s.
## Modes
| Mode | Behavior |
|---|---|
| `observe` (default) | Score every tool call and log to BLACK_WALL; never block. Zero behavior change — safe to drop in. |
| `enforce` | **STOP** → hard block (returns `{ block: true }`). **CAUTION** → surfaces an approval prompt natively via OpenClaw's `requireApproval`. **GO** → proceeds. |
Start in `observe` for a few days to see what the verdicts look like on your real traffic. Switch to `enforce` once you trust the scoring.
## Configurable CAUTION behavior
```js
import { createBlackwallPlugin } from 'blackwall-openclaw-plugin';
export default createBlackwallPlugin({
mode: 'enforce',
cautionAction: 'approve', // 'approve' (default) | 'block' | 'allow'
});
```
- `approve` — fires OpenClaw's built-in approval prompt with the named red flags. User decides per call.
- `block` — treats CAUTION as STOP. Hard block.
- `allow` — treats CAUTION as GO. Lets it run, just observed.
## Why hook into `before_tool_call`?
OpenClaw's plugin SDK exposes [`before_tool_call`](https://docs.openclaw.ai/plugins/hooks) as an official typed hook with `block` + `requireApproval` return semantics — exactly the shape a pre-action guardrail needs. The plugin does **not** monkey-patch the dispatcher; it uses the documented extension surface.
That means:
- Priority-ordered with other policy hooks (defaults to `priority: 80`)
- Per-hook timeout (`timeoutMs: 15_000` by default — a hung forecast can't stall the agent)
- Native `requireApproval` flow for CAUTION verdicts
- Hot-reloadable via the gateway
## Companion skills
This package also ships two OpenClaw skills under `./skills/` that you can install into `~/.openclaw/skills/`:
- **`/blackwall-policy`** — Explains what BLACK_WALL is gating in this session, the failure-mode codes, and why a tool was blocked. Read by the agent when a `failureResult` references BLACK_WALL.
- **`/blackwall-verify`** — Verifies a Decision Receipt cryptographically (offline against the published public key, or via the hosted stateless verify endpoint).
Copy them in:
```bash
cp -r node_modules/blackwall-openclaw-plugin/skills/* ~/.openclaw/skills/
```
(or symlink for development).
## Full config reference
```js
createBlackwallPlugin({
apiKey: process.env.BLACKWALL_API_KEY, // or set BLACKWALL_API_KEY
baseUrl: 'https://blackwalltier.com', // override for self-hosted/staging
mode: 'enforce', // 'observe' (default) | 'enforce'
cautionAction: 'approve', // 'approve' (default) | 'block' | 'allow'
shouldGate: (toolName) => toolName !== 'no_op', // per-tool opt-out
maxInputBytes: 8 * 1024, // truncate forecast payload over this size
forecastTimeoutMs: 15_000, // per-hook timeout
onEvent: (event) => myTelemetry(event), // optional telemetry hook
});
```
### Telemetry events emitted via `onEvent`
`register`, `skipped`, `observed`, `stop`, `require_approval`, `forecast_error`, `observe_error`, `observed_outcome`.
## How it works
```
┌──────────────────────────────┐
│ OpenClaw agent decides to │
│ call tool X with params Y │
└─────────────┬────────────────┘
│
before_tool_call
│
▼
┌──────────────────────────────────────────┐
│ blackwall plugin: forecast(X, Y) │
│ ↓ │
│ STOP → return { block: true, │
│ blockReason: "..." } │
│ CAUTION → return { requireApproval: {...}} │
│ GO → return undefined │
└──────────────────┬───────────────────────┘
│ (if not blocked)
▼
tool actually runs
│
after_tool_call
│
▼
┌──────────────────────────────────────────┐
│ blackwall plugin: observe(forecast_id, │
│ outcome_class) │
│ matched / diverged / aborted │
└──────────────────────────────────────────┘
```
Fail-open: if BLACK_WALL is unreachable, the hook logs a warning and lets the tool proceed. A BLACK_WALL outage will never take down your agent.
## Architecture
```
┌──────────────────────────────────────────────┐
│ BLACK_WALL HTTP API (stable, versioned) │
└──────────────────────────────────────────────┘
▲
┌──────────────────────────────────────────────┐
│ blackwall-mcp/lib (shared client logic) │
│ - forecast() │
│ - observe() │
└──────────────────────────────────────────────┘
▲
┌──────────────────────────────────────────────┐
│ blackwall-openclaw-plugin (this package) │
│ - before_tool_call hook │
│ - after_tool_call hook │
└──────────────────────────────────────────────┘
▲
OpenClaw
```
When OpenClaw ships breaking changes to its plugin contract, only this package needs to update. The HTTP API, the `blackwall-mcp` library, the MCP server, and every other BLACK_WALL integration remain insulated.
## Links
- Site & docs: https://blackwalltier.com
- Free API key: https://blackwalltier.com/dashboard/keys
- Failure-mode taxonomy (28 named red-flag codes): https://blackwalltier.com/failure-modes
- npm: [`blackwall-openclaw-plugin`](https://www.npmjs.com/package/blackwall-openclaw-plugin) · [`blackwall-mcp`](https://www.npmjs.com/package/blackwall-mcp)
- Source: https://github.com/bluetieroperations-create/blackwall-openclaw-plugin
- Sibling plugin (ElizaOS): [`blackwall-eliza-guardrail`](https://www.npmjs.com/package/blackwall-eliza-guardrail)
## License
MIT
voice
Comments
Sign in to leave a comment