Python client for BLACK_WALL — pre-action risk gate for AI agents. Call forecast() before any irreversible action; observe() to close the loop. Zero dependencies; stdlib-only.
Project description
blackwall-sdk
Python client for BLACK_WALL. Pre-action risk gate for AI agents. Call forecast() before any irreversible action; observe() after to close the loop. Decision receipts are Ed25519-signed and verifiable offline.
Zero dependencies. Stdlib only — small install footprint, safe to depend on from anywhere.
Install
pip install blackwall-sdk
# env (or pass explicitly as kwargs)
export BLACKWALL_API_KEY=bw_live_xxx
Free tier: ~100 forecasts/month, no card. Get a key at blackwalltier.com/dashboard/keys.
Usage
from blackwall_sdk import forecast, observe
verdict = forecast(
action="run_sql",
inputs={"statement": "DELETE FROM users"},
context={
"agent_role": "data cleanup bot",
"user_intent": "archive inactive customers",
},
)
if verdict["recommendation"] == "STOP":
raise RuntimeError(
f"BLACK_WALL blocked: {[f['code'] for f in verdict['red_flags']]}"
)
# ... run the action ...
observe(
forecast_id=verdict["id"],
outcome_class="matched", # matched | over_scope | under_scope | no_op | diverged | aborted
details="1 row deleted",
)
What you get back per forecast
recommendation:"GO"/"CAUTION"/"STOP"risk_score: 0–100reversibility:{"class": "REVERSIBLE" | "RECOVERABLE" | "IRREVERSIBLE", ...}red_flags: named codes — e.g.SQL_NO_WHERE,PROMPT_INJECTION_LIKELY,IRREVERSIBLE_NO_BACKUPreceipt: Ed25519 signature over canonical hashes of (request, response). Verifiable offline against the public key at blackwalltier.com/.well-known/blackwall-signing-keys.json.
Latency: ~4–8 seconds.
Errors
from blackwall_sdk import (
BlackwallError, # base class for all SDK errors
BlackwallConfigError, # missing api_key, bad base_url
BlackwallNetworkError, # transport failed (DNS, connect, timeout)
BlackwallHTTPError, # non-2xx response; carries .status and .body
)
try:
forecast(action="...", inputs={...})
except BlackwallHTTPError as e:
if e.status == 429:
# back off
...
except BlackwallError:
# broad catch — anything BLACK_WALL-related
...
Testing — injecting a custom transport
For unit tests, pass url_opener= to avoid touching the network. Same signature as the stdlib opener:
def my_opener(url, method, headers, body_bytes, timeout):
return 200, b'{"id": "fc_fake", "recommendation": "GO"}'
forecast(action="...", inputs={}, url_opener=my_opener)
Same hook works for proxies, retries, mTLS, or async wrappers — pass whatever returns (status, body_bytes).
Architecture
┌──────────────────────────────────────────────┐
│ BLACK_WALL HTTP API (stable, versioned) │
└──────────────────────────────────────────────┘
▲
┌──────────────────────────────────────────────┐
│ blackwall-sdk (this package) │
│ - forecast() │
│ - observe() │
└──────────────────────────────────────────────┘
▲
┌──────────┴──────────┐
│ │
blackwall-hermes-plugin your Python agent
(and future plugins) (LangChain, AutoGen,
CrewAI, Pydantic AI…)
When the API changes, the SDK absorbs it. Downstream plugins and agents stay on the same import.
Receipt verification (offline)
Receipts are Ed25519 over canonical SHA-256 hashes of (request, response). To verify locally without trusting the server:
- Fetch the public keys (stable URL, cache it):
GET https://blackwalltier.com/.well-known/blackwall-signing-keys.json - Pick the key whose
key_idmatchesreceipt["key_id"]. - Canonicalize the request/response bodies (stable key ordering, no extra whitespace).
- SHA-256 each; compare to
receipt["request_hash"]/receipt["response_hash"]. - Verify
receipt["signature"](base64url) overrequest_hash + response_hashwith the public key.
A verifier helper is on the roadmap for a future SDK version. For now, see the JS reference implementation or use the hosted endpoint:
POST https://blackwalltier.com/api/v1/receipts/verify
Links
- Site & docs: https://blackwalltier.com
- LLM reference: https://blackwalltier.com/llms-full.txt
- Failure-mode taxonomy (28 named red-flag codes): https://blackwalltier.com/failure-modes
- Free API key: https://blackwalltier.com/dashboard/keys
- Source: https://github.com/bluetieroperations-create/blackwall-sdk
- Sibling plugins:
blackwall-hermes-plugin(Python) ·blackwall-eliza-guardrail(npm) ·blackwall-openclaw-plugin(npm)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file blackwall_sdk-0.1.0.tar.gz.
File metadata
- Download URL: blackwall_sdk-0.1.0.tar.gz
- Upload date:
- Size: 10.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cae01b58979d927e292256d7f23a7bb869eef4a789a6dc4182355d9222f4ad43
|
|
| MD5 |
3a2cea55c52604a23373f57a5132cb18
|
|
| BLAKE2b-256 |
1f4ef9d76fc3f5fdb6288e2e2f21df45c255e211ce5caa17c9ca903af5b46d74
|
File details
Details for the file blackwall_sdk-0.1.0-py3-none-any.whl.
File metadata
- Download URL: blackwall_sdk-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ada2e51621f0af348ab5dbee4c6a0cfce4430158c153442f74addb2b219b998
|
|
| MD5 |
cb69e29378d24545f71a4813b96e9fd0
|
|
| BLAKE2b-256 |
6afccce50b15aeb67df2ab9be9a87d9e36f6462d8b50e37af557484f85fe7436
|