# ADR-013 — Miner distribution policy: standalone, never bundled, never in a browser - **Status:** Accepted - **Date:** 2026-10-10 - **Related:** ADR-006 (founder-mining disclosure; both miners released publicly with no hidden speed edge), audit 2026-09-22 finding B2 (checksum drift), audit 2026-10-03 (supply chain is the real risk; `moonbite-wallet.exe` tracked next to the miner), infra audit 2026-10-09 L5 (release authenticity integrity-only), `deploy/RELEASE-SIGNING.md`. ## Context MoonBite is a CPU-mined proof-of-work coin. Its miner is the full node (`moonbited`) driven by a small script that calls `generatetoaddress` over loopback RPC. The wallet is a separate program that handles keys and never mines. Both are distributed as downloads from moonbite.org and GitHub Releases. Three pressures act on how these are packaged: 1. **User trust.** A download that quietly installs a miner next to a wallet, or a wallet that turns out to use the CPU, is indistinguishable from cryptojacking malware. The project's credibility rests on the miner being something the user explicitly chose, started and can see running. 2. **Antivirus heuristics.** A RandomX miner is, behaviourally, what AV engines are tuned to catch: a JIT writing and executing memory, several gigabytes of RAM, every core saturated for hours, from an unsigned binary almost no one has seen. Every additional suspicious trait (packer, self-extraction to `%TEMP%`, auto-start, downloading code) compounds the score. 3. **Pseudonymity.** The project is run under a pseudonym with no legal entity. Authenticode OV/EV certificates and Apple Developer ID notarization require a verified legal identity. That path is closed until an entity exists, so provenance has to come from somewhere else. Until this ADR, `release/miner/` in the repository held `moonbite-wallet.exe` next to `moonbited.exe`, the PyInstaller spec for the desktop wallet used UPX and the build docs recommended `--onefile`, and the Windows launcher invoked PowerShell with `-ExecutionPolicy Bypass`. ### Survey: is there any browser mining? `static/` and `templates/` were searched for `WebAssembly`, `.wasm`, `new Worker`, `importScripts`, `SharedArrayBuffer`, `hashcash`, `cryptonight` and `coinhive`. There are no matches. `static/mining-god.js` draws a particle field and a sparkline from a synthetic, `Math.random`-jittered "hashrate"; it performs no hashing and talks to no node. The only `RandomX` strings in `templates/` are prose describing the algorithm. The site-side `/api/mining/*` endpoints and the `/start` page are a demo surface, and `release/miner/README.md` already says so. Conclusion: no browser mining exists anywhere in the web app, and this ADR forbids adding any. ## Decision 1. **The miner is never bundled with the wallet, and the wallet never carries a miner.** Two archives per platform, from two source directories: | Archive | Contents | Source | |---|---|---| | `moonbite-miner--.{zip,tar.gz}` | `moonbited`, `moonbite-cli`, `mine.ps1`/`Mine-MoonBite.bat` or `mine.sh`, `README.md`, `ANTIVIRUS.md` | `release/miner/` | | `moonbite-wallet--.{zip,tar.gz}` | the wallet app, `README.md` | `release/wallet/` | `deploy/miner/build-windows-bundle.py` refuses to build an archive whose member list crosses the line. `moonbite-wallet.exe` moves from `release/miner/` to `release/wallet/`. 2. **The miner never runs in a browser.** No WebAssembly, Web Worker or server-side mining-on-behalf-of-the-user is ever added to the site. Any visual on the site that resembles mining is labelled a demo and performs no proof-of-work. Real mining is a native node process the user starts. 3. **Standalone download, started by the user, running only while the user keeps it running.** No installer, no auto-start entry, scheduled task, service, cron job or login item is created by anything in a user download. Operator tooling that does install persistence on seed/explorer hosts (`install-autostart.sh`) is gated behind an explicit `--i-am-the-operator` flag and root, and is not shipped to users. 4. **No runtime packers and no self-extraction.** `upx=False` in every PyInstaller spec; one-directory builds, never `--onefile`; no obfuscation, no bytecode cipher. The node binaries are plain mingw/gcc output, stripped of debug symbols only. 5. **No self-update and no downloading.** The miner scripts and the Python miner never fetch, write or execute code. Updates are a new release the user downloads and verifies. 6. **No privilege and no security-setting changes.** The scripts never request administrator or root rights, never add Defender exclusions and never override the PowerShell execution policy. The `.bat` wrapper calls `powershell -NoProfile -File mine.ps1` and, if the policy blocks it, explains the user-scope `Set-ExecutionPolicy -Scope CurrentUser RemoteSigned` plus `Unblock-File` so the choice is the user's. 7. **Every launcher prints the SHA-256 of the binaries it is about to run** and points at the published `SHA256SUMS.txt`. 8. **A full Windows version resource** (CompanyName "MoonBite Labs", FileDescription, ProductName, FileVersion matching the release tag) is embedded in PyInstaller builds via `windows-version-info.txt`. 9. **Signed where identity allows; attested and reproducible everywhere.** - `SHA256SUMS.txt` for every archive and every executable inside it, generated by the build from the artifacts, never hand-typed; verified in CI by `deploy/verify-release-checksums.py`. - A minisign signature over the manifest with the key in `deploy/moonbite-release.pub` (key ceremony per `deploy/RELEASE-SIGNING.md`). - GitHub build-provenance attestations (Sigstore) for CI-built archives, verifiable with `gh attestation verify`. - Deterministic archives (fixed member order, fixed timestamps, fixed compression) and documented build inputs so a third party can rebuild and compare. - Authenticode and Apple notarization are adopted the day a legal entity exists to hold the certificate. Until then `codesign_identity=None` and `skip_notarization=True` are stated in the spec rather than faked with a self-signed certificate, which buys nothing with SmartScreen and looks like evasion. 10. **AV vendor submissions each release.** Every new executable is submitted to the major vendors' false-positive portals as part of the release checklist, and users are given the same list in `release/miner/ANTIVIRUS.md` together with the reasons a legitimate RandomX miner trips heuristics. ### Amendment 2026-10-15: the launcher bypasses the execution policy for itself Item 6 is changed for `Mine-MoonBite.bat` only, by the owner's decision. Most Windows 11 PCs ship with the `Restricted` execution policy, which blocks every script, signed or not, and downloaded scripts also carry the "from the internet" mark. In practice the double-click launcher failed for nearly every new miner, who then had to type policy commands first. Signing does not solve it (a signed script is still blocked under `Restricted`), and the signing routes open to a pseudonymous project are uncertain (SignPath Foundation, applied for separately). The launcher now runs `powershell -NoProfile -ExecutionPolicy Bypass -File mine.ps1`. The bypass is scoped to that one process and that one script next to the launcher; no policy, registry key or other setting changes, and the scripts still never request administrator rights or touch Defender. The cost named in the rationale below stands: antivirus engines score this line, so the launcher may be flagged more often. `ANTIVIRUS.md` and the per-release AV submissions remain the mitigation. Running `mine.ps1` directly still obeys the user's policy. ## Rationale - Separation is the only way to make "we did not put a miner on your machine" provable: a user who downloaded the wallet can open the archive and see that no node binary is present. Bundling for convenience would save one download and cost the project its clearest honesty signal. - Browser mining is either theatre (a page cannot run RandomX at a useful rate) or abuse (using visitors' CPUs). Neither is acceptable for a coin whose premise is that the user's own machine mines for the user. - Each AV-hygiene item removes a trait that the engines score, so the only remaining signal is the one the miner cannot avoid: it is a miner. That residual is addressed by documentation and vendor submissions, not by asking users to lower their defences. - `-ExecutionPolicy Bypass` is the most common line in malicious batch droppers. Even though the policy is not a security boundary, shipping the bypass trains users to accept it and gives engines a reason to flag the wrapper. - The pseudonymity constraint is real and is stated rather than worked around. Checksums prove integrity, minisign proves the manifest came from the project key, attestations prove which commit and workflow produced the file, and reproducibility lets anyone check that the commit produces the file. Together they are stronger provenance than an OV certificate bought by a shell company; what they do not buy is SmartScreen reputation, and the user-facing documents say so plainly. ## Consequences - Two download buttons and two archives per platform; `web_app.py`'s `_MINER_BUNDLES["wallet"]` currently serves a bare `moonbite-wallet.exe` and should move to the `moonbite-wallet-windows-x86_64.zip` name when the web route owner next touches it. - Desktop-wallet builds are larger (no UPX, one directory). Acceptable. - Users on a default Windows execution policy see one explanatory message the first time instead of a silent bypass; the README documents the two user-scope commands. - Release checklist grows: build both archives, regenerate and sign `SHA256SUMS.txt`, confirm attestations, submit executables to AV portals, bump `windows-version-info.txt` with the tag. - `install-autostart.sh` now exits with an explanation unless invoked with `--i-am-the-operator` as root. - Any future proposal to embed mining in the wallet, the site or a browser extension requires superseding this ADR, not amending it.