Download SYSTEM_ANALYSIS_BOOK.md from Architect8999/rhodawk-ai-devops-engine: direct link, hf CLI and curl.
- Browser
- Download file 79.7 kB
-
https://huggingface.co/spaces/Architect8999/rhodawk-ai-devops-engine/resolve/main/SYSTEM_ANALYSIS_BOOK.md
- Command line
-
hf download hf://spaces/Architect8999/rhodawk-ai-devops-engine/SYSTEM_ANALYSIS_BOOK.md
-
curl -L -o SYSTEM_ANALYSIS_BOOK.md https://huggingface.co/spaces/Architect8999/rhodawk-ai-devops-engine/resolve/main/SYSTEM_ANALYSIS_BOOK.md
Rhodawk AI β System Analysis Book
Complete End-to-End Mechanics, Logic, and Operational Reference
Companion to FOUNDER_PLAYBOOK.md β written from the live source tree
Purpose of this document. The existing
FOUNDER_PLAYBOOK.mdis the canonical investor-facing narrative of what Rhodawk does and why it matters. It remains the source of truth for mission, business model, and high-level architecture and is not modified.This book sits beside it and answers a different question: how does every piece actually work, end-to-end, in the code as it stands today? It is written for engineers who must run, debug, extend, or migrate the system, and it intentionally crosses every layer β from Dockerfile, through provider routing, through each Python module, into the MCP servers, into the test suite, and out to the data on disk.
Where the playbook says "the system has a 5-layer safety pipeline," this book says "
process_failing_testinapp.pycallssast_gate.run_sast, which forks bandit and semgrep, parses their JSON, returns aSastVerdictdataclass, and onBLOCKraises an early-exit thatverification_loopconverts into a retry prompt with the SAST critique inlined."Read the playbook for what and why. Read this book for how.
Table of Contents
- Recent Change Log β The Last Mile of Fixes
- Provider Routing β DO Primary, OpenRouter Fallback
- Top-Level Topology
- Container & Build β Dockerfile and Requirements
- Process Map at Runtime
- Master Orchestrator β
app.py - Hermes Six-Phase Pipeline β
hermes_orchestrator.py - Safety Gate Modules
- Memory, Learning, and Data Flywheel
- Autonomous Operation β Harvester, Worker Pool, Job Queue
- GitHub Surface β
github_app.py,webhook_server.py,commit_watcher.py - Red Team & Offense Modules
- Notification, Audit, Disclosure, Bounty
- Architect Subsystem β Tier Routing, Sandbox, Skills, Night Mode
- Mythos Subsystem β Multi-Agent + RL + 17 MCP Servers
- MCP Suite β Every Server, Every Domain
- Test Suite β What Each Test Asserts
- Data on Disk β Files, SQLite Schemas, Audit Chain
- Complete Environment Variable Reference (Updated)
- Failure Modes and Recovery Procedures
- Security Model β Trust Boundaries and Threat Mitigation
- Migration Playbook β HF Space β Paid Server
- Glossary of Internal Names
1. Recent Change Log β The Last Mile of Fixes
The Space went through five iterative dependency-and-build fixes after the
original FOUNDER_PLAYBOOK.md was written at commit 8a23fcf. These changes
do not appear in the playbook because they post-date it. They are critical
to understand because they affect both runtime behaviour (provider selection)
and build behaviour (how the container is assembled).
| Order | Commit | What changed | Why |
|---|---|---|---|
| 1 | 504dde2 |
Added DigitalOcean Serverless Inference as primary, OpenRouter as fallback, in app.py::run_aider and hermes_orchestrator.py::_hermes_llm_call. Added env vars DO_INFERENCE_API_KEY, DO_INFERENCE_BASE_URL, DO_INFERENCE_MODEL, HERMES_DO_MODEL. |
Move the hot path off the OpenRouter free tier (rate-limit-prone) onto DigitalOcean's paid llama3.3-70b-instruct. Keep OpenRouter as resilience. |
| 2 | 1e909b0 |
Bumped aider-chat to 0.87.0 to fix the module 'litellm' has no attribute 'APIConnectionError' crash. |
The aider 0.86.x series hard-pinned litellm==1.75.0, whose top-level module was missing public symbols at runtime. This bump failed because aider 0.87.0 was never published to PyPI. |
| 3 | da5ce03 |
Reverted to aider-chat==0.86.2 and added a Dockerfile post-step: pip install --no-cache-dir --upgrade --no-deps "litellm==1.78.5". |
aider only consumes litellm via getattr and a small public surface; replacing the broken pin with a known-good newer release restores APIConnectionError, _logging, encode, token_counter. |
| 4 | ad06d84 |
Added gitpython==3.1.46 to requirements.txt. |
aider 0.86.2 hard-pins gitpython; pip's resolver was bouncing between our floor (>=3.1.40) and aider's pin. Pinning explicitly removes the resolver thrash. |
| 5 | a913714 |
Switched the Space SDK from gradio to docker in README.md front-matter and bumped gradio>=5.49.0,<6 in requirements.txt. |
HF was auto-injecting gradio[oauth,mcp]==5.29.0 because the Space was registered as sdk: gradio. That injection conflicted with aider's pillow==12.1.1 pin. sdk: docker tells HF to use the existing Dockerfile verbatim, with no auto-injection. |
| 6 | dd4ccce |
Removed aider-chat from requirements.txt entirely. The Dockerfile now installs it with --no-deps plus a curated runtime-deps list. |
Even with sdk: docker, aider's pillow==12.1.1 pin still conflicted with gradio's pillow<12 constraint at the resolver level. --no-deps lets gradio's pillow 11 win, and the curated dep list provides everything aider actually imports at runtime. |
| 7 | current | Aider eliminated entirely. Vendored OpenClaude headless gRPC daemon now drives every code-generation turn. Two daemons (:50051 DigitalOcean primary, :50052 OpenRouter fallback) launched from entrypoint.sh. New Python bridge openclaude_grpc/ exposes run_openclaude(...) with the legacy (combined_output, exit_code) return contract. run_aider is now a thin alias. |
The --no-deps + litellm 1.78.5 + curated 27-package list workaround was a fragile patchwork; any aider/gradio/pillow upstream bump could re-break the build. OpenClaude is a single Bun-built bundle with no Python dependency surface and a stable gRPC contract, so the Dockerfile loses ~30 lines of dependency hacks. |
Net effect today. The Space SDK is docker. The build runs the
Dockerfile end-to-end in three stages: (1) Bun compiles
vendor/openclaude/ to dist/cli.mjs; (2) Python 3.12-slim with system
tooling, uv, Node and Bun is provisioned; (3) the runtime image generates
Python protobuf stubs from vendor/openclaude/src/proto/openclaude.proto
into openclaude_grpc/. requirements.txt no longer mentions
aider-chat, litellm, configargparse, or any of the other 27 curated
aider runtime imports β they have all been deleted. entrypoint.sh
boots the OpenClaude DO daemon on :50051 and (when an OpenRouter key is
present) the OpenClaude OR daemon on :50052, then execs app.py.
Provider behaviour today. When DO_INFERENCE_API_KEY is present the hot
path uses DigitalOcean Serverless Inference at
https://inference.do-ai.run/v1 with model llama3.3-70b-instruct.
OpenRouter is the configured fallback for any non-zero exit, 429, or 5xx.
When DO is absent the system silently runs OpenRouter-only.
2. Provider Routing β DigitalOcean Primary, OpenRouter Fallback
Two independent code paths need an LLM: OpenClaude (the patch generator, replaces aider) and Hermes (the multi-phase research orchestrator + adversarial reviewer). Both are wired to the same provider chain β DigitalOcean Inference primary, OpenRouter fallback.
2.1 OpenClaude path β app.py::run_openclaude (alias run_aider)
entrypoint.sh boots two OpenClaude headless gRPC daemons:
ββ DO_INFERENCE_API_KEY β :50051 (PRIMARY, llama3.3-70b-instruct)
ββ OPENROUTER_API_KEY β :50052 (FALLBACK, qwen-2.5-coder-32b)
run_openclaude(mcp_config_path, prompt, context_files):
β
βββΊ writes /tmp/mcp_runtime.json (the daemon hot-reloads it per chat)
βββΊ forwards prompt + valid context-file list to the bridge
β
βββΊ openclaude_grpc.run_openclaude builds the chain [primary, fallback]:
for each (port, label, model) in chain:
client = OpenClaudeClient(host=127.0.0.1, port=port)
if not client.wait_ready(15s): record + continue
result = client.chat(message, working_directory=REPO_DIR, model=model)
βββ streams text_chunk β result.stdout
βββ streams tool_start β result.tool_calls + stdout marker
βββ streams tool_result β result.stdout / .stderr
βββ auto-replies "y" to any action_required prompt
βββ on done event β exit_code 0
if exit_code == 0: return (combined_output, 0)
return (last_output, last_code)
There is no litellm, no --openai-api-base shell argument, no per-model
prefix munging. Each daemon is launched with OPENAI_API_KEY,
OPENAI_BASE_URL, OPENAI_MODEL set in its own process environment, so
the gRPC client just speaks to whichever port matches the desired
provider. The legacy run_aider symbol is preserved as an alias for
backwards compatibility with the Hermes/SAST/red-team callers.
2.2 Hermes path β hermes_orchestrator.py::_hermes_llm_call
build provider list:
if DO_INFERENCE_API_KEY:
providers.append( ("DigitalOcean", DO_INFERENCE_BASE, DO_KEY, HERMES_DO_MODEL, {}) )
if OPENROUTER_API_KEY:
providers.append( ("OpenRouter", OPENROUTER_BASE, OR_KEY, HERMES_OR_MODEL, {HTTP-Referer: ...}) )
for (name, base, key, model, extra_headers) in providers:
POST {base}/chat/completions with Bearer key, body {model, messages, ...}
on HTTP 429:
sleep exponential(attempt) and retry up to N times
on other 5xx or network error:
record reason, continue to next provider
on 200:
return {"content": choice.message.content, "provider": name, "model": model}
if all providers exhausted:
return {"error": "all providers failed", "details": [...]}
This is implemented in the helpers _post_chat_completion (raw HTTP +
retry), _strip_provider_prefix (litellm-style prefix removal so the
DigitalOcean endpoint sees a clean model name), and _hermes_llm_call
(orchestrates the chain). The same chain is used by adversarial reviewer
calls because they delegate through _hermes_llm_call.
2.3 Why DO first
DigitalOcean's Serverless Inference is paid, predictable, and sized for the hot path. OpenRouter's free tier exists, but rate limits and 429s during adversarial bursts (3 concurrent reviewer models) make it unreliable as a primary. Keeping OpenRouter as a fallback preserves resilience without making the burst case the steady state.
2.4 Required env vars
| Var | Purpose | Default |
|---|---|---|
DO_INFERENCE_API_KEY |
DigitalOcean Serverless Inference key | none β if unset, DO path is skipped |
DO_INFERENCE_BASE_URL |
Endpoint base | https://inference.do-ai.run/v1 |
DO_INFERENCE_MODEL |
Aider's primary model name on DO | llama3.3-70b-instruct |
HERMES_DO_MODEL |
Hermes' primary model name on DO (may differ) | falls back to DO_INFERENCE_MODEL |
OPENROUTER_API_KEY |
OpenRouter key for fallback + adversarial models | none β if unset, OR path is skipped |
HERMES_OR_MODEL |
Hermes' OpenRouter fallback model | qwen/qwen-2.5-coder-32b-instruct:free |
If neither DO nor OpenRouter is configured the system logs a single explicit error per audit. There is no silent degradation β by design.
3. Top-Level Topology
The Space is a single Docker container that runs:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Container (port 7860 exposed, 7861 + 7862 internal) β
β β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββ β
β β Gradio dashboard β β Webhook server β β
β β app.py:demo β β webhook_server.py β β
β β port 7860 β β port 7861 β β
β β 10 tabs + chat inbox β β /webhook/github β β
β ββββββββββββ¬ββββββββββββ ββββββββββββ¬ββββββββββββ β
β β β β
β βββββββββββ¬βββββββββββββββββββ β
β βΌ β
β ββββββββββββββββββββββββββ β
β β enterprise_audit_loop β β background threads dispatched β
β β (app.py) β for each repo audit β
β βββββββββββ¬βββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββ β
β β Worker Pool β β ThreadPoolExecutor, optionally β
β β worker_pool.py β process-isolated per job β
β βββββββββββ¬βββββββββββββββ β
β β β
β βΌ β
β process_failing_test() β¦ 15-step healing loop β
β β
β Background daemons (started conditionally): β
β β’ repo_harvester.py (autonomous target selection, every 6h) β
β β’ commit_watcher.py (silent-patch detection) β
β β’ lora_scheduler.py (training-data export) β
β β’ red_team_fuzzer.py (when all tests are green) β
β β’ mythos.api.fastapi_server (optional, port 7863) β
β β’ public_leaderboard.py (optional, port 7862) β
β β
β Persistent storage (mounted at /data): β
β β’ job_queue.sqlite β
β β’ training_store.sqlite β
β β’ embedding_index.sqlite (or Qdrant remote) β
β β’ audit_trail.jsonl β
β β’ harvester_feed.json β
β β’ lora_exports/*.jsonl β
β β’ disclosure_vault/ β
β β’ repo/ (cloned target repositories, ephemeral) β
β β
β External calls: β
β β’ GitHub API (clone, PR, fork, check_run, merge) β
β β’ DigitalOcean Inference (primary) β
β β’ OpenRouter (fallback + adversarial models) β
β β’ OpenRouter for adversarial trio (Qwen/Gemma/Mistral) β
β β’ Telegram & Slack (notifications) β
β β’ HackerOne / Bugcrowd (bounty submissions, optional) β
β β’ NVD / OSV / Snyk (CVE intelligence) β
β β’ Shodan, Wayback, crt.sh (recon, optional) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
4. Container & Build β Dockerfile and Requirements
4.1 README.md front-matter (the HF Space manifest)
title: Rhodawk AI DevSecOps Engine
sdk: docker
app_port: 7860
license: apache-2.0
sdk: docker is the critical line. With sdk: gradio, HF Spaces injects
gradio[oauth,mcp]==<sdk_version> plus uvicorn, websockets, spaces,
and mcp into the build's pip command β overriding our explicit pins and
breaking the resolver. With sdk: docker, HF runs the Dockerfile verbatim
and exposes only app_port to the public preview iframe.
4.2 Dockerfile (logical structure)
FROM python:3.12-slim AS base
# system deps for: git (clone), build-essential (some wheels),
# libpq-dev (psycopg2), libssl/libffi (cryptography), curl, jq, nodejs (MCP servers)
RUN apt-get update && apt-get install -y --no-install-recommends \
git build-essential libpq-dev libssl-dev libffi-dev curl jq \
nodejs npm && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt /app/requirements.txt
# Stage A: install everything pip can solve cleanly
RUN pip install --no-cache-dir -r requirements.txt mcp-server-fetch && \
# Stage B: install aider WITHOUT its strict pins (pillow==12.1.1, litellm==1.75.0)
pip install --no-cache-dir --no-deps "aider-chat==0.86.2" && \
# Stage C: replace aider's broken litellm pin with a working release
pip install --no-cache-dir --upgrade --no-deps "litellm==1.78.5" && \
# Stage D: provide aider's actual runtime imports (subset of its setup.py)
pip install --no-cache-dir \
configargparse jsonschema rich prompt_toolkit pyyaml \
packaging pathspec diskcache networkx scipy \
beautifulsoup4 pypandoc flake8 importlib_resources \
pyperclip pexpect json5 psutil watchfiles socksio \
mixpanel posthog tree-sitter grep_ast oslex \
tokenizers google-generativeai openai diff-match-patch \
soundfile sounddevice
COPY . /app
EXPOSE 7860 7861
CMD ["python", "app.py"]
Why this layered install pattern works. The pip resolver cannot satisfy
pillow<12 (gradio) and pillow==12.1.1 (aider) simultaneously. By
installing aider with --no-deps we let gradio's pillow 11 win. Aider only
imports a small fraction of its declared deps at runtime, and those that
matter are installed explicitly in Stage D. The litellm replacement is
necessary because the version aider pins (1.75.0) ships a broken module
surface β litellm.APIConnectionError, litellm._logging,
litellm.encode, and litellm.token_counter are all referenced by aider
but not exported by 1.75.0. 1.78.5 restores them.
4.3 requirements.txt (resolved set)
The file declares: requests, pytest, uv>=0.7.0, gitpython==3.1.46,
gradio>=5.49.0,<6, jinja2==3.1.6, ruff, tenacity, bandit[toml],
pip-audit, radon, hypothesis[cli]>=6.100.0, semgrep>=1.45.0,
sentence-transformers>=2.7.0, sqlite-vec>=0.1.1, pygithub>=2.3.0,
PyJWT>=2.8.0, datasets>=2.19.0, numpy>=1.26.0, psycopg2-binary>=2.9.9,
rapidfuzz>=3.0.0, z3-solver>=4.12.0, qdrant-client>=1.9.0,
transformers>=4.40.0, torch>=2.2.0, starlette, plus optional FastAPI
deps used by the Mythos API server.
aider-chat is intentionally absent β see Stage B above.
5. Process Map at Runtime
| Process / Thread | Started by | Lifetime | Listens on | Purpose |
|---|---|---|---|---|
| Main Python process | python app.py |
container lifetime | β | imports modules, starts threads, hosts Gradio |
| Gradio Uvicorn worker | Gradio's demo.launch() |
container lifetime | 7860 | serves the dashboard UI |
| Webhook Uvicorn worker | webhook_server.start() thread |
container lifetime | 7861 | receives GitHub & CI webhooks |
| Audit threads | submit_repo_audit() per request |
per audit | β | runs enterprise_audit_loop for one repo |
| Worker pool threads | worker_pool.run() inside an audit |
per audit | β | parallel test repair |
| Worker subprocesses | optional, when RHODAWK_PROCESS_ISOLATE=true |
per job | β | per-job blast radius isolation |
| Aider subprocess | subprocess.Popen per fix attempt |
per attempt | β | LLM patch generation |
| MCP server processes | npx/uvx spawned by aider |
per attempt | stdio | tools (fetch, github, filesystem, etc.) |
| Adversarial review threads | concurrent.futures in adversarial_reviewer |
per gate | β | 3-model parallel review |
| Harvester daemon | repo_harvester.start_daemon() if enabled |
container lifetime | β | autonomous target search |
| Commit watcher | commit_watcher.start_daemon() if enabled |
container lifetime | β | silent-patch correlation |
| LoRA scheduler | lora_scheduler.start_daemon() if enabled |
container lifetime | β | training data export trigger |
| Mythos FastAPI | optional | container lifetime | 7863 | external programmatic API |
| Leaderboard | optional | container lifetime | 7862 | public stats Gradio |
All daemons are gated by their respective RHODAWK_*_ENABLED env vars and
are off by default to keep the cold-start container minimal.
6. Master Orchestrator β app.py
app.py is 2,704 lines. It is the wiring file. Conceptually it has six
sections.
6.1 Module imports & global config
Lines ~1β200. Imports every other module in the project. Reads
~50 environment variables into module-level constants
(DEFAULT_MODEL, MAX_RETRIES, WORKERS, OPENROUTER_API_KEY,
DO_INFERENCE_API_KEY, DO_INFERENCE_BASE_URL, DO_INFERENCE_MODEL,
FALLBACK_MODELS, RHODAWK_TENANT_ID, audit/disclosure/training paths,
adversarial config, conviction thresholds, harvester config, etc.).
6.2 MCP runtime config writer
Lines ~200β470. Reads mcp_config.json (the template), substitutes
__INJECTED_BY_APP_AT_RUNTIME__ placeholders with real values from env,
and writes the materialized config to /tmp/mcp_runtime.json. Aider is
launched with --mcp-config /tmp/mcp_runtime.json so that all MCP tools
(fetch-docs, github-manager, filesystem-research, semgrep-sast, β¦) are
available during patch generation.
6.3 run_aider(prompt, repo_dir, model=None) β provider chain
Lines ~600β700. The function described in Β§2.1. Chooses the provider list
based on which API keys are set, runs aider as a subprocess with the
right env and CLI flags, captures stdout/stderr, parses the diff, and
returns (stdout, stderr, exit_code, model_used). On non-zero exit it
moves to the next provider.
6.4 process_failing_test(...) β the 15-step healing loop
The single most important function in the project.
1. Memory retrieval β embedding_memory.retrieve_similar_fixes_v2(failure_text)
2. Build prompt β verification_loop.build_initial_prompt(test_path, failure, similar)
3. Aider call β run_aider(prompt, repo_dir) (provider chain)
4. Re-run test β runtime.run_tests(test_path)
5. If still FAIL β append failure delta, build_retry_prompt, GOTO 3 (up to MAX_RETRIES)
6. SAST gate β sast_gate.run_sast(repo_dir, diff)
7. If BLOCK β append SAST critique, GOTO 3
8. Supply chain β supply_chain.run_supply_chain(diff, language)
9. If BLOCK β append supply-chain critique, GOTO 3
10. Z3 verify β formal_verifier.verify(diff) (if enabled)
11. If UNSAFE β append Z3 critique, GOTO 3
12. Adversarial β adversarial_reviewer.review_concurrent(diff, failure, repo)
13. If REJECT β append adversarial critique, GOTO 3 (with extended budget)
14. Persist β training_store.record_attempt(...)
15. Return verdict β VerificationResult(success, attempts, verdicts...)
The retry budget is normally MAX_RETRIES (default 5) but is multiplied by
ADVERSARIAL_REJECTION_MULTIPLIER when the retry was triggered by an
adversarial reject β to give the model more chances when the gate is the
strict adversarial trio rather than a hard test failure.
6.5 process_audit_test(...) β wraps healing with PR + conviction
Calls process_failing_test, then on success:
github_app.open_pr_for_repo(repo, branch, title, body)β URLconviction_engine.evaluate(verification_result, adversarial_result, memory_match)βConviction- If
Conviction.metandRHODAWK_AUTO_MERGE=true:github_app.merge_pr(url) audit_logger.append({event: PR_OPENED, ...})notifier.notify_pr_opened(repo, url)
6.6 enterprise_audit_loop(repo) β the per-audit driver
- Clones the repo into
/data/repo/<sanitized-owner>__<repo> RuntimeFactory.for_repo(repo_dir)returns the rightLanguageRuntimeruntime.setup_env()(creates venv, installs deps)runtime.discover_tests()returns a list of test file paths- Runs each test once to find the failing set
- Submits each failing test to the worker pool, which calls
process_audit_test - On completion:
red_team_fuzzer.start(repo_dir)if all tests are now green - Logs a final
AUDIT_COMPLETEevent
6.7 Gradio UI
The demo block defines 10 tabs:
- Chat Inbox β submit
owner/repoto start an audit - Live Agent Log β real-time tail of the audit log with auto-refresh (3 s)
- Audit Trail β paginated view of
audit_trail.jsonlwith filters - Memory Browser β search the embedding memory by failure text
- Training Store β stats and JSONL export trigger
- Harvester β refresh feed, view ranked candidates, dispatch manually
- Findings β vulnerability findings from Hermes / red team
- Hermes Sessions β list of research sessions with phases & VES scores
- System Status β env-var presence, daemon status, queue depth
- Settings β read-only display of effective configuration
The Live Agent Log uses a gr.Timer that fires every 3 seconds to repaint
the latest 200 lines of the in-memory log buffer.
7. Hermes Six-Phase Pipeline β hermes_orchestrator.py
The Hermes orchestrator is a research-and-disclosure pipeline parallel to
the test-healing loop. It runs against a target codebase or live host and
produces structured VulnerabilityFinding records.
7.1 Phases
| # | Enum value | Module(s) called | Output |
|---|---|---|---|
| 1 | RECON |
repo_harvester, mythos.mcp.reconnaissance_mcp, subdomain_enum_mcp, httpx_probe_mcp, wayback_mcp, shodan_mcp |
target inventory + tech fingerprint |
| 2 | STATIC |
taint_analyzer, semantic_extractor, mythos.static.{treesitter_cpg, joern_bridge, codeql_bridge, semgrep_bridge} |
candidate sinks + CWE hits |
| 3 | DYNAMIC |
fuzzing_engine, harness_factory, mythos.dynamic.{aflpp_runner, klee_runner, qemu_harness, frida_instr, gdb_automation} |
crashes, traces, coverage |
| 4 | EXPLOIT |
exploit_primitives, mythos.exploit.{pwntools_synth, rop_chain, heap_exploit, privesc_kb} |
working PoC artifacts |
| 5 | CONSENSUS |
adversarial_reviewer, _run_acts_consensus() |
model-quorum verdict + ACTS score |
| 6 | DISCLOSURE |
disclosure_vault, bounty_gateway, notifier |
encrypted writeup + optional submission |
7.2 Tool dispatch
Each phase exposes a small set of HermesTool subclasses
(ReconTool, TaintTool, SymbolicTool, FuzzTool, ExploitTool,
CVETool, CommitWatchTool, SSECTool, ChainAnalyzerTool). The
_dispatch_tool(tool_name, args, session) function looks up the class by
name and runs it with the session context. Tool output is appended to
session.findings and persisted via persist_hermes_session(session).
7.3 Scoring
compute_ves(...)β Vulnerability Evidence Score: weighted combination of reproducibility, exploitability, impact, and code-confidence signals.compute_acts(model_verdicts)β Adversarial Consensus Trust Score: measures inter-model agreement on the diff/exploit, used as an additional gate before disclosure.
7.4 LLM call surface
Every Hermes-triggered LLM call goes through _hermes_llm_call, which
implements the DO-primary / OpenRouter-fallback chain described in Β§2.2.
This means even adversarial review and disclosure-prose generation
benefit from the same provider resilience.
7.5 Session persistence
HermesSession is a dataclass (session_id, target, phase,
findings, tool_invocations, started_at, finished_at,
provider_history, ves, acts). persist_hermes_session(session)
writes a JSON artifact under /data/hermes_sessions/<session_id>.json
and appends an audit-trail event. The Gradio "Hermes Sessions" tab reads
from this directory.
7.6 TVG β Threat-Vector Graph
build_tvg(repo_dir, findings) produces a directed graph of
(source β sink, primitive, finding_id) edges suitable for downstream
visualization or LLM-driven exploit-chain reasoning. Used by
mythos/reasoning/attack_graph.py to compute reachable attack chains.
8. Safety Gate Modules
8.1 sast_gate.py
Runs bandit on Python diffs, semgrep with language-appropriate rule
sets on every diff, and a hand-rolled 16-pattern secret scanner over diff
additions only. Patterns include: AWS access keys (AKIA[0-9A-Z]{16}),
generic API keys (api[_-]?key.*[=:].{20,}), JWTs (eyJ[\w-]+\.[\w-]+\.[\w-]+),
private key headers (-----BEGIN (RSA|EC|OPENSSH|PGP) PRIVATE KEY-----),
.env-style assignments, OAuth tokens, SSH host keys, hardcoded passwords
in connection strings, etc. Returns SastVerdict(level, findings, raw)
where level β {PASS, BLOCK}. A single CRITICAL or HIGH finding flips to
BLOCK; MEDIUM/LOW are surfaced but advisory.
8.2 supply_chain.py
Two passes per diff:
- Known CVEs. Extract added packages from
requirements.txt,package.json,pom.xml,go.mod,Cargo.toml,Gemfile. Run the matching CVE scanner:pip-audit,npm audit --json, OWASPdependency-check,govulncheck,cargo audit,bundler-audit. - Typosquatting. For each new package name, compute Levenshtein distance against a 40+ entry list of canonical popular package names. Anything within distance 1 of a popular name (and not equal to it) is flagged as a likely typosquat.
8.3 formal_verifier.py
Three Z3-backed checks over diff additions:
- Div-by-zero. Pattern-extract
expr / divisorandexpr % divisor, parsedivisoras a Z3 expr, querysolver.check(divisor == 0). - Negative literal index. Find
arr[k]wherekis an integer literal, query satisfiability ofk < 0. - Always-false assert. For each
assert expr, walk the surrounding scope forname = literalconstants, substitute, querysolver.check(Not(expr)). ReturnsFormalVerdict(SAFE | UNSAFE | SKIP, witnesses). Disabled by default (RHODAWK_Z3_ENABLED=false) because Z3 is a heavy import.
8.4 adversarial_reviewer.py
Sends the diff + failure + repo identity to three reviewer models in
parallel via concurrent.futures.ThreadPoolExecutor(max_workers=3). Each
model receives an instruction template that demands a strict JSON envelope:
{verdict, confidence, critical_issues[], warnings[], retry_guidance}.
The reviewer parses each envelope, computes:
consensus_votes = Counter(verdicts)consensus_fraction = max(votes.values()) / 3- final verdict = majority (β₯
RHODAWK_CONSENSUS_THRESHOLDof 0.67) critical_issues = union(per-model critical lists)
Sequential mode (RHODAWK_ADVERSARY_SEQUENTIAL=true) runs the same models
serially. Used as a fallback when concurrent calls hit OpenRouter's
per-key concurrency limits.
8.5 conviction_engine.py
Seven boolean criteria, all of which must be true to allow autonomous merge:
adversarial.verdict == APPROVE(not just CONDITIONAL)adversarial.confidence β₯ RHODAWK_CONVICTION_CONFIDENCE(default 0.92)adversarial.consensus_fraction β₯ RHODAWK_CONVICTION_CONSENSUS(0.85)verification.attempts == 1(fixed on first try)sast.findings == [](zero SAST findings)supply_chain.added_packages == [](no new deps)memory.best_match.similarity β₯ RHODAWK_CONVICTION_MEMORY_SIMANDmemory.best_match.merged_by_human == True
Returns Conviction(met: bool, missing_criteria: list, score: float).
The score is a weighted combination useful for analytics even when
met is False.
8.6 taint_analyzer.py
Lightweight per-language source/sink dataflow analyzer used during the
Hermes STATIC phase (not in the patch healing loop). Tracks tainted
variables from common sources (HTTP request data, file reads, env vars,
CLI args) to dangerous sinks (eval, subprocess, raw SQL, pickle.loads,
yaml.load, etree.fromstring).
8.7 symbolic_engine.py
Wraps Z3 for richer symbolic execution beyond the single-statement checks
in formal_verifier.py. Used by Hermes SymbolicTool.
8.8 vuln_classifier.py
Maps raw findings (from SAST tools, taint, fuzzers) to CWE IDs and
estimated CVSS using a rule table. Output feeds disclosure_vault and
bounty_gateway.
9. Memory, Learning, and Data Flywheel
9.1 embedding_memory.py
Two interchangeable backends:
SQLite + MiniLM (default). sentence-transformers/all-MiniLM-L6-v2 for
encoding. Embeddings stored in a SQLite table (id, failure_norm, embedding BLOB, fix_diff, outcome, repo, ts) and queried by cosine similarity using
sqlite-vec. Lightweight, runs entirely in-process, no external service.
Qdrant + CodeBERT (optional). microsoft/codebert-base for code-aware
encoding. Vectors pushed to a Qdrant collection (HNSW index) β local or
remote. Switched on via RHODAWK_EMBEDDING_BACKEND=qdrant.
Public API used by the rest of the system:
retrieve_similar_fixes_v2(failure_text, top_k=5)β list of past fixesrecord_fix(failure_text, diff, outcome, repo)β persists for future retrievalrebuild_embedding_index()β re-encode entire training_store on demand
Failure normalization strips file paths, line numbers, addresses, and hex IDs so that semantically identical failures across different repos collide in embedding space.
9.2 memory_engine.py
Legacy v1 store. Exact-key lookup by normalized failure signature. Kept for cold-start scenarios where the embedding index has zero entries.
9.3 training_store.py
SQLite database (/data/training_store.sqlite) with two tables:
fix_attempts(id, ts, repo, test_path, failure, diff, model, attempt, success)fix_patterns(signature, success_count, attempt_count, last_seen)
Entry points:
record_attempt(...)β every fix attempt, success or failureexport_training_data(jsonl_path)β writes{"messages": [{"role": "system", ...}, {"role": "user", ...}, {"role": "assistant", "content": diff}]}β directly compatible with HuggingFace TRL/PEFT SFT trainers.get_statistics()β counts for the dashboard
9.4 lora_scheduler.py
Background daemon. Polls the training store. When either
RHODAWK_LORA_MIN_SAMPLES (default 50) new successful fix pairs accumulate
or RHODAWK_LORA_MAX_AGE_HOURS (default 168 = 1 week) elapse since the
last export, it calls training_store.export_training_data() to a new
JSONL file under /data/lora_exports/lora_<timestamp>.jsonl.
9.5 knowledge_rag.py
Retrieval-augmented generation helper for Hermes. Indexes long-form security
documentation (the architect/skills/*.md library plus optionally fetched
CVE writeups) and exposes a retrieve(query, top_k) helper that the
research planner can call to ground exploit reasoning in vetted prior art.
10. Autonomous Operation β Harvester, Worker Pool, Job Queue
10.1 repo_harvester.py
- Background daemon, gated by
RHODAWK_HARVESTER_ENABLED=true. - Cycle period:
RHODAWK_HARVESTER_POLL_SECONDS(default 21600 = 6 h). - Per cycle: GitHub Search API for repos in 7 supported languages
(
language:python,language:javascript, β¦) with at leastRHODAWK_HARVESTER_MIN_STARS(default 100) and recent activity. - Cross-references each candidate's
check-runsAPI to find currently failing CI. - Scoring:
0.35*log(stars+1)/log(MAX_STARS+1) + 0.40*recency_score + 0.25*failing_check_count_score. - Persists ranked feed to
/data/harvester_feed.json. - Dispatches the top
RHODAWK_HARVESTER_MAX_REPOS(default 20) targets into the audit loop viasubmit_repo_audit().
10.2 worker_pool.py
ThreadPoolExecutor(max_workers=RHODAWK_WORKERS)(default 8).- When
RHODAWK_PROCESS_ISOLATE=true: each job runs inmultiprocessing.get_context("fork").Processwith a resultQueueand a hard timeout ofRHODAWK_ISOLATE_TIMEOUTseconds (default 600). - On timeout: process is
terminate()d thenkill()ed if still alive, job is markedFAILED, audit-trail event recorded. - Falls back gracefully to in-process execution if
forkis not available (e.g., Windows host β irrelevant to HF but matters for self-hosters).
10.3 job_queue.py
- SQLite-backed (
/data/job_queue.sqlite). - Schema:
(tenant_id, repo, test_path)UNIQUE β(status, pr_url, model_version, started_at, updated_at, attempts, last_error). - States:
PENDING,RUNNING,DONE,FAILED,SAST_BLOCKED,ADVERSARIAL_REJECTED,CONVICTION_NOT_MET. - Idempotency: a
DONErow is skipped on resubmission. ARUNNINGrow older than 1 hour (stale, from a crashed previous container) is reset toPENDINGafter a branch-cleanup pass. prune_done_jobs(older_than_hours=72)keeps the table from growing unbounded.
11. GitHub Surface β github_app.py, webhook_server.py, commit_watcher.py
11.1 github_app.py
- PAT mode (default). Uses
GITHUB_TOKENdirectly via PyGithub. - GitHub App mode. Uses
RHODAWK_APP_ID+RHODAWK_APP_PRIVATE_KEYto issue a 10-minute JWT, exchange it for a 1-hour installation token, and refresh on each call. Enterprise-grade auth. open_pr_for_repo(repo, branch, title, body)β chooses standard or fork mode based onRHODAWK_FORK_MODE.- Standard mode. Push branch to upstream, open PR upstreamβupstream.
- Fork mode.
fork_repo(repo)(waits for GitHub's async fork to complete by polling), push branch to fork, open cross-repo PR forkβupstream. This is what enables fixing repos you don't own. merge_pr(url)β used by the conviction engine when criteria are met.
11.2 webhook_server.py
HTTP server on port 7861. Endpoints:
POST /webhook/githubβ validatesX-Hub-Signature-256HMAC againstRHODAWK_WEBHOOK_SECRET. Handlespushandcheck_runevents.POST /webhook/ciβ generic CI failure trigger (token in header).POST /webhook/triggerβ manual trigger (admin token).GET /webhook/healthβ liveness.GET /webhook/queueβ current queue depth + last 20 events. Per-IP token bucket rate limiter (default 30 req/min per IP).
11.3 commit_watcher.py
Daemon for silent-patch detection. Polls a configured set of
high-value upstream repos for new commits. Heuristics flag commits whose
message says "fix" / "security" / "CVE" but which have no associated
public advisory β a known pattern for CAD (Coordinated Asynchronous
Disclosure) or under-the-radar security fixes. Findings are routed to
disclosure_vault for downstream attribution.
11.4 chain_analyzer.py
Walks PR commit chains and groups related commits into "fix series" so that the training store records the full fix, not just the first commit in a multi-commit fix. Important for accurate (failure β fix) pair generation.
12. Red Team & Offense Modules
12.1 red_team_fuzzer.py
1,561 lines. The Blue Team-to-Red Team transition. When
process_audit_test finishes and all tests are green, this module:
- Generates property-based tests using Hypothesis strategies inferred from function signatures.
- Runs them with
pytest --hypothesis-show-statistics. - Captures shrunken counterexamples.
- Feeds the counterexamples into a CEGIS loop: each refuted property becomes the spec for the next attack synthesis round.
- Zero-day candidates are written as JSON artifacts under
/data/findings/and handed back to the Blue Team healing loop so the bug becomes a fix.
12.2 fuzzing_engine.py
Lower-level fuzzing primitives consumed by both red_team_fuzzer.py and
the Hermes DYNAMIC phase. Bridges to mythos/dynamic/aflpp_runner.py,
klee_runner.py, and qemu_harness.py when those are available.
12.3 harness_factory.py
Generates fuzz harnesses from function signatures: type inference,
seed corpus extraction from existing tests, AFL++/libFuzzer wrapper
emission. Used by red_team_fuzzer.py and Hermes.
12.4 exploit_primitives.py
Catalogs reusable exploitation primitives: arbitrary read/write,
function-pointer overwrite, format-string leak, integer-overflow ladder,
heap-grooming templates. Each primitive has a match(finding) β bool
predicate and an apply(finding) β ExploitArtifact synthesizer.
12.5 cve_intel.py
NVD/OSV/Snyk lookup for prior-art correlation. Given a finding, returns the closest known CVE and similarity score so the disclosure isn't a duplicate.
13. Notification, Audit, Disclosure, Bounty
13.1 notifier.py
- Telegram via Bot API (
TELEGRAM_BOT_TOKEN+TELEGRAM_CHAT_ID). - Slack via incoming webhook (
SLACK_WEBHOOK_URL). - All sends are non-blocking (background threads with bounded queue).
- Templates for: AUDIT_START, TEST_FAIL, PR_CREATED, PATCH_FAIL, SAST_BLOCK, AUDIT_COMPLETE, ZERO_DAY_FOUND, DISCLOSURE_SUBMITTED.
13.2 audit_logger.py
Append-only JSONL at /data/audit_trail.jsonl. Each entry:
{
"ts": "2026-04-22T12:34:56Z",
"event": "ADVERSARIAL_REVIEW",
"tenant": "acme",
"repo": "owner/name",
"payload": {...},
"prev_hash": "sha256:...",
"hash": "sha256:..."
}
prev_hash is the hash of the previous entry; hash is the SHA-256 of
the current entry (excluding the hash field itself). The genesis entry
has prev_hash = "0"*64.
verify_chain_integrity() walks the file from genesis, recomputes each
hash, and asserts equality. Any tamper anywhere breaks the chain at the
tampered point and every subsequent entry. SOC 2 / ISO 27001 evidence
artifact.
13.3 disclosure_vault.py
Encrypted at-rest storage for vulnerability writeups. Uses Fernet with a
key derived from DISCLOSURE_VAULT_PASSPHRASE. Each entry:
finding metadata + full PoC + suggested fix + CVE correlation. Read API
requires the same passphrase. Used by Hermes DISCLOSURE phase before
any public submission.
13.4 bounty_gateway.py
Programmatic submission to HackerOne, Bugcrowd, Intigriti, YesWeHack via their REST APIs. Submission requires:
- Finding has passed adversarial CONSENSUS phase
- VES β₯ configured floor
- Manual approval flag (default: required) OR
RHODAWK_BOUNTY_AUTO_SUBMIT=true(off by default β kept off in production)
13.5 oss_guardian.py
Stewardship layer for fixes pushed to OSS repos. Tracks PR status, maintainer responses, and time-to-merge. Feeds analytics for the public leaderboard and for the conviction engine's "merged by human" signal.
13.6 oss_target_scorer.py
Scoring helper used by both the harvester and the public leaderboard to rank repos by community impact (stars, dependents, ecosystem centrality).
13.7 public_leaderboard.py
Standalone Gradio interface (port 7862) showing PRs submitted, PRs
merged, repos touched, patterns learned, zero-days reported. All numbers
read directly from audit_trail.jsonl and training_store.sqlite β
no synthetic metrics.
13.8 swebench_harness.py
Runs the Rhodawk healing loop against SWE-bench Verified instances. Reports pass@1. Same pipeline as production β no special-cased logic. Provides reproducible benchmarks for investor/customer claims.
14. Architect Subsystem β Tier Routing, Sandbox, Skills, Night Mode
The architect/ package is the higher-order control layer that sits above
the per-test healing loop and decides which model, which skill, and which
sandbox each task should use.
14.1 architect/model_router.py
Five-tier model router. Each task is classified by complexity and routed to the cheapest tier that can satisfy it:
- Tier 1 β Ultra. DeepSeek 3.2, MiniMax 2.5. Used for global strategy and multi-repo planning.
- Tier 2 β Strong. Qwen 2.5 Coder 32B. Default patch generator.
- Tier 3 β Balanced. Llama 3.3 70B (DigitalOcean), DeepSeek V3, Gemma 2 27B. Adversarial reviewers.
- Tier 4 β Lite. Mistral 7B, Gemma 2 9B. Cheap second-opinion calls.
- Tier 5 β Local. Embedded MiniLM/CodeBERT for embeddings β no LLM call.
The router consumes (task_type, code_size_tokens, security_sensitivity, required_capabilities) and returns a routing decision with provider,
model, and expected_cost_usd.
14.2 architect/sandbox.py
SandboxManager β abstraction over (a) plain subprocess, (b) bwrap
(bubblewrap) namespace isolation, (c) Firecracker microVM (planned).
Currently used in subprocess + bwrap modes for any tool execution that
must not touch the host filesystem outside /tmp/sandbox/<id>/.
14.3 architect/skill_registry.py
Registers the 28 skill markdown files under architect/skills/ as
discoverable knowledge units. Each skill file declares: domain
(api-security, container-escape, smart-contract-audit, β¦), required
tools, suggested model tier, and reference references. The registry
exposes find_skills(query) β list[Skill] for the planner.
14.4 architect/skills/
28 long-form security playbooks covering: api-security, ai-ml-security,
automotive-security, aviation-aerospace, binary-analysis, browser-engine
security, ci-cd-pipeline-attack, cloud-security, container-escape,
cryptographic-implementation, cryptography-attacks, firmware-analysis,
hardware-protocols, ics-scada, linux-kernel-exploitation, llm-system-
prompt-injection, memory-safety, mobile-android, mobile-ios, network-
protocol, reverse-engineering, rf-radio-security, satellite-comms,
smart-contract-audit, supply-chain, vibe-coded-app-hunter, web-security
advanced, zero-day-research, plus bb-methodology-claude.md and
bug-bounty-reference-index.md.
14.5 architect/nightmode.py
The autonomous "night mode" loop. When enabled, between human-driven
audits the system pulls in scope from connected bug-bounty platforms
(via mythos.mcp.scope_parser_mcp), enumerates targets, and runs
Hermes pipelines against authorized scope only β submitting findings
through bounty_gateway. Hard-gated by ARCHITECT_NIGHTMODE_ENABLED=true
and a per-platform scope-acceptance check.
14.6 architect/godmode_consensus.py
A heavier-weight consensus protocol used by night mode that runs the adversarial trio AND a Tier 1 model, requiring unanimous agreement before any external submission. Higher false-negative rate, near-zero false-positive rate β appropriate when the action is irreversible.
14.7 architect/master_redteam_prompt.py
Centralizes the master prompt used by the red-team modules. Externalizing the prompt makes it tunable without code changes and auditable for prompt-injection resistance.
14.8 architect/parseltongue.py
Internal DSL for declaring multi-step research plans. Compiles to a
sequence of HermesTool invocations. Used by the Mythos planner agent.
14.9 architect/embodied_bridge.py
Bridge to the EmbodiedOS / OpenClaw / Hermes Agent runtime when present externally. Stubs gracefully when EmbodiedOS is not reachable.
14.10 architect/rl_feedback_loop.py
RL feedback collector. After each fix, an outcome reward is computed (merge=+1, rejected=-0.5, never-reviewed-after-30-days=-0.1) and the plan-level statistics are updated for the planner's policy table.
15. Mythos Subsystem β Multi-Agent + RL + 17 MCP Servers
mythos/ is the deepest research layer β designed to close the gap between
Rhodawk's deterministic 6-phase pipeline and a Mythos-class autonomous
research agent.
15.1 mythos/MYTHOS_PLAN.md
Living blueprint document mapping Rhodawk's gaps to concrete Mythos modules. Read this first to understand the design intent.
15.2 mythos/agents/
base.pyβ abstractAgentclass withobserve,plan,act.planner.pyβ generates research plans from a target description. Uses the Tier 1 model + RL policy table.explorer.pyβ enumeration agent for recon and surface mapping.executor.pyβ runs concrete tools (calls intomythos/static,mythos/dynamic,mythos/exploit).orchestrator.pyβ top-level coordinator that wires planner β explorer β executor β consensus and persists the trace.
15.3 mythos/static/
treesitter_cpg.pyβ Tree-sitterβbased Code Property Graph builder.joern_bridge.pyβ Joern CPG queries for taint chains.codeql_bridge.pyβ CodeQL pack runner with predefined query sets.semgrep_bridge.pyβ Semgrep with curated security rule packs.
15.4 mythos/dynamic/
aflpp_runner.pyβ AFL++ harness execution.klee_runner.pyβ KLEE symbolic execution wrapper.qemu_harness.pyβ full-system QEMU with snapshot/restore.frida_instr.pyβ Frida runtime instrumentation sessions.gdb_automation.pyβ scripted GDB triage of crashes.
15.5 mythos/exploit/
pwntools_synth.pyβ pwntools-based PoC synthesis.rop_chain.pyβ ROP gadget search + chain assembly via ROPGadget.heap_exploit.pyβ heap exploitation primitives (tcache, fastbin, unsafe-unlink).privesc_kb.pyβ privilege escalation knowledge base + matcher.
15.6 mythos/learning/
rl_planner.pyβ RL planner using the reward signal fromarchitect/rl_feedback_loop.py.curriculum.pyβ curriculum learning over progressively harder vulnerability classes.episodic_memory.pyβ episodic store of full (target, plan, action, observation, reward) trajectories.mlflow_tracker.pyβ MLflow run tracking for training experiments.lora_adapters.pyβ LoRA adapter loader; lets the system swap in domain-specific adapters per task.
15.7 mythos/reasoning/
probabilistic.pyβ probabilistic attack-vector reasoning.attack_graph.pyβ attack-graph construction over(asset, action, result)triples; computes minimum-cost reachable goal paths.
15.8 mythos/api/
fastapi_server.pyβ optional FastAPI server (port 7863) exposing/audit,/research,/findings,/leaderboardJSON APIs.auth.pyβ bearer-token auth middleware.schemas.pyβ Pydantic request/response models.webhooks.pyβ webhook delivery on async events.
15.9 mythos/skills/
registry.pyβ runtime skill discovery and ranking. Bridges toarchitect/skill_registry.pyto expose skills via MCP.
15.10 mythos/integration.py
Top-level wiring. Initializes the Mythos subsystem from app.py's
startup. If Mythos modules fail to import (optional dependencies
missing), it logs a warning and lets the system continue without the
Mythos features.
15.11 mythos/diagnostics.py
Self-test CLI. python -m mythos.diagnostics prints which agents,
MCP servers, and external tools are reachable, and exits non-zero if
any required component is broken. Used by the mythos.__main__ entry
point and by container health checks.
15.12 mythos/__main__.py
Allows python -m mythos to launch the Mythos subsystem standalone.
16. MCP Suite β Every Server, Every Domain
The mcp_config.json template declares 34 MCP server entries (with
some duplicates β see note below). Aider is launched with the rendered
/tmp/mcp_runtime.json so all of these tools become callable during
patch generation. Hermes also calls them directly.
16.1 Generic / shared servers
| Server | Command | Purpose |
|---|---|---|
fetch-docs |
uvx mcp-server-fetch |
HTTP fetch with SSRF allow-list (60+ domains) |
github-manager |
npx @modelcontextprotocol/server-github |
full GitHub API |
filesystem-research |
npx @modelcontextprotocol/server-filesystem |
RO access to /data/repo, /tmp/research, /tmp/findings |
memory-store |
npx @modelcontextprotocol/server-memory |
persistent KG of exploit chains |
sequential-thinking |
npx @modelcontextprotocol/server-sequential-thinking |
structured CoT |
web-search |
npx @modelcontextprotocol/server-brave-search |
Brave search API |
git-forensics |
npx @modelcontextprotocol/server-git |
deep git-history analysis |
postgres-intelligence |
npx @modelcontextprotocol/server-postgres |
findings DB queries |
sqlite-findings |
npx @modelcontextprotocol/server-sqlite |
local findings DB |
16.2 Security tooling shells (mcp-server-shell allow-list)
| Server | Allowed binaries | Purpose |
|---|---|---|
nuclei-scanner |
nuclei,nuclei-templates |
DAST + CVE templates |
semgrep-sast |
semgrep |
taint + CWE + secrets |
trufflehog-secrets |
trufflehog |
git-history secret scan |
bandit-sast |
bandit |
Python AST SAST |
pip-audit-sca |
pip-audit,pip |
OSV-backed Python SCA |
osv-scanner |
osv-scanner |
multi-ecosystem SCA |
z3-formal-verifier |
python3 |
Z3 verification scripts |
hypothesis-fuzzer |
python3,pytest,hypothesis |
property-based testing |
atheris-fuzzer |
python3,atheris |
coverage-guided fuzzing |
angr-symbolic |
python3 |
binary symbolic execution |
radon-complexity |
radon |
complexity / attack surface |
ruff-linter |
ruff |
anti-pattern detection |
aider-patcher |
aider |
patch synthesis (recursive β careful) |
16.3 Intelligence + bounty
| Server | Purpose |
|---|---|
cve-intelligence |
NVD / CVE.org / OSV fetch |
bounty-platform |
HackerOne/Bugcrowd/Intigriti/YesWeHack APIs |
supply-chain-monitor |
PyPI/npm/crates typosquatting + dep-confusion |
16.4 Mythos-native MCP servers (Python modules)
| Server | Module | Purpose |
|---|---|---|
reconnaissance-mcp |
mythos.mcp.reconnaissance_mcp |
language/framework/dep fingerprinting + attack surface |
static-analysis-mcp |
mythos.mcp.static_analysis_mcp |
Tree-sitter CPG + Joern + CodeQL + Semgrep |
dynamic-analysis-mcp |
mythos.mcp.dynamic_analysis_mcp |
AFL++ + KLEE + QEMU + Frida + GDB |
exploit-generation-mcp |
mythos.mcp.exploit_generation_mcp |
Pwntools + ROP + heap + privesc |
vulnerability-database-mcp |
mythos.mcp.vulnerability_database_mcp |
NVD/OSV/Exploit-DB lookup |
web-security-mcp |
mythos.mcp.web_security_mcp |
OWASP ZAP + nuclei + sqlmap orchestration |
browser-agent-mcp |
mythos.mcp.browser_agent_mcp |
Playwright live browser |
scope-parser-mcp |
mythos.mcp.scope_parser_mcp |
bug-bounty scope ingestion |
subdomain-enum-mcp |
mythos.mcp.subdomain_enum_mcp |
subfinder + amass + dnsx + crt.sh |
httpx-probe-mcp |
mythos.mcp.httpx_probe_mcp |
concurrent HTTP probing + tech fingerprint |
shodan-mcp |
mythos.mcp.shodan_mcp |
Shodan REST passive recon |
wayback-mcp |
mythos.mcp.wayback_mcp |
Wayback / CommonCrawl historical URL recall |
frida-runtime-mcp |
mythos.mcp.frida_runtime_mcp |
live Frida instrumentation |
ghidra-bridge-mcp |
mythos.mcp.ghidra_bridge_mcp |
headless Ghidra / radare2 bridge |
can-bus-mcp |
mythos.mcp.can_bus_mcp |
automotive CAN-bus + UDS (ISO 14229) |
sdr-analysis-mcp |
mythos.mcp.sdr_analysis_mcp |
GNU Radio / rtl_sdr RF capture |
Duplicate-key note.
mcp_config.jsoncurrently declaresscope-parser-mcp,subdomain-enum-mcp,wayback-mcp,httpx-probe-mcp, andshodan-mcptwice. JSON parse semantics use the last value, so the ARCHITECT-flavored variants (withenvinjections for HackerOne/Shodan tokens) are what wins at runtime. The earlier entries are dead weight and could be removed in a future cleanup commit.
16.5 Runtime materialization
On startup, app.py reads mcp_config.json, recursively replaces every
__INJECTED_BY_APP_AT_RUNTIME__ placeholder with the corresponding env
var value (OPENROUTER_API_KEY, BRAVE_API_KEY, DATABASE_URL,
HACKERONE_API_TOKEN, BUGCROWD_API_TOKEN, INTIGRITI_API_TOKEN,
SHODAN_API_KEY, NVD_API_KEY, NUCLEI_API_KEY, SEMGREP_APP_TOKEN,
GITHUB_PERSONAL_ACCESS_TOKEN), drops any server whose required secret
is missing, and writes the result to /tmp/mcp_runtime.json. Aider
launches with --mcp-config /tmp/mcp_runtime.json. Secrets are never
committed.
17. Test Suite β What Each Test Asserts
tests/ contains 9 test modules and one conftest.py.
| Test file | What it asserts |
|---|---|
test_audit_chain.py |
The SHA-256 audit chain in audit_logger.py rejects tampering. Writes synthetic events, mutates one entry, expects verify_chain_integrity() to flag the break point. |
test_job_queue.py |
Idempotency guarantees: identical (tenant, repo, test_path) submissions don't duplicate. Stale RUNNING rows older than 1h reset to PENDING. Status transitions are valid. |
test_mcp_servers_load.py |
The MCP runtime config materializes correctly: all __INJECTED__ placeholders are resolved or the server is dropped. No secrets leak into the rendered file. |
test_model_router.py |
The 5-tier router produces deterministic routing for the same input. Tier promotions happen on capability misses. Cost estimates are monotonic with tier. |
test_mythos_diagnostics.py |
mythos.diagnostics.run_diagnostics() exits 0 in healthy state and non-zero when any required Mythos module is missing. |
test_nightmode_smoke.py |
Architect night mode initializes without external services and refuses to act when no scope source is configured. |
test_scope_parser.py |
The HackerOne / Bugcrowd / Intigriti scope parsers correctly partition assets into IN_SCOPE / OUT_OF_SCOPE buckets with edge cases (wildcards, port specs, regex policies). |
test_skill_registry.py |
The 28 skill files in architect/skills/ are all parseable, declare required metadata, and are discoverable by find_skills(query). |
test_webhook_hmac.py |
webhook_server.py rejects requests with invalid HMAC signatures and accepts valid ones. Constant-time comparison is used (no timing side channel). |
conftest.py defines fixtures for: temporary /data overrides, mock
GitHub API, mock OpenRouter API, in-memory SQLite for the job queue and
training store, and a synthetic failing-test repo factory.
18. Data on Disk β Files, SQLite Schemas, Audit Chain
/data/
βββ job_queue.sqlite # job_queue.py
βββ training_store.sqlite # training_store.py (fix_attempts, fix_patterns)
βββ embedding_index.sqlite # embedding_memory.py SQLite backend
βββ memory_engine.sqlite # legacy v1 pattern memory
βββ rhodawk_findings.db # MCP sqlite-findings server
βββ audit_trail.jsonl # SHA-256 chained event log
βββ harvester_feed.json # ranked candidate repos
βββ disclosure_vault/
β βββ <finding_id>.fernet # encrypted writeups
βββ lora_exports/
β βββ lora_<timestamp>.jsonl # SFT-ready training data
βββ hermes_sessions/
β βββ <session_id>.json # persisted Hermes research sessions
βββ findings/
β βββ <finding_id>.json # raw findings from red team / Mythos
βββ repo/
β βββ <owner>__<name>/ # cloned target repos (ephemeral)
βββ nuclei-templates/ # nuclei DAST templates cache
βββ research/ # MCP filesystem-research scratch
/tmp/:
/tmp/
βββ mcp_runtime.json # rendered MCP config (with secrets)
βββ sandbox/<id>/ # bwrap sandbox roots
βββ findings/ # MCP filesystem-research output
18.1 SQLite schemas (effective)
-- training_store.sqlite
CREATE TABLE fix_attempts (
id INTEGER PRIMARY KEY,
ts TEXT NOT NULL,
repo TEXT NOT NULL,
test_path TEXT NOT NULL,
failure TEXT NOT NULL,
diff TEXT,
model TEXT,
attempt INTEGER,
success INTEGER NOT NULL
);
CREATE INDEX ix_fix_attempts_repo ON fix_attempts(repo);
CREATE INDEX ix_fix_attempts_success ON fix_attempts(success);
CREATE TABLE fix_patterns (
signature TEXT PRIMARY KEY,
success_count INTEGER NOT NULL DEFAULT 0,
attempt_count INTEGER NOT NULL DEFAULT 0,
last_seen TEXT NOT NULL
);
-- job_queue.sqlite
CREATE TABLE jobs (
tenant_id TEXT NOT NULL,
repo TEXT NOT NULL,
test_path TEXT NOT NULL,
status TEXT NOT NULL,
pr_url TEXT,
model_version TEXT,
started_at TEXT,
updated_at TEXT NOT NULL,
attempts INTEGER NOT NULL DEFAULT 0,
last_error TEXT,
PRIMARY KEY (tenant_id, repo, test_path)
);
-- embedding_index.sqlite (sqlite-vec)
CREATE TABLE embeddings (
id INTEGER PRIMARY KEY,
failure_norm TEXT,
embedding BLOB, -- vector serialized via sqlite-vec
fix_diff TEXT,
outcome TEXT,
repo TEXT,
ts TEXT
);
CREATE VIRTUAL TABLE embedding_index USING vec0(
embedding float[384]
);
18.2 Audit chain entry shape
{
"ts": "2026-04-22T13:14:15.123Z",
"event": "ADVERSARIAL_REVIEW",
"tenant": "default",
"repo": "owner/name",
"test_path": "tests/test_x.py",
"payload": {
"verdict": "APPROVE",
"confidence": 0.93,
"consensus_fraction": 1.0,
"models": ["qwen-2.5-7b", "gemma-2-9b", "mistral-7b"],
"critical_issues": [],
"warnings": ["minor style nit"]
},
"prev_hash": "sha256:f3a1...c0",
"hash": "sha256:9b22...ee"
}
19. Complete Environment Variable Reference (Updated)
This table supersedes the playbook's reference for everything related to inference providers and the build-changed paths.
19.1 Required for any meaningful run
| Var | Purpose |
|---|---|
GITHUB_TOKEN |
PAT with repo scope (or use App mode below) |
OPENROUTER_API_KEY |
needed for fallback + adversarial trio |
DO_INFERENCE_API_KEY |
strongly recommended β enables paid DO primary |
19.2 Inference providers (new since playbook)
| Var | Default | Description |
|---|---|---|
DO_INFERENCE_API_KEY |
β | DigitalOcean Serverless Inference key |
DO_INFERENCE_BASE_URL |
https://inference.do-ai.run/v1 |
DO endpoint |
DO_INFERENCE_MODEL |
llama3.3-70b-instruct |
Aider's primary model on DO |
HERMES_DO_MODEL |
${DO_INFERENCE_MODEL} |
Hermes' primary model on DO |
HERMES_OR_MODEL |
qwen/qwen-2.5-coder-32b-instruct:free |
Hermes' OpenRouter fallback |
OPENROUTER_API_KEY |
β | Fallback + adversarial models |
19.3 Models, retries, consensus
| Var | Default | Description |
|---|---|---|
RHODAWK_MODEL |
(computed: DO if available else OR free) | Aider primary model |
RHODAWK_ADVERSARY_MODEL |
openrouter/qwen/qwen-2.5-7b-instruct:free |
lead reviewer |
RHODAWK_CONSENSUS_THRESHOLD |
0.67 |
majority fraction |
RHODAWK_ADVERSARY_SEQUENTIAL |
false |
serial vs concurrent reviewers |
MAX_RETRIES |
5 |
healing-loop retry budget |
ADVERSARIAL_REJECTION_MULTIPLIER |
2 |
extra retries when reject reason is adversarial |
19.4 Conviction (auto-merge)
| Var | Default | Description |
|---|---|---|
RHODAWK_AUTO_MERGE |
false |
enable autonomous merge |
RHODAWK_CONVICTION_CONFIDENCE |
0.92 |
min adversarial confidence |
RHODAWK_CONVICTION_CONSENSUS |
0.85 |
min consensus fraction |
RHODAWK_CONVICTION_MEMORY_SIM |
0.85 |
min memory similarity |
19.5 Memory backend
| Var | Default | Description |
|---|---|---|
RHODAWK_EMBEDDING_BACKEND |
sqlite |
sqlite or qdrant |
RHODAWK_EMBEDDING_MODEL |
all-MiniLM-L6-v2 |
SQLite backend encoder |
RHODAWK_CODEBERT_MODEL |
microsoft/codebert-base |
Qdrant backend encoder |
QDRANT_URL |
β | Qdrant remote URL when not local |
QDRANT_API_KEY |
β | Qdrant cloud auth |
19.6 LoRA scheduler
| Var | Default | Description |
|---|---|---|
RHODAWK_LORA_ENABLED |
false |
enable scheduler |
RHODAWK_LORA_MIN_SAMPLES |
50 |
min new fixes per export |
RHODAWK_LORA_MAX_AGE_HOURS |
168 |
max time between exports |
RHODAWK_LORA_OUTPUT_DIR |
/data/lora_exports |
JSONL destination |
19.7 Harvester
| Var | Default | Description |
|---|---|---|
RHODAWK_HARVESTER_ENABLED |
false |
start daemon |
RHODAWK_HARVESTER_POLL_SECONDS |
21600 |
cycle interval |
RHODAWK_HARVESTER_MIN_STARS |
100 |
min stars to consider |
RHODAWK_HARVESTER_MAX_REPOS |
20 |
targets per cycle |
19.8 Worker pool & isolation
| Var | Default | Description |
|---|---|---|
RHODAWK_WORKERS |
8 |
parallel workers |
RHODAWK_PROCESS_ISOLATE |
false |
per-job subprocess isolation |
RHODAWK_ISOLATE_TIMEOUT |
600 |
per-job timeout (seconds) |
19.9 GitHub
| Var | Default | Description |
|---|---|---|
GITHUB_TOKEN |
β | PAT auth |
RHODAWK_FORK_MODE |
false |
enable fork-and-PR for any public repo |
RHODAWK_FORK_OWNER |
(authenticated user) | org to fork into |
RHODAWK_APP_ID |
β | GitHub App ID |
RHODAWK_APP_PRIVATE_KEY |
β | GitHub App PEM |
RHODAWK_WEBHOOK_SECRET |
β | HMAC for /webhook/github |
19.10 Adversarial / red team / formal
| Var | Default | Description |
|---|---|---|
RHODAWK_RED_TEAM_ENABLED |
true |
enable CEGIS fuzzer when all tests green |
RHODAWK_Z3_ENABLED |
false |
enable Z3 formal verification gate |
19.11 Architect / Mythos / night mode
| Var | Default | Description |
|---|---|---|
ARCHITECT_NIGHTMODE_ENABLED |
false |
enable autonomous night mode |
ARCHITECT_GODMODE_REQUIRED |
true |
require unanimous consensus before external action |
MYTHOS_API_ENABLED |
false |
start FastAPI on 7863 |
MYTHOS_API_TOKEN |
β | bearer token for the FastAPI |
DISCLOSURE_VAULT_PASSPHRASE |
β | Fernet key derivation passphrase |
RHODAWK_BOUNTY_AUTO_SUBMIT |
false |
auto-submit to bounty platforms |
19.12 External intelligence
| Var | Description |
|---|---|
BRAVE_API_KEY |
Brave Search MCP |
SHODAN_API_KEY |
Shodan recon MCP |
NVD_API_KEY |
NVD CVE intelligence MCP |
NUCLEI_API_KEY |
Nuclei templates premium feed |
SEMGREP_APP_TOKEN |
Semgrep Cloud rules |
HACKERONE_USERNAME, HACKERONE_API_TOKEN, HACKERONE_API_KEY |
HackerOne |
BUGCROWD_API_TOKEN |
Bugcrowd |
INTIGRITI_API_TOKEN |
Intigriti |
19.13 Notifications
| Var | Description |
|---|---|
TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID |
Telegram alerts |
SLACK_WEBHOOK_URL |
Slack alerts |
19.14 Multitenancy
| Var | Default | Description |
|---|---|---|
RHODAWK_TENANT_ID |
default |
namespace prefix for jobs, audits, exports |
20. Failure Modes and Recovery Procedures
| Symptom | Most likely cause | Recovery |
|---|---|---|
Build fails on pillow resolver conflict |
requirements.txt re-lists aider-chat |
Remove it; aider must be --no-deps only in Dockerfile |
Build fails with gradio[oauth,mcp]==5.29.0 injection |
Space SDK reverted to gradio |
Confirm sdk: docker in README.md front-matter |
Aider crashes litellm has no attribute APIConnectionError |
litellm 1.75.0 reinstalled by transitive dep | Re-run the pip install --no-deps litellm==1.78.5 step or pin in Dockerfile |
| All LLM calls fail with 429 | OpenRouter rate-limited and DO not configured | Set DO_INFERENCE_API_KEY; calls will route to DO first |
All LLM calls fail with No inference provider configured |
Both DO_INFERENCE_API_KEY and OPENROUTER_API_KEY missing |
Set at least one; restart container |
| Webhook 401 from GitHub | RHODAWK_WEBHOOK_SECRET mismatch |
Re-set the secret in the GitHub repo's webhook config to match |
| Audit hangs forever on a single test | Aider subprocess wedged | Set RHODAWK_PROCESS_ISOLATE=true and RHODAWK_ISOLATE_TIMEOUT=600 |
embedding_index.sqlite corrupted |
Hard kill mid-write | Delete the file; rebuild_embedding_index() will reconstruct from training_store.sqlite |
| Audit chain integrity fails | Manual edit of audit_trail.jsonl |
The chain is correctly rejecting tamper. To start a new chain, archive and remove the file; a new genesis entry will be written. |
| Conviction never fires | Memory has zero matches at threshold β₯0.85 | Expected on cold start; lower RHODAWK_CONVICTION_MEMORY_SIM to 0.75 in early life if you want auto-merge sooner β but be honest with yourself about what you're trading. |
| MCP server fails to spawn | npx/uvx missing or required env var unset |
Check container has nodejs+npm and uvx (uv); confirm injected env var is present at startup |
| Harvester feed empty | Token lacks search scope or rate limited | Confirm GITHUB_TOKEN has public_repo; raise RHODAWK_HARVESTER_MIN_STARS |
| Mythos FastAPI 401 | Wrong bearer token | Confirm MYTHOS_API_TOKEN matches client header |
21. Security Model β Trust Boundaries and Threat Mitigation
21.1 Trust boundaries
- Container β host. Container runs as root in the Docker image but
touches only
/data(mounted) and/tmp(ephemeral). No host paths leak. - Container β target repo. Cloned repos live in
/data/repo/<id>/. They are treated as untrusted: scripts in target repos are neverpython <target_script>'d directly β only the runtime's allowed commands (pytest,npm test,go test, β¦) are invoked. - Container β LLM provider. Code snippets and failure traces are sent over the wire to DigitalOcean Inference and OpenRouter. This is the primary data-leakage surface β controlled by deployment mode (HF Spaces is multi-tenant; self-hosted is single-tenant).
- MCP fetch β internet.
fetch-docsand similar fetch MCPs useFETCH_ALLOWED_DOMAINSallow-lists to prevent SSRF against internal services. - Webhook β public internet. All webhook endpoints validate HMAC signatures with constant-time comparison. Per-IP rate limiting in front. No untrusted JSON is unpickled.
21.2 Threat mitigation by attack
| Threat | Mitigation |
|---|---|
| Prompt injection in target source | Multi-model adversarial review catches divergent reactions; SAST/supply-chain catch the resulting bad diffs |
LLM-introduced typosquat (reqeusts) |
supply_chain.py Levenshtein typosquatting check |
| LLM-introduced backdoor | SAST + adversarial trio + zero-package-introduction conviction criterion |
| Tampered audit trail | SHA-256 chain detects any post-hoc edit |
| Webhook spoofing | HMAC-SHA256 with constant-time compare |
| Secret leakage via logs | Secret scanner runs over diffs; mcp_runtime.json is in /tmp not the repo |
| Subprocess sandbox escape | Runtime command allow-lists; optional bwrap; planned Firecracker |
| Bug-bounty submission of duplicate finding | cve_intel.py correlation + manual approval default |
| Auto-merge of an unsafe diff | 7 conviction criteria; default OFF; passes only the cleanest fixes |
| Provider compromise (e.g., OpenRouter MITM) | TLS verification; provider chain falls back rather than blindly trusting bad responses |
21.3 Secret hygiene
mcp_config.jsonis a template with__INJECTED_BY_APP_AT_RUNTIME__placeholders. The realized config goes to/tmp/mcp_runtime.jsonwhich is not committed and is recreated on each startup..env-style files are never read; everything goes throughos.getenv. HF Spaces / Docker-eare the only injection paths.- The disclosure vault uses Fernet with key derived from
DISCLOSURE_VAULT_PASSPHRASE. Lose that passphrase, lose the vault β by design.
22. Migration Playbook β HF Space β Paid Server
The Space is a great PoC environment but has hard limits: ephemeral storage on free tier, single-container topology, and shared GPU resources. The paid-server migration target is a single Linux box (DigitalOcean Droplet, Hetzner CCX, or AWS EC2) running the same Docker image.
22.1 Pre-migration checklist
- All env vars from Β§19 documented and stored in a secrets manager
-
/datadirectory size on Space measured (du -sh /data) and provisioned on the new host (recommend β₯50 GB to start) - DigitalOcean Inference key budgeted for the expected request volume
- Webhook secret rotated for the new endpoint URL
- DNS or reverse-proxy plan in place if you want HTTPS in front of ports 7860/7861/7862/7863
- Decision made on Qdrant: keep SQLite/MiniLM (simpler) or stand up a Qdrant container alongside (better recall on large corpora)
22.2 Migration steps
- Snapshot data. On the Space:
Download via the HF Spaces file browser or via git LFS.tar czf /tmp/rhodawk-data.tgz /data - Provision the new host. Install Docker + Docker Compose. Mount a
block volume at
/var/lib/rhodawk-data. - Restore data.
sudo mkdir -p /var/lib/rhodawk-data sudo tar xzf rhodawk-data.tgz -C /var/lib/rhodawk-data --strip-components=1 - Build the image (or pull from a private registry if you've pushed
one):
git clone https://huggingface.co/spaces/Architect8999/rhodawk-ai-devops-engine cd rhodawk-ai-devops-engine docker build -t rhodawk:latest . - Run with all env vars + persistent volume.
docker run -d --name rhodawk \ -p 7860:7860 -p 7861:7861 \ -v /var/lib/rhodawk-data:/data \ -e DO_INFERENCE_API_KEY=... \ -e OPENROUTER_API_KEY=... \ -e GITHUB_TOKEN=... \ -e RHODAWK_WEBHOOK_SECRET=... \ -e RHODAWK_TENANT_ID=acme \ -e RHODAWK_AUTO_MERGE=false \ -e RHODAWK_HARVESTER_ENABLED=true \ rhodawk:latest - Update GitHub webhook payload URL to the new host.
- Verify the audit chain integrity on the new host:
docker exec rhodawk python -c \ "from audit_logger import verify_chain_integrity; verify_chain_integrity()" - Run a known-failing-test repo through the chat inbox or a webhook to confirm end-to-end.
22.3 Recommended additions on paid host
- Reverse proxy (Caddy or Traefik) terminating TLS, fronting 7860/7861.
- Docker Compose file checking the container into a restart-policy.
cronor systemd timer that runsdocker exec rhodawk python -m mythos.diagnosticsevery 5 minutes and pages on non-zero exit.- Off-host backup of
/var/lib/rhodawk-datanightly. The training store is the proprietary asset β losing it loses the moat. - Optional Qdrant container (
qdrant/qdrant:latest) on a private network, withRHODAWK_EMBEDDING_BACKEND=qdrant+QDRANT_URL=http://qdrant:6333.
22.4 What changes at scale (later)
- Move
job_queuefrom SQLite to PostgreSQL (psycopg2-binaryalready installed, seemcp_config.jsonpostgres-intelligence server). - Move audit trail to S3 with versioning (the SHA-256 chain remains; only the storage backend changes).
- Replace single-host worker pool with a queue + worker fleet (Redis/RQ or Celery).
- Replace Gradio dashboard with a Next.js front-end calling the
mythos.api.fastapi_serverJSON API.
23. Glossary of Internal Names
| Name | Meaning |
|---|---|
| Aider | Open-source AI pair-programming CLI, used as the patch generator |
| APIConnectionError | Symbol that aider expects in litellm; missing in 1.75.0 β fixed by upgrading to 1.78.5 |
| ACTS | Adversarial Consensus Trust Score (Hermes) |
| Audit chain | The SHA-256-chained JSONL log in audit_logger.py |
| Architect | Higher-order control package (architect/) β tier router, sandbox, skills, night mode |
| CEGIS | Counterexample-Guided Inductive Synthesis (red team loop) |
| Conviction | The 7-criteria gate that allows autonomous merge |
| DO | DigitalOcean Serverless Inference (the new primary inference provider) |
| EmbodiedOS | External persistent runtime that hosts OpenClaw + Hermes Agent (optional bridge) |
| Fork mode | Forking any public repo and PR'ing back β enables fixing repos you don't own |
| Godmode consensus | Stricter consensus (adversarial trio + Tier 1) used by night mode |
| Harvester | Daemon that finds its own targets on GitHub |
| Hermes | The 6-phase research orchestrator (hermes_orchestrator.py) |
| LoRA scheduler | Daemon that exports successful (failure, fix) pairs as SFT JSONL |
| MCP | Model Context Protocol β Anthropic's tool-server protocol |
| Mythos | The deepest research package (mythos/) β multi-agent + RL + 17 native MCP servers |
| Mythos-level | Aspirational target capability class β autonomous frontier vulnerability research |
| Night mode | Autonomous bug-bounty loop running between human-driven audits |
| OpenClaw | Local-gateway component of EmbodiedOS |
| OR | OpenRouter (the new fallback inference provider) |
| PoC | Proof of Concept (exploit) |
| Provider chain | The ordered list [DO_primary, OpenRouter_fallback] consulted on every LLM call |
| Sandbox | bwrap (or planned Firecracker) isolation for tool execution |
| SAST gate | Static analysis security gate (bandit + semgrep + secret patterns) |
| Supply chain gate | CVE + typosquatting check on newly added packages |
| Tier 1β5 | Five-tier model router classification |
| Training store | SQLite DB of every fix attempt β the proprietary data asset |
| TVG | Threat-Vector Graph |
| VES | Vulnerability Evidence Score (Hermes) |
| Z3 gate | Optional formal-verification gate using the Z3 SMT solver |
Rhodawk AI β System Analysis Book
Companion to FOUNDER_PLAYBOOK.md v4.0 (which remains the canonical investor narrative)
Generated from the live source tree; last updated to reflect the DigitalOcean primary / OpenRouter fallback inference chain, the --no-deps aider install pattern, and the Docker-SDK Space configuration.