SignalForge helps local AI agents check claims, find evidence, and answer with the right level of confidence
Project description
SignalForge Firewall: Receipts for AI answers.
SignalForge is a local-first Evidence Firewall for AI answers: it gives local models live web context, then stops them from repeating claims that are unsupported, contradicted, stale, or sourced from weak evidence.
SignalForge is not a generic chatbot and not a generic RAG app. It is a claim-level evidence control layer for Ollama, Open WebUI, AnythingLLM, MCP tools, and local agent workflows.
Core loop:
Answer -> Receipt -> Snapshot -> Replay
Why This Exists
Local models are useful, private, and cheap to run. The moment you give them web access, they inherit the web's problems: copied rumors, stale pages, thin sources, prompt injection, private-network fetch risks, and confident claims that trace back to one weak origin.
Normal RAG retrieves context. SignalForge decides what the model is allowed to say.
The product promise is simple:
- Receipts for AI answers
- Git commits for AI answers
- Evidence Firewall for local AI
- Local models can now refuse unsupported claims
- MCP needs a firewall
What It Does
SignalForge takes a claim or model answer and produces a signed Evidence Receipt:
- normalizes the claim
- classifies risk domain and verifiability
- searches through local SearXNG
- optionally fetches, extracts, hashes, sanitizes, and redacts source text
- scores support strength, source independence, source reputation, freshness, copy-chain risk, prompt-injection risk, and contradiction pressure
- assigns a FIRE permission
- stores a replay snapshot
- renders JSON, Markdown, share text, receipt card data, and a downloadable receipt bundle
- exposes graph, replay, policy, receipt, OpenAI-compatible proxy, browser extension, and MCP surfaces
FIRE permissions:
VERIFIED
SUPPORTED
WEAKLY_SUPPORTED
RUMOR_ONLY
UNSUPPORTED
CONTRADICTED
EXPIRED
BLOCKED
60-Second Demo
Start the stack:
docker compose up -d --build
docker exec signalforge-firewall-ollama-1 ollama pull qwen2.5:3b-instruct
open http://localhost:4011
Verify a claim:
curl -X POST http://localhost:4010/v1/firewall/verify-claim \
-H "Content-Type: application/json" \
-d '{"claim":"Company X officially confirmed a partnership with Company Y","mode":"strict"}'
Then open:
curl http://localhost:4010/v1/firewall/receipt/<run_id>/card
curl http://localhost:4010/v1/firewall/receipt/<run_id>/markdown
curl http://localhost:4010/v1/firewall/replay/<run_id>
Screenshot placeholders for launch assets:
docs/assets/dashboard-claim-verifier.pngdocs/assets/receipt-card.pngdocs/assets/evidence-graph.pngdocs/assets/replay-snapshot.png
Quickstart With Docker
cp .env.example .env
docker compose up -d --build
open http://localhost:4011
Services:
- API: http://localhost:4010
- Dashboard: http://localhost:4011
- SearXNG: http://localhost:8089
- Ollama: http://localhost:11434
- Qdrant: http://localhost:6333
- Neo4j Browser: http://localhost:7474
- Optional Open WebUI profile: http://localhost:3000
Optional Open WebUI profile:
docker compose --profile openwebui up -d --build
Quickstart With Python
pnpm install
uv sync --extra dev
uv run pytest
uv run signalforge serve
Dashboard in another shell:
cd dashboard
npm install
npm run dev
Dashboard: http://localhost:4011
How agents should use SignalForge
SignalForge is not only a yes/no checker. It tells an agent how strongly it may speak.
SUPPORTEDorVERIFIED: the agent can answer normally and include the source.WEAKLY_SUPPORTED: the agent should use attribution, for example “DW reports that...”.UNSUPPORTED,CONTRADICTED, orBLOCKED: the agent should not state the claim as fact.
A single strong source should count as useful evidence, but multiple independent sources are still better for high-confidence claims. See docs/AGENT_USE_CASES_AND_SCORING.md.
CLI Usage
The package installs both signalforge and sf:
sf verify "Company X confirmed a partnership with Company Y"
sf search "Company X Company Y official confirmation"
sf answer "Did Company X confirm a partnership with Company Y?" --with-receipt
sf receipt <run_id>
sf replay <run_id>
sf inspect examples/sample_answer.md
sf doctor
sf policy list
sf policy show finance
REST API Examples
Verify a claim:
curl -X POST http://localhost:4010/v1/firewall/verify-claim \
-H "Content-Type: application/json" \
-d '{"claim":"The company officially confirmed the partnership.","mode":"strict"}'
Search evidence:
curl -X POST http://localhost:4010/v1/firewall/search \
-H "Content-Type: application/json" \
-d '{"query":"official source partnership confirmation","mode":"research","max_results":5}'
Inspect a model answer:
curl -X POST http://localhost:4010/v1/firewall/inspect-answer \
-H "Content-Type: application/json" \
-d '{"answer":"Company X confirmed the deal. Analysts expect the stock to double.","mode":"strict"}'
Receipt exports:
curl http://localhost:4010/v1/firewall/receipt/<run_id>
curl http://localhost:4010/v1/firewall/receipt/<run_id>/card
curl http://localhost:4010/v1/firewall/receipt/<run_id>/markdown
curl -OJ http://localhost:4010/v1/firewall/receipt/<run_id>/bundle
curl http://localhost:4010/v1/firewall/replay/<run_id>
Policy packs:
curl http://localhost:4010/v1/firewall/policies
curl http://localhost:4010/v1/firewall/policies/medical
OpenAI-Compatible Proxy
SignalForge exposes an OpenAI-compatible chat endpoint:
POST http://localhost:4010/v1/chat/completions
Point Open WebUI, AnythingLLM, or an OpenAI-compatible local client at:
Base URL: http://localhost:4010/v1
API key: local
Model: your local upstream model name
SignalForge forwards to OPENAI_PROXY_UPSTREAM_URL, inspects the upstream answer claim by claim, and rewrites the output when claims are downgraded or blocked.
Open WebUI / Ollama
Default Docker wiring:
OPENAI_PROXY_UPSTREAM_URL=http://ollama:11434/v1
OLLAMA_BASE_URL=http://ollama:11434
Open WebUI should use:
OpenAI-compatible base URL: http://signalforge-firewall:4010/v1
API key: local
See docs/integrations/OPEN_WEBUI.md.
MCP Firewall
SignalForge includes an optional MCP server and a tool-call firewall. The firewall provides:
- allowlist and denylist controls
- private IP, localhost, metadata IP, and
.localblocking - URL validation
- basic argument schema validation
- risk labels
- clear denial reasons
Run:
sf mcp
See docs/MCP_TOOLS.md.
Evidence Map
SignalForge includes an Evidence Map that explains why a claim received its FIRE permission. The default view is now Why this verdict?, which shows the conclusion path instead of dumping every relationship at once.
The map supports:
- guided conclusion layout
- support, contradiction, independence, receipt, replay, and full explorer modes
- mouse wheel zoom
- drag-to-pan
- minimap overview
- keyboard shortcuts:
+,-,f,0 - plain-language verdict explanation panel
See docs/GRAPH_REDESIGN_SPEC.md.
Browser Extension
The alpha browser extension supports:
- right-click selected text -> Verify with SignalForge
- local API verification
- notification with permission and proof score/share text
- popup with copy proof text
- open dashboard receipt
Load integrations/browser-extension as an unpacked Manifest V3 extension. See docs/integrations/BROWSER_EXTENSION.md.
Receipt Card Example
{
"title": "SignalForge FIRE Receipt",
"subtitle": "Evidence-limited proof card",
"run_id": "sf_1234",
"claim": "Company X officially confirmed a partnership with Company Y",
"permission": "RUMOR_ONLY",
"confidence": 0.42,
"independent_source_count": 1,
"contradiction_count": 0,
"replay_url": "/v1/firewall/replay/sf_1234",
"markdown_url": "/v1/firewall/receipt/sf_1234/markdown",
"bundle_url": "/v1/firewall/receipt/sf_1234/bundle",
"share_text": "Evidence-limited proof card: ...",
"signed_metadata": {
"signature_algorithm": "hmac-sha256"
}
}
Security And Privacy Notes
SignalForge is local-first and does not require paid APIs. It can run with Ollama, SearXNG, Neo4j, Qdrant, and local storage.
Alpha safety controls include:
- local/metadata/private-IP blocking in fetch and MCP tool paths
- bounded fetch size, timeout, content-type checks, and redirect limits
- prompt-injection warning and sanitizer heuristics
- optional minimized snapshots
- optional PII redaction for stored extracted text
- domain allowlist and blocklist settings
- robots/opt-out placeholder hooks for teams to wire into their own source policy
Careful wording: SignalForge helps teams apply source policies. It does not provide legal advice.
Roadmap
- stronger deterministic claim extraction
- optional local NLI/cross-encoder contradiction profile
- richer replay comparison with live source refetching
- PNG receipt cards
- signed release artifacts
- better browser extension UX
- larger benchmark set
- policy-pack enforcement inside the verifier
- team review and audit workflows
Contributing
Contributions are welcome, but every change must protect the evidence-firewall mission: claim-level evidence control, receipts, snapshots, replay, contradiction detection, source independence, local-first operation, and MCP/tool safety.
Contribution Rules
- All changes must go through a pull request. Direct pushes to
mainare blocked after the initial repository upload. mainis protected. A pull request must pass required CI before it can merge.- At least one approving review is required before merge.
- Reviews are dismissed when new commits are pushed, so reviewers always approve the latest code.
- Force pushes and branch deletion are disabled for
main. CODEOWNERSassigns repository ownership to@karimbaidar; security-sensitive or product-direction changes should wait for owner review.- Keep the project local-first and zero-dollar by default. Do not add paid API dependencies or hosted LLM requirements.
- Do not turn SignalForge into a generic chatbot or generic RAG app.
- Do not rename SignalForge, FIRE receipts, or the FIRE permission model without an explicit product decision.
- Keep public API, receipt, replay, and graph schemas stable unless the pull request clearly documents a breaking change.
- Tests must not call external networks or hosted APIs. Mock SearXNG, Neo4j, Qdrant, Ollama, MCP, and browser-extension integrations.
- Keep pull requests focused. Separate unrelated refactors, feature work, documentation, and release chores.
- Update documentation when behavior, commands, APIs, policies, receipts, or dashboard workflows change.
Required CI
Every pull request must satisfy the repository CI workflow:
python -m pip install -e ".[dev]"
python -m pip check
python -m compileall -q src tests
python -m pytest
cd dashboard && npm ci && npm run build
python -m build
docker compose -f compose.yaml config
The protected branch requires these GitHub Actions checks:
Python 3.11Python 3.12Dashboard buildPackage buildDocker compose config
Start with CONTRIBUTING.md for development setup, product boundaries, and pull request expectations.
Star The Repo
If SignalForge helps your local AI workflow, please star the GitHub repo i.e. https://github.com/karimbaidar/signalforge. Stars make it easier for builders working on local AI safety, agent security, and open-source evidence tooling to find the project.
License
Apache-2.0. See LICENSE.
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 signalforge_firewall-0.1.1.tar.gz.
File metadata
- Download URL: signalforge_firewall-0.1.1.tar.gz
- Upload date:
- Size: 92.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dfe9e9e11522ba875565dd02306f674b7559b542ac1f97342b2ea89b0ddce352
|
|
| MD5 |
b7ebe79a8cd3ca39fb72c3467ce4d05f
|
|
| BLAKE2b-256 |
69cee06eef375cc8c660473bede1f94b7077da3e35d1b124865d1372c67903d8
|
File details
Details for the file signalforge_firewall-0.1.1-py3-none-any.whl.
File metadata
- Download URL: signalforge_firewall-0.1.1-py3-none-any.whl
- Upload date:
- Size: 90.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9872ae931c21bb63047349ea459fd2cb602e50e1c21250c7b1a49b1508e16ef1
|
|
| MD5 |
5c91eee82a583c11f0cef5ceb50ed71b
|
|
| BLAKE2b-256 |
3803b54a9fd8f8d8d05ece97fb55a11a7ef157ed0263ae161a8d2fc094db16ff
|