#+TITLE: Proposal — wrap-it-up teardown + "wrap it up and shutdown" variant * Source Raised by Craig in a home-project session, 2026-06-23, after talking the design through. Two related additions to =wrap-it-up.org=. Both touch the Claude-session lifecycle (workflow + hook + the =ai-term= buffer/tmux pair), so they're rulesets — with one companion piece that has to live in =.emacs.d/modules/ai-term.el= (flagged below). Originally floated as an archsetup task; archsetup owns the Hyprland/waybar layer, not the Claude-session lifecycle, so it was re-routed here. * Architecture this depends on (so the design is grounded) - =ai-term.el= (=.emacs.d=) is the in-Emacs launcher: a vertical-split vterm buffer running a tmux session named =aiv-= (prefix =aiv-=). Layering: =claude= process → tmux session =aiv-= → Emacs vterm buffer. - Killing the tmux session takes the =claude= process with it, so "quit Claude Code" is a *consequence* of killing =aiv-=, not a separate step. - Hooks already exist under =~/.claude/hooks/= (e.g. =session-clear-resume.sh=, =precompact-priorities.sh=) — the teardown trigger fits that pattern. - =sudo= is =NOPASSWD: ALL= on Craig's machines, so =sudo shutdown now= runs unattended. * Item 1 — wrap-up also removes the buffer, quits Claude, removes the tmux session Recommend: yes, with one structural rule — the wrap-up runs *inside* the things it tears down, so teardown is self-terminating and must be the last, decoupled action, or the valediction may not flush before the session dies. Design: 1. *Teardown lives in =ai-term.el=* (companion, see below): one function =cj/ai-term-quit= that kills the =aiv-= tmux session (takes =claude= with it), kills the vterm buffer, and restores the saved window geometry — =ai-term.el= already owns the buffer↔session pair and the geometry logic. 2. *Trigger from a Stop / SessionEnd hook, not inline.* Wrap-up does all its git/archive work, delivers the valediction, then drops a sentinel (flag file, e.g. =/tmp/ai-wrap-teardown-=). The hook fires when Claude finishes, sees the sentinel, and runs =cj/ai-term-quit= via =emacsclient=. Decoupling guarantees the valediction lands before the session dies. 3. *Gate on commit+push verified* — never tear down before the session record is pushed (wrap-up's existing Step 4 / validation checklist already enforces push; teardown is strictly after it). 4. *Phrase split — teardown IS the default* (Craig's decision 2026-06-23). Bare "wrap it up" does the full wrap AND removes the buffer/session/quits — that's his typical case. The non-destructive variant gets the explicit qualifier: "wrap it up with summary" summarizes + commits + pushes + archives but keeps the buffer (no teardown), so the summary stays readable. So: "wrap it up" → teardown; "wrap it up with summary" → no teardown; "wrap it up and shutdown" → wrap + poweroff (supersedes teardown, Item 2). * Item 2 — "wrap it up and shutdown": 10-count then =sudo shutdown now= Recommend: yes, but the safety gate is load-bearing and the countdown has a rendering gotcha. Design: 1. *"Only ai-term left" = hard blocking precondition*, evaluated BEFORE the countdown. Count live sessions (=tmux ls | grep '^aiv-'= or =pgrep -fc claude=). If more than this one is alive, ABORT the shutdown, list what's running, and fall back to a normal wrap. Never power the box off out from under another active Claude session. This is the most important part of the item. 2. *The live countdown can't run through Claude's tool output.* The Bash tool buffers stdout until the command returns, so a =for i in $(seq 10 -1 1); sleep 1= prints all ten at once at the end, not one per second. It has to run detached or in Emacs: - tty writer: =for i in $(seq 10 -1 1); do printf '\rShutting down in %2d…' "$i" > /dev/tty; sleep 1; done; sudo shutdown now= (backgrounded), or - an Emacs =run-at-time= timer printing 10→1 in the echo area, then =(shell-command "sudo shutdown now")=. 3. *Make it abort-able* (Ctrl-C / keypress cancels). A 10-second countdown's whole purpose is a last-chance window; a non-cancellable one is just a delay. 4. *Sequencing.* "...and shutdown" supersedes Item 1's teardown — if the box is powering off, killing the buffer/session first is moot. Wrap (commit + push + archive) → session-count gate → countdown → =shutdown=. Packaging: a small rulesets bin script (e.g. =ai-wrap-shutdown=) doing the gate → abort-able countdown → shutdown, invoked by the workflow after the wrap commit/push. Countdown either in that script (tty) or handed to Emacs. * Companion — required change in =.emacs.d/modules/ai-term.el= Item 1's teardown function =cj/ai-term-quit= must live in =ai-term.el= (it owns =aiv-= session naming, the vterm buffer, and geometry restore). rulesets owns the workflow + hook + bin script that *call* it; =.emacs.d= owns the function itself. Spec for the =.emacs.d= side: - =cj/ai-term-quit (&optional project)= — resolve the =aiv-= session for the current/!named project, =tmux kill-session= it, =kill-buffer= the associated vterm buffer, restore saved geometry. Idempotent / no-op if the session or buffer is already gone. Callable from =emacsclient -e= so the Stop hook can invoke it headlessly. - (Optional) a count helper =cj/ai-term-live-count= so the Item-2 gate can ask Emacs how many ai-term sessions are live, as an alternative to =tmux ls= / =pgrep=. When rulesets builds the workflow/hook side, route this companion to =.emacs.d= (inbox-send) so the two land together. * Open decisions for Craig - Phrase set: DECIDED (2026-06-23) — "wrap it up" tears down (default); "wrap it up with summary" wraps without teardown; "wrap it up and shutdown" is the poweroff variant. Remaining nuance: confirm the exact non-destructive qualifier wording is "with summary" (vs e.g. "and summarize"). - Countdown home: tty-writer bin script vs Emacs timer. (Emacs timer reads cleaner inside the vterm and is trivially abort-able.) - Session-count mechanism for the gate: =tmux ls=, =pgrep claude=, or =cj/ai-term-live-count=. * Verify - Item 1: bare "wrap it up" → valediction renders fully, THEN buffer + =aiv-= session + claude all gone, geometry restored; "wrap it up with summary" → wrap completes but the buffer stays intact (no teardown). - Item 2 gate: with a second =aiv-*= session alive, "wrap it up and shutdown" refuses, lists the other session, and does a normal wrap (no poweroff). - Item 2 happy path: sole session → 10→1 renders one-per-second, is cancellable, then =shutdown= fires. - Teardown never runs before commit+push is verified.