aboutsummaryrefslogtreecommitdiff
path: root/.ai/workflows/suspend.org
blob: 3691f603d7aa85ce99e9c37463faf7247deaa100 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#+TITLE: Session Suspend Workflow
#+AUTHOR: Craig Jennings
#+DATE: 2026-06-28

* Overview

This workflow captures the live state of a session when Craig must leave
abruptly, so a future session resumes with nothing lost. It is the fast,
capture-only workflow for departure: it writes down where every thread stands,
notes any uncommitted work, then STOPS — no cleanup, no archive, no teardown.

Triggered by Craig saying "suspend the session," "suspend," "I need to go,"
"stick a pin in everything," or similar. "I need to go" is broad — if it reads
as a conversational aside rather than a request to suspend, confirm before
running.

* Where suspend sits among its neighbors

Three workflows touch the session anchor (=.ai/session-context.org=); keep them
straight:

- =flush= ([[file:../../flush/SKILL.md]] / =/flush=) — *stay and sharpen.*
  Refreshes the anchor in place, prompts Craig to type =/clear=, and a hook
  resumes the *same* logical session in a fresh context. Craig is still here.
- *suspend* (this workflow) — *leave.* Captures richly into the anchor, leaves
  the file in place, and Craig walks away. The next session is a cold startup
  that detects the present anchor and resumes from it.
- =wrap-it-up= ([[file:wrap-it-up.org][wrap-it-up.org]]) — *end.* Writes the
  Summary, archives the anchor into =.ai/sessions/=, commits + pushes, and runs
  the phrase-dependent teardown.

Suspend and flush share one core — capture into the anchor, leave it in place.
They differ in the exit (leave vs clear-and-continue) and the resume path
(startup vs the =/clear= hook). Suspend reuses flush's capture discipline (its
Phase 1 anchor-refresh) rather than restating it, and adds a richer,
resume-weighted Session Log entry because it's written for a cold resume after a
gap, not a same-session reset.

* Suspend vs wrap-up — the one structural difference

=wrap-it-up= ARCHIVES =.ai/session-context.org= (renames it into
=.ai/sessions/=); its absence at the next startup is the signal that the last
session ended cleanly.

Suspend does the opposite: it LEAVES =.ai/session-context.org= in place. Its
presence at startup is exactly the signal that the previous session was
interrupted, so the startup workflow reads it and resumes. Suspend provides only
the *capture* half — startup's existing interrupted-session path (Phase A checks
for the anchor, Phase B reads it, Phase C offers to resume) is the *resume* half,
already built.

So: never archive, never rename the context file in a suspend. Capture into it
and leave it.

* What gets captured

The point is zero lost information, weighted toward RESUME. Into the
=* Session Log= of =.ai/session-context.org=, append one dated
=** YYYY-MM-DD ... — SUSPENDED= entry holding:

1. *Open threads — resume here.* For each active or pending thread: the topic,
   its status (ACTIVE / PINNED / SET ASIDE / DEFERRED), the immediate next
   step, and the pointers needed to act on it cold (files + line numbers,
   commit SHAs, the specific finding or decision). This is the core; spend the
   most words here. Order newest / most-active first.
2. *Pending decisions / open questions* awaiting Craig — anything blocked on
   his input, with enough context that the answer is actionable.
3. *Shipped this session* — a terse list of what landed, each with its commit
   SHA, so the resume knows what is already done and need not re-derive it.
4. *Uncommitted work* — anything modified on disk but not committed, named
   file by file, so the resume knows what state the tree is in.
5. *Key findings not yet recorded elsewhere* — anything learned this session
   that isn't already in a commit, a file, or memory, so it survives.
6. *Background work* — any running task, agent, or job, and how to check it.
7. *Resume hint* — the single most likely "start here" next action.

Also update the top of =* Summary= (Active Goal) with a one-line SUSPENDED
pointer to the entry, so startup reading the top sees the current state even
when the Summary body is from an earlier thread.

* Steps

1. *Write the SUSPENDED entry* into the Session Log, per "What gets captured"
   above. Timestamp with =date "+%Y-%m-%d %a @ %H:%M:%S %z"=.
2. *Update the Active Goal pointer* at the top of =* Summary=.
3. *Record uncommitted work, don't force-commit it.* A suspend records state, it
   does not tidy it. Name every uncommitted change in the SUSPENDED entry and
   leave the tree as it is — on an abrupt departure, a dirty tree (like any
   crash) is safer than a blind commit of arbitrary mid-work state. (If a
   project defines a standing always-commit set in its own workflow, commit only
   that set — but the default shared behavior is to leave the tree alone.)
4. *Leave =.ai/session-context.org= in place.* Do not archive it.
5. *Brief handoff* — one or two lines: what was captured, where the resume
   pointer is, the most-active thread. End and let Craig go.

* What suspend does NOT do

Speed over completeness. A suspend deliberately skips everything wrap-it-up
does beyond capture:

- No =* Summary= rewrite beyond the one-line Active Goal pointer.
- No todo.org cleanup / archive-done.
- No KB / memory promotion sweep.
- No Linear / board reconciliation.
- No session-record archive (the file stays live).
- No teardown (the ai-term buffer + tmux session stay up). It drops no
  =Stop=-hook teardown sentinel, so the wrap-teardown hook stays dormant.
- No blind commit of working files (step 3).
- No valediction. A suspend is a pause, not a goodbye.

If Craig later wants the clean end, he runs wrap-it-up, which picks up the
captured state and finishes the job.