From d4f132b716a6cdbc3a6a521a21fd2811c9da3480 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Thu, 2 Jul 2026 01:38:24 -0400 Subject: feat(flush): add auto mode with self-injected /clear for unattended runs Long autonomous sessions bloat or hit auto-compaction because /clear is a prompt keystroke no tool call can execute. Auto mode closes that gap: after the write-verified checkpoint, the agent derives its own tmux pane, arms self-inject.sh through tmux run-shell -b, and ends the turn so /clear and a resume line land at an idle prompt. The server-owned arm is load-bearing: a detached child of a tool call dies at the turn boundary. The pane must be derived before arming because ancestry detection can't work under the tmux server. self-inject.sh joins the synced scripts with a six-test bats suite, tmux stubbed at the boundary. work-the-backlog now auto-flushes between tasks when context grows heavy, and its speedrun preset gained the per-item disposition rule: feature-level work gets a spec, unguessable decisions get a VERIFY, well-defined tasks get implemented. The mechanism was proven live in another project's session and its design note is preserved under docs/design/. --- flush/SKILL.md | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'flush') diff --git a/flush/SKILL.md b/flush/SKILL.md index 4c2709a..ca139c1 100644 --- a/flush/SKILL.md +++ b/flush/SKILL.md @@ -1,6 +1,6 @@ --- name: flush -description: Mid-session context flush — the checkpoint half of the wrap/restart rhythm. Refresh the session-context anchor in place, prompt the user to /clear, then resume the same logical session from the anchor without re-running startup. Cheaper tokens and a sharper context window without fragmenting the session into archive files. Agent-callable and agent-initiated: the agent may run the pre-clear checkpoint on its own judgment at a clean task boundary, but /clear is user-only — the agent does all the work, then prompts for the single /clear keystroke. Use when the current task has a clean boundary and the context window is large enough that a reset would sharpen the work. Do NOT use for end-of-day or done-for-now (use wrap-it-up, which archives to .ai/sessions/ and commits), or for a genuine fresh start after being away or on another machine (use startup, which pulls + syncs + surfaces inbox). +description: Mid-session context flush — the checkpoint half of the wrap/restart rhythm. Refresh the session-context anchor in place, prompt the user to /clear (or in auto mode self-inject it via tmux), then resume the same logical session from the anchor without re-running startup. Cheaper tokens and a sharper context window without fragmenting the session into archive files. Agent-callable and agent-initiated: the agent may run the pre-clear checkpoint on its own judgment at a clean task boundary; interactively /clear stays the user's keystroke, while auto mode ("/flush auto", for unattended runs like the no-approvals speedrun or a recurring loop) arms .ai/scripts/self-inject.sh so tmux types /clear and a resume line at the agent's own idle prompt — zero human keystrokes. Use when the current task has a clean boundary and the context window is large enough that a reset would sharpen the work. Do NOT use for end-of-day or done-for-now (use wrap-it-up, which archives to .ai/sessions/ and commits), or for a genuine fresh start after being away or on another machine (use startup, which pulls + syncs + surfaces inbox). --- # /flush — Mid-Session Context Checkpoint @@ -20,9 +20,11 @@ This is the checkpoint half of the wrap/restart rhythm. It is distinct from two The skill is agent-callable. The agent may also **initiate** a flush on its own judgment when the rhythm calls for it (see below) — it runs the pre-clear checkpoint, then prompts the user to type `/clear`. -## The hard constraint +## The constraint, and the auto-mode exception -`/clear` is a user-only command. The agent **cannot** execute it. "Agent-initiated" means the agent runs the pre-clear checkpoint (refresh the anchor + verify the write landed) on its own, then **prompts** the user: "checkpoint saved, type /clear to reset." The agent proposes and does all the work; the user supplies the single `/clear` keystroke. Never design or imply a flow where the agent self-triggers `/clear`. +`/clear` is a prompt command — the agent cannot execute it as a tool call. Interactively, "agent-initiated" means the agent runs the pre-clear checkpoint (refresh the anchor + verify the write landed) on its own, then **prompts** the user: "checkpoint saved, type /clear to reset." The user supplies the single `/clear` keystroke. + +**Auto mode** (`/flush auto`) is the sanctioned exception for unattended sessions: after the checkpoint, the agent arms the tmux server to type `/clear` and a resume line at its own idle prompt (see Auto mode below). The constraint that never bends is the **gate order**: the anchor write is verified on disk *before* anything arms or prompts a clear. There is no recovering the conversation afterward. ## When the agent should initiate @@ -68,6 +70,30 @@ That is the wrap/restart rhythm. When both conditions hold, run Phase 1 and end 6. **Hand off the clear.** Tell the user the checkpoint is saved, name the anchor path, and prompt: type `/clear` now, then send any message to resume. +## Auto mode — self-injected clear for unattended sessions + +`/flush auto` runs Phase 1 in full (steps 1-5, including the write-verified gate), then replaces step 6's user prompt with a self-injection. Proven live in the archsetup session 2026-07-02; the mechanism and its gotchas live in `.ai/scripts/self-inject.sh` (synced into every project). + +1. **Derive the pane first, synchronously, from this shell:** + + ```bash + pane=$(.ai/scripts/self-inject.sh) + ``` + + This must happen before arming: the armed step runs under the tmux *server*, where ancestry-based pane detection cannot work. + +2. **Arm the injection via the tmux server, then end the turn immediately:** + + ```bash + tmux run-shell -b ".ai/scripts/self-inject.sh -t $pane 25 '/clear' 15 'go (auto-flush resume: continue per Next Steps)'" + ``` + + `run-shell -b` is load-bearing — a detached child of a tool call (`setsid`/`nohup`/`&`) dies when the tool call ends; only a server-owned process survives the turn boundary. The delays let the turn fully end before `/clear` lands (25s) and let the `SessionStart` hook finish before the resume line lands (15s). + +3. **End the turn.** The prompt must be idle when the keys arrive. The injected `/clear` fires the same `SessionStart(clear)` hook as a hand-typed one; the injected resume line starts the next turn. Zero human keystrokes. + +**When to use it:** unattended runs only — the no-approvals speedrun, a recurring loop, any session where nobody is at the keyboard. The collision hazard is real: keys injected while a human is mid-keystroke merge into their input (`/clear` has become `/clearto`). If a user may be present, say the window is armed and to keep hands off, or use the interactive prompt instead. + ## Phase 2 — Post-clear resume (hook-driven) This half is driven by the `SessionStart(clear)` hook, not by this skill — but it is documented here so the loop is legible. -- cgit v1.2.3