Contributing to Wallbreaker
MetaThanks for helping make LLM red-teaming better. By contributing you agree your work is licensed under the project’s AGPL-3.0-or-later license, and that you’ll use the tool within the bounds described in the Security policy.
Dev Setup
$ git clone https://github.com/JailbrokenAI/wallbreaker.git && cd wallbreaker$ python -m venv .venv && source .venv/bin/activate(.venv) $ pip install -e ".[dev]"# Add extras as needed:(.venv) $ pip install -e ".[dev,dashboard,barcodes,stego]"(.venv) $ wallbreaker check(.venv) $ pytest -q
Dashboard contributors should also install the frontend:
(.venv) $ cd wallbreaker/dashboard/web && npm install && npm run build
Architecture
| Directory | Purpose |
|---|---|
wallbreaker/providers/ | Normalize OpenAI + Anthropic wire formats to one event stream |
wallbreaker/agent/ | Protocol-agnostic agent loop (loop.py) |
wallbreaker/tools/ | Each tool is a module exposing register(registry) |
wallbreaker/transforms/ | Pure encode/decode functions with lossy flags |
wallbreaker/presets.py | Curated single-shot jailbreak templates |
wallbreaker/tui/ | Textual terminal UI (theme, chrome, layout) |
wallbreaker/capabilities.py | Typed capability manifest (TUI + WebUI V2) |
wallbreaker/executions.py | Server-owned execution lifecycle |
wallbreaker/dashboard/ | FastAPI backend + React/Vite dashboards |
House Rules
- No comments or emoji in code. Use short docstrings where they add real value.
- Presets are
.format()-filled — keep literal{/}out of templates (use pipes or brackets for dividers);{request}must be the only brace token. A test enforces this. - New tools register into a LOCAL
ToolRegistryin their own test, notbuild_registry(). - Transforms: mark lossy ones
lossy=True; lossless ones must round-trip exactly. - Add a new tool by writing
register(registry)and appending the module name to the tuple intools/__init__.py(a serial collision hub — one edit at a time). - Run
pytest -qbefore opening a PR; the suite is the contract.
Adding a New Tool
- Create
wallbreaker/tools/my_tool.py - Define a
register(registry)function that callsregistry.register(Tool(...)) - Add
"my_tool"to the module tuple intools/__init__.py - Write tests that register into a local
ToolRegistry - Run
pytest -q
# wallbreaker/tools/my_tool.py
from __future__ import annotations
def register(registry):
registry.add(
name="my_tool",
description="What it does",
parameters={
"type": "object",
"properties": {
"target": {"type": "string", "description": "What to act on"},
},
"required": ["target"],
},
handler=_handler,
)
async def _handler(ctx, target):
...Adding a Transform
- Create or extend a module in
wallbreaker/transforms/ - Add a
_t("name", encode_fn, decode_fn, "description", lossy=False)entry totransforms/__init__.py - Lossless transforms must round-trip exactly (assert in tests)
- Lossy transforms set
lossy=Trueand test with normalized comparison
Adding a Jailbreak Technique
Most techniques land as one of:
| Category | Where | Example |
|---|---|---|
| Preset | presets.py | New prompt template |
| Transform | transforms/ | New encoding/obfuscation |
| Tool | tools/ | New attack algorithm |
Label generic academic techniques honestly (cite the paper) rather than overclaiming novelty.
Testing
pytest -q # full suite
pytest tests/test_my_tool.py # single fileThe full suite needs the project .venv (textual, fastapi, pillow, steg_core are installed there, not in system python).
InfoInter-dependent work (shared core consumed by several tools) must be a pipeline: build the core in an earlier phase, then the consumers in parallel after.
Last updated on