workstation: rename tmux persistence out of the t3 namespace [ci skip]
Viktor's correction: this feature is about the tmux web-terminal sessions, not t3 — t3 auto-saves its own threads (~/.t3 state + daily t3-backup-state). Renamed t3-tmux-sessions -> tmux-persist (units tmux-persist-save.timer / tmux-persist-restore.service, state /var/lib/tmux-persist), header rescoped to say exactly that. Same mechanism, correct taxonomy. Old units removed, state migrated, re-verified live (5 emo + 3 wizard sessions snapshotted). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
2e4f48f3fc
commit
e7fbf986fb
6 changed files with 17 additions and 12 deletions
|
|
@ -553,7 +553,7 @@ Separate from the in-cluster namespace-owner model above, the **devvm** (`10.0.1
|
|||
5. (Optional — Viktor's call per user) Grant direct master push: add their login to the `master` branch-protection push + merge whitelists (`PATCH /api/v1/repos/viktor/infra/branch_protections/master`). Done for `ebarzin` 2026-06-10.
|
||||
6. Verify: branch push succeeds; a `master` push succeeds for whitelisted users and is rejected with `Not allowed to push to protected branch` otherwise.
|
||||
|
||||
**Session persistence (2026-06-10):** named tmux sessions (each running one Claude conversation) survive devvm reboots — `t3-tmux-save.timer` (5-min) snapshots every roster user's sessions (name, cwd, conversation uuid from argv or the cwd-slug transcript dir) to `/var/lib/t3-tmux-state/<user>.tsv`, and `t3-tmux-restore.service` recreates missing sessions at boot with `claude --resume <uuid>` (per-session idempotent; also handles partial loss). Conversations themselves were always durable (`~/.claude/projects/`); this persists the session wiring.
|
||||
**Web-terminal session persistence (2026-06-10):** the tmux-based web terminal's named sessions (each running one Claude conversation) survive devvm reboots — `tmux-persist-save.timer` (5-min) snapshots every terminal user's sessions (name, cwd, conversation uuid from argv or the cwd-slug transcript dir) to `/var/lib/tmux-persist/<user>.tsv`, and `tmux-persist-restore.service` recreates missing sessions at boot with `claude --resume <uuid>` (per-session idempotent; also handles partial loss). This is a **tmux/terminal-surface** feature, deliberately outside the t3 namespace: the t3 chat surface persists its own threads (`~/.t3` state, plus the daily `t3-backup-state` dump), and Claude conversations themselves were always durable (`~/.claude/projects/`) — what this adds is the volatile tmux wiring.
|
||||
|
||||
**Status (2026-06-10):** built + verified on the live host — capacity (8 GiB swap), config inheritance, roster-driven provisioner, per-user locked clone, per-user OIDC kubeconfig + the `oidc-power-user-readonly` ClusterRole + emo's `k8s_users` entry (applied + impersonation-verified), the Authentik `T3 Users` edge gate, **the emo Phase-5 cutover (own clone + launcher repoint + `code-shared` removal, completed 2026-06-10) and emo's contribute access (`ebarzin` write collaborator + PAT + protected `master`)**. Per the live `/etc/skel` design, non-admin `~/.claude/{rules,skills}` symlinks into the admin base are **kept** (they ARE the shared-base delivery mechanism — the plan's step to remove them is obsolete). **Remaining (held / future):** the offboarding apply-side (Phase 7), per-user MCP/auth injection, and roster-reconciled `T3 Users` membership. See `../runbooks/offboard-user.md` for deprovisioning.
|
||||
|
||||
|
|
|
|||
|
|
@ -259,8 +259,8 @@ run systemctl enable t3-autoupdate.timer >/dev/null 2>&1 || true
|
|||
# tmux session persistence: periodic snapshot + boot-time restore (reboot
|
||||
# survival for users' named claude sessions). Safe to --now: save is a
|
||||
# read-only snapshot; restore is per-session idempotent.
|
||||
run systemctl enable --now t3-tmux-save.timer >/dev/null 2>&1 || true
|
||||
run systemctl enable t3-tmux-restore.service >/dev/null 2>&1 || true
|
||||
run systemctl enable --now tmux-persist-save.timer >/dev/null 2>&1 || true
|
||||
run systemctl enable tmux-persist-restore.service >/dev/null 2>&1 || true
|
||||
|
||||
# 6) regenerate /etc/ttyd-user-map + dispatch.json from the desired state (SSoT:
|
||||
# a roster entry removed here DISAPPEARS, which is what the offboarding cut relies on)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ After=network.target local-fs.target
|
|||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/t3-tmux-sessions restore
|
||||
ExecStart=/usr/local/bin/tmux-persist restore
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
@ -3,4 +3,4 @@ Description=Snapshot workstation tmux sessions (name -> claude conversation) for
|
|||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/t3-tmux-sessions save
|
||||
ExecStart=/usr/local/bin/tmux-persist save
|
||||
|
|
@ -1,28 +1,33 @@
|
|||
#!/usr/bin/env bash
|
||||
# Persist workstation tmux sessions across devvm reboots.
|
||||
# Persist WEB-TERMINAL (ttyd/tmux) sessions across devvm reboots.
|
||||
#
|
||||
# Scope: the tmux-based web terminal only. The t3 chat surface persists its
|
||||
# own threads (~/.t3 state.sqlite, backed up daily by t3-backup-state) — this
|
||||
# script is about the tmux sessions, which are otherwise memory-only. Users
|
||||
# come from /etc/ttyd-user-map (the terminal surface's roster-derived map).
|
||||
#
|
||||
# save — snapshot every roster user's live tmux sessions to
|
||||
# /var/lib/t3-tmux-state/<user>.tsv (name, cwd, claude session
|
||||
# /var/lib/tmux-persist/<user>.tsv (name, cwd, claude session
|
||||
# uuid). The uuid is sniffed from the claude process's OPEN
|
||||
# transcript fd (~/.claude/projects/<slug>/<uuid>.jsonl), so it is
|
||||
# correct regardless of how the session was launched (fresh via
|
||||
# start-claude.sh or an explicit --resume). Runs every 5 min via
|
||||
# t3-tmux-save.timer. A user with no tmux server keeps their last
|
||||
# tmux-persist-save.timer. A user with no tmux server keeps their last
|
||||
# manifest (so a post-reboot save can't wipe it before restore).
|
||||
# restore — recreate manifest sessions that don't currently exist, resuming
|
||||
# each saved conversation (claude --resume <uuid>). Per-session
|
||||
# idempotent: existing names are left alone, so it is safe both at
|
||||
# boot (t3-tmux-restore.service) and after a partial loss.
|
||||
# boot (tmux-persist-restore.service) and after a partial loss.
|
||||
#
|
||||
# v1 limitation: one window/pane per session is captured (the workstation
|
||||
# usage pattern — one named claude conversation per tmux session).
|
||||
set -euo pipefail
|
||||
|
||||
STATE_DIR=/var/lib/t3-tmux-state
|
||||
STATE_DIR=/var/lib/tmux-persist
|
||||
MAP=/etc/ttyd-user-map
|
||||
MODE="${1:-}"
|
||||
|
||||
log() { echo "[t3-tmux-sessions] $*"; }
|
||||
log() { echo "[tmux-persist] $*"; }
|
||||
|
||||
users() { [[ -r "$MAP" ]] && cut -d= -f2 "$MAP" | sort -u; }
|
||||
|
||||
|
|
@ -106,5 +111,5 @@ restore() {
|
|||
case "$MODE" in
|
||||
save) save ;;
|
||||
restore) restore ;;
|
||||
*) echo "usage: t3-tmux-sessions save|restore" >&2; exit 1 ;;
|
||||
*) echo "usage: tmux-persist save|restore" >&2; exit 1 ;;
|
||||
esac
|
||||
Loading…
Add table
Add a link
Reference in a new issue