@jeffober/thatch 0.1.14 → 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.
@@ -18,6 +18,12 @@ Identify what to review:
18
18
  - If a git range was specified (A..B form), use it directly.
19
19
  - If no target was specified, review the current branch against its base, resolving the base from `origin/main` (or the appropriate remote tracking ref) after fetching.
20
20
 
21
+ Also detect whether the current branch has a **connected PR/MR** even when none was specified — this is what enables follow-up-round detection in Step 2. Inspect `git remote -v` to recognize the VCS host (github.com → GitHub/`gh`; gitlab.* → GitLab/`glab`; bitbucket.org → Bitbucket Cloud; dev.azure.com → Azure DevOps). Then probe for an open PR/MR on the current branch using the matching CLI or REST API:
22
+ - GitHub: `gh pr view --head <branch> --json number,headRefOid,baseRefOid`
23
+ - GitLab: `glab mr list --source-branch <branch>`
24
+ - Other providers: equivalent detection via their CLI or REST API.
25
+ - If you cannot detect or cannot interact with the VCS (no CLI, no REST access), treat the change as a **local-branch review** and proceed with the existing procedure. A local-branch review is not a defect — it just means there is no prior-comments register to build.
26
+
21
27
  Also fetch any refs not locally reachable so branches and PRs that were never checked out can be reviewed (e.g. `git fetch origin <branch>` for a PR head).
22
28
 
23
29
  Run git diff --stat on the resolved range and git log --oneline to understand the change.
@@ -32,8 +38,9 @@ Load the thatch-review-context skill and follow its methodology to build a conte
32
38
  - thatch_memory_recall for feature/project status, design decisions, ticket dependencies
33
39
  - Project docs, READMEs, design docs
34
40
  - Issue tracker (gh issue/view) if ticket IDs are found
41
+ - **Prior review comments** — if Step 1 detected a connected PR/MR, fetch ALL prior review comments on it (see source #8 in the review-context skill) and build the prior-comments register with a preliminary addressed-check status per comment. This is what distinguishes a **follow-up round** (register non-empty) from the **first round** (register empty or PR has no prior reviews). If Step 1 found no connected PR/MR, the brief explicitly states `Local-branch review — no prior-comment fetch`.
35
42
 
36
- Produce the context brief in the format the skill prescribes (project context, this change's scope, deferred work, dependencies, relevant constraints).
43
+ Produce the context brief in the format the skill prescribes (project context, this change's scope, deferred work, dependencies, relevant constraints, and the prior review comments section when present).
37
44
 
38
45
  If context is sparse (no PR description, no ticket references, no relevant memories), note that the change appears standalone. Even a sparse brief is valuable: it tells specialists you looked and found nothing, so they do not need to repeat the search.
39
46
 
@@ -101,13 +108,16 @@ After all sub-agents complete, load the thatch-review-synthesizer skill to verif
101
108
 
102
109
  Confirmed LOW findings are mandatory in the final report, including mechanical findings (pedantic, no-slop, breadcrumbs, docs, naming, style, comments). Do not omit them for being non-functional.
103
110
 
111
+ **Follow-up round cross-reference** — if Step 2 built a prior-comments register, the synthesizer must cross-reference every confirmed and rejected finding against it (see the synthesizer skill's "Cross-reference against prior review comments" section). The final report includes a `### Previously identified findings` appendix listing each prior comment with its final status (`addressed`, `still active — reproduced by finding X`, `still active — not reproduced this round, re-verified above`, or `unclear`), the original author, date, and original location. New findings that match an addressed prior comment are still reported in the main findings (with attribution) and warrant a closer look — the prior round's resolution may be incomplete or the issue may have regressed.
112
+
104
113
  Alternatively, perform the synthesis yourself:
105
114
  1. Read each finding's cited location to verify evidence accuracy.
106
115
  2. Deduplicate findings flagged by multiple specialists.
107
116
  3. Group findings by root cause where multiple findings stem from the same issue.
108
117
  4. Classify each as CONFIRMED, REJECTED, or UNVERIFIABLE. For behavioral findings, apply citation verification, reachability, and intent verification. For mechanical findings, verify the cited text exists, is branch-introduced or newly made relevant, and violates the stated guideline or specialist taxonomy.
109
- 5. Calibrate severity (BLOCKING > HIGH > MEDIUM > LOW) based on your verification.
110
- 6. Produce a final report grouped by severity, with coverage gaps noted. Include every confirmed LOW finding.
118
+ 5. Cross-reference against the prior-comments register if one was built in Step 2: tag matching findings `Provenance: previously identified by @author, PR #N, DATE` and produce the `### Previously identified findings` appendix per the synthesizer skill.
119
+ 6. Calibrate severity (BLOCKING > HIGH > MEDIUM > LOW) based on your verification.
120
+ 7. Produce a final report grouped by severity, with coverage gaps noted. Include every confirmed LOW finding.
111
121
 
112
122
  ## Specialist briefing template
113
123
 
@@ -118,6 +128,7 @@ When dispatching each sub-agent, include in the prompt:
118
128
  - The diff stat for this unit's files
119
129
  - **The project context brief** from Step 2, filtered to what is relevant to this unit's scope. Explicitly list any deferred work that falls within this unit's files, and call out TODO ($ticket) markers the specialists should recognize as intentional.
120
130
  - **The workflow guide** from Step 3, filtered to the workflows relevant to this unit's scope. Use it to understand the purpose and evolution of the code before flagging issues. It provides the code-level context (flows, contracts, history, constraints) that prevents false positives about intentional behavior and long-standing design decisions.
131
+ - **The prior review comments register** from Step 2 when present — the list of issues other reviewers already raised, with each comment's current-HEAD location and preliminary status. This is a **hint list, not a finding list**: it saves specialists the work of treating an already-identified issue as newly discovered. Specialists still produce their own findings normally. For any finding that matches a prior comment, set `Provenance` to `previously identified by @author, PR #N, DATE` in addition to the branch-introduced / pre-existing classification — the synthesizer does the final cross-reference and dedup.
121
132
  - Any design context or specific concerns
122
133
  - Explicit scope boundaries ("your scope is X; do NOT review Y")
123
134
  - Instruction to produce markdown findings with: severity, category, file:line, finding, evidence, trigger scenario, reachability, source of truth, producer chain, provenance
@@ -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`.
@@ -56,6 +56,62 @@ If ticket IDs were found:
56
56
  - Look for milestone assignments, dependencies, and blocking relationships
57
57
  - Check for epic or parent issues that describe the overall feature
58
58
 
59
+ ### 8. Prior review comments (follow-up round detection)
60
+
61
+ If the change under review has a connected PR/MR on the upstream remote, fetch all prior review comments so this review does not duplicate already-identified issues. Any prior review activity on the PR/MR means **this is a follow-up round**, not the first review. If no PR/MR is connected, this is a **local-branch review** — skip this source entirely; the existing review procedure applies.
62
+
63
+ #### Detect the VCS provider
64
+
65
+ `git remote -v` lists remotes and URLs. Parse the upstream URL:
66
+ - `github.com` → GitHub (`gh`)
67
+ - `gitlab.*` → GitLab (`glab`)
68
+ - `bitbucket.org` → Bitbucket Cloud
69
+ - `dev.azure.com` → Azure DevOps
70
+ - Unknown host or no upstream → local-branch review, skip this source.
71
+
72
+ If the matching CLI tool (`gh`, `glab`, etc.) is not on PATH and you cannot call the provider's REST API via available HTTP tools, skip this source — the missing integration is not a finding.
73
+
74
+ #### Detect the connected PR/MR
75
+
76
+ Use the current branch name (without remote or merge-base prefix) to look up an open PR/MR:
77
+ - **GitHub**: `gh pr view --head <branch> --json number,title,state,headRefName,baseRefName,headRefOid,baseRefOid`. Fallback: `gh api repos/{owner}/{repo}/pulls --jq ".[] | select(.head.ref==\"<branch>\")"`.
78
+ - **GitLab**: `glab mr list --source-branch <branch>`.
79
+ - **Bitbucket Cloud**: REST `https://api.bitbucket.org/2.0/repositories/<owner>/<slug>/pullrequests?q=source.branch.name="<branch>"` (no widely-adopted CLI; call via available HTTP tool).
80
+ - **Azure DevOps**: `az repos pr list --source-branch <branch> --org <org-url> -r <project>`.
81
+
82
+ If a PR/MR is found and has zero prior review comments/reviews by other users, treat this as the first round on this PR/MR — skip the addressed-check, but still record the PR/MR identity in the brief for reference.
83
+
84
+ #### Fetch ALL prior review comments
85
+
86
+ Pull review threads and summaries regardless of resolved state — the goal is to see everything that has been raised, not just unresolved threads.
87
+ - **GitHub**: `gh api repos/{owner}/{repo}/pulls/{N}/reviews` (review summaries: body, user, state, submitted_at) AND `gh api repos/{owner}/{repo}/pulls/{N}/comments` (inline file:line comments with `path`, `line`, `original_line`, `commit_id`, `body`, `user`).
88
+ - **GitLab**: `glab api projects/:id/merge_requests/:iid/discussions` returns discussion threads with anchored positions; threads expose `resolved` and `resolved_by` (use as a supplementary addressed signal).
89
+ - **Bitbucket Cloud**: REST `activities` endpoint for the PR.
90
+ - **Azure DevOps**: REST `threads` endpoint for the PR.
91
+
92
+ #### Build the prior-comments register
93
+
94
+ For each prior comment, record:
95
+ - Author, submitted date
96
+ - Original commit SHA, file, line range (or `summary` for non-inline review)
97
+ - Comment body (quoted)
98
+ - The semantic claim raised (what the reviewer said was wrong — paraphrase the core issue, one sentence)
99
+ - VCS resolve state if available (GitLab `resolved`/`resolved_by`; GitHub `isResolved` via GraphQL if accessible)
100
+
101
+ #### Addressed-check methodology
102
+
103
+ For each comment, attempt to determine whether it has been addressed in the **current HEAD** under review:
104
+ 1. **Locate the original code location.** If the file was deleted, mark `unclear`. If the file was renamed, follow it with `git log --diff-filter=R -- <path>`.
105
+ 2. **Anchor to current HEAD.** Read the cited line plus 3-5 lines of context at the original commit (`git show <comment-SHA>:<file>`). Find the equivalent region in the current HEAD file by matching the surrounding text (search for unique tokens from that region). Determine the new line range.
106
+ 3. **Judge the issue.** Read the code at the new location. Does the issue the comment described still exist, or has it been fixed, refactored away, or otherwise made moot by changes in this change's commit range?
107
+ 4. **Tag preliminary status:**
108
+ - `addressed` — the code at the equivalent location no longer exhibits the issue, or the referenced structure was refactored away in a way that resolves the comment.
109
+ - `still active` — the issue persists at the equivalent location.
110
+ - `unclear` — file gone, line unlocatable, or the substantive change makes comparison impossible.
111
+ 5. **VCS resolve signal as a supplement, not a substitute.** If the VCS exposes a resolved flag (GitLab `resolved: true`, GitHub `isResolved` via GraphQL), record it as supporting evidence. When the resolved flag disagrees with the code-state verdict, trust the code state — a thread can be marked resolved in the UI while the bug persists, and an unresolved thread may already have been fixed by a later commit. Note both signals in the register so the synthesizer can weigh them.
112
+
113
+ The register produced here is a **preliminary** classification. The synthesizer produces the final cross-reference, including any prelim-status overrides when new findings from the specialist round reproduce or refute a prior comment.
114
+
59
115
  ## Context brief format
60
116
 
61
117
  Produce a structured brief:
@@ -83,6 +139,19 @@ List each deferred piece:
83
139
  - Design decisions or architectural constraints from memories or docs
84
140
  - Conventions that reviewers should be aware of
85
141
 
142
+ ### Prior review comments (only when the change has a connected PR/MR with prior reviews)
143
+
144
+ List the prior-comments register (one entry per prior comment):
145
+ - Author and submitted date
146
+ - Original location (`file:line @ commit-SHA`, or `summary review`) and current HEAD location (`file:line`) if locatable
147
+ - The semantic claim raised (one-sentence paraphrase)
148
+ - Preliminary status: `addressed` / `still active` / `unclear` — with the code-state evidence (a short quote from the current HEAD that supports the verdict)
149
+ - VCS resolve flag if applicable (and any disagreement with the code-state verdict)
150
+
151
+ If context gathering found a connected PR/MR but no prior reviews by other users, state `First round on PR #N — no prior comments to register`.
152
+
153
+ If context gathering found no connected PR/MR (local-branch review), state `Local-branch review — no prior-comment fetch`. This is not a gap; the existing review procedure applies.
154
+
86
155
  ## If context is sparse
87
156
 
88
157
  Not every PR will have rich context. If you find minimal context:
@@ -54,6 +54,26 @@ The same issue may be flagged by multiple specialists when it spans category bou
54
54
 
55
55
  Multiple findings may stem from the same underlying issue (e.g., a contract mismatch causes errors in 3 call sites). Group these under the root cause.
56
56
 
57
+ ## Cross-reference against prior review comments
58
+
59
+ If your input includes a **prior-comments register** (built by the coordinator via `thatch-review-context` source #8 — prior review comments retrieved from the PR/MR's review history), cross-reference every confirmed and rejected finding against it so the final report does not present already-identified issues as fresh discoveries.
60
+
61
+ For each new finding:
62
+ 1. **Search for a matching prior comment** by location and semantic claim. Match if both hold:
63
+ - The finding's cited file:line falls within (or has moved to) the prior comment's referenced location in current HEAD, AND
64
+ - The finding's core claim restates the prior comment's semantic claim (the same code-level issue, even if worded differently or covering a slightly wider scope).
65
+ 2. **If a match is found**, tag the finding's `Provenance` field as `previously identified by @author, PR #N, DATE` in addition to its branch-introduced / pre-existing classification. Do not drop the finding. Keep it in the main findings (with attribution) so the user sees what still needs attention this round.
66
+
67
+ For each entry in the prior-comments register, finalize its status using both the register's preliminary verdict and this round's findings:
68
+ - **`addressed`** — the register's preliminary status was `addressed` AND no new finding reproduces the comment. Re-read the cited current-HEAD location to confirm the issue is gone; if you find the issue persists, override to `still active — not reproduced this round, re-verified above`.
69
+ - **`still active — reproduced by finding X`** — a new finding this round matches the prior comment. Cite the finding's severity and source specialist.
70
+ - **`still active — not reproduced this round, re-verified above`** — no new finding matches, but you re-read the code and the issue described in the prior comment still persists. Include a one-line quote from current HEAD as evidence.
71
+ - **`unclear`** — the original line is unlocatable in current HEAD, the file is gone, or substantive change makes the comparison impossible. State which.
72
+
73
+ New findings that match a prior comment tagged `addressed` (preliminary) are still reported — they may indicate the resolution was incomplete or that the issue regressed. Note this in the finding's `Provenance` field so the user investigates.
74
+
75
+ When the VCS resolve flag (GitLab `resolved`, GitHub `isResolved`) disagrees with the code-state verdict (e.g., thread marked resolved in the UI but the bug persists), trust the code state and call out the disagreement in the appendix entry.
76
+
57
77
  ## Severity calibration
58
78
 
59
79
  Assign final severity based on YOUR verification:
@@ -82,7 +102,7 @@ For each finding, grouped by severity (BLOCKING > HIGH > MEDIUM > LOW). Each fin
82
102
  4. **Finding**: what the problem is
83
103
  5. **Evidence**: the code you read to confirm it (quote the exact lines you verified)
84
104
  6. **Trigger/Proof**: the workflow trigger, and for state/data/behavior issues the producer then transform then consumer chain you verified
85
- 7. **Provenance**: branch-introduced or pre-existing
105
+ 7. **Provenance**: branch-introduced or pre-existing. If the finding matches a prior review comment, append `; previously identified by @author, PR #N, DATE` to this field. For findings matching an `addressed` prior comment, also add a one-line note on why the finding persists so the user can investigate whether the prior resolution is incomplete or the issue has regressed.
86
106
 
87
107
  ### Rejected findings (appendix, brief)
88
108
  Findings you rejected and a one-line reason why. Include the specialist and location for each.
@@ -90,5 +110,19 @@ Findings you rejected and a one-line reason why. Include the specialist and loca
90
110
  ### Pre-existing bugs (appendix, brief)
91
111
  Findings you verified as real but pre-existing, with a one-line note on the issue and its potential impact.
92
112
 
113
+ ### Previously identified findings (appendix — only when a prior-comments register was provided)
114
+ List every entry from the prior-comments register here. For each entry, produce a one-block record:
115
+ 1. **Author and date** of the original comment
116
+ 2. **Original location** (`file:line @ commit-SHA`, or `summary review`) and **current HEAD location** (`file:line`) if locatable
117
+ 3. **Claim**: one-sentence paraphrase of what the prior reviewer raised
118
+ 4. **Final status**: one of
119
+ - `addressed` — issue confirmed gone in current HEAD
120
+ - `still active — reproduced by finding X` — with the cross-referenced finding's severity and source specialist
121
+ - `still active — not reproduced this round, re-verified above` — with a one-line quote from current HEAD as evidence
122
+ - `unclear` — with the reason (file gone, line unlocatable, etc.)
123
+ 5. **VCS resolve flag** if applicable, and any disagreement with the code-state verdict (e.g., thread marked resolved in the UI but the bug persists) — trust the code state and surface the disagreement.
124
+
125
+ If no prior-comments register was provided (local-branch review or first round on the PR/MR), state `None — no prior review comments to cross-reference` and move on.
126
+
93
127
  ### Coverage gaps
94
128
  Note which files or areas were NOT covered by any specialist.
@@ -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
  |-------|------|
@@ -36,16 +36,18 @@ description: Extract durable project facts ... Use when ...
36
36
  | `thatch-review-no-slop` | AI writing anti-patterns: change narration, fourth-wall breaks, em dashes, filler. |
37
37
  | `thatch-review-breadcrumbs` | Comment narrative: do comments form a coherent outline of behavior? |
38
38
  | `thatch-review-mark-and-sweep` | Mechanical change completeness: whole-repo sweep for stragglers after renames, flag removals, API substitutions. |
39
- | `thatch-review-synthesizer` | Verify specialist findings against code, dedupe, classify, calibrate severity. |
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. |
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
+ | `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:
45
47
 
46
48
  | Skill | Role |
47
49
  |-------|------|
48
- | `thatch-code-review` | Resolve review target, gather project context, research affected workflows, estimate complexity, partition, dispatch the 6 specialists in parallel, synthesize. |
50
+ | `thatch-code-review` | Resolve review target (incl. VCS detection and connected PR/MR lookup for follow-up round detection), gather project context, research affected workflows, estimate complexity, partition, dispatch the 6 specialists in parallel, synthesize (incl. cross-referencing findings against prior review comments). |
49
51
 
50
52
  ## REVIEW_COMMON
51
53
 
@@ -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.14",
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) }));