Rhodawk Mythos Agent commited on
Commit
df75169
Β·
1 Parent(s): 14b1bbe

docs: add full end-to-end architectural analysis (5-phase recon, flow, build & stability)

Browse files
Files changed (1) hide show
  1. ARCHITECTURE_ANALYSIS.md +527 -0
ARCHITECTURE_ANALYSIS.md ADDED
@@ -0,0 +1,527 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Rhodawk AI DevSecOps Engine β€” End-to-End Architectural Analysis
2
+
3
+ > Generated by an automated architect/security-researcher pass over commit
4
+ > `14b1bbe` of `Architect8999/rhodawk-ai-devops-engine` on the
5
+ > HuggingFace Spaces repository.
6
+ > Scope: every Python module in the repo root + the new `mythos/` package
7
+ > (~17 kLOC of Python, 30 MCP servers, 1 Dockerfile, 1 Gradio UI).
8
+
9
+ ---
10
+
11
+ ## Phase 1 β€” High-Level Reconnaissance & Topology
12
+
13
+ ### 1.1 Virtual directory tree (top two levels)
14
+
15
+ ```
16
+ rhodawk-ai-devops-engine/
17
+ β”œβ”€β”€ app.py # Gradio control plane + main loop (~117 KB)
18
+ β”œβ”€β”€ hermes_orchestrator.py # Multi-phase research brain (~30 KB)
19
+ β”œβ”€β”€ language_runtime.py # Polyglot runtime sandbox (~70 KB)
20
+ β”œβ”€β”€ red_team_fuzzer.py # CEGIS-style adversarial fuzzer (~62 KB)
21
+ β”‚
22
+ β”œβ”€β”€ adversarial_reviewer.py # 3-model concurrent LLM verdict
23
+ β”œβ”€β”€ audit_logger.py # Hash-chained tamper-evident log
24
+ β”œβ”€β”€ bounty_gateway.py # H1 / GHSA submission pipeline
25
+ β”œβ”€β”€ chain_analyzer.py # Commit-history attack graphs
26
+ β”œβ”€β”€ commit_watcher.py # CAD β€” silent-patch detector
27
+ β”œβ”€β”€ conviction_engine.py # Multi-criterion auto-merge gate
28
+ β”œβ”€β”€ cve_intel.py # NVD / OSV / Exploit-DB lookups
29
+ β”œβ”€β”€ disclosure_vault.py # Encrypted finding storage
30
+ β”œβ”€β”€ embedding_memory.py # sentence-transformers + sqlite-vec
31
+ β”œβ”€β”€ exploit_primitives.py # ROP / heap / shellcode helpers
32
+ β”œβ”€β”€ formal_verifier.py # Z3 bounded verification
33
+ β”œβ”€β”€ fuzzing_engine.py # Hypothesis fuzzer driver
34
+ β”œβ”€β”€ github_app.py # GitHub App JWT / installation token
35
+ β”œβ”€β”€ harness_factory.py # Auto-generates fuzzing harnesses
36
+ β”œβ”€β”€ job_queue.py # JSON-file-backed job ledger
37
+ β”œβ”€β”€ lora_scheduler.py # Threshold-triggered LoRA exports
38
+ β”œβ”€β”€ memory_engine.py # TF-IDF retrieval (legacy)
39
+ β”œβ”€β”€ notifier.py # Slack / Discord / email fan-out
40
+ β”œβ”€β”€ public_leaderboard.py # Public stats endpoint
41
+ β”œβ”€β”€ repo_harvester.py # Antagonist target picker
42
+ β”œβ”€β”€ sast_gate.py # bandit + 16 secret patterns
43
+ β”œβ”€β”€ semantic_extractor.py # Function / call-graph extraction
44
+ β”œβ”€β”€ supply_chain.py # pip-audit + typosquat heuristics
45
+ β”œβ”€β”€ swebench_harness.py # SWE-bench evaluation runner
46
+ β”œβ”€β”€ symbolic_engine.py # angr planner + Z3 solver glue
47
+ β”œβ”€β”€ taint_analyzer.py # Sourceβ†’sink taint tracking
48
+ β”œβ”€β”€ training_store.py # SQLite/PG attempt ledger + HF push
49
+ β”œβ”€β”€ verification_loop.py # Retry / prompt-build state machine
50
+ β”œβ”€β”€ vuln_classifier.py # CWE taxonomy + scoring
51
+ β”œβ”€β”€ webhook_server.py # GitHub webhook HTTPServer (port 7861)
52
+ β”œβ”€β”€ worker_pool.py # Process-isolated parallel audits
53
+ β”‚
54
+ β”œβ”€β”€ mythos/ # β¬… NEW: Mythos-level upgrade package
55
+ β”‚ β”œβ”€β”€ MYTHOS_PLAN.md
56
+ β”‚ β”œβ”€β”€ __init__.py / integration.py
57
+ β”‚ β”œβ”€β”€ agents/ # planner / explorer / executor / orchestrator
58
+ β”‚ β”œβ”€β”€ reasoning/ # probabilistic + attack_graph
59
+ β”‚ β”œβ”€β”€ static/ # tree-sitter, joern, codeql, semgrep bridges
60
+ β”‚ β”œβ”€β”€ dynamic/ # aflpp, klee, qemu, frida, gdb
61
+ β”‚ β”œβ”€β”€ exploit/ # pwntools, ROP, heap, privesc KB
62
+ β”‚ β”œβ”€β”€ learning/ # rl_planner, mlflow, lora, curriculum, episodic
63
+ β”‚ β”œβ”€β”€ mcp/ # 5 new MCP servers
64
+ β”‚ β”œβ”€β”€ skills/ # agentskills.io registry
65
+ β”‚ └── api/ # FastAPI productization (auth, webhooks, schemas)
66
+ β”‚
67
+ β”œβ”€β”€ mcp_config.json # 30 MCP servers registered
68
+ β”œβ”€β”€ Dockerfile # python:3.12-slim + uv + node + Gradio
69
+ β”œβ”€β”€ requirements.txt # ~30 first-class deps + Mythos optional
70
+ β”œβ”€β”€ pitch_deck/, pitch-deck/ # Marketing collateral (PDF/PPTX/HTML)
71
+ β”œβ”€β”€ FOUNDER_PLAYBOOK.md, SECURITY_RESEARCH_PLAYBOOK.md, README.md
72
+ └── .git/
73
+ ```
74
+
75
+ ### 1.2 Structural paradigm
76
+
77
+ A **flat-module monolith with a side-car package**. There is no explicit
78
+ layered or hexagonal partitioning at the root: every concern (UI, orchestration,
79
+ analysis tools, persistence, networking) lives as a peer `*.py` module
80
+ imported by `app.py`. Communication is **in-process function calls** plus
81
+ **JSON files on `/data`** for cross-process state (jobs, audit chain, memory).
82
+ The new `mythos/` package adds a proper Python package with sub-modules per
83
+ concern, intended as the migration target for a cleaner future architecture.
84
+
85
+ ### 1.3 Technology stack
86
+
87
+ | Layer | Technology |
88
+ |---|---|
89
+ | Runtime | Python 3.12 (slim Docker), Node.js 20 (npm-installed for some MCP servers) |
90
+ | UI / Control plane | **Gradio 5.29** on port 7860 |
91
+ | Webhooks | Stdlib `http.server.BaseHTTPRequestHandler` on port 7861 |
92
+ | LLM gateway | **OpenRouter** (DeepSeek-R1 / V3 free tier, plus Qwen βˆ₯ Gemma βˆ₯ Mistral consensus); env-driven model tiers in Mythos |
93
+ | Code patching | **Aider 0.86** (driven via subprocess + MCP config) |
94
+ | Static / SAST | bandit, ruff, semgrep, radon, custom 16-pattern secret scanner |
95
+ | Symbolic / Formal | **z3-solver**, **angr**, custom symbolic engine |
96
+ | Fuzzing | Hypothesis (atheris removed β€” see Dockerfile comments) |
97
+ | Embeddings / Memory | sentence-transformers + sqlite-vec, optional Qdrant |
98
+ | Persistence | SQLite (default) / Postgres (`psycopg2-binary`) for training store |
99
+ | ML / Training | transformers, torch, datasets, custom LoRA scheduler |
100
+ | MCP | `@modelcontextprotocol/server-github` (npm), `mcp-server-fetch` (uvx), and **30** servers in `mcp_config.json` (25 base + 5 new Mythos ones) |
101
+ | Mythos add-ons | FastAPI + uvicorn + pydantic; optional Pyro/PyMC, MLflow, RLlib, pwntools, Frida, tree-sitter-languages |
102
+ | Versioning / VCS | GitPython, PyGithub, PyJWT |
103
+ | Container | Two-stage `python:3.12-slim` Dockerfile, non-root UID 1000, `/data` writable, `EXPOSE 7860`, `CMD ["python","-u","app.py"]` |
104
+ | Deployment target | HuggingFace Spaces (declared in README YAML front-matter) |
105
+
106
+ ### 1.4 Headline metrics
107
+
108
+ - **Python LOC:** 16 981 across 47 root modules + 47 Mythos modules.
109
+ - **Top three by size:** `app.py` (β‰ˆ3 200 LOC), `language_runtime.py` (β‰ˆ70 KB),
110
+ `red_team_fuzzer.py` (β‰ˆ62 KB), `hermes_orchestrator.py` (β‰ˆ900 LOC).
111
+ - **Tests:** none in the repo root β€” `pytest` is invoked **on the target
112
+ repository** being audited, not on Rhodawk itself.
113
+
114
+ ---
115
+
116
+ ## Phase 2 β€” Entry Point & Execution Flow Mapping
117
+
118
+ ### 2.1 Entry points
119
+
120
+ | Surface | Entry | Listens on | Triggered by |
121
+ |---|---|---|---|
122
+ | **Primary** | `python -u app.py` (Dockerfile `CMD`) | TCP `:7860` (Gradio) | User opens HF Space URL |
123
+ | **Webhook** | `webhook_server.start_webhook_server()` invoked from `app.py` `__main__` | TCP `:7861` (HTTPServer in a daemon thread) | GitHub `push` / `pull_request` events |
124
+ | **Mythos API** | `uvicorn mythos.api.fastapi_server:app` (manual / opt-in) | configurable | `POST /v1/analyze_target` and webhook callbacks |
125
+ | **MCP servers** | Spawned on demand by Aider via `mcp_config.json` (`stdio` JSON-RPC) | stdin/stdout | Aider's tool calls during patching |
126
+
127
+ ### 2.2 Boot sequence (from `if __name__ == "__main__"` in `app.py`)
128
+
129
+ ```
130
+ 1. ui_log("Rhodawk AI v3.0 starting …")
131
+ 2. Daemon thread β†’ embedding_memory.pre_warm_model()
132
+ (downloads sentence-transformers model in background to avoid first-call latency)
133
+ 3. start_webhook_server()
134
+ β†’ HTTPServer on 0.0.0.0:7861, daemon thread,
135
+ registers _webhook_dispatch as the job dispatcher
136
+ 4. demo.launch(server_name=0.0.0.0, server_port=$PORT or 7860)
137
+ β†’ Gradio Blocks UI bound to enterprise_audit_loop, Hermes tabs,
138
+ job table, audit chain viewer, leaderboard, etc.
139
+ 5. gr.Timer(3) ticks every 3 s β†’ get_combined_refresh()
140
+ (single SSE stream β€” comment in app.py notes it replaced
141
+ three concurrent streams that were exhausting connection limits)
142
+ ```
143
+
144
+ ### 2.3 Control flow β€” primary "audit" loop
145
+
146
+ `enterprise_audit_loop()` in `app.py` (l. 965) is the heart. Per repo:
147
+
148
+ ```
149
+ configure_git_credentials() # writes ~/.git-credentials from env
150
+ clone target β†’ /tmp/repo
151
+ discover failing tests via pytest --collect-only + run
152
+ for each failing_test:
153
+ process_audit_test()
154
+ β”œβ”€ retrieve_similar_fixes_v2() # embedding_memory (fallback: TF-IDF memory_engine)
155
+ β”œβ”€ build_initial_prompt() # verification_loop
156
+ β”œβ”€ write_mcp_config() β†’ mcp_config.json on disk
157
+ β”œβ”€ run_aider(mcp_config_path, prompt, context_files) # subprocess Aider with MCP
158
+ β”œβ”€ re-run pytest β†’ VerificationAttempt
159
+ β”œβ”€ if fail and attempts < MAX_RETRIES:
160
+ β”‚ build_retry_prompt(failure + previous diff) β†’ loop
161
+ β”œβ”€ run_sast_gate() # bandit + 16 secret patterns
162
+ β”œβ”€ run_supply_chain_gate() # pip-audit + typosquat
163
+ β”œβ”€ run_adversarial_review() # 3 LLMs in parallel; ACTS Bayesian score
164
+ β”œβ”€ run_formal_verification() # Z3 bounded checks
165
+ β”œβ”€ if adversary REJECT:
166
+ β”‚ retry with critique * ADVERSARIAL_REJECTION_MULTIPLIER
167
+ β”œβ”€ evaluate_conviction() # multi-criteria gate
168
+ β”œβ”€ if conviction high β†’ auto_merge_pr() else create_github_pr()
169
+ β”œβ”€ record_attempt() / update_test_result() # training_store (SQLite/PG)
170
+ β”œβ”€ record_fix_outcome() # memory_engine writes back lesson
171
+ └─ maybe_trigger_training() # lora_scheduler exports HF dataset
172
+ ```
173
+
174
+ A parallel **Hermes research mode** (`hermes_orchestrator.run_hermes_research`)
175
+ sits beside the audit loop. It runs the six phases RECON β†’ STATIC β†’ DYNAMIC β†’
176
+ EXPLOIT β†’ CONSENSUS β†’ DISCLOSURE and produces a `HermesSession` containing
177
+ `VulnerabilityFinding`s with VES / TVG / ACTS / CAD / SSEC scores.
178
+
179
+ ### 2.4 Data flow
180
+
181
+ ```
182
+ GitHub repo ──clone──► /tmp/repo/<sha> (ephemeral)
183
+ β”‚
184
+ pytest output ─────────
185
+ β–Ό
186
+ memory_engine ◄── embedding_memory (sqlite-vec @ /data)
187
+ β”‚
188
+ β–Ό
189
+ MCP-equipped Aider ── subprocess ──► fixed source
190
+ β”‚
191
+ adversarial verdicts ──
192
+ β–Ό
193
+ conviction_engine ──► PR / auto-merge
194
+ β”‚
195
+ attempt row ──────────┴───────────► training_store
196
+ (SQLite at /data/store.db
197
+ or Postgres if DATABASE_URL)
198
+ β”‚
199
+ β–Ό
200
+ lora_scheduler ──► HF dataset
201
+ ```
202
+
203
+ All persistent state lives under `/data` (writable in HF Spaces, mode 777
204
+ in the Dockerfile). Job ledger files: `/data/jobs/<job_id>.json`. Hash-chained
205
+ audit log: `/data/audit_chain.jsonl`. Embeddings vector store: `/data/mem.db`.
206
+ Mythos adds `/data/mythos/{rl_state.json,episodic.sqlite,skills/}`.
207
+
208
+ ---
209
+
210
+ ## Phase 3 β€” Functional Breakdown
211
+
212
+ ### 3.1 Executive summary
213
+
214
+ Rhodawk is an **autonomous DevSecOps control plane**. Point it at a GitHub
215
+ repo; it (1) reproduces failing tests, (2) drives an LLM coding agent (Aider,
216
+ through 30 MCP-exposed tools) to write a patch, (3) re-runs the tests in a
217
+ verification loop, (4) gates the patch through SAST + supply-chain + multi-LLM
218
+ adversarial review + Z3 formal verification + a conviction engine, (5) opens
219
+ or auto-merges a pull request, and (6) feeds every attempt into a training
220
+ store so a LoRA fine-tune can be scheduled. A parallel **Hermes** mode flips
221
+ the polarity from "fix bugs" to "find bugs": coordinated multi-phase
222
+ vulnerability research with custom scoring algorithms (VES/TVG/ACTS/CAD/SSEC)
223
+ and a HackerOne / GitHub Security Advisory submission gateway. The new
224
+ **Mythos package** layers a multi-agent (planner / explorer / executor)
225
+ framework, probabilistic Bayesian reasoning, advanced static / dynamic /
226
+ exploit tooling, RL-driven self-improvement, 5 additional MCP servers, and a
227
+ FastAPI productization surface on top of all of the above.
228
+
229
+ ### 3.2 Module responsibilities (selected)
230
+
231
+ | Module | Responsibility |
232
+ |---|---|
233
+ | `app.py` | Gradio UI, audit loop, Aider subprocess driver, refresh timer, boot sequence |
234
+ | `hermes_orchestrator.py` | Phase state machine, custom security metrics (VES/ACTS/TVG), tool dispatcher |
235
+ | `verification_loop.py` | Retry policy, prompt construction, attempt accounting |
236
+ | `adversarial_reviewer.py` | 3-model parallel verdict β†’ consensus, used by both audit and Hermes |
237
+ | `conviction_engine.py` | Boolean / weighted gate that decides auto-merge vs human review |
238
+ | `sast_gate.py`, `supply_chain.py`, `formal_verifier.py` | Independent gates the patch must pass |
239
+ | `language_runtime.py` | Polyglot sandbox factory β€” sets up Python venvs, Node, Java, etc. for the target repo |
240
+ | `red_team_fuzzer.py` | CEGIS adversarial fuzzer β€” counter-example guided refinement |
241
+ | `embedding_memory.py` / `memory_engine.py` | v2 semantic retrieval (sentence-transformers + sqlite-vec); v1 TF-IDF fallback |
242
+ | `training_store.py` | SQLite / Postgres attempt ledger + `export_hf_dataset` for HF push |
243
+ | `lora_scheduler.py` | Threshold-triggered LoRA training-data export |
244
+ | `audit_logger.py` | Append-only hash-chained log + `verify_chain_integrity` |
245
+ | `webhook_server.py` | HMAC-verified GitHub webhook receiver, IP rate-limit, dispatcher hook |
246
+ | `worker_pool.py` | Process-isolated parallel test handling (`MAX_WORKERS`) |
247
+ | `bounty_gateway.py` | Holds findings for human approval β†’ submits to HackerOne / opens GHSA |
248
+ | `vuln_classifier.py` / `cve_intel.py` | CWE taxonomy + NVD/OSV/Exploit-DB lookup |
249
+ | `commit_watcher.py` / `chain_analyzer.py` | Silent-patch detection + per-commit attack-graph diffing |
250
+ | `mythos/agents/*` | Planner produces a probabilistic plan; Explorer enumerates hypotheses; Executor runs tools; Orchestrator routes |
251
+ | `mythos/reasoning/probabilistic.py` | Bayesian hypothesis sampling (Pyro / PyMC / NumPy fallback) |
252
+ | `mythos/learning/rl_planner.py` | Tool-selection policy (RLlib / SB3 / UCB1 fallback), state at `/data/mythos/rl_state.json` |
253
+ | `mythos/api/fastapi_server.py` | `POST /v1/analyze_target`, auth middleware, webhook callbacks |
254
+ | `mythos/mcp/*` | 5 new servers exposed via `python -m mythos.mcp.<name>` and registered in `mcp_config.json` |
255
+
256
+ ### 3.3 Background work / scheduled tasks
257
+
258
+ - **Embedding pre-warm thread** (daemon, `app.py` `__main__`).
259
+ - **Webhook HTTPServer thread** (daemon).
260
+ - **Gradio refresh timer** (3 s SSE tick) β€” coalesced into one stream.
261
+ - **Worker-pool subprocesses** for per-test isolation (`worker_pool._run_isolated`).
262
+ - **LoRA scheduler** triggers on attempt-count threshold (no cron β€” checked at the end of each audit).
263
+ - **MCP server lifecycle** β€” Aider spawns each declared MCP server on demand and tears it down with the patch session.
264
+
265
+ There is **no Celery / RQ / APScheduler** β€” concurrency is purely
266
+ threading + subprocess + ad-hoc daemons.
267
+
268
+ ---
269
+
270
+ ## Phase 4 β€” Build & Execution Guide
271
+
272
+ ### 4.1 Prerequisites
273
+
274
+ | Required | Notes |
275
+ |---|---|
276
+ | Python **3.12** | Pinned in README front-matter and Dockerfile |
277
+ | Node.js + npm | Only for `@modelcontextprotocol/server-github` |
278
+ | `uv` (Astral) | Used by `language_runtime` to materialise per-target venvs |
279
+ | `git` | GitPython invokes the system binary |
280
+ | Writable `/data` (Linux) or local equivalent | All persistent state lives here |
281
+ | **Env vars** | `OPENROUTER_API_KEY` (mandatory for any LLM call); `GITHUB_TOKEN` *or* GitHub App creds (`GITHUB_APP_ID`, `GITHUB_APP_PRIVATE_KEY`, `GITHUB_INSTALLATION_ID`); optional `DATABASE_URL` for Postgres training store; `HF_TOKEN` for HF dataset push; `GITHUB_WEBHOOK_SECRET` for webhook HMAC; Slack/Discord URLs for notifier; Mythos tier overrides `MYTHOS_TIER1_PRIMARY` / `MYTHOS_TIER2_PRIMARY` etc.; `RHODAWK_MYTHOS=1` to engage multi-agent loop |
282
+ | Optional native tools | Joern, CodeQL, AFL++, KLEE, QEMU, Frida, GDB, ROPGadget, pwntools β€” Mythos bridges degrade gracefully if absent |
283
+
284
+ ### 4.2 Setup β€” local
285
+
286
+ ```bash
287
+ # 1. Clone
288
+ git clone https://huggingface.co/spaces/Architect8999/rhodawk-ai-devops-engine
289
+ cd rhodawk-ai-devops-engine
290
+
291
+ # 2. Python deps
292
+ python3.12 -m venv .venv && source .venv/bin/activate
293
+ pip install --upgrade pip
294
+ pip install -r requirements.txt mcp-server-fetch
295
+
296
+ # 3. Node-based MCP server
297
+ npm install -g @modelcontextprotocol/server-github
298
+
299
+ # 4. (Optional) astral uv for runtime sandboxing
300
+ curl -LsSf https://astral.sh/uv/install.sh | sh
301
+
302
+ # 5. Persistent state directory
303
+ sudo mkdir -p /data && sudo chmod 777 /data
304
+
305
+ # 6. Environment
306
+ export OPENROUTER_API_KEY=sk-or-...
307
+ export GITHUB_TOKEN=ghp_... # or GITHUB_APP_* trio
308
+ export GITHUB_WEBHOOK_SECRET=whsec_...
309
+ # Optional
310
+ export DATABASE_URL=postgres://...
311
+ export HF_TOKEN=hf_...
312
+ export RHODAWK_MYTHOS=1
313
+ ```
314
+
315
+ ### 4.3 Run
316
+
317
+ ```bash
318
+ # Primary control plane (Gradio on :7860, webhook on :7861)
319
+ PORT=7860 python -u app.py
320
+
321
+ # Or via Docker (the way HF Spaces runs it)
322
+ docker build -t rhodawk-ai .
323
+ docker run -it --rm \
324
+ -p 7860:7860 -p 7861:7861 \
325
+ -e OPENROUTER_API_KEY -e GITHUB_TOKEN -e GITHUB_WEBHOOK_SECRET \
326
+ -v $PWD/data:/data \
327
+ rhodawk-ai
328
+
329
+ # Mythos productization API (independent of the Gradio loop)
330
+ uvicorn mythos.api.fastapi_server:app --host 0.0.0.0 --port 8000
331
+
332
+ # Run a single Mythos MCP server manually (smoke test)
333
+ python -m mythos.mcp.static_analysis_mcp
334
+ ```
335
+
336
+ ### 4.4 Verification
337
+
338
+ ```bash
339
+ # 1. Gradio UI returns HTML
340
+ curl -sf http://localhost:7860/ | head -n 5
341
+
342
+ # 2. Webhook server is up (expect 405 Method Not Allowed on GET)
343
+ curl -sv http://localhost:7861/webhook 2>&1 | grep "HTTP/1"
344
+
345
+ # 3. Send a synthetic GitHub ping (replace SECRET)
346
+ BODY='{"zen":"hello"}'
347
+ SIG="sha256=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$GITHUB_WEBHOOK_SECRET" | cut -d' ' -f2)"
348
+ curl -sv -X POST http://localhost:7861/webhook \
349
+ -H "X-GitHub-Event: ping" \
350
+ -H "X-Hub-Signature-256: $SIG" \
351
+ -H "Content-Type: application/json" \
352
+ -d "$BODY"
353
+
354
+ # 4. Mythos API health
355
+ curl -sf http://localhost:8000/healthz
356
+ curl -sX POST http://localhost:8000/v1/analyze_target \
357
+ -H "Content-Type: application/json" \
358
+ -d '{"target":"https://github.com/octocat/Hello-World","mode":"recon"}'
359
+
360
+ # 5. Verify the audit chain is internally consistent
361
+ python -c "from audit_logger import verify_chain_integrity; print(verify_chain_integrity())"
362
+
363
+ # 6. Confirm 30 MCP servers register
364
+ jq '.mcpServers | length' mcp_config.json # β†’ 30
365
+ ```
366
+
367
+ In the Gradio UI you should see live logs ticking every 3 s, the metrics
368
+ row populating, and the **Hermes** and **CWE Reference** tabs available.
369
+
370
+ ---
371
+
372
+ ## Phase 5 β€” Architectural Thoughts & Stability Assessment
373
+
374
+ ### 5.1 Patterns in use
375
+
376
+ - **Pipeline / chain-of-responsibility** β€” the audit loop is a clean
377
+ sequence of independent gates (`sast_gate β†’ supply_chain β†’ adversarial β†’
378
+ formal β†’ conviction`). Each gate exposes a single function returning a
379
+ decision dataclass; they are trivially composable.
380
+ - **Strategy + graceful-degradation wrappers** β€” Mythos bridges
381
+ (`mythos/static/joern_bridge.py`, etc.) all expose `available()` plus a
382
+ pure-Python fallback. The orchestrator can plan with whatever is on the
383
+ PATH today.
384
+ - **Tier-routing for LLMs** β€” Hermes has two model tiers (`HERMES_MODEL`
385
+ reasoning + `HERMES_FAST_MODEL` for cheap triage); Mythos generalises this
386
+ to env-driven `MYTHOS_TIER{1,2}_{PRIMARY,FALLBACK}`.
387
+ - **Bayesian / consensus voting** β€” `compute_acts()` produces a Bayesian
388
+ multi-model trust score that is reused by both adversarial review and
389
+ conviction.
390
+ - **Append-only hash chain** β€” `audit_logger` builds a Merkle-style chain
391
+ with `verify_chain_integrity()`, which is the right primitive for
392
+ compliance evidence.
393
+ - **MCP as the universal tool bus** β€” every external capability (SAST,
394
+ fuzzers, vuln DBs, web search, GitHub, Postgres) is exposed through
395
+ `mcp_config.json`; this is by far the strongest piece of architecture in
396
+ the codebase and is what makes Aider's tool use uniform.
397
+ - **Multi-agent (Mythos)** β€” Planner emits a probabilistic plan, Explorer
398
+ enumerates hypotheses, Executor invokes tools, Orchestrator routes β€” a
399
+ textbook multi-agent shape with clean message contracts in
400
+ `mythos/agents/base.py`.
401
+
402
+ ### 5.2 Strengths
403
+
404
+ - **Sharp separation between "fix mode" (audit loop) and "find mode"
405
+ (Hermes)** β€” they share gates and the training store but never tangle.
406
+ - **Robust webhook surface** β€” HMAC verification, IP rate-limit, dispatcher
407
+ injection (`set_job_dispatcher`) keeps the receiver pure.
408
+ - **Worker-pool isolation** β€” `worker_pool._run_isolated` puts each test fix
409
+ in its own subprocess, which contains LLM/aider blow-ups well.
410
+ - **Mythos add-on is non-invasive** β€” opt-in via `RHODAWK_MYTHOS=1` and a
411
+ separate FastAPI surface, so the existing Gradio UX is unchanged unless
412
+ you want it.
413
+ - **Persistent learning loop** β€” every attempt, success or failure, lands
414
+ in `training_store` and feeds `lora_scheduler.maybe_trigger_training`.
415
+ The flywheel is real and not aspirational.
416
+
417
+ ### 5.3 Bug surfaces & risks
418
+
419
+ The list below is **prioritised** β€” items are ordered by likely real-world
420
+ impact on stability or security.
421
+
422
+ #### High
423
+
424
+ 1. **`app.py` is a 117 KB god-module.** Boot, UI definition, audit loop,
425
+ subprocess management, MCP-config writing, Hermes UI bindings, and the
426
+ refresh timer all live in one file. This is the biggest stability risk:
427
+ any change ripples broadly and there are no unit tests on Rhodawk
428
+ itself. Recommend extracting the UI definition into `ui/`, the audit
429
+ loop into `audit/`, and process management into `procctl.py`.
430
+ 2. **No test suite for Rhodawk.** `pytest` is invoked only against target
431
+ repos. There is no CI guard against regressions in the orchestration
432
+ logic. This is the single highest-leverage fix.
433
+ 3. **`/data` mode `777` and shared by every tenant.** The Dockerfile sets
434
+ `chmod 777 /data` (because of HF Spaces UID quirks). All tenants share
435
+ `/data/jobs/`, `/data/audit_chain.jsonl`, `/data/store.db`, etc. The
436
+ `tenant_id` is stamped on each job key, but a buggy import or path-
437
+ traversal-style filename would let one tenant's data overwrite
438
+ another's. Add a `pathlib` allowlist + per-tenant subdirectories.
439
+ 4. **Shell-out via `git`, `pytest`, `aider`, `npm`** with target-controlled
440
+ filenames. `run_subprocess_safe` exists, but several callers stitch
441
+ strings before reaching it. Audit every `subprocess.run` for
442
+ `shell=True` and for unvalidated repo paths.
443
+ 5. **Embedding model pre-warm runs in a daemon thread without back-off.**
444
+ If `sentence-transformers` fails (rate-limited HF, no disk), every
445
+ subsequent retrieval call falls back silently to TF-IDF β€” a real
446
+ correctness regression that is invisible to operators. Surface this
447
+ state on the dashboard.
448
+ 6. **Hermes phase state is in-process.** `HermesSession` lives in module
449
+ memory; if `app.py` restarts mid-research the entire session is lost.
450
+ Persist `HermesSession.asdict()` to `/data/hermes/<session_id>.json`
451
+ on every phase transition.
452
+
453
+ #### Medium
454
+
455
+ 7. **`memory_engine.py` (TF-IDF) and `embedding_memory.py` (vec) compete.**
456
+ `app.py` imports both, and the audit loop calls v2 with v1 as silent
457
+ fallback. Two stores will drift. Pick one as the source of truth and
458
+ demote the other to "legacy".
459
+ 8. **Webhook server uses stdlib HTTPServer (single-threaded by default).**
460
+ `start_webhook_server()` should use `ThreadingHTTPServer` (or, ideally,
461
+ move the same handlers to FastAPI now that uvicorn is a dep).
462
+ 9. **`MAX_RETRIES * ADVERSARIAL_REJECTION_MULTIPLIER`** can produce long
463
+ tail loops where a stubborn adversary blocks the pipeline. Add an
464
+ absolute wall-clock cap per audit.
465
+ 10. **JSON job ledger is read/written without `flock`.** Two parallel
466
+ workers updating the same job file race. Use SQLite (which is already
467
+ a dependency) for the job queue too β€” this also fixes (3) by giving
468
+ you per-tenant rows instead of files.
469
+ 11. **`audit_logger` chain integrity is only verified on demand.** If the
470
+ chain has been tampered with, no one notices until someone clicks the
471
+ button. Add a periodic background verifier that pages on a break.
472
+ 12. **Mythos optional deps are mostly commented out** β€” anyone who pip-
473
+ installs the file gets the FastAPI surface but not Pyro/MLflow/RLlib.
474
+ Document the on-demand install path more loudly in `MYTHOS_PLAN.md`.
475
+
476
+ #### Low / hygiene
477
+
478
+ 13. `language_runtime.py` is ~70 KB with deep `if-lang ==` ladders. Replace
479
+ with a `Runtime` class registry plus `entry_points` so adding Go, Rust,
480
+ or .NET is a one-file change.
481
+ 14. Many modules use `time.sleep()` for backoff instead of `tenacity` even
482
+ though `tenacity` is already imported in `app.py`.
483
+ 15. `red_team_fuzzer.py` (62 KB) duplicates patterns that
484
+ `fuzzing_engine.py` already has β€” consolidate.
485
+ 16. `notifier.py` swallows exceptions silently; add a structured failure
486
+ counter.
487
+ 17. `pitch_deck/` and `pitch-deck/` (hyphen vs underscore) coexist as
488
+ sibling directories β€” pick one.
489
+
490
+ ### 5.4 Memory / leak surfaces
491
+
492
+ - `_hermes_logs: list[str]` is unbounded β€” every Hermes run appends without
493
+ truncation. Add a ring buffer (`collections.deque(maxlen=10_000)`).
494
+ - The Gradio `gr.Timer(3)` keeps building string responses even when no
495
+ client is connected. The single-stream coalescing helps, but the
496
+ `live_logs` textbox still grows unboundedly.
497
+ - Aider subprocesses inherit the parent file descriptors; a long-running
498
+ audit can exhaust FDs. Add `close_fds=True` everywhere.
499
+ - The embedding store grows monotonically. Add a TTL eviction in
500
+ `embedding_memory`.
501
+
502
+ ### 5.5 Targeted stabilisation roadmap
503
+
504
+ | Priority | Change | Effort | Payoff |
505
+ |---|---|---|---|
506
+ | πŸ”₯ P0 | Add a `tests/` directory with pytest covering: webhook signature, audit-loop happy path with mocked Aider, audit-chain integrity, MCP-config render | M | Catches future breakage of every gate |
507
+ | πŸ”₯ P0 | Per-tenant subdirectory under `/data/<tenant>/` and a path-allowlist helper | S | Hard isolation between tenants |
508
+ | πŸ”₯ P0 | Migrate `job_queue` from JSON files to the existing SQLite store | S | Removes file-locking races |
509
+ | ⚑ P1 | Carve `app.py` into `ui_blocks.py` + `audit_loop.py` + `procctl.py` (no behaviour change) | M | Drops blast radius of every future change |
510
+ | ⚑ P1 | Switch `webhook_server` to `ThreadingHTTPServer` *or* mount it under the new FastAPI app | S | Concurrency + one fewer port |
511
+ | ⚑ P1 | Surface "embedding model healthy?" on the dashboard | XS | Stops silent fallback to TF-IDF |
512
+ | ⚑ P1 | Persist `HermesSession` after every phase transition | S | Crash-safe research mode |
513
+ | πŸ›  P2 | Replace `if-lang ==` ladders in `language_runtime` with a registry | M | Future polyglot support |
514
+ | πŸ›  P2 | Bounded ring buffers for `_hermes_logs` + Gradio `live_logs` | XS | Stops slow memory growth |
515
+ | πŸ›  P2 | Consolidate `memory_engine` and `embedding_memory` behind one interface | M | One source of retrieval truth |
516
+ | πŸ›‘ P2 | Explicit security pass on every `subprocess.run` for shell injection / path traversal in target-controlled inputs | M | Hardens the polyglot runtime |
517
+ | πŸ›‘ P3 | Background verifier thread for the audit hash-chain that pages on break | S | Compliance evidence stays trustworthy |
518
+
519
+ ### 5.6 Bottom line
520
+
521
+ The architecture is **ambitious, coherent, and unusually mature for a
522
+ single-Space project** β€” the gating pipeline, the MCP tool bus, and the
523
+ Mythos multi-agent / RL extension are genuinely well-thought-out. The two
524
+ things holding it back from production-grade are (a) the absence of a
525
+ self-test suite and (b) the size of `app.py`. Both are mechanical, not
526
+ architectural, problems. Address P0 + P1 above and Rhodawk graduates from
527
+ "impressive HuggingFace Space" to "shippable security platform".