Metadata-Version: 2.4
Name: blackwall-sdk
Version: 0.1.0
Summary: 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-URL: Homepage, https://blackwalltier.com
Project-URL: Documentation, https://blackwalltier.com/llms-full.txt
Project-URL: Source, https://github.com/bluetieroperations-create/blackwall-sdk
Project-URL: Issues, https://github.com/bluetieroperations-create/blackwall-sdk/issues
Project-URL: Free API key, https://blackwalltier.com/dashboard/keys
Author-email: BlueTier Operations <bluetier.operations@gmail.com>
License: MIT
License-File: LICENSE
Keywords: agent-governance,ai-agents,ai-safety,blackwall,decision-receipt,guardrails,preflight
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# blackwall-sdk

**Python client for [BLACK_WALL](https://blackwalltier.com).** 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

```bash
pip install blackwall-sdk
```

```bash
# 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](https://blackwalltier.com/dashboard/keys).

## Usage

```python
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–100
- `reversibility`: `{"class": "REVERSIBLE" | "RECOVERABLE" | "IRREVERSIBLE", ...}`
- `red_flags`: named codes — e.g. `SQL_NO_WHERE`, `PROMPT_INJECTION_LIKELY`, `IRREVERSIBLE_NO_BACKUP`
- `receipt`: Ed25519 signature over canonical hashes of (request, response). Verifiable offline against the public key at [blackwalltier.com/.well-known/blackwall-signing-keys.json](https://blackwalltier.com/.well-known/blackwall-signing-keys.json).

Latency: ~4–8 seconds.

## Errors

```python
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:

```python
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:

1. Fetch the public keys (stable URL, cache it):
   `GET https://blackwalltier.com/.well-known/blackwall-signing-keys.json`
2. Pick the key whose `key_id` matches `receipt["key_id"]`.
3. Canonicalize the request/response bodies (stable key ordering, no extra whitespace).
4. SHA-256 each; compare to `receipt["request_hash"]` / `receipt["response_hash"]`.
5. Verify `receipt["signature"]` (base64url) over `request_hash + response_hash` with the public key.

A verifier helper is on the roadmap for a future SDK version. For now, see [the JS reference implementation](https://github.com/bluetieroperations-create/blackwall-mcp/blob/main/lib/forecast.mjs) 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`](https://pypi.org/project/blackwall-hermes-plugin/) (Python) · [`blackwall-eliza-guardrail`](https://www.npmjs.com/package/blackwall-eliza-guardrail) (npm) · [`blackwall-openclaw-plugin`](https://www.npmjs.com/package/blackwall-openclaw-plugin) (npm)

## License

MIT
