eleven / ocho Public

Clone
git clone https://amadan.net/eleven/ocho

Plain git — no account needed to clone.

Download

Download this file

1#!/usr/bin/env sh
2# πŸ€– ops ledger β€” draft the public SSH-access why-entry for this session.
3#
4# ./deploy/ops ledger "canary session for the search dropdown" \
5# --ref https://github.com/elevenmessenger/messenger/pull/1193
6#
7# Every session that opens an operator SSH session into a box owes a why-entry
8# in web/status/ssh/ (RUNBOOK.md Β§ Box access) β€” the rule is per-session, not
9# per-mutation, so read-only sessions count too. The box-side collector
10# publishes the who/when metadata automatically; the entry here is the human
11# "why" half, PR-reviewed (review is the redaction gate), merged like any
12# other change. This verb only DRAFTS the file β€” writing prose about why you
13# were on a box is a judgement call, so a human reads it before it ships.
14#
15# --slug <s> filename slug (default: derived from the why text)
16# --window "..." e.g. "09:00–11:30 UTC" (default: now, marked ongoing)
17# --ref <url> a PR/issue this session was for (repeatable)
18set -eu
19
20root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
21command -v jq >/dev/null 2>&1 || {
22 echo "ops ledger: jq is required (it builds the JSON safely)" >&2; exit 1; }
23
24why=""; slug=""; window=""; refs=""
25while [ $# -gt 0 ]; do
26 case "$1" in
27 --slug) slug="${2:?}"; shift 2 ;;
28 --window) window="${2:?}"; shift 2 ;;
29 --ref) refs="$refs $2"; shift 2 ;;
30 -*) echo "ops ledger: unknown flag $1" >&2; exit 2 ;;
31 *) why="$1"; shift ;;
32 esac
33done
34[ -n "$why" ] || {
35 echo 'usage: ops ledger "why this session was on the boxes" [--slug s] [--window "..."] [--ref url]...' >&2
36 exit 2; }
37
38# The operator name is public β€” take it from git identity, which is what the
39# existing entries use, and never guess from the machine's username.
40operator="$(git -C "$root" config user.name || true)"
41[ -n "$operator" ] || {
42 echo "ops ledger: git config user.name is empty β€” set it; the entry names the operator publicly" >&2
43 exit 1; }
44
45date="$(date -u +%Y-%m-%d)"
46[ -n "$window" ] || window="$(date -u +%H:%M)– UTC (ongoing β€” fill in the end before the PR)"
47if [ -z "$slug" ]; then
48 # First few words of the why, lowercased, non-alphanumerics folded to hyphens.
49 slug="$(printf '%s' "$why" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' \
50 | cut -c1-40 | sed 's/^-//; s/-$//')"
51fi
52
53out="$root/web/status/ssh/$date-$slug.json"
54[ ! -e "$out" ] || { echo "ops ledger: $out already exists β€” pick another --slug" >&2; exit 1; }
55
56# jq does the quoting, so the why text can contain anything.
57jq -n --arg date "$date" --arg operator "$operator" --arg window "$window" \
58 --arg why "$why" --arg refs "$refs" \
59 '{date: $date, operator: $operator, window: $window, why: $why,
60 refs: ($refs | split(" ") | map(select(. != "")))}' > "$out"
61
62cat <<EOF
63drafted $out
64$(cat "$out")
65
66Next: read it as a stranger would (it is published, forever), fix the window,
67then commit it as a tiny standalone PR β€” review is the redaction gate.
68EOF
69