diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-28 12:24:59 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-28 12:24:59 -0400 |
| commit | 797c4267022699527a5e7c51f67be52e6fac1409 (patch) | |
| tree | bfc15660f2928b5e5e785ed2179ba2231f8f4b2f | |
| parent | d4e9d7d63916aae12b6b640e1bbdacb7de9a50b2 (diff) | |
| download | rulesets-797c4267022699527a5e7c51f67be52e6fac1409.tar.gz rulesets-797c4267022699527a5e7c51f67be52e6fac1409.zip | |
feat(workflows): add suspend and readability-audit workflows
suspend is a capture-only mid-session pause for an abrupt departure: it writes a resume-weighted entry and leaves the session anchor in place, so the next startup resumes from it. It's the capture half. Startup is the resume half. I registered it with its trigger phrases.
readability-audit is a language-agnostic pass over comments, file headers, names, and organization. The cheap comment and name fixes land inline. Structural findings get filed as :refactor: tasks. It feeds /refactor rather than duplicating it.
| -rw-r--r-- | .ai/protocols.org | 4 | ||||
| -rw-r--r-- | .ai/workflows/INDEX.org | 7 | ||||
| -rw-r--r-- | .ai/workflows/readability-audit.org | 242 | ||||
| -rw-r--r-- | .ai/workflows/suspend.org | 112 | ||||
| -rw-r--r-- | claude-templates/.ai/protocols.org | 4 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/INDEX.org | 7 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/readability-audit.org | 242 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/suspend.org | 112 |
8 files changed, 730 insertions, 0 deletions
diff --git a/.ai/protocols.org b/.ai/protocols.org index 3048df2..46bea50 100644 --- a/.ai/protocols.org +++ b/.ai/protocols.org @@ -242,6 +242,10 @@ Execute the wrap-up workflow (details in Session Protocols section below): 2. Git commit and push all changes 3. Valediction summary +** "Suspend the session" / "Suspend" / "I need to go" / "Stick a pin in everything" + +Execute the suspend workflow ([[file:workflows/suspend.org][suspend.org]]): a capture-only mid-session pause for an abrupt departure. It appends a resume-weighted =SUSPENDED= entry to the Session Log, notes uncommitted work, and LEAVES =.ai/session-context.org= in place so the next startup resumes from it — no archive, no teardown, no valediction. The capture-only counterpart to "wrap it up" (which ends + archives + tears down) and to =/flush= (which prompts =/clear= and resumes the same session). "I need to go" is broad — if it reads as a conversational aside, confirm before suspending. + * User Information ** Calendar Management diff --git a/.ai/workflows/INDEX.org b/.ai/workflows/INDEX.org index eef81df..807410d 100644 --- a/.ai/workflows/INDEX.org +++ b/.ai/workflows/INDEX.org @@ -22,6 +22,8 @@ This index must list every =.org= file in =.ai/workflows/= except this one and e - Triggers: "wrap it up", "that's a wrap", "let's call it a wrap" - No-teardown triggers: "wrap it up with summary", "wrap it up and summarize" - Shutdown trigger: "wrap it up and shutdown" +- =suspend.org= — capture-only mid-session pause for an abrupt departure: append a resume-weighted =SUSPENDED= entry to the Session Log, note uncommitted work, and LEAVE =.ai/session-context.org= in place so the next startup resumes from it. The capture-only counterpart to =wrap-it-up= (which archives + tears down) and to =flush= (=/flush=, which prompts =/clear= and resumes the same session). Provides only the capture half; startup's interrupted-session path is the resume half. + - Triggers: "suspend the session", "suspend", "I need to go", "stick a pin in everything" - =retrospective.org= — post-mortem after a tough session. - Triggers: "let's do a retrospective", "retrospective time" @@ -87,6 +89,11 @@ This index must list every =.org= file in =.ai/workflows/= except this one and e - =spec-response.org= — fold a spec review back in: decide accept / modify / reject for every finding, weave accepts into the spec body, complete each finding task in place (the reason recorded on modifies and rejects), reconcile cross-spec tensions, iterate to implementation-ready. The *author* side; consumes the =* Review findings= =spec-review.org= produces. - Triggers: "respond to the review", "process the spec reviews", "spec-response workflow", "fold in the review" +** Code quality + +- =readability-audit.org= — make code readable to a future maintainer: audit file-top commentary, inline comments (why-not-what), names (intention-revealing), and organization (co-location / stepdown / cohesion). The cheap comment- and name-only fixes (dimensions A/B/C) land inline, verified by a green suite; the structural findings (dimension D — split a module, rename a public symbol) are *filed* as =:refactor:= tasks, not done here. Language-agnostic. Feeds =/refactor= (which executes the filed structural work); distinct from =/refactor='s metric scans and =/simplify='s diff cleanup. + - Triggers: "let's run the readability-audit workflow", "audit the comments and commentary in <area>", "clean up the structure/organization of <module>", "readability audit" + ** Tools and meta - =process-meeting-transcript.org= — record → transcript → labeled archive. diff --git a/.ai/workflows/readability-audit.org b/.ai/workflows/readability-audit.org new file mode 100644 index 0000000..8223a03 --- /dev/null +++ b/.ai/workflows/readability-audit.org @@ -0,0 +1,242 @@ +#+TITLE: Readability Audit Workflow +#+AUTHOR: Craig Jennings & Claude +#+DATE: 2026-06-28 + +* Overview + +A pass over one file, a set of modules, or the whole tree that makes the code +*readable to a future maintainer*. It checks four things and fixes the cheap +ones in place: the file-top commentary, the inline comments, the names, and the +physical organization of the code. Structural changes that need a real refactor +(splitting a module, renaming a public symbol) are not done here — they are +filed as =:refactor:= tasks so they get their own design and test pass. + +This is language-agnostic. Where a step names a language-specific tool or +convention, it's stated as "the project's <X>, if it has one" — read the +project's =CLAUDE.md= / =notes.org= and the language bundle to resolve the +concrete tool. + +* Where it sits among the code-quality tools + +These tools are a pipeline, not duplicates. Knowing which to reach for: + +- *readability-audit* (this workflow) — prose and human-reader clarity: + comments, file headers, names, and physical organization. Judgment-driven + (does this comment lie? does this name reveal intent? can a newcomer place + this file in a minute?). +- =/refactor= — structure on measurable metrics: complexity, duplication, + dead-code, the =simplification= lens (behavior-preserving logic/size + reduction), and =rename= (executes a codebase-wide symbol rename). +- =/simplify= — behavior-preserving cleanup of the current diff, applied + directly. + +The link that keeps them from overlapping: when this audit finds a structural +problem too big for a comment/name fix — a module to split, a *public* symbol to +rename across call sites — it *files* a =:refactor:= task rather than doing it +here. =/refactor= (rename, simplification) or =/start-work= then executes that +filed task with a proper design and test plan. Readability finds and files; +=/refactor= transforms. + +* Problem We're Solving + +Source files drift toward two opposite failure modes, and both hurt the next +person to open the file: + +- *Documentation rot and noise.* Headers carry stale user-manual content + (quick-starts, full option matrices, setup walkthroughs) that belongs in user + docs; comments restate what the next line already says; comments go out of + date and start lying; placeholder =TODO=/=FIXME= stubs and conversational + asides accumulate. A blank summary or a missing file-top description leaves a + reader with no map. +- *Structural fog.* Names that don't reveal intent force the reader to decode + them; related functions scatter; a public entry point sits far from the + private helpers it calls; a file grows to hold several unrelated + responsibilities. + +Left alone, opening a file costs more every month. The fix is a repeatable audit +with a clear, checkable standard, run on demand or as files are touched. + +* Exit Criteria + +For the audited scope: + +1. *Every file has an accurate top section* that states what the file does and + how it fits the rest of the codebase — terse, no user-manual content, and + carrying the project's file-header convention where it has one. +2. *Every surviving comment earns its place* — it explains a *why* the code + can't (a constraint, a workaround and its reason, an ordering dependency, a + warning), it is accurate against the current code, and it is terse. Obvious + "describe the next line" comments are gone. +3. *Names reveal intent* — no cryptic abbreviations; the project's + public/private visibility convention is applied consistently. +4. *Related code is co-located* — a public function's private helpers sit right + after it; the file reads top-to-bottom by descending abstraction; sections + group what belongs together. +5. *Structural problems too big to fix in a comment pass are filed* as + =:refactor:= tasks, not left as a vague note and not half-done inline. +6. *Nothing broke* — the build is clean and the test suite is green + (comment/name edits are behavior-preserving, so this should always hold; it + is the proof, not a hope). See "Graceful degradation" for projects without a + suite. + +* When to Use This Workflow + +- "Let's run the readability-audit workflow." +- "Audit the comments and commentary in <file/area>." +- "Clean up the structure/organization of <module>." +- After landing a feature, on the files it touched, before moving on. +- On a single file you just found hard to read. +- As a tree-wide sweep: inventory all the source files, audit each, batch the + fixes. + +Do NOT use this to *perform* the structural refactors themselves (use +=/refactor= or =/start-work= against a filed task) or to hunt for bugs / +complexity / duplication (that is =/refactor=, not a readability pass). + +* Approach: How We Work Together + +** Phase 1 — Scope and inventory + +Pick the target: one file, a named module set, or the whole tree. For a sweep, +list the source files (honor =.aiignore=) and decide coverage. Lean on the +language's own doc linters as a first filter where they exist — many flag a +missing or blank file summary and malformed headers; run the project's lint +target first. + +** Phase 2 — Audit each file against the four dimensions + +Record findings as =file:line — issue — proposed fix=. The four dimensions: + +*** A. File-top commentary (the map) + +- Present, and *accurate* against what the file now does. +- States purpose, the file's role/architecture, and key entry points — + *tersely*. A reader should learn what this is and how it connects in a few + lines. +- Carries the project's file-header convention where it has one (a metadata + block, a module docstring, a standard header comment). If the project has no + header convention, skip this sub-check — don't invent one. +- Does *not* carry user-manual content — quick-starts, full option matrices, + step-by-step setup. That belongs in user docs; move it, don't keep it in the + source header. +- Mechanics are correct for the language: a filled summary line (not blank), the + expected section markers, the expected footer. + +*** B. Inline comments (why, not what) + +- Explains a *why* the code cannot: a workaround *and its reason*, an ordering + or load dependency, business-logic rationale, a real warning ("do not reorder + these — deadlock"). +- Is *accurate* — matches the current code. A wrong comment is worse than none; + fix or delete on sight. +- Is *terse and useful*. Delete the obvious "describe the next line" comment + unless it names a non-obvious constraint. Replace a stale placeholder or a + rambling aside with the real one-line reason, or remove it. +- Convert a comment that's only restating the code into a better *name* instead + (see C). + +*** C. Names (carry the what/how so comments don't have to) + +- Intention-revealing variable and function names; no cryptic single letters or + abbreviations outside tight local scopes. +- The project's public/private convention is applied consistently and correctly: + a helper only called within the file is private; a user-facing or + intentionally-reusable symbol is public. (Resolve the concrete convention from + the language and the project — a naming prefix, an export list, an + access modifier.) +- When a comment exists only to explain a name, rename instead. + +*** D. Organization (co-location and ordering) + +- Related functions sit together. A public function's private helpers come + *right after* it (stepdown / proximity / "reads like a newspaper"). +- The file reads top-to-bottom by descending abstraction. +- Sections group what belongs together. +- *Cohesion check:* if the file holds several unrelated responsibilities, or has + grown large enough that the top no longer describes one coherent thing, flag a + split into layered owners — but see Phase 4: that's a filed refactor, not an + inline fix. + +** Phase 3 — Apply the cheap, safe fixes inline + +Dimensions A, B, and C are *comment- and name-only* and *solo* (no design or +preference call): apply them directly. After each file (or a batch), verify with +the project's gates: parse/syntax check, a clean build (no new warnings), and a +green test suite. Comment/name edits can't change behavior, so green is the proof +the edit was clean, not a behavior check. + +For a tree-wide sweep, drive the uniform rewrites mechanically and verify the +whole batch at once: a *mechanical applier with a boundary assertion* that +replaces a well-defined header span is reliable and fast, then one suite run +covers the batch. Keep the varied cases (header-line fixes, summary fixes that +must preserve surrounding metadata, inline-comment surgery, generated-file +headers) as careful per-file edits. (The boundary markers are language-specific; +the principle — mechanical applier + assert + one suite run for uniform +rewrites, per-file judgment for varied cases — is not.) + +** Phase 4 — File the structural refactors, don't do them here + +Dimension D's bigger findings — split a module, rename a *public* symbol across +call sites, move a function to a different file — are real refactors with their +own risk and test surface. Do *not* slip them into a readability pass. File each +as a =:refactor:= task in =todo.org= with the specific finding, so it gets +=/refactor= or =/start-work= with a proper design and test plan. This is the +line between the cheap clarity win and the structural change; keeping it sharp is +what lets the audit stay safe and fast. + +** Phase 5 — Verify and commit in logical batches + +Full suite green, build clean. Commit the doc/comment changes as =docs:= (or +=refactor:= where a header/structure normalized) in cohesive batches — one +commit per coherent slice (a set of condensed commentaries, the +generated-file-header fixes, the obvious-comment prune), not one mega-commit and +not one-per-file. Generated files are fixed *in their generator* and then +regenerated, so the next regen stays compliant. + +* Graceful degradation + +The audit adapts to what the project provides: + +- *No file-header convention* → skip dimension A's metadata sub-check; still + check the summary/description for accuracy and terseness. +- *No test suite* → the green-suite proof in Phases 3 and 5 is unavailable. Fall + back to the strongest gate the project has (compile/byte-compile, parse check, + linters) and *flag the weaker proof as a known limit* — a behavior-preserving + edit is lower-risk, but say plainly that there's no suite to confirm it. +- *No doc linter* → do the Phase 1 first-filter by reading instead; the audit + still runs, just without the cheap pre-pass. + +* Principles to Follow + +- *Comments explain why; code explains what.* If a comment restates the code, + delete it or turn it into a better name. +- *Accuracy beats completeness.* A wrong or stale comment is worse than no + comment. When in doubt, delete. +- *Terse and useful.* Every comment and every header line earns its place. The + source header is not the user manual — move manuals to user docs. +- *Readable means the next person, fast.* The test of the top-section and the + organization is whether a maintainer who has never seen the file can place it + and navigate it in under a minute. +- *Keep the cheap pass cheap.* Comment/name fixes are solo and land inline. + Structural splits and public renames are not — they get filed, designed, and + tested separately. +- *Preserve legal and attribution headers verbatim.* Vendored / GPL / copyright + notices are never condensed away by a readability pass. +- *Manual validation is still Craig's.* Solo means no input is needed to *do* + the work; visual/behavior confirmation afterward is expected where relevant. + +* Living Document + +Update this with what real runs teach. Lessons worth keeping as the standard +sharpens: + +- *Interpretation default for "fix blank summary":* when a rewrite shows only a + header + summary and omits a metadata block the file already has, keep the + existing metadata and replace only the header line and the summary. Its + absence from the rewrite means "leave it," not "delete it." +- *Generated files:* fix the *generator*, then regenerate. Editing the generated + file directly is reverted on the next regen. +- *Vendored files:* preserve the copyright/attribution; do not auto-condense a + licensed header. +- *Mechanical applier + assert + one suite run* is the safe way to do a + many-file uniform rewrite; per-file judgment is for the varied cases. diff --git a/.ai/workflows/suspend.org b/.ai/workflows/suspend.org new file mode 100644 index 0000000..1c16bb9 --- /dev/null +++ b/.ai/workflows/suspend.org @@ -0,0 +1,112 @@ +#+TITLE: Session Suspend Workflow +#+AUTHOR: Craig Jennings & Claude +#+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. diff --git a/claude-templates/.ai/protocols.org b/claude-templates/.ai/protocols.org index 3048df2..46bea50 100644 --- a/claude-templates/.ai/protocols.org +++ b/claude-templates/.ai/protocols.org @@ -242,6 +242,10 @@ Execute the wrap-up workflow (details in Session Protocols section below): 2. Git commit and push all changes 3. Valediction summary +** "Suspend the session" / "Suspend" / "I need to go" / "Stick a pin in everything" + +Execute the suspend workflow ([[file:workflows/suspend.org][suspend.org]]): a capture-only mid-session pause for an abrupt departure. It appends a resume-weighted =SUSPENDED= entry to the Session Log, notes uncommitted work, and LEAVES =.ai/session-context.org= in place so the next startup resumes from it — no archive, no teardown, no valediction. The capture-only counterpart to "wrap it up" (which ends + archives + tears down) and to =/flush= (which prompts =/clear= and resumes the same session). "I need to go" is broad — if it reads as a conversational aside, confirm before suspending. + * User Information ** Calendar Management diff --git a/claude-templates/.ai/workflows/INDEX.org b/claude-templates/.ai/workflows/INDEX.org index eef81df..807410d 100644 --- a/claude-templates/.ai/workflows/INDEX.org +++ b/claude-templates/.ai/workflows/INDEX.org @@ -22,6 +22,8 @@ This index must list every =.org= file in =.ai/workflows/= except this one and e - Triggers: "wrap it up", "that's a wrap", "let's call it a wrap" - No-teardown triggers: "wrap it up with summary", "wrap it up and summarize" - Shutdown trigger: "wrap it up and shutdown" +- =suspend.org= — capture-only mid-session pause for an abrupt departure: append a resume-weighted =SUSPENDED= entry to the Session Log, note uncommitted work, and LEAVE =.ai/session-context.org= in place so the next startup resumes from it. The capture-only counterpart to =wrap-it-up= (which archives + tears down) and to =flush= (=/flush=, which prompts =/clear= and resumes the same session). Provides only the capture half; startup's interrupted-session path is the resume half. + - Triggers: "suspend the session", "suspend", "I need to go", "stick a pin in everything" - =retrospective.org= — post-mortem after a tough session. - Triggers: "let's do a retrospective", "retrospective time" @@ -87,6 +89,11 @@ This index must list every =.org= file in =.ai/workflows/= except this one and e - =spec-response.org= — fold a spec review back in: decide accept / modify / reject for every finding, weave accepts into the spec body, complete each finding task in place (the reason recorded on modifies and rejects), reconcile cross-spec tensions, iterate to implementation-ready. The *author* side; consumes the =* Review findings= =spec-review.org= produces. - Triggers: "respond to the review", "process the spec reviews", "spec-response workflow", "fold in the review" +** Code quality + +- =readability-audit.org= — make code readable to a future maintainer: audit file-top commentary, inline comments (why-not-what), names (intention-revealing), and organization (co-location / stepdown / cohesion). The cheap comment- and name-only fixes (dimensions A/B/C) land inline, verified by a green suite; the structural findings (dimension D — split a module, rename a public symbol) are *filed* as =:refactor:= tasks, not done here. Language-agnostic. Feeds =/refactor= (which executes the filed structural work); distinct from =/refactor='s metric scans and =/simplify='s diff cleanup. + - Triggers: "let's run the readability-audit workflow", "audit the comments and commentary in <area>", "clean up the structure/organization of <module>", "readability audit" + ** Tools and meta - =process-meeting-transcript.org= — record → transcript → labeled archive. diff --git a/claude-templates/.ai/workflows/readability-audit.org b/claude-templates/.ai/workflows/readability-audit.org new file mode 100644 index 0000000..8223a03 --- /dev/null +++ b/claude-templates/.ai/workflows/readability-audit.org @@ -0,0 +1,242 @@ +#+TITLE: Readability Audit Workflow +#+AUTHOR: Craig Jennings & Claude +#+DATE: 2026-06-28 + +* Overview + +A pass over one file, a set of modules, or the whole tree that makes the code +*readable to a future maintainer*. It checks four things and fixes the cheap +ones in place: the file-top commentary, the inline comments, the names, and the +physical organization of the code. Structural changes that need a real refactor +(splitting a module, renaming a public symbol) are not done here — they are +filed as =:refactor:= tasks so they get their own design and test pass. + +This is language-agnostic. Where a step names a language-specific tool or +convention, it's stated as "the project's <X>, if it has one" — read the +project's =CLAUDE.md= / =notes.org= and the language bundle to resolve the +concrete tool. + +* Where it sits among the code-quality tools + +These tools are a pipeline, not duplicates. Knowing which to reach for: + +- *readability-audit* (this workflow) — prose and human-reader clarity: + comments, file headers, names, and physical organization. Judgment-driven + (does this comment lie? does this name reveal intent? can a newcomer place + this file in a minute?). +- =/refactor= — structure on measurable metrics: complexity, duplication, + dead-code, the =simplification= lens (behavior-preserving logic/size + reduction), and =rename= (executes a codebase-wide symbol rename). +- =/simplify= — behavior-preserving cleanup of the current diff, applied + directly. + +The link that keeps them from overlapping: when this audit finds a structural +problem too big for a comment/name fix — a module to split, a *public* symbol to +rename across call sites — it *files* a =:refactor:= task rather than doing it +here. =/refactor= (rename, simplification) or =/start-work= then executes that +filed task with a proper design and test plan. Readability finds and files; +=/refactor= transforms. + +* Problem We're Solving + +Source files drift toward two opposite failure modes, and both hurt the next +person to open the file: + +- *Documentation rot and noise.* Headers carry stale user-manual content + (quick-starts, full option matrices, setup walkthroughs) that belongs in user + docs; comments restate what the next line already says; comments go out of + date and start lying; placeholder =TODO=/=FIXME= stubs and conversational + asides accumulate. A blank summary or a missing file-top description leaves a + reader with no map. +- *Structural fog.* Names that don't reveal intent force the reader to decode + them; related functions scatter; a public entry point sits far from the + private helpers it calls; a file grows to hold several unrelated + responsibilities. + +Left alone, opening a file costs more every month. The fix is a repeatable audit +with a clear, checkable standard, run on demand or as files are touched. + +* Exit Criteria + +For the audited scope: + +1. *Every file has an accurate top section* that states what the file does and + how it fits the rest of the codebase — terse, no user-manual content, and + carrying the project's file-header convention where it has one. +2. *Every surviving comment earns its place* — it explains a *why* the code + can't (a constraint, a workaround and its reason, an ordering dependency, a + warning), it is accurate against the current code, and it is terse. Obvious + "describe the next line" comments are gone. +3. *Names reveal intent* — no cryptic abbreviations; the project's + public/private visibility convention is applied consistently. +4. *Related code is co-located* — a public function's private helpers sit right + after it; the file reads top-to-bottom by descending abstraction; sections + group what belongs together. +5. *Structural problems too big to fix in a comment pass are filed* as + =:refactor:= tasks, not left as a vague note and not half-done inline. +6. *Nothing broke* — the build is clean and the test suite is green + (comment/name edits are behavior-preserving, so this should always hold; it + is the proof, not a hope). See "Graceful degradation" for projects without a + suite. + +* When to Use This Workflow + +- "Let's run the readability-audit workflow." +- "Audit the comments and commentary in <file/area>." +- "Clean up the structure/organization of <module>." +- After landing a feature, on the files it touched, before moving on. +- On a single file you just found hard to read. +- As a tree-wide sweep: inventory all the source files, audit each, batch the + fixes. + +Do NOT use this to *perform* the structural refactors themselves (use +=/refactor= or =/start-work= against a filed task) or to hunt for bugs / +complexity / duplication (that is =/refactor=, not a readability pass). + +* Approach: How We Work Together + +** Phase 1 — Scope and inventory + +Pick the target: one file, a named module set, or the whole tree. For a sweep, +list the source files (honor =.aiignore=) and decide coverage. Lean on the +language's own doc linters as a first filter where they exist — many flag a +missing or blank file summary and malformed headers; run the project's lint +target first. + +** Phase 2 — Audit each file against the four dimensions + +Record findings as =file:line — issue — proposed fix=. The four dimensions: + +*** A. File-top commentary (the map) + +- Present, and *accurate* against what the file now does. +- States purpose, the file's role/architecture, and key entry points — + *tersely*. A reader should learn what this is and how it connects in a few + lines. +- Carries the project's file-header convention where it has one (a metadata + block, a module docstring, a standard header comment). If the project has no + header convention, skip this sub-check — don't invent one. +- Does *not* carry user-manual content — quick-starts, full option matrices, + step-by-step setup. That belongs in user docs; move it, don't keep it in the + source header. +- Mechanics are correct for the language: a filled summary line (not blank), the + expected section markers, the expected footer. + +*** B. Inline comments (why, not what) + +- Explains a *why* the code cannot: a workaround *and its reason*, an ordering + or load dependency, business-logic rationale, a real warning ("do not reorder + these — deadlock"). +- Is *accurate* — matches the current code. A wrong comment is worse than none; + fix or delete on sight. +- Is *terse and useful*. Delete the obvious "describe the next line" comment + unless it names a non-obvious constraint. Replace a stale placeholder or a + rambling aside with the real one-line reason, or remove it. +- Convert a comment that's only restating the code into a better *name* instead + (see C). + +*** C. Names (carry the what/how so comments don't have to) + +- Intention-revealing variable and function names; no cryptic single letters or + abbreviations outside tight local scopes. +- The project's public/private convention is applied consistently and correctly: + a helper only called within the file is private; a user-facing or + intentionally-reusable symbol is public. (Resolve the concrete convention from + the language and the project — a naming prefix, an export list, an + access modifier.) +- When a comment exists only to explain a name, rename instead. + +*** D. Organization (co-location and ordering) + +- Related functions sit together. A public function's private helpers come + *right after* it (stepdown / proximity / "reads like a newspaper"). +- The file reads top-to-bottom by descending abstraction. +- Sections group what belongs together. +- *Cohesion check:* if the file holds several unrelated responsibilities, or has + grown large enough that the top no longer describes one coherent thing, flag a + split into layered owners — but see Phase 4: that's a filed refactor, not an + inline fix. + +** Phase 3 — Apply the cheap, safe fixes inline + +Dimensions A, B, and C are *comment- and name-only* and *solo* (no design or +preference call): apply them directly. After each file (or a batch), verify with +the project's gates: parse/syntax check, a clean build (no new warnings), and a +green test suite. Comment/name edits can't change behavior, so green is the proof +the edit was clean, not a behavior check. + +For a tree-wide sweep, drive the uniform rewrites mechanically and verify the +whole batch at once: a *mechanical applier with a boundary assertion* that +replaces a well-defined header span is reliable and fast, then one suite run +covers the batch. Keep the varied cases (header-line fixes, summary fixes that +must preserve surrounding metadata, inline-comment surgery, generated-file +headers) as careful per-file edits. (The boundary markers are language-specific; +the principle — mechanical applier + assert + one suite run for uniform +rewrites, per-file judgment for varied cases — is not.) + +** Phase 4 — File the structural refactors, don't do them here + +Dimension D's bigger findings — split a module, rename a *public* symbol across +call sites, move a function to a different file — are real refactors with their +own risk and test surface. Do *not* slip them into a readability pass. File each +as a =:refactor:= task in =todo.org= with the specific finding, so it gets +=/refactor= or =/start-work= with a proper design and test plan. This is the +line between the cheap clarity win and the structural change; keeping it sharp is +what lets the audit stay safe and fast. + +** Phase 5 — Verify and commit in logical batches + +Full suite green, build clean. Commit the doc/comment changes as =docs:= (or +=refactor:= where a header/structure normalized) in cohesive batches — one +commit per coherent slice (a set of condensed commentaries, the +generated-file-header fixes, the obvious-comment prune), not one mega-commit and +not one-per-file. Generated files are fixed *in their generator* and then +regenerated, so the next regen stays compliant. + +* Graceful degradation + +The audit adapts to what the project provides: + +- *No file-header convention* → skip dimension A's metadata sub-check; still + check the summary/description for accuracy and terseness. +- *No test suite* → the green-suite proof in Phases 3 and 5 is unavailable. Fall + back to the strongest gate the project has (compile/byte-compile, parse check, + linters) and *flag the weaker proof as a known limit* — a behavior-preserving + edit is lower-risk, but say plainly that there's no suite to confirm it. +- *No doc linter* → do the Phase 1 first-filter by reading instead; the audit + still runs, just without the cheap pre-pass. + +* Principles to Follow + +- *Comments explain why; code explains what.* If a comment restates the code, + delete it or turn it into a better name. +- *Accuracy beats completeness.* A wrong or stale comment is worse than no + comment. When in doubt, delete. +- *Terse and useful.* Every comment and every header line earns its place. The + source header is not the user manual — move manuals to user docs. +- *Readable means the next person, fast.* The test of the top-section and the + organization is whether a maintainer who has never seen the file can place it + and navigate it in under a minute. +- *Keep the cheap pass cheap.* Comment/name fixes are solo and land inline. + Structural splits and public renames are not — they get filed, designed, and + tested separately. +- *Preserve legal and attribution headers verbatim.* Vendored / GPL / copyright + notices are never condensed away by a readability pass. +- *Manual validation is still Craig's.* Solo means no input is needed to *do* + the work; visual/behavior confirmation afterward is expected where relevant. + +* Living Document + +Update this with what real runs teach. Lessons worth keeping as the standard +sharpens: + +- *Interpretation default for "fix blank summary":* when a rewrite shows only a + header + summary and omits a metadata block the file already has, keep the + existing metadata and replace only the header line and the summary. Its + absence from the rewrite means "leave it," not "delete it." +- *Generated files:* fix the *generator*, then regenerate. Editing the generated + file directly is reverted on the next regen. +- *Vendored files:* preserve the copyright/attribution; do not auto-condense a + licensed header. +- *Mechanical applier + assert + one suite run* is the safe way to do a + many-file uniform rewrite; per-file judgment is for the varied cases. diff --git a/claude-templates/.ai/workflows/suspend.org b/claude-templates/.ai/workflows/suspend.org new file mode 100644 index 0000000..1c16bb9 --- /dev/null +++ b/claude-templates/.ai/workflows/suspend.org @@ -0,0 +1,112 @@ +#+TITLE: Session Suspend Workflow +#+AUTHOR: Craig Jennings & Claude +#+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. |
