Skip to content

chore(ops): the erlich fleet-cadence units — fleet-status collection + projection refresh (the Fleet (live) block's freshness backbone) #1560

Description

@aarontrowbridge

Problem

The Fleet (live) system-prompt block (amicode #1106, P3b-2) reads two machine-local artifacts:

  • ~/.amico/ops/fleet/projection.json — the role line, refreshed by amico fleet status --projection (requires the amicissimo entitlement + checkout, both now staged on erlich);
  • ~/.amico/ops/fleet-status.json — the devices line ("3/3 reachable… refreshed N min ago").

On the mini both are wired (launchd: co.harmoniqs.fleet-status every 5 min). On erlich — the canonical server since 2026-09 — neither has a cadence: the ops README documents fleet-status as "every 5 min (launchd)" only, ops/systemd/ carries no fleet-status unit, and the live fleet-status.json was last collected ~2026-09-20 (the block rendered "refreshed 7187 min ago" — five days stale — while claiming a 5-min cadence). The projection is currently a one-shot (generated 2026-09-25 by hand during the #1301 deployment pass); nothing refreshes it, so the role line will drift silent/stale exactly the way the June notturno timer did — regime-2 breakage, invisible by construction.

Same family: co.harmoniqs.role-parity.{service,timer} is versioned but was never installed on erlich either (discovered in the same pass).

Approach

  1. Add a versioned systemd pair ops/systemd/co.harmoniqs.fleet-status.{service,timer}:
    • ExecStart runs the already-versioned ~/.amico/ops/fleet-status.sh then the projection refresh (~/.local/bin/amico fleet status --projection), OnCalendar=*:0/5 (launchd parity), Persistent=true.
    • Environment=PATH=%h/.local/bin:... in the unit itself — the shard-watch deployment proved systemd's default PATH resolves /usr/bin/node v12 on erlich, which SyntaxErrors the dist; the PATH must be carried by the versioned unit, not only by machine-local drop-ins (one place, all hosts).
    • Honest failure shape: fleet-status.sh is set -uo pipefail and its ssh probes already degrade to warnings; the projection verb's exit 75 (bootstrap exception) must NOT mark the cadence failed on an unenrolled host — either SuccessExitStatus=75 or an explicit guard in the invocation.
  2. Install + enable on erlich (one-time, per the ops README's systemd convention); live-verify: fleet-status.json collected_at < 6 min old, projection freshness.counter advancing, and a fresh session's Fleet (live) block shows a fresh devices line.
  3. README row: the fleet-status entry's cadence column gains the erlich systemd pair (mirroring how session-archive/shard-watch document both surfaces).

Acceptance criteria

  • ops/systemd/co.harmoniqs.fleet-status.{service,timer} versioned; timer cadence 5 min; PATH + SuccessExitStatus=75 (or equivalent guard) carried in the unit.
  • ops/README fleet-status row documents both surfaces (launchd + erlich systemd) and the projection-refresh responsibility.
  • Installed and armed on erlich; live verification receipts: fresh collected_at, advancing projection freshness.counter, Fleet (live) block shows fresh devices age.
  • role-parity pair also installed on erlich while we're in the units dir (its README row already documents it — erlich was simply skipped).

Prior art

  • Deployment pass evidence (2026-09-25, session ledger session-20260925-system-engine-phase0): projection generated by hand (amico fleet status --projection → ok, role: server); fleet-status.json last collected ~5 days prior; no fleet-status or role-parity systemd units present on erlich.
  • The stale-fleet-status symptom was visible in the live prompt of the session doing the deploying ("refreshed 7187 min ago" beside a claimed 5-min cadence).
  • ADR-0001 (amicissimo Managed Tunnel: self-healing component + extension launcher + connect flow #286) names exactly this class as regime β.2 — Vendor + pin opencode in the VSIX #2 — the fix is registration, not a local cron.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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