181 lines · 11.4 KB · HTML
RawDownload
<header>  <h1>Hermes Box Lite</h1>  <p class="dek">A practical guide to creating, using, backing up, restoring, and repairing isolated agent boxes.</p></header> <div class="callout note">  <span class="ico" aria-hidden="true">i</span>  <div class="body">    <div class="title">The operating model</div>    <p>Tools are replaceable; state is precious. Claude Code, Codex, Hermes, Executor, and Neovim live in an isolated smolvm VM. User state lives under <code>/data</code> and travels through encrypted backups.</p>  </div></div> <div class="page-layout">  <aside class="section-nav" aria-label="On this page">    <p class="label">On this page</p>    <nav>      <ul>        <li><a href="#quick-start">Quick start</a></li>        <li><a href="#daily-use">Daily use</a></li>        <li><a href="#backup-restore">Backup and restore</a></li>        <li><a href="#health-repair">Health and repair</a></li>        <li><a href="#configuration">Configuration</a></li>        <li><a href="#security">Security model</a></li>        <li><a href="#troubleshooting">Troubleshooting</a></li>      </ul>    </nav>  </aside>   <div class="page-content">    <section id="quick-start">      <h2>Quick start</h2>      <p>Run these commands from the <code>hermes-box-lite</code> repository on macOS, or on x86_64/arm64 Linux with KVM available and your user allowed to access <code>/dev/kvm</code>. Install <code>smolvm</code>, GPG, curl, jq, tar, awk, and standard Bash command-line tools first.</p>      <p>On Linux, verify virtualization access before creating a box:</p>      <pre><code>test -r /dev/kvm -a -w /dev/kvmsmolvm machine ls</code></pre>       <h3>1. Create and verify a box</h3>      <pre><code>./box new alpha./box doctor alpha</code></pre>      <p>Creation boots Ubuntu with configurable CPU, memory, and a 64 GiB default overlay, installs the toolchain and a full-SHA-pinned Hermes checkout, starts Executor, registers its authenticated HTTP MCP endpoint with Claude and Codex, and runs health checks. Hermes begins durably disabled until setup or a migration cutover is complete.</p>       <h3>2. Enter and authenticate</h3>      <pre><code>./box enter alpha</code></pre>      <p>You enter as <code>agent</code> in a persistent tmux session under <code>~/workspace</code>. Authenticate the tools you intend to use:</p>      <pre><code>hermes setup --portalclaudecodex</code></pre>       <h3>3. Open Executor and save the state</h3>      <pre><code>./box open alpha./box save alpha</code></pre>      <p><code>box open</code> waits for the authenticated forwarded endpoint, then launches the Executor UI without printing its bearer token. <code>box save</code> quiesces Hermes and Executor, checkpoints and verifies SQLite, excludes transient/native caches and locks, validates and encrypts the archive, then selectively restores the prior service state.</p>    </section>     <section id="daily-use">      <h2>Daily use</h2>      <p>The full command reference (every <code>box</code> subcommand and what it does) lives in        <a href="../README.md#commands">the README's Commands table</a> — kept there as the single        source of truth so it can't drift out of sync with this page.</p>       <h3>Inside the box</h3>      <pre><code>hb statushb versionshb doctorhb logs executorhb logs hermeshb verify-statehb acknowledge-active-pathshb cutover-ready</code></pre>      <p>The workload supervises Executor and the Hermes gateway without duplicate processes. Doctor is read-only and treats deliberate quiescence as policy, while start and repair remain explicit mutations. Gateway enable requires the full single-writer confirmation phrase printed by <code>hb gateway-enable</code>.</p>    </section>     <section id="backup-restore">      <h2>Backup and restore</h2>      <p>The exact guarantees each of these commands makes — what gets quiesced, validated,        excluded, and verified, step by step — are documented once, in        <a href="../README.md#backup-and-restore-guarantees">README's Backup and restore guarantees</a>,        so they can't quietly drift out of sync with this walkthrough. What follows here is the        practical "what do I actually type" version.</p>       <h3>Create a backup</h3>      <pre><code>./box save alpha</code></pre>      <p>By default, this creates <code>backups/alpha-&lt;timestamp&gt;.tar.gz.gpg</code> and refuses to overwrite an existing destination. Set a passphrase in the environment for unattended use:</p>      <pre><code>BOX_PASSPHRASE='your-local-secret' ./box save alpha</code></pre>       <h3>Restore into a new box</h3>      <pre><code>./box load backups/alpha-20260625-120000.tar.gz.gpg beta</code></pre>      <p>The archive is decrypted and validated before a VM is even created. The Hermes gateway stays disabled afterward, so a restore rehearsal can never accidentally claim a live messaging identity.</p>       <h3>Import from Eventide or another Hermes host</h3>      <pre><code>./box import-hermes alpha hermes-backup.zip --map /Users/davis=/data/home/agent</code></pre>      <p>Validates and atomically imports native Hermes state with the gateway left disabled. Review the        import manifest, run <code>hb acknowledge-active-paths</code>, then require <code>hb cutover-ready</code>        before enabling the gateway — see the README link above for exactly what the import does and skips.</p>       <h3>Inspect a backup without a VM</h3>      <pre><code>./box extract backups/alpha-20260625-120000.tar.gz.gpg</code></pre>      <p>Extraction validates the archive and writes to a new directory under <code>backups/</code>. Treat extracted contents as sensitive: they can contain credentials, sessions, private work, and Executor data.</p>       <div class="callout warn">        <span class="ico" aria-hidden="true">!</span>        <div class="body">          <div class="title">Backups preserve state, not an exact machine</div>          <p>Hermes is pinned by full Git SHA and can be seeded from an ignored local Git bundle for a custom Eventide commit. Other OS and tool packages can still drift; this remains a state backup, not an offline VM image.</p>        </div>      </div>    </section>     <section id="health-repair">      <h2>Health and repair</h2>      <p>Start with the doctor whenever a box feels partly broken:</p>      <pre><code>./box doctor alpha</code></pre>      <p>Doctor performs a bounded, authenticated MCP handshake through the guest-local endpoint and, when web exposure is enabled, the forwarded host endpoint. It uses jq to validate the HTTP 200 JSON <code>initialize</code> result, negotiated protocol version, response content type, and session ID, sends the initialized notification, then closes the session best-effort. A bare listener, malformed result, 404, or HTTP 500 response fails health. Without an exposed port, doctor reports the host check as skipped.</p>      <p>If managed tools, profiles, or MCP wiring need repair, re-run provisioning:</p>      <pre><code>./box repair alpha</code></pre>      <p>Repair quiesces Hermes and Executor, refreshes packages and repository-owned guest assets, checks out the configured Hermes SHA exactly, resumes the prior service policy, repairs MCP wiring, and runs the doctor.</p>       <h3>Remove a box safely</h3>      <pre><code>./box rm alpha</code></pre>      <p>The command reports whether it can find a recent backup and requires the exact box name as confirmation. For intentional non-interactive deletion:</p>      <pre><code>./box rm alpha --force</code></pre>    </section>     <section id="configuration">      <h2>Configuration</h2>      <p>Edit <code>box.env</code> before creating or repairing a box.</p>      <div class="table-wrap" role="region" aria-label="Hermes Box Lite configuration" tabindex="0">        <table>          <caption>Where each setting lives</caption>          <thead>            <tr><th scope="col">Topic</th><th scope="col">See</th></tr>          </thead>          <tbody>            <tr><th scope="row">Every setting and its effect</th><td><code>box.env</code> itself — each key has an inline comment, and it's the literal source of truth this page would otherwise just be restating.</td></tr>            <tr><th scope="row">Tool installation paths and durable state</th><td><a href="../README.md#tool-installation-and-state">README's Tool installation and state table</a>.</td></tr>          </tbody>        </table>      </div>      <p>Provisioning installs a root-owned copy at <code>/etc/hermes-box.env</code>, so guest helpers use the same settings as the host workflow.</p>    </section>     <section id="security">      <h2>Security model</h2>      <ul>        <li>The VM has no host filesystem mounts.</li>        <li>Executor's forwarded web port is host-loopback-only.</li>        <li>Hermes API forwarding is disabled by default and host-loopback-only when enabled.</li>        <li>Networking is always enabled for provisioning and agent tools.</li>        <li>Claude, Codex, Hermes, Executor, and plugins share one guest account and credential set.</li>        <li>The <code>agent</code> user has passwordless sudo inside the guest.</li>        <li>Encrypted backups and extracted state should be handled as secret material.</li>      </ul>      <p>The VM is the host-protection boundary. Tools inside a box are not isolated from one another. A compromised tool, plugin, MCP source, or prompt-injected agent may access the other tools' credentials and workspace.</p>    </section>     <section id="troubleshooting">      <h2>Troubleshooting</h2>      <h3>Executor or MCP is unhealthy</h3>      <pre><code>./box doctor alpha./box repair alpha</code></pre>      <p>Inside the box, inspect <code>hb status</code> and <code>hb logs executor</code>. Run <code>hb wire-mcp</code> to replace stale legacy stdio wiring with the authenticated HTTP configuration.</p>       <h3><code>box open</code> reports success but no browser appears</h3>      <p>This is expected on a headless host reached over SSH or Tailscale rather than at its console — see <a href="../README.md#executor-and-mcp">README's Executor and MCP section</a> for how to reach the UI from a separate client machine instead.</p>       <h3>An operation says the box is locked</h3>      <p>Another mutation may be running. Locks contain an owning PID and stale locks are recovered automatically after that process exits. Do not manually remove a lock while a save, load, repair, or delete is active.</p>       <h3>A restore fails before VM creation</h3>      <p>The passphrase may be incorrect, or the decrypted archive may be corrupt or unsafe. This failure intentionally occurs before provisioning so it does not leave an orphan VM.</p>       <h3><code>box new</code> fails with a Hermes installer checksum error</h3>      <p>Upstream has rotated <code>install.sh</code> since <code>HERMES_INSTALLER_SHA256</code> in <code>box.env</code> was last pinned. Run <code>make check-hermes-pin</code> to confirm the drift and see the current upstream hash, review the new installer, then update <code>box.env</code> yourself.</p>       <h3>Validate the repository</h3>      <pre><code>make check</code></pre>      <p>This requires ShellCheck, Python 3, and jq, then runs Bash/Python syntax checks, static contracts, protocol-health regressions, encrypted archive round trips, native Hermes ZIP/import safety tests, validation-before-VM tests, cleanup checks, and mock failure rollback.</p>    </section>  </div></div>