#!/usr/bin/env sh # ๐Ÿค– ops ledger โ€” draft the public SSH-access why-entry for this session. # # ./deploy/ops ledger "canary session for the search dropdown" \ # --ref https://github.com/elevenmessenger/messenger/pull/1193 # # Every session that opens an operator SSH session into a box owes a why-entry # in web/status/ssh/ (RUNBOOK.md ยง Box access) โ€” the rule is per-session, not # per-mutation, so read-only sessions count too. The box-side collector # publishes the who/when metadata automatically; the entry here is the human # "why" half, PR-reviewed (review is the redaction gate), merged like any # other change. This verb only DRAFTS the file โ€” writing prose about why you # were on a box is a judgement call, so a human reads it before it ships. # # --slug filename slug (default: derived from the why text) # --window "..." e.g. "09:00โ€“11:30 UTC" (default: now, marked ongoing) # --ref a PR/issue this session was for (repeatable) set -eu root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" command -v jq >/dev/null 2>&1 || { echo "ops ledger: jq is required (it builds the JSON safely)" >&2; exit 1; } why=""; slug=""; window=""; refs="" while [ $# -gt 0 ]; do case "$1" in --slug) slug="${2:?}"; shift 2 ;; --window) window="${2:?}"; shift 2 ;; --ref) refs="$refs $2"; shift 2 ;; -*) echo "ops ledger: unknown flag $1" >&2; exit 2 ;; *) why="$1"; shift ;; esac done [ -n "$why" ] || { echo 'usage: ops ledger "why this session was on the boxes" [--slug s] [--window "..."] [--ref url]...' >&2 exit 2; } # The operator name is public โ€” take it from git identity, which is what the # existing entries use, and never guess from the machine's username. operator="$(git -C "$root" config user.name || true)" [ -n "$operator" ] || { echo "ops ledger: git config user.name is empty โ€” set it; the entry names the operator publicly" >&2 exit 1; } date="$(date -u +%Y-%m-%d)" [ -n "$window" ] || window="$(date -u +%H:%M)โ€“ UTC (ongoing โ€” fill in the end before the PR)" if [ -z "$slug" ]; then # First few words of the why, lowercased, non-alphanumerics folded to hyphens. slug="$(printf '%s' "$why" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' \ | cut -c1-40 | sed 's/^-//; s/-$//')" fi out="$root/web/status/ssh/$date-$slug.json" [ ! -e "$out" ] || { echo "ops ledger: $out already exists โ€” pick another --slug" >&2; exit 1; } # jq does the quoting, so the why text can contain anything. jq -n --arg date "$date" --arg operator "$operator" --arg window "$window" \ --arg why "$why" --arg refs "$refs" \ '{date: $date, operator: $operator, window: $window, why: $why, refs: ($refs | split(" ") | map(select(. != "")))}' > "$out" cat <