diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-06 21:59:52 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-06 21:59:52 -0500 |
| commit | d81b23ad6b6e437dfe3c338a00a4be39bc555146 (patch) | |
| tree | 2d4b0d7890fd1fc70d81282b81fed2808c28a106 /.ai/workflows/wrap-it-up.org | |
| parent | 201377f57430ef28d02e703a2191434bbee55c75 (diff) | |
| download | rulesets-d81b23ad6b6e437dfe3c338a00a4be39bc555146.tar.gz rulesets-d81b23ad6b6e437dfe3c338a00a4be39bc555146.zip | |
chore(ai): initialize project notes and Claude tooling surfaces
Replace the seed notes.org with project-specific context (layout, install modes, task tracker location, recent inflection point). Bring in the synced template surfaces (protocols, workflows, scripts, references, retrospectives, someday-maybe) as tracked content for this content/documentation project.
Diffstat (limited to '.ai/workflows/wrap-it-up.org')
| -rw-r--r-- | .ai/workflows/wrap-it-up.org | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/.ai/workflows/wrap-it-up.org b/.ai/workflows/wrap-it-up.org new file mode 100644 index 0000000..37d2522 --- /dev/null +++ b/.ai/workflows/wrap-it-up.org @@ -0,0 +1,235 @@ +#+TITLE: Session Wrap-Up Workflow +#+AUTHOR: Craig Jennings & Claude +#+DATE: 2026-04-20 + +* Overview + +This workflow defines the process for ending a Claude Code session cleanly. It finalizes the session record, commits + pushes all work, and provides a warm handoff. + +Triggered by Craig saying "wrap it up," "that's a wrap," "let's call it a wrap," or similar. + +* The Session Record + +Throughout the session, =.ai/session-context.org= has been maintained with: +- =* Summary= — structured distillation (empty or draft during session) +- =* Session Log= — chronological narrative of what happened, written as you go + +At wrap-up, this file becomes the permanent session record by being renamed to =.ai/sessions/YYYY-MM-DD-HH-MM-description.org=. No transcription elsewhere. The file IS the record. + +* Exit Criteria + +The wrap-up is complete when: + +1. *Summary is written.* The =* Summary= section of =.ai/session-context.org= is populated by reading the =* Session Log= — Active Goal, Decisions, Data Collected / Findings, Files Modified, Next Steps. +2. *File is archived.* =.ai/session-context.org= has been renamed to =.ai/sessions/YYYY-MM-DD-HH-MM-description.org=. The old path no longer exists. +3. *todo.org is clean.* Cleanup script ran. Any auto-fixes are staged for the wrap-up commit. Orphan planning lines surfaced for manual fix if there are any. +4. *Git state is clean.* All changes committed + pushed to all remotes. Working tree clean. +5. *Valediction delivered.* Brief, warm closing with key accomplishments and reminders. + +The absence of =.ai/session-context.org= is the signal that the last session wrapped up cleanly. Its presence at session start means the previous session was interrupted. + +* The Workflow + +** Step 1: Finalize the Summary + +Read through the =* Session Log= in =.ai/session-context.org=. Populate (or refine) the =* Summary= section: + +- *Active Goal* — one or two sentences describing the session's focus +- *Decisions* — key choices made, with enough context to recall the /why/ +- *Data Collected / Findings* — anything concrete (measurements, root causes, paths, discoveries) +- *Files Modified* — what was changed, with one-line rationale per significant file +- *Next Steps* — what should happen in the next session + +Don't repeat everything from the Log in the Summary. The Summary is distillation — pull out what's load-bearing. The Log stays in the file and is available if a future reader wants detail. + +** Step 2: Pick a description + rename + +Read the Summary's Active Goal and the prominent entries in the Session Log. Pick a 4-6 word description that would make sense as a git-commit-message-series summary for the whole session. + +Good descriptions are concrete nouns/verbs: +- =docs-ai-migration-and-ai-launcher= +- =mybitch-usb-disconnect-diagnosis= +- =ratio-system-health-check= +- =orchestration-dashboard-bug-triage= + +Avoid vague ones: +- =session-work= (useless) +- =various-improvements= (useless) +- =updates= (useless) + +Get current time and rename: + +#+begin_src bash +mkdir -p .ai/sessions +now=$(date +%Y-%m-%d-%H-%M) +mv .ai/session-context.org .ai/sessions/${now}-DESCRIPTION.org +#+end_src + +Replace =DESCRIPTION= with your picked slug. + +** Step 3: todo.org hygiene pass + +If the project has a =todo.org= at its root, run the cleanup script before committing. It catches a recurring pattern: org sometimes leaves noise lines like =- State "X" from "X" [date]= when a state-change log lands outside a =:LOGBOOK:= drawer and the state didn't actually change. These lines carry no information and they break org's planning-line parser by wedging between the heading and =DEADLINE:=/=SCHEDULED:=, which kicks the entry out of agenda views. + +#+begin_src bash +[ -f todo.org ] && emacs --batch -q -l .ai/scripts/todo-cleanup.el todo.org +#+end_src + +The script is fast (under half a second on a 4000-line file) and idempotent — if there's nothing to fix, it reports zero changes and exits clean. + +What it does: + +1. *Auto-deletes* bogus state-log lines (matched on identical from/to states). Any deletions show up in the wrap-up commit's diff, so they get reviewed before push. +2. *Reports* "orphan planning lines" — entries whose body has =DEADLINE:= or =SCHEDULED:= but =org-entry-get= can't read it (some other malformation kept it out of canonical position). The script doesn't auto-rewrite these because the right fix depends on whether real state-log history needs preserving — surface them and fix manually if they matter for the agenda. + +Run the report-only variant first if you want to see what would change without writing: + +#+begin_src bash +emacs --batch -q -l .ai/scripts/todo-cleanup.el --check todo.org +#+end_src + +** Step 4: Git commit + push + +*** Review changes + +#+begin_src bash +git status +git diff --stat +#+end_src + +Decide the scope of the wrap-up commit. Usually everything that changed during the session goes into one commit. If anything is intentionally not part of this session's work (pre-existing WIP, unrelated files), leave it out. + +*** Stage + +Add the renamed session file and all other session changes: + +#+begin_src bash +git add .ai/sessions/ [other modified paths] +#+end_src + +Do NOT blindly =git add .= — review what's being staged so unrelated dirty state isn't dragged in. + +*** Commit + +Commit message rules (also see protocols.org "Git Commit Requirements"): + +- Subject line: concise, describes what /shipped/. Use conventional prefixes (=docs:=, =refactor:=, =fix:=, =feat:=, =chore:=) — NEVER =session:=. +- Body: 1-3 terse sentences describing what was accomplished. +- NO Claude Code attribution. NO =Co-Authored-By=. NO references to =notes.org=, =session-context.org=, =.ai/sessions/=, "session wrap-up", or session timestamps. + +*Wrap-up commits skip the inline-approval gate.* The =commits.md= rule that requires writing the message to =/tmp/commit-<slug>.md=, printing inline, and waiting for an approve / request-changes / open-in-editor response does *not* apply to wrap-up commits. The wrap-up flow is meant to be quick — Craig has already authorized the wrap by triggering the workflow ("wrap it up"), and stopping again to approve a commit message disrupts the cadence. + +Still apply the prose-quality passes silently before committing — humanizer + jargon-rewrite + semicolon-swap + contractions + sentence-split — so the message reads cleanly. Just don't print and ask. Commit directly with the cleaned message. + +If a wrap-up commit needs Craig's eyes for a content reason (sensitive change, unusual scope, something he flagged earlier), surface it explicitly. Otherwise commit and move on. + +Example: +#+begin_example +docs: restructure docs/ to .ai/ and unify aix+hey into ai launcher + +Hidden .ai/ now holds Claude tooling; project-level docs/ reserved +for user-facing docs. Single 'ai' launcher (fzf multi + smart tmux ++ git-aware fetch/pull) replaces the aix script and hey alias. +#+end_example + +Use heredoc for multi-line: +#+begin_src bash +git commit -m "$(cat <<'EOF' +subject line here + +body sentences here. +EOF +)" +#+end_src + +*** Push to all remotes + +#+begin_src bash +git remote -v +#+end_src + +Push the current branch to every remote (preserves the mirror behavior — rulesets and a few other repos have github.com + cjennings.net mirrors that should both stay current): + +#+begin_src bash +current=$(git symbolic-ref --short HEAD) +for r in $(git remote); do git push "$r" "$current"; done +#+end_src + +Then push every other local branch with a tracking upstream to its tracking remote. This catches feature branches that advanced during the session but aren't the one being wrapped up — without it, work-in-progress branches stay local-only and are at risk if the machine dies before the next wrap-up. + +#+begin_src bash +git for-each-ref --format='%(refname:short) %(upstream:remotename)' refs/heads/ | \ +while read branch remote; do + [ "$branch" = "$current" ] && continue + if [ -z "$remote" ]; then + echo " $branch: no tracking upstream — skipped (push manually with 'git push -u')" + else + git push "$remote" "$branch" + fi +done +#+end_src + +Behavior: +- *Tracked branches* → pushed to their upstream remote. +- *Untracked branches* (no upstream set) → surfaced, not pushed. Craig sets the upstream manually with =git push -u <remote> <branch>= when he's ready. Auto-creating an upstream would commit to a remote choice the workflow can't make safely. +- *Diverged or rejected pushes* → surface and stop. Don't force-push from this workflow; resolve manually. + +*** Verify clean + +#+begin_src bash +git status +#+end_src + +Should show "working tree clean" and "branch is up to date" with each remote. If not, resolve before proceeding. + +** Step 5: Valediction + +Brief, warm closing. 3-4 sentences max. + +Include: +- What was accomplished (specific, not generic) +- What's ready for next session +- Any critical reminders or deadlines + +Tone: warm but professional. No emoji unless Craig has explicitly requested. Acknowledge effort when session was long or difficult. + +Example: +#+begin_example +That's a wrap. Today we restructured the entire claude-templates +ecosystem: docs/ → .ai/ across all 23 projects, unified aix + hey +into a single 'ai' launcher with git-aware fetch/pull, and cleaned +up 4 code projects on velox. Both machines fully in sync. + +Two things to pick up next: the chime README WIP (your inline notes +from earlier) and archsetup's layout-navigate tests. Both are +ratio-local uncommitted state. + +Good session. Talk tomorrow. +#+end_example + +* Common Mistakes to Avoid + +1. *Skipping Step 1 (Summary)* — the file becomes the record; an empty Summary makes it hard to scan at catch-up +2. *Vague description in filename* — =2026-04-20-updates.org= is useless next to =2026-04-20-13-45-docs-ai-migration.org= +3. *=git add .= without review* — drags in unrelated dirty state +4. *=session:= prefix in commit message* — explicitly forbidden; use real change categories +5. *Claude-tooling references in commit message* — describes tooling, not what shipped +6. *Forgetting to push to all remotes* — check =git remote -v=, push to each +7. *Leaving =.ai/session-context.org= in place* — its presence means "interrupted session", confuses next startup +8. *Long preachy valediction* — brief beats thorough + +* Validation Checklist + +Before considering wrap-up complete: + +- [ ] =.ai/session-context.org= =* Summary= section populated +- [ ] File renamed to =.ai/sessions/YYYY-MM-DD-HH-MM-description.org= +- [ ] =.ai/session-context.org= no longer exists +- [ ] =todo-cleanup.el= ran (if =todo.org= exists at project root) +- [ ] Any orphan-planning-line warnings reviewed (fix or accept) +- [ ] =git status= clean after commit + push +- [ ] Current branch pushed to ALL remotes (verified with =git remote -v=) +- [ ] All other local branches with a tracking upstream pushed to their remote +- [ ] Any untracked-upstream branches surfaced for manual =git push -u= +- [ ] Commit message follows format (no =session:=, no Claude attribution) +- [ ] Valediction delivered (brief, specific, warm) |
