Skip to content

Fleet hardening: lid-close/internet-loss disconnect and fork guard #324

Closed

Description

@aarontrowbridge

Important

Problem — Closing the MacBook lid kills the fleet tunnel, so chat sessions appear to stop even though the canonical server on the Mac mini (707 sessions, KeepAlive) keeps running. Tunnel used 30s/3 (90s detection) and the fleet guard was missing on the mini with a stale ~/harmoniqs path, so a port-race could fork a laptop-local opencode.db (3.2M, 1 session) during reconnect gaps. Dangling ~/.config/opencode/opencode.json symlink and duplicate Host the-feynmachine masked health.
Approach — Harden the fleet as ops: install fleet guard on both hosts with frozen-binary resolution (mini execs ~/.amico/server/bin/opencode, client exits 1), tune amico-tunnel to 15/2 + TCPKeepAlive via launchd, archive the forked client DB to restore single-writer invariant, fix the opencode.json symlink and ssh dup. No silent fork, faster rejoin on wake or internet loss (LAN-first .local survives offline).
Scope — in: guard script both hosts, tunnel plist keepalive, fork archive/cleanup, symlink/ssh hygiene, verification. out: full Managed Fleet product feature (ADR 0005 server mode/token/rejoin)
Assumptions — mini is canonical server, macbook is client, LAN-first Match host is desired

Acceptance Criteria

  • ~/.local/bin/amico-opencode-fleet-guard exists on mini and macbook: exits 1 on client, execs frozen binary on server (version check passes)
  • ~/Library/LaunchAgents/co.harmoniqs.amico-tunnel.plist on macbook uses ServerAliveInterval 15, CountMax 2, TCPKeepAlive yes, 127.0.0.1:4096:127.0.0.1:4096, KeepAlive true
  • No live opencode*.db on macbook (archived to ~/.local/share/opencode/archive/), curl http://127.0.0.1:4096/session 200 via tunnel, lsof :4096 shows ssh LISTEN only
  • ~/.config/opencode/opencode.json symlink points to vault-aaron/dotfiles/config/opencode.json, fleet-status.json guard ok, served 639/707
  • Lid-close/wake and internet-loss on LAN still show 200 within ~30s after wake (launchd respawn)

Testing Decisions

Extend existing fleet_verb / fleet_registry tests and ADR 0005 fixtures; reuse fleet-status.sh guard check. No new suite for ops-only hardening — verify via curl/lsof/sqlite3 counts.

Key Decisions

Guard resolves frozen bin first (same order as amicode-server.sh) to survive VSIX refresh channel-flip. Tunnel 15/2 matches amico-mini Host block, trades 90s for 30s detection without flapping.

Constraints & Invariants

Single writer on opencode-dev.db on mini, client never spawns, loopback-only binding.

Prior Art

ADR 0005 Managed Fleet, fleet skill playbook, 2026-08-07 incident fixtures

Source

Part of fleet hardening

Notes

Operational fix applied 2026-08-09 directly on hosts; issue tracks hardening for review and repo template.

Metadata

Metadata

Assignees

No one assigned

    Labels

    hitlNeeds human review before merge

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions