#!/usr/bin/env sh # ๐Ÿค– ops โ€” the one operator command surface for deploying and managing the # fleet. Every verb encodes knowledge that used to live only in prose spread # across CLAUDE.md, docs/server-releases.md, docs/multi-edge-dev-cutover.md and # the operator runbook โ€” prose drifts silently; a script that runs drifts # loudly. When a verb's advice goes stale, fix it IN THE SCRIPT, not in a doc. # # This file is deliberately nothing but a signpost: each verb stays a readable # standalone script beside it (the outlive-AI rule โ€” a human can open any one # of them and understand it in a sitting), and this dispatcher only routes. # Add a verb = add a script + one case arm + one usage line. set -eu here="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" usage() { cat <<'EOF' ops โ€” the operator command surface ./deploy/ops doctor [section] can I deploy right now? (read-only preflight) ./deploy/ops validate [section] run every local check (go|web|shell|infra) ./deploy/ops provision [args] refresh box systemd units / set the short-link apex / create an operator account on a box ./deploy/ops publish "notes" build main -> release -> point edge at it ./deploy/ops promote move beta/stable to a published version ./deploy/ops ship [box...] make every box's instances catch up NOW ./deploy/ops canary [slug] per-session test instances (test-.11ch.at) ./deploy/ops dev the two-node dev mesh (tofu / scp+stage+swap) ./deploy/ops ledger "why..." draft the public SSH-access why-entry ./deploy/ops mesh seed [--prune] [box] replicate routes (+env) to a mesh peer ./deploy/ops pages push [file...] push committed web/status data files to the status box (default: carbon.json) Start with `ops doctor` โ€” it checks every credential and access path the other verbs need, and prints the fix under each failure. `ops validate` is its code-side twin: every local check (Go, web, shell, tofu) in one pass, needing no credentials and touching no box โ€” run it before opening a PR. Verbs that open box SSH sessions (ship, canary, dev deploy) incur a why-entry in the public access ledger; `ops ledger` drafts it. Env overrides (defaults live in the verb scripts): LCHAT_BOXES fleet box ssh aliases (doctor, ship) LCHAT_CANARY_BOX the box canaries live on (default: the dev mesh; prod is the deliberate exception) LCHAT_RELEASES_REPO the public releases repo No verb for your task? EXTEND ops โ€” a new verb or flag in a small PR (deploy/README.md ยง The operator surface) โ€” never a hand-run sequence reconstructed from docs or runbooks. EOF } verb="${1:-}" [ $# -gt 0 ] && shift case "$verb" in doctor) exec "$here/doctor.sh" "$@" ;; validate) exec "$here/ops-validate.sh" "$@" ;; provision) exec "$here/ops-provision.sh" "$@" ;; publish|promote|ship) exec "$here/ops-release.sh" "$verb" "$@" ;; canary) exec "$here/ops-canary.sh" "$@" ;; dev) exec "$here/ops-dev.sh" "$@" ;; ledger) exec "$here/ops-ledger.sh" "$@" ;; mesh) exec "$here/ops-mesh.sh" "$@" ;; pages) exec "$here/ops-pages.sh" "$@" ;; ""|-h|--help|help) usage ;; *) printf 'ops: unknown verb %s\n\n' "$verb" >&2 usage >&2 exit 2 ;; esac