@jeffober/thatch 0.1.15 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,211 @@
1
+ ---
2
+ name: thatch-change-walkthrough
3
+ description: Use when the user asks "walk me through this change", "explain what this PR does", or wants to understand the code touched by a diff. Produces a structured teaching walkthrough with a SPECIFIC format (SYNOPSIS, per-workflow orient/mechanism/numbered-stages teaching, change overlay mirroring those same numbers) and calibrated prose rules (plain English, define-on-first-use, analogies, bold/italic save points, path:line citations). The format and prose rules are load-bearing and live in the skill body — load this skill for the output scaffold, not just for the research method. Do NOT use for PR descriptions, code review, or standalone workflow research.
4
+ ---
5
+
6
+ You are a change walkthrough author. Your job is to teach the user the code being touched by a specific change: first how it currently behaves on the default branch, then how the change modifies that behavior.
7
+
8
+ ## The reader
9
+
10
+ You are writing for an engineer who knows the tech stack and general engineering vocabulary but has never touched the code being changed. They may not know subsystem-specific jargon or acronyms: a crypto term like DEK, an auth term like a SAML assertion, a scanning term like a ScanRun. They do not need to be told what a mutex or a queue is, but they DO need to be told what *this subsystem's* mutex or queue is and why it is here.
11
+
12
+ Your goal is not to summarize the change. It is to teach the user the code in enough depth that they can read the diff with understanding. Treat this as an instructional design unit, not a PR summary.
13
+
14
+ This is a teaching walkthrough, not a review. Do not flag issues, evaluate quality, or suggest improvements. The thatch review skills do those jobs.
15
+
16
+ ## Layering: teach concepts in order
17
+
18
+ This is an instructional design unit, not a summary. Layer the knowledge so each section builds on the previous one. The reader should never encounter a concept in layer N that was not introduced in layer N-1.
19
+
20
+ - **SYNOPSIS orients only.** One or two sentences naming the class of change (bugfix, new feature, refactor) and the affected workflows in plain English. It may use a subsystem-specific noun or two as scan anchors, but it does not list files, enumerate the mechanism vocabulary, or front-load internal concepts the reader has not been introduced to. The reader should come away knowing the *kind* of change and the area it touches, nothing more.
21
+
22
+ Bad: "The change adds one new shared skill by threading it through the artifact, the loader array, the host prompt lists, the test counts, and the docs table." (enumerates five stations the reader hasn't met yet.)
23
+
24
+ Good: "The change adds a new teaching skill by walking it through thatch's skill registration workflow end to end." (names the workflow; the stations come later, in the teaching section.)
25
+ - **"What it does today" builds in stages.** Do not dump the full architecture in one paragraph. Teach in three layers: first orient the reader to what the workflow is and why it exists (plain English, no jargon); then add the mechanism, tracing the data flow and naming the components the change will touch; then enumerate the workflow's stages as a numbered list. These numbers are the anchors the change overlay will reuse. Each layer earns the next. Scale the mechanism paragraph to the workflow's surface area: a pipeline of five stations gets one sentence per station, not one paragraph per station. A workflow with one decision point gets one sentence. The numbered list must be preceded by the orientation and mechanism prose; do not use ONLY numbered steps. Conditional sub-paths are fine: "1.a) if the key is not in the cache, skip to step 3" or "2. read from the database (or from the replica, if configured)"; the goal is visual simplicity, not rigid formatting. The walkthrough must be _idempotent for its scope and level of abstraction_: reading it once at its chosen level gives the complete picture. If a reader would need to look up code to parse a step, the step is at the wrong abstraction level.
26
+ - **"How this change modifies it" mirrors the numbered list.** Repeat the same step numbers from "What it does today." Under each step, a sub-bullet notes what changed (cited `path:line` where the change landed). Steps that don't change are listed with no annotation. New steps inserted between existing ones get fractional numbers (e.g., 2.5) so the numbering stays aligned. If a touch point references a component or state the reader has not met yet, go back and introduce it in the teaching section, or drop it from the overlay.
27
+
28
+ The didactic spine: SYNOPSIS orients, "What it does today" builds the mental model, "How this change modifies it" overlays the diff onto that model. The numbered stages are the shared scaffolding between the two halves. The reader builds one model, not three.
29
+
30
+ ## What this skill produces
31
+
32
+ A markdown walkthrough for the user, rendered in chat by default. The walkthrough:
33
+
34
+ 1. Resolves the change range (merge-base..HEAD, a PR head/base, or an explicit git range).
35
+ 2. Identifies the discrete business-logic workflows the diff touches.
36
+ 3. For each workflow, reads the merge-base state of the touch-point files (`git show $MERGE_BASE:<path>`) to teach current behavior.
37
+ 4. Overlays how the change modifies each touch point, citing `path:line` for HEAD and quoting the merge-base behavior prose-side.
38
+ 5. Uses plain English, defines subsystem-specific terms on first use, leans on analogies for complex behaviors, and bold/italicizes the save points so a reader skimming only the bold and italic fragments still gets the shape.
39
+
40
+ ## Step 1: Resolve the change range
41
+
42
+ Mirror Step 1 of the thatch-code-review coordinator.
43
+
44
+ Run `git fetch origin` (NOT `git pull`). Resolve the base against the remote-tracking ref (e.g. `origin/main`), not the local branch, in case local `main` is stale on a long-lived feature checkout.
45
+
46
+ Identify the range:
47
+
48
+ - If a branch was given: compute `git merge-base HEAD origin/main`, walk `merge-base..HEAD`.
49
+ - If a PR number was given: use `gh pr view` to resolve head and base, fetch both refs, walk `merge-base..head`.
50
+ - If an explicit git range (`A..B`) was given: use it directly.
51
+ - If nothing was given: walk the current branch against `origin/main`.
52
+
53
+ If `HEAD == merge-base`, there is nothing to walk. Say so plainly and stop.
54
+
55
+ Run `git diff --stat $MERGE_BASE..HEAD` and `git log --oneline $MERGE_BASE..HEAD` to identify the change set.
56
+
57
+ ## Step 2: Read light intent, then identify workflows
58
+
59
+ Read the `git log $MERGE_BASE..HEAD` commit messages once. Use them to write a one-or-two sentence intent opener for the walkthrough; do not let them drive the body. This is light context: do not load thatch-review-context, fetch tickets, or pull prior review comments. The walkthrough teaches code mechanics, not project management.
60
+
61
+ From the diff, identify which discrete business-logic workflows the change touches. A workflow is a coherent business process (a request lifecycle, a key rotation, a backfill, a reconciliation), not "the function `bar()` changed". One file may participate in several workflows; one workflow may span several files. A tiny diff may touch a single workflow; a cross-cutting diff may touch several.
62
+
63
+ Call `thatch_memory_recall` with a query for the area to pull prior investigator notes. Prior sessions may have already mapped what you are about to teach.
64
+
65
+ ## Step 3: Research each workflow at the merge-base
66
+
67
+ For each workflow, work through these steps. Skip steps that produce nothing rather than forcing a narrative.
68
+
69
+ 1. **Read the merge-base state of touch-point files.** Use `git show $MERGE_BASE:<path>` to read each file as it exists on the default branch before the change. This is the state you teach. Do not teach HEAD; teach what is on main today.
70
+ 2. **Trace the data flow** from each entry point the workflow owns. Follow the objects through the functions and modules involved. Identify decision points where behavior branches or where invariants are enforced. These become the anchors for the change overlay in Step 4.
71
+ 3. **Read the comments in the flow.** Comments encode intention and design rationale the code alone does not show.
72
+ 4. **Note contracts**: what each function or module assumes about its inputs, what it guarantees about its outputs.
73
+ 5. **Read docs and READMEs** for the area if they exist.
74
+ 6. **Read git history** of touch-point files (`git log --oneline -- <path>`, optionally `git blame` for a contested region) when the *why it is shaped this way* matters for teaching. Use sparingly; do not lecture the user on history unless it clarifies current behavior.
75
+
76
+ ### Dispatching sub-agents (optional, large changes only)
77
+
78
+ If the change touches several workflows and one workflow's research would require reading more than roughly 3-4 files, you may dispatch a sub-agent per workflow to research in parallel. In opencode, pass each sub-agent the merge-base SHA, the touch-point files for that workflow, and an instruction to follow this Step 3 only. Collect each brief before composing.
79
+
80
+ Inline research is fine for small changes and preserves a single mental model. Default to inline; reach for sub-agents only when context pressure is real.
81
+
82
+ ## Step 4: Identify the change's touch points in each workflow
83
+
84
+ Cross-reference the diff (`git diff $MERGE_BASE..HEAD -- <path>`) against the merge-base state you just studied. For each workflow, list the touch points: the specific hunks that modify the flow, in execution order along the workflow path (not file order).
85
+
86
+ For each touch point, note:
87
+
88
+ - Where the touch point sits in the workflow (which decision point or step it modifies).
89
+ - What the merge-base code did there (a sentence, quoting a line if precise).
90
+ - What the change does instead.
91
+ - Why that modification matters for this workflow's behavior.
92
+
93
+ ## Step 5: Compose the walkthrough
94
+
95
+ ### Structure
96
+
97
+ ```
98
+ # Walkthrough: <one-line summary of the change>
99
+
100
+ ## SYNOPSIS
101
+ <one or two sentences naming the class of change and the affected workflows in plain English; may use a subsystem noun as a scan anchor but does not list files or enumerate the mechanism vocabulary>
102
+
103
+ ## Intent
104
+ <one short paragraph from commit messages; omit the section if commit messages carry no intent signal>
105
+
106
+ ## Workflow: <name>
107
+ ### What it does today
108
+ <teach in three staged layers: (1) orient - what this workflow is and why it exists, plain English, no jargon; (2) mechanism - trace the data flow, name the components the change will touch, define subsystem terms on first use, use an analogy for complex parts; (3) stages - enumerate the workflow's steps as a numbered list; these numbers are the anchors the change overlay will reuse>
109
+
110
+ ### How this change modifies it
111
+ <mirror the same numbered list from "What it does today"; under each step, a sub-bullet notes what changed (cited path:line for HEAD where the change landed); steps that don't change are listed with no sub-bullet; new steps inserted between existing ones get fractional numbers (e.g., 2.5) so the numbering stays aligned>
112
+
113
+ ## Workflow: <next>
114
+ ...
115
+
116
+ ## Notes
117
+ <optional: scope disclaimers, deferred follow-ups, anything the user will misread>
118
+ ```
119
+
120
+ Drop the `## Notes`, the `## Intent`, or any per-workflow section that has no content. Mandatory headers: `## SYNOPSIS` and one `## Workflow:` section per affected workflow.
121
+
122
+ ### Citations
123
+
124
+ - Cite `path:line` whenever you reference a specific line in the current checkout (HEAD).
125
+ - When you teach current behavior (the merge-base state), the reader can `git show $MERGE_BASE:<path>` to follow along. Say in prose that the line is *today* or *before this change* when it would otherwise be ambiguous. Where you can pin a merge-base line, pin it.
126
+ - Cite ranges as `path:start-end`.
127
+ - Prefer prose to symbol soup. "the handler then calls the rotation lock helper" beats "`rotateBatch -> acquireLock()`". Punctuation in citations is `path:line` only; do not parenthesize every code mention.
128
+
129
+ ## Prose style
130
+
131
+ Hard rules, not suggestions.
132
+
133
+ 1. **One idea per sentence, one topic per paragraph.** The reader who skims paragraph leads should get the section's structure. Make verbosity proportional to surface area: a workflow with N touch points earns at most N sentences of mechanism, not N paragraphs. A single-stage workflow gets one sentence. Cut until each sentence earns its place.
134
+ 2. **No undefined internal references.** General engineering vocabulary (constants, module, exports, init, compile, transaction) is fine; the reader knows these. Replace two things: (a) compressed idiom — "reading the key from the database" not "the row read"; "overwritten with zeros" not "zeroized"; (b) internal identifiers the reader has no way to know — "reads from the PRVB to populate fooBarBaz" is opaque if PRVB and fooBarBaz have not been introduced. Define on first use or replace with what the thing does in plain English.
135
+ 3. **No implementation verbs in prose.** "store the result in the in-memory cache" not "publish it"; "check the cache" not "peek the cache".
136
+ 4. **Define subsystem-specific terms on first use.** A crypto term like DEK is expanded "DEK (the symmetric key used to encrypt secrets at rest)" the first time it appears. Internal markers and identifiers are subsystem-specific too: `REVIEW_COMMON` (the shared block of review-framework text interpolated into review specialist skills), `SHARED_SKILLS` (the array of skill names the loader admits), `pg_advisory_lock` (a Postgres advisory lock: a cross-process mutex backed by the database). General engineering vocabulary (mutex, queue, transaction, module, constants) needs no expansion. After the first definition, use the term freely. Definitions go in the first teaching section, not SYNOPSIS.
137
+ 5. **Analogies for complex behaviors.** When a flow is non-obvious, scale-shape, or state-machine-heavy, anchor it to something the reader already knows: "this is like a checkout line where each worker holds a numbered ticket; a worker can only be served once the cashier before them has finished". Use one analogy per concept; do not extend analogies past where they hold.
138
+ 6. **Conclusion-first when claiming a behavior.** "There is a circular wait in the rotator: <explanation>" not "<explanation>. That is a circular wait." Bottom line in the lead sentence, then the evidence.
139
+ 7. **Plain ASCII only.** No smart quotes, smart apostrophes, em dashes, en dashes, ellipsis glyphs, or arrow glyphs. Use plain hyphens (sparingly); semicolons are often better.
140
+ 8. **No design-narration, no authoring-sequence.** "The change moves the lock acquisition inside the loop" not "this PR first moves the lock, then in the next commit ...". Describe the change as it stands.
141
+ 9. **No buzzwordy abstractions.** If a phrase sounds like it is trying to sound smart, replace it with concrete nouns. "identity contract" -> "the struct field that identifies the owner".
142
+ 10. **No loaded language without reason.** Prefer allowlist/blocklist, primary/replica. Use the repo's established name when one exists.
143
+
144
+ ## Emphasis for scanning: bold and italics
145
+
146
+ Bold and italicize the "save points": the phrases that carry meaning. A reader who skims *only* the bold and italic fragments should get the shape of the walkthrough.
147
+
148
+ - **Bold:** phrases that name the change or the mechanism (components, states, thresholds, behaviors). The "what".
149
+ - **Italicize:** phrases that orient to significance (the conclusion a paragraph is building toward, the outcome that makes a touch point matter). At most one per paragraph. The "why it matters".
150
+ - Do not bold or italicize: history, hazard detail, justification, connective tissue.
151
+ - Never bold a whole sentence or bullet.
152
+ - A phrase may be both bold and italic when it is both a change-naming noun and a paragraph's load-bearing insight (e.g. **_circular wait_**). Use sparingly.
153
+
154
+ ## Synoptic check
155
+
156
+ Read only your bold and italic fragments top-to-bottom. If that reading does not convey the shape of the change, you bolded the wrong words or your prose is padding around them.
157
+
158
+ ## Output
159
+
160
+ Default: render the walkthrough as your chat reply. Use markdown. Put each narrative paragraph on one physical line so it renders cleanly in the TUI.
161
+
162
+ On request ("save this", "write it to a file", "put it in docs"): write the markdown to a workspace file. Choose the path with the user when the obvious one (e.g. `docs/walkthroughs/<range>.md` under the repo, or a scratch path outside the repo) is ambiguous. Do not write to a file unless asked; do not litter the worktree.
163
+
164
+ ## What this skill is NOT
165
+
166
+ - It is not a PR description (that is `pr-description`). The audience here is the user, not an external reviewer; the goal is teaching the code in depth, not orienting someone to a diff.
167
+ - It is not a code review. Do not flag issues or evaluate quality. That is the review specialist skills' job.
168
+ - It is not a project context brief (that is `thatch-review-context`). Do not pull tickets, prior reviews, or deferred-work registers. The walkthrough teaches code mechanics using only light commit-message intent.
169
+ - It is not a workflow research guide for specialist consumption (that is `thatch-workflow-research`). The output here is a human-readable teaching unit, not a briefing block.
170
+ - It is not a memory writer. Do not call `thatch_memory_remember`. If you discover durable facts, note them in the walkthrough's Notes; the session-reflection or fact-extractor skills persist them later.
171
+
172
+ ## Worked example (one-workflow excerpt)
173
+
174
+ # Walkthrough: Narrow the rotation advisory lock to DB writes only
175
+
176
+ ## SYNOPSIS
177
+ The change moves the **rotation advisory lock** inside the rotation batch loop, releasing it across **KMS I/O** so concurrent rotations from unrelated tenants no longer stall.
178
+
179
+ ## Intent
180
+ Commit messages frame this as unblocking multi-tenant rotations held back by a single shared lock.
181
+
182
+ ## Workflow: secret rotation batch
183
+
184
+ ### What it does today
185
+
186
+ The rotator processes batches of keys that need re-encryption. It exists because keys must be rotated periodically to limit blast radius if any one key is compromised.
187
+
188
+ The flow lives in `src/rotate/batch.ts`. The rotator calls **`pg_advisory_lock`** (a Postgres advisory lock: a cross-process mutex backed by the database) at the top of `rotateBatch` (`src/rotate/batch.ts:75`), then loops over every key in the batch. The **advisory lock** is held for the whole loop, including the KMS network calls. This is like a single cashier that hands out numbered tickets to every waiting worker, but then refuses to call the next worker's number until the current worker has walked across the store to fetch their own parcel. Every other worker (here, every other tenant's rotation) waits on the parcel walk to finish.
189
+
190
+ The workflow's stages are:
191
+
192
+ 1. **Acquire advisory lock** at the top of the batch (`src/rotate/batch.ts:75`).
193
+ 2. **Read key** from the database for the next key in the batch.
194
+ 3. **Call KMS** (the cloud key-management service) to encrypt the key material over the network.
195
+ 4. **Write ciphertext** back to the database.
196
+ 5. **Advance cursor** so a crash can resume from the right place.
197
+ 6. **Release advisory lock** at the end of the batch.
198
+
199
+ ### How this change modifies it
200
+
201
+ 1. **Acquire advisory lock**
202
+ - **changed**: the acquire moves inside the loop (`src/rotate/batch.ts:88`), wrapping only steps 2 and 4.
203
+ 2. **Read key**
204
+ 3. **Call KMS**
205
+ - **changed**: the KMS call (`src/rotate/batch.ts:104`) now runs outside the lock. The call itself is the same; only its lock context changes.
206
+ 4. **Write ciphertext**
207
+ 5. **Advance cursor**
208
+ 6. **Release advisory lock**
209
+ - **changed**: the release now happens at the end of each iteration, not at the end of the batch.
210
+
211
+ The change does **_unblock unrelated tenants_**: their rotations no longer wait on a long KMS round trip they do not share.
@@ -0,0 +1,194 @@
1
+ ---
2
+ name: thatch-code-walkthrough
3
+ description: 'Use when the user asks "walk me through this feature", "how does X work", or wants on-demand documentation about a feature, module, or workflow. Also use when building a new feature, working with undocumented code, or revisiting code whose docs have drifted: the skill produces a clean high-level overview draft suitable for `path/to/pkg/README.md`, `docs/features/some-feature.md`, or a "# Feature Overview" section of a broader doc (adjust headers as needed). Produces a structured teaching walkthrough with a SPECIFIC format (SYNOPSIS, per-workflow orient/mechanism/numbered-stages teaching, Key files list) and calibrated prose rules (plain English, define-on-first-use, analogies, bold/italic save points, path:line citations). The format and prose rules are load-bearing and live in the skill body — load this skill for the output scaffold, not just for the research method. Do NOT use for explaining a specific change (use thatch-change-walkthrough) or for specialist-consumption research briefs (use thatch-workflow-research).'
4
+ ---
5
+
6
+ You are a code walkthrough author. Your job is to teach the user how a feature, module, or workflow fits together as it stands today. There is no change to overlay; the user wants on-demand documentation about how a piece of the system works.
7
+
8
+ ## Use cases
9
+
10
+ This skill serves two distinct triggers:
11
+
12
+ - **On-demand explanation.** The user asks "walk me through X", "how does X work", or "I want to understand X" for a feature, module, or workflow. Render the walkthrough in chat (or write to a scratch file on request).
13
+ - **Doc drafting.** While building a new feature, working with undocumented code, or revisiting code whose docs have drifted, proactively reach for this skill to produce a high-level overview draft. The output shape is suitable for `path/to/pkg/README.md`, `docs/features/<name>.md`, or as a `# Feature Overview` section of a broader doc. When embedding in a larger doc, drop the top-level `# Walkthrough: <name>` header, demote the `## SYNOPSIS` and `## Workflow:` headers to fit the surrounding section structure, and keep the teaching prose and Key files list. State where you are writing the draft before composing, and confirm the destination path with the user if it is ambiguous.
14
+
15
+ ## The reader
16
+
17
+ You are writing for an engineer who knows the tech stack and general engineering vocabulary but has never touched the code being explained. They may not know subsystem-specific jargon or acronyms: a crypto term like DEK, an auth term like a SAML assertion, a scanning term like a ScanRun. They do not need to be told what a mutex or a queue is, but they DO need to be told what *this subsystem's* mutex or queue is and why it is here.
18
+
19
+ Your goal is not to summarize the feature. It is to teach the user the code in enough depth that they can read it with understanding. Treat this as an instructional design unit.
20
+
21
+ This is a teaching walkthrough, not a review. Do not flag issues, evaluate quality, or suggest improvements. The thatch review skills do those jobs.
22
+
23
+ ## What this skill produces
24
+
25
+ A markdown walkthrough for the user, rendered in chat by default. The walkthrough:
26
+
27
+ 1. Identifies the code area from the user's prompt, optionally anchored to a branch or PR.
28
+ 2. Researches how the feature works at the resolved code state (the branch's HEAD, or HEAD if no branch was given).
29
+ 3. Teaches it in depth: orient, mechanism, numbered stages, with subsystem terms defined on first use and analogies for complex parts.
30
+ 4. Lists the key files that implement the feature, with `path:line` references for entry points.
31
+
32
+ ## Step 1: Identify the code area
33
+
34
+ The user names a feature, module, or workflow ("the extraction pipeline", "how does rotation work", "the scan scheduler"). They may anchor it to a branch or PR.
35
+
36
+ Resolve where to look:
37
+
38
+ - If a branch was given, work from that branch's HEAD. `git checkout <branch>` is not needed; use `git show <branch>:<path>` to read files at that branch's state, or `git rev-parse <branch>` to pin the SHA if you need a stable reference.
39
+ - If a PR was given, use `gh pr view <N>` to fetch the PR's title, body, and list of changed files. The PR is a POINTER to the code area, not the subject. Use its files and description to identify which feature or workflow to teach, then teach the feature at the PR's HEAD state. Do NOT teach the PR's diff; that is `thatch-change-walkthrough`'s job.
40
+ - If nothing was given, work from the current HEAD (the working checkout).
41
+
42
+ From the user's prompt and the resolved code state, identify which files implement the feature. Use grep/glob to find entry points and trace outward. A single feature may span several files; a single file may participate in several features. Identify the discrete business-logic workflows the feature contains.
43
+
44
+ Call `thatch_memory_recall` with a query for the area. Prior sessions may have already mapped what you are about to teach.
45
+
46
+ If the user's prompt is too vague to identify a code area ("tell me about thatch"), ask one clarifying question. Do not guess.
47
+
48
+ ## Step 2: Research the feature
49
+
50
+ For each identified workflow or sub-component, work through these steps. Skip steps that produce nothing rather than forcing a narrative.
51
+
52
+ 1. **Read the code at the resolved state.** Use `git show <SHA>:<path>` for a pinned branch, or read files directly if working from the current HEAD. This is the state you teach.
53
+ 2. **Trace the data flow** from each entry point the feature owns. Follow the objects through the functions and modules involved. Identify decision points where behavior branches or where invariants are enforced.
54
+ 3. **Read the comments in the flow.** Comments encode intention and design rationale the code alone does not show.
55
+ 4. **Note contracts**: what each function or module assumes about its inputs, what it guarantees about its outputs.
56
+ 5. **Read docs and READMEs** for the area if they exist.
57
+ 6. **Read git history** of the feature's files (`git log --oneline -- <path>`, optionally `git blame` for a contested region) when the *why it is shaped this way* matters for teaching. Use sparingly; do not lecture the user on history unless it clarifies current behavior.
58
+
59
+ ### Dispatching sub-agents (optional, large features only)
60
+
61
+ If the feature spans several workflows and one workflow's research would require reading more than roughly 3-4 files, you may dispatch a sub-agent per workflow to research in parallel. In opencode, pass each sub-agent the resolved SHA, the entry-point files for that workflow, and an instruction to follow this Step 2 only. Collect each brief before composing.
62
+
63
+ Inline research is fine for small features and preserves a single mental model. Default to inline; reach for sub-agents only when context pressure is real.
64
+
65
+ ## Step 3: Compose the walkthrough
66
+
67
+ ### Structure
68
+
69
+ ```
70
+ # Walkthrough: <one-line summary of the feature>
71
+
72
+ ## SYNOPSIS
73
+ <one or two sentences naming what the feature is and why it exists, in plain English; may use a subsystem noun as a scan anchor but does not list files or enumerate internal concepts>
74
+
75
+ ## Workflow: <name>
76
+ ### What it does
77
+ <teach in three staged layers: (1) orient - what this workflow is and why it exists, plain English, no jargon; (2) mechanism - trace the data flow, name the components, define subsystem terms on first use, use an analogy for complex parts; (3) stages - enumerate the workflow's steps as a numbered list>
78
+
79
+ ## Workflow: <next>
80
+ ...
81
+
82
+ ## Key files
83
+ <flat list of the files that implement the feature, each with a one-line role and a `path:line` reference to its primary entry point>
84
+
85
+ ## Notes
86
+ <optional: scope disclaimers, known limitations, anything the user will misread>
87
+ ```
88
+
89
+ Drop the `## Notes` or any per-workflow section that has no content. Mandatory headers: `## SYNOPSIS`, one `## Workflow:` section, and `## Key files`.
90
+
91
+ ### Layering
92
+
93
+ Layer the knowledge so each section builds on the previous one. The reader should never encounter a concept in layer N that was not introduced in layer N-1.
94
+
95
+ - **SYNOPSIS orients only.** One or two sentences naming what the feature is and why it exists, in plain English. It may use a subsystem-specific noun as a scan anchor, but it does not list files, enumerate internal concepts, or front-load mechanism vocabulary the reader has not been introduced to. The reader should come away knowing *what the feature is* and *why it exists*, nothing more.
96
+ - **"What it does" builds in stages.** Teach in three layers: first orient the reader to what the workflow is and why it exists (plain English, no jargon); then add the mechanism, tracing the data flow and naming the components; then enumerate the workflow's stages as a numbered list. Each layer earns the next. Scale the mechanism paragraph to the workflow's surface area: a pipeline of five stages gets one sentence per stage, not one paragraph per stage. A workflow with one decision point gets one sentence. The numbered list must be preceded by the orientation and mechanism prose; do not use ONLY numbered steps. Conditional sub-paths are fine: "1.a) if the key is not in the cache, skip to step 3"; the goal is visual simplicity, not rigid formatting. The walkthrough must be _idempotent for its scope and level of abstraction_: reading it once at its chosen level gives the complete picture. If a reader would need to look up code to parse a step, the step is at the wrong abstraction level.
97
+
98
+ The didactic spine: SYNOPSIS orients, "What it does" builds the mental model in three staged layers ending in a numbered stage list, "Key files" gives the reader the entry points to read the code themselves. The reader builds one model, not three.
99
+
100
+ ### Key files
101
+
102
+ List the files that implement the feature. Each entry has:
103
+
104
+ - The file path.
105
+ - A one-line role: what this file does in the feature.
106
+ - A `path:line` reference to the primary entry point (the function, handler, or module declaration that kicks off the feature's main flow).
107
+
108
+ Format:
109
+
110
+ ```
111
+ - `src/rotate/batch.ts` - the rotation batch loop; entry point is `rotateBatch` at `src/rotate/batch.ts:42`.
112
+ - `src/rotate/lock.ts` - the advisory lock helpers; entry point is `acquireLock` at `src/rotate/lock.ts:18`.
113
+ ```
114
+
115
+ Order the list by the feature's data flow: the entry point first, then the files it calls, in execution order. Do not list files that are only tangentially related; the reader uses this list to read the code themselves, so it must be a clean reading order.
116
+
117
+ ### Citations
118
+
119
+ - Cite `path:line` whenever you reference a specific line in the code state you are teaching.
120
+ - If you pinned a branch SHA, say in prose that the line is "at branch `<branch>`" when it would otherwise be ambiguous.
121
+ - Cite ranges as `path:start-end`.
122
+ - Prefer prose to symbol soup. "the handler then calls the rotation lock helper" beats "`rotateBatch -> acquireLock()`". Punctuation in citations is `path:line` only; do not parenthesize every code mention.
123
+
124
+ ## Prose style
125
+
126
+ Hard rules, not suggestions.
127
+
128
+ 1. **One idea per sentence, one topic per paragraph.** The reader who skims paragraph leads should get the section's structure. Make verbosity proportional to surface area: a workflow with N touch points earns at most N sentences of mechanism, not N paragraphs. A single-stage workflow gets one sentence. Cut until each sentence earns its place.
129
+ 2. **No undefined internal references.** General engineering vocabulary (constants, module, exports, init, compile, transaction) is fine; the reader knows these. Replace two things: (a) compressed idiom ( "reading the key from the database" not "the row read"; "overwritten with zeros" not "zeroized"); (b) internal identifiers the reader has no way to know ( "reads from the PRVB to populate fooBarBaz" is opaque if PRVB and fooBarBaz have not been introduced). Define on first use or replace with what the thing does in plain English.
130
+ 3. **No implementation verbs in prose.** "store the result in the in-memory cache" not "publish it"; "check the cache" not "peek the cache".
131
+ 4. **Define subsystem-specific terms on first use.** A crypto term like DEK is expanded "DEK (the symmetric key used to encrypt secrets at rest)" the first time it appears. Internal markers and identifiers are subsystem-specific too: `REVIEW_COMMON` (the shared block of review-framework text interpolated into review specialist skills), `SHARED_SKILLS` (the array of skill names the loader admits), `pg_advisory_lock` (a Postgres advisory lock: a cross-process mutex backed by the database). General engineering vocabulary (mutex, queue, transaction, module, constants) needs no expansion. After the first definition, use the term freely. Definitions go in the first teaching section, not SYNOPSIS.
132
+ 5. **Analogies for complex behaviors.** When a flow is non-obvious, scale-shape, or state-machine-heavy, anchor it to something the reader already knows: "this is like a checkout line where each worker holds a numbered ticket; a worker can only be served once the cashier before them has finished". Use one analogy per concept; do not extend analogies past where they hold.
133
+ 6. **Conclusion-first when claiming a behavior.** "There is a circular wait in the rotator: <explanation>" not "<explanation>. That is a circular wait." Bottom line in the lead sentence, then the evidence.
134
+ 7. **Plain ASCII only.** No smart quotes, smart apostrophes, em dashes, en dashes, ellipsis glyphs, or arrow glyphs. Use plain hyphens (sparingly); semicolons are often better.
135
+ 8. **No design-narration, no authoring-sequence.** Describe the feature as it stands. Do not narrate the order you discovered things, which files you read first, or what a later commit added.
136
+ 9. **No buzzwordy abstractions.** If a phrase sounds like it is trying to sound smart, replace it with concrete nouns. "identity contract" -> "the struct field that identifies the owner".
137
+ 10. **No loaded language without reason.** Prefer allowlist/blocklist, primary/replica. Use the repo's established name when one exists.
138
+
139
+ ## Emphasis for scanning: bold and italics
140
+
141
+ Bold and italicize the "save points": the phrases that carry meaning. A reader who skims *only* the bold and italic fragments should get the shape of the walkthrough.
142
+
143
+ - **Bold:** phrases that name the component, mechanism, or behavior (the "what").
144
+ - **Italicize:** phrases that orient to significance (the conclusion a paragraph is building toward, the reason a mechanism matters). At most one per paragraph. The "why it matters".
145
+ - Do not bold or italicize: history, hazard detail, justification, connective tissue.
146
+ - Never bold a whole sentence or bullet.
147
+ - A phrase may be both bold and italic when it is both a component-naming noun and a paragraph's load-bearing insight (e.g. **_circular wait_**). Use sparingly.
148
+
149
+ ## Synoptic check
150
+
151
+ Read only your bold and italic fragments top-to-bottom. If that reading does not convey the shape of the feature, you bolded the wrong words or your prose is padding around them.
152
+
153
+ ## Output
154
+
155
+ Default: render the walkthrough as your chat reply. Use markdown. Put each narrative paragraph on one physical line so it renders cleanly in the TUI.
156
+
157
+ On request ("save this", "write it to a file", "put it in docs"): write the markdown to a workspace file. Choose the path with the user when the obvious one (e.g. `docs/walkthroughs/<feature>.md` under the repo, or a scratch path outside the repo) is ambiguous. Do not write to a file unless asked; do not litter the worktree.
158
+
159
+ ## What this skill is NOT
160
+
161
+ - It is not `thatch-change-walkthrough`. That skill teaches a diff: current behavior, then how the change modifies it. This skill has no change to overlay; it teaches the feature as it stands. If the user asks "walk me through THIS CHANGE" or "what does this PR do," defer to `thatch-change-walkthrough`.
162
+ - It is not `thatch-workflow-research`. That skill produces a briefing block for specialist agents (purpose, key files, data flow, major evolutions, constraints, current state). This skill produces a human-readable teaching unit with plain English, analogies, and bold/italic save points.
163
+ - It is not a code review. Do not flag issues or evaluate quality. That is the review specialist skills' job.
164
+ - It is not a memory writer. Do not call `thatch_memory_remember`. If you discover durable facts, note them in the walkthrough's Notes; the session-reflection or fact-extractor skills persist them later.
165
+
166
+ ## Worked example (one-workflow excerpt)
167
+
168
+ # Walkthrough: The secret rotation batch
169
+
170
+ ## SYNOPSIS
171
+ The **secret rotation batch** periodically re-encrypts keys with fresh key material to limit blast radius if any one key is compromised.
172
+
173
+ ## Workflow: rotation batch
174
+
175
+ ### What it does
176
+
177
+ The rotator processes batches of keys that need re-encryption. It exists because keys must be rotated periodically to limit blast radius if any one key is compromised.
178
+
179
+ The flow lives in `src/rotate/batch.ts`. The rotator calls **`pg_advisory_lock`** (a Postgres advisory lock: a cross-process mutex backed by the database) at the top of `rotateBatch` (`src/rotate/batch.ts:75`), then loops over every key in the batch. The **advisory lock** is held for the whole loop, including the KMS network calls. This is like a single cashier that hands out numbered tickets to every waiting worker, but then refuses to call the next worker's number until the current worker has walked across the store to fetch their own parcel. Every other worker (here, every other tenant's rotation) waits on the parcel walk to finish.
180
+
181
+ The workflow's stages are:
182
+
183
+ 1. **Acquire advisory lock** at the top of the batch (`src/rotate/batch.ts:75`).
184
+ 2. **Read key** from the database for the next key in the batch.
185
+ 3. **Call KMS** (the cloud key-management service) to encrypt the key material over the network.
186
+ 4. **Write ciphertext** back to the database.
187
+ 5. **Advance cursor** so a crash can resume from the right place.
188
+ 6. **Release advisory lock** at the end of the batch.
189
+
190
+ ## Key files
191
+
192
+ - `src/rotate/batch.ts` - the rotation batch loop; entry point is `rotateBatch` at `src/rotate/batch.ts:42`.
193
+ - `src/rotate/lock.ts` - the advisory lock helpers; entry point is `acquireLock` at `src/rotate/lock.ts:18`.
194
+ - `src/rotate/cursor.ts` - the crash-resumption cursor; entry point is `advanceCursor` at `src/rotate/cursor.ts:25`.
@@ -21,9 +21,9 @@ description: Extract durable project facts ... Use when ...
21
21
  - `description` drives when the agent loads the skill (both opencode and
22
22
  Cursor auto-discover skills and use the description for relevance).
23
23
 
24
- ## The 14 skills
24
+ ## The 16 skills
25
25
 
26
- **Shared (13)** — installed everywhere; no sub-agents required:
26
+ **Shared (15)** — installed everywhere; no sub-agents required:
27
27
 
28
28
  | Skill | Role |
29
29
  |-------|------|
@@ -39,6 +39,8 @@ description: Extract durable project facts ... Use when ...
39
39
  | `thatch-review-synthesizer` | Verify specialist findings against code, dedupe, classify, calibrate severity. Cross-references findings against prior review comments when a follow-up round register is provided; produces a Previously identified appendix. |
40
40
  | `thatch-review-context` | Gather project/feature context (PR descriptions, git archaeology, ticket references, memory) before fan-out. Prevents false positives about intentionally deferred work. Also fetches prior review comments on a connected PR/MR for follow-up-round detection and builds a register with preliminary addressed-check status per comment. |
41
41
  | `thatch-workflow-research` | Research code workflows/features affected by a change or planned change. Reads code flows, comments, git history, memories, docs. Produces a guide to the code for reviewers or planners. |
42
+ | `thatch-change-walkthrough` | Explain a change to the user as a teaching walkthrough: resolve the delta, research each affected workflow at the merge-base, teach current behavior, then overlay the modifications with file:line citations and analogies. |
43
+ | `thatch-code-walkthrough` | Explain a feature, module, or workflow to the user as a teaching walkthrough: identify the code area (optionally from a branch or PR), research how it works, teach it with file:line citations and analogies, list the key files. |
42
44
  | `thatch-session-reflection` | End-of-session memory recording (project, user, tools, self). |
43
45
 
44
46
  **opencode-only (1)** — the coordinator needs sub-agent support:
@@ -79,7 +81,7 @@ The synthesizer reuses the same verification rigor but has its own structure
79
81
  ## The two arrays
80
82
 
81
83
  ```ts
82
- const SHARED_SKILLS: SkillDef[] = [ /* 13 skills above */ ];
84
+ const SHARED_SKILLS: SkillDef[] = [ /* 15 skills above */ ];
83
85
  const OPENCODE_ONLY_SKILLS: SkillDef[] = [ /* code-review coordinator */ ];
84
86
  ```
85
87
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jeffober/thatch",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Persistent memory for AI coding agents — local embeddings, SQLite stores, zero config. Works with OpenCode (as a plugin), Claude Code (as an MCP server), and Cursor (as an MCP server).",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -30,7 +30,8 @@
30
30
  "@opencode-ai/plugin": "^1.17.13",
31
31
  "@types/bun": "latest",
32
32
  "markdownlint-cli2": "^0.23.0",
33
- "typescript": "^5.7.0"
33
+ "typescript": "^5.7.0",
34
+ "yaml": "^2.7.0"
34
35
  },
35
36
  "peerDependencies": {
36
37
  "@opencode-ai/plugin": "^1.17.0"
package/src/prompts.ts CHANGED
@@ -34,6 +34,8 @@ workflows. The host auto-discovers them, but reach for them proactively:
34
34
 
35
35
  - \`thatch-code-review\` — full multi-agent code review (dispatches 6 specialists + synthesizer). Requires sub-agent support.
36
36
  - \`thatch-workflow-research\` — research code workflows affected by a change or planned change, before reviewing or planning.
37
+ - \`thatch-change-walkthrough\` — produces a teaching walkthrough of a diff with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + change overlay mirroring the same numbers) and calibrated prose rules. Load the skill for the format and prose rules, not just for the research method.
38
+ - \`thatch-code-walkthrough\` — produces a teaching walkthrough for a feature/workflow as it stands today with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + Key files) and calibrated prose rules. Also use proactively to draft high-level docs for new or undocumented features (suitable for pkg/README.md or docs/features/<name>.md). Load the skill for the format and prose rules, not just for the research method.
37
39
  - \`thatch-review-context\` — gather project context (PRs, tickets, TODOs, deferred work) before a review.
38
40
  - \`thatch-project-primer\` — investigate a new project and write foundational memories.
39
41
  - \`thatch-session-reflection\` — record what you learned at end of session.
@@ -164,6 +166,8 @@ Thatch ships skills for code review, project investigation, and memory
164
166
  workflows. The host auto-discovers them, but reach for them proactively:
165
167
 
166
168
  - \`thatch-workflow-research\` — research code workflows affected by a change or planned change, before reviewing or planning.
169
+ - \`thatch-change-walkthrough\` — produces a teaching walkthrough of a diff with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + change overlay mirroring the same numbers) and calibrated prose rules. Load the skill for the format and prose rules, not just for the research method.
170
+ - \`thatch-code-walkthrough\` — produces a teaching walkthrough for a feature/workflow as it stands today with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + Key files) and calibrated prose rules. Also use proactively to draft high-level docs for new or undocumented features (suitable for pkg/README.md or docs/features/<name>.md). Load the skill for the format and prose rules, not just for the research method.
167
171
  - \`thatch-review-context\` — gather project context (PRs, tickets, TODOs, deferred work) before a review.
168
172
  - \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` / \`-mark-and-sweep\` — six specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
169
173
  - \`thatch-project-primer\` — investigate a new project and write foundational memories.
@@ -357,6 +361,8 @@ Thatch ships skills for code review, project investigation, and memory
357
361
  workflows. The host auto-discovers them, but reach for them proactively:
358
362
 
359
363
  - \`thatch-workflow-research\` — research code workflows affected by a change or planned change, before reviewing or planning.
364
+ - \`thatch-change-walkthrough\` — produces a teaching walkthrough of a diff with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + change overlay mirroring the same numbers) and calibrated prose rules. Load the skill for the format and prose rules, not just for the research method.
365
+ - \`thatch-code-walkthrough\` — produces a teaching walkthrough for a feature/workflow as it stands today with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + Key files) and calibrated prose rules. Also use proactively to draft high-level docs for new or undocumented features (suitable for pkg/README.md or docs/features/<name>.md). Load the skill for the format and prose rules, not just for the research method.
360
366
  - \`thatch-review-context\` — gather project context (PRs, tickets, TODOs, deferred work) before a review.
361
367
  - \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` / \`-mark-and-sweep\` — six specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
362
368
  - \`thatch-project-primer\` — investigate a new project and write foundational memories.
package/src/skills.ts CHANGED
@@ -16,11 +16,14 @@ function loadSkillFile(name: string): string {
16
16
  const artifactsDir = join(__dirname, "..", "artifacts", "skills");
17
17
  const filePath = join(artifactsDir, name + ".md");
18
18
  const raw = readFileSync(filePath, "utf8");
19
- // Interpolate REVIEW_COMMON
20
- if (raw.includes("${REVIEW_COMMON}")) {
19
+ // Interpolate REVIEW_COMMON only when it appears on its own line (the
20
+ // directive form used by review specialist skills). Inline mentions in
21
+ // other skills (e.g. as examples in prose) are content, not directives,
22
+ // and must not be interpolated.
23
+ if (/^[ \t]*\$\{REVIEW_COMMON\}[ \t]*$/m.test(raw)) {
21
24
  const commonPath = join(artifactsDir, "common.md");
22
25
  const commonContent = readFileSync(commonPath, "utf8");
23
- return raw.replace(/\$\{REVIEW_COMMON\}/g, commonContent);
26
+ return raw.replace(/^[ \t]*\$\{REVIEW_COMMON\}[ \t]*$/gm, commonContent);
24
27
  }
25
28
  return raw;
26
29
  }
@@ -39,6 +42,8 @@ function loadSharedSkills(): SkillDef[] {
39
42
  "thatch-review-synthesizer",
40
43
  "thatch-review-context",
41
44
  "thatch-workflow-research",
45
+ "thatch-change-walkthrough",
46
+ "thatch-code-walkthrough",
42
47
  "thatch-session-reflection",
43
48
  ];
44
49
  return names.map((name) => ({ name, content: loadSkillFile(name) }));