@jeffober/thatch 0.1.8 → 0.1.10

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.
package/README.md CHANGED
@@ -2,18 +2,23 @@
2
2
 
3
3
  [![CI](https://github.com/sysread/thatch/actions/workflows/ci.yml/badge.svg)](https://github.com/sysread/thatch/actions/workflows/ci.yml)
4
4
 
5
- Persistent memory and operational methodology for AI coding agents — local
6
- embeddings, SQLite stores, zero config.
5
+ ## Synopsis
6
+
7
+ Persistent memory and useful dev skills for AI coding agents that requires zero
8
+ manual config.
7
9
 
8
10
  Works with **OpenCode** (as a plugin), **Claude Code** (as an MCP server), and
9
11
  **Cursor** (as an MCP server).
12
+
10
13
  Each session inherits the accumulated knowledge of every session before it —
11
14
  project architecture, conventions, gotchas, user preferences — so your agent
12
- starts with context instead of a blank slate. Stores are per-repo with a
13
- shared `global` store. On top of the memory layer, thatch ships a suite of
14
- skills that prime, maintain, and reflect on memory, plus a structured
15
- multi-agent code review framework. No API keys, no cloud services —
16
- everything runs on your machine.
15
+ starts with context instead of a blank slate. Stores are per-repo with a shared
16
+ `global` store.
17
+
18
+ On top of the memory layer, thatch ships a suite of skills for managing memories,
19
+ performing in-depth, structured code reviews, and researching your code base.
20
+
21
+ No API keys, no cloud services; everything runs on your machine.
17
22
 
18
23
  ## Quick start
19
24
 
@@ -118,6 +123,8 @@ agent follows to maintain its own memory and review code systematically.
118
123
  | `thatch-review-no-slop` | AI writing anti-pattern detection — change narration, fourth wall breaks, hedging |
119
124
  | `thatch-review-breadcrumbs` | Comment narrative — do comments form a coherent outline of the code's behavior? |
120
125
  | `thatch-review-synthesizer` | Verify specialist findings against actual code, deduplicate, produce severity-grouped report |
126
+ | `thatch-review-context` | Gather project/feature context (PRs, tickets, TODOs, deferred work) before a review |
127
+ | `thatch-workflow-research` | Research code workflows affected by a change or planned change, before reviewing or planning |
121
128
  | `thatch-code-review` | Multi-agent review coordinator — triage, partition, dispatch specialists in parallel (opencode only) |
122
129
 
123
130
  The five review specialists run independently and can be used standalone. The
@@ -142,7 +149,7 @@ thatch prime Prime project memory (runs via opencode or clau
142
149
  thatch mcp Start the stdio MCP server (for Claude Code)
143
150
  thatch reminder Print session-start reminder (for hooks)
144
151
  thatch hygiene Print the hygiene report (standalone)
145
- thatch setup --claude [--global] Install config + instructions + hooks + skills
152
+ thatch setup --claude [--cursor] [--global] Install config + instructions + hooks + skills
146
153
  ```
147
154
 
148
155
  Stores default to the repo detected from `git remote`. Use `global` for the
@@ -190,17 +197,18 @@ buffer and flush. On Claude Code, `PostToolBatch` and `UserPromptSubmit`
190
197
  hooks drive a file-backed queue. Both paths produce the same payload for the
191
198
  fact-extractor skill.
192
199
 
193
- ## OpenCode vs Claude Code parity
194
-
195
- | Feature | OpenCode (plugin) | Claude Code (MCP + hooks) |
196
- |---------|-------------------|--------------------------|
197
- | Tools | Plugin tool registration | MCP `tools/list` + `tools/call` |
198
- | System prompt | Injected at runtime with repo name | Static CLAUDE.md (repo auto-detected by MCP server) |
199
- | Session-start reminder | `session.created` event | `SessionStart` hook → `thatch reminder` |
200
- | Compaction context | `experimental.session.compacting` hook | **Gap**: no equivalent (CLAUDE.md persists through compaction) |
201
- | Extraction nudge | `tool.execute.after` + `chat.message` | `PostToolBatch` + `UserPromptSubmit` (file-backed queue) |
202
- | Skills | `$XDG_CONFIG_HOME/opencode/skills` | `~/.claude/skills/` |
203
- | Store detection | `worktree` param from plugin | `CLAUDE_PROJECT_DIR` env var |
200
+ ## OpenCode vs Claude Code vs Cursor parity
201
+
202
+ | Feature | OpenCode (plugin) | Claude Code (MCP + hooks) | Cursor (MCP + hooks) |
203
+ |---------|-------------------|--------------------------|---------------------|
204
+ | Tools | Plugin tool registration | MCP `tools/list` + `tools/call` | MCP `tools/list` + `tools/call` |
205
+ | System prompt | Injected at runtime with repo name | Static CLAUDE.md (repo auto-detected by MCP server) | Static AGENTS.md (repo auto-detected at startup) |
206
+ | Session-start reminder | `session.created` event | `SessionStart` hook → `thatch reminder` | `sessionStart` hook → `thatch reminder --json` |
207
+ | Compaction context | `experimental.session.compacting` hook | **Gap**: no equivalent (CLAUDE.md persists) | **Gap**: no equivalent |
208
+ | Extraction nudge | `tool.execute.after` + `chat.message` | `PostToolBatch` + `UserPromptSubmit` (file-backed queue) | `postToolUse` + `beforeSubmitPrompt` (file-backed queue) |
209
+ | Setup detection at startup | n/a (plugin auto-installs) | `checkSetup` in MCP server: detects missing/broken instructions | Same as Claude Code |
210
+ | Skills | 13 (shared + coordinator) | 12 (shared only) | 12 (shared only) |
211
+ | Store detection | `worktree` param from plugin | `CLAUDE_PROJECT_DIR` env var | `CURSOR_PROJECT_DIR` then `CLAUDE_PROJECT_DIR` |
204
212
 
205
213
  See [docs/dev/mcp-parity.md](docs/dev/mcp-parity.md) for the full analysis.
206
214
 
package/bin/release CHANGED
@@ -22,6 +22,27 @@ echo " bump: $v"
22
22
  echo " next: $next"
23
23
  echo
24
24
 
25
+ # Pre-flight: verify the current version is published on npm before allowing a
26
+ # new release. A tagged-but-unpublished version means the prior publish failed;
27
+ # stacking another release on top hides the gap and complicates recovery.
28
+ if git rev-parse -q --verify "refs/tags/v$curr" >/dev/null 2>&1; then
29
+ pub_status=$(npm view "@jeffober/thatch@$curr" version 2>&1 || true)
30
+ if ! echo "$pub_status" | grep -q "^$curr$"; then
31
+ if echo "$pub_status" | grep -q "E404"; then
32
+ echo "ERROR: v$curr is tagged but not published to npm."
33
+ echo " The previous release failed. Check: gh run view --workflow=publish.yml"
34
+ echo " Fix the workflow, delete and re-tag v$curr, push, then re-run this release."
35
+ echo " To re-tag: git tag -d v$curr && git tag v$curr <commit> && git push origin :refs/tags/v$curr && git push origin v$curr"
36
+ exit 1
37
+ else
38
+ echo "WARN: npm registry check failed (not a 404 — may be a network issue or npm outage):"
39
+ echo " $pub_status"
40
+ echo " Proceeding anyway. Verify v$curr is published before relying on this."
41
+ echo
42
+ fi
43
+ fi
44
+ fi
45
+
25
46
  echo "▸ running checks (typecheck + tests + markdown lint)..."
26
47
  mise run check
27
48
  echo " ✓ checks passed"
@@ -26,6 +26,7 @@ This document maps the feature parity and documents the remaining gaps.
26
26
  | **Prompt-aware recall nudge** | `chat.message` hook embeds the prompt with the in-process warm model, searches `db.search()`, pushes a nudge part if matches ≥ threshold | `UserPromptSubmit` hook → `thatch flush-tools` connects to the MCP server's sideband socket; the warm server embeds + searches; hook prints the nudge or falls back to the write nudge | `beforeSubmitPrompt` hook → `thatch flush-tools --json` (same sideband path) | **Full** — sideband socket gives cold hook processes access to the warm MCP server's model |
27
27
  | **Skills** | Installed to `$XDG_CONFIG_HOME/opencode/skills` at plugin init (shared **+** opencode-only) | Installed to `$CLAUDE_CONFIG_DIR/skills/` by `thatch setup` (shared only) | Installed to `~/.cursor/skills/` by `thatch setup` (shared only) | **Full** — same SKILL.md format; the code-review coordinator is opencode-only (needs sub-agents) |
28
28
  | **Store detection** (repo identity from git remote) | `worktree` parameter from the opencode plugin | `CLAUDE_PROJECT_DIR` env (set by Claude Code for stdio MCP servers) | `CURSOR_PROJECT_DIR` then `CLAUDE_PROJECT_DIR` then cwd | **Full** |
29
+ | **Setup detection at startup** | n/a — plugin auto-installs at init | `checkSetup` in MCP server: detects missing or broken instructions in CLAUDE.md | Same as Claude Code (checks AGENTS.md) | **Full** — warns the agent to tell the user to run `thatch setup` |
29
30
  | **Hook config format** | n/a — plugin registers hooks in code | Nested: `.claude/settings.json` `{hooks:{Event:{hooks:[{type,command}]}}}` | Flat: `.cursor/hooks.json` `{version:1,hooks:{event:[{command}]}}` | n/a |
30
31
 
31
32
  ## Tool name conventions
@@ -132,3 +132,39 @@ All setup operations are idempotent:
132
132
  `thatch setup` resolves `<bin>` from PATH, falling back to the absolute path of
133
133
  the running script. This is baked into every installed hook command, so the
134
134
  hooks keep working after the session that ran setup ends.
135
+
136
+ ## Setup detection at MCP startup
137
+
138
+ When the MCP server starts (`thatch mcp`, spawned by Claude Code or Cursor),
139
+ it calls `checkSetup` (`src/setup.ts`) to verify that `thatch setup` was run
140
+ for the current host. This catches two failure modes that would otherwise leave
141
+ the agent without usage instructions:
142
+
143
+ ### Host detection
144
+
145
+ The host is determined from env vars set by the host process:
146
+
147
+ - `CURSOR_PROJECT_DIR` set → Cursor
148
+ - `CLAUDE_PROJECT_DIR` set (and Cursor not) → Claude Code
149
+ - Neither set → returns `null` (no check — manual `thatch mcp` invocation)
150
+
151
+ Cursor takes priority because Cursor also sets `CLAUDE_PROJECT_DIR` as an alias.
152
+
153
+ ### What it checks
154
+
155
+ `checkSetup` looks for the instruction markers (start and end) in the host's
156
+ instructions file — `CLAUDE.md` for Claude Code, `AGENTS.md` for Cursor. It
157
+ checks local (in the project directory) first, then global (in the config
158
+ directory). Local takes priority.
159
+
160
+ ### Three outcomes
161
+
162
+ | Outcome | Condition | Action |
163
+ |---------|-----------|--------|
164
+ | **installed** | Markers found in local or global instructions file | No warning — setup is complete |
165
+ | **not-installed** | No instructions file with markers found anywhere | Warning to stderr + prepended to first `tools/call` response: "Tell the user to run `thatch setup --<host>`" |
166
+ | **markers-broken** | Start marker found but end marker missing (file edited externally) | Warning with the specific file path and fix instructions: run `thatch setup`, or manually remove the corrupted block and re-run |
167
+
168
+ The warning is cleared after the first `tools/call` response so it surfaces
169
+ once, not on every tool call. The message instructs the LLM to notify the user
170
+ with the specific `thatch setup` command to run.
@@ -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 11 skills
24
+ ## The 13 skills
25
25
 
26
- **Shared (10)** — installed everywhere; no sub-agents required:
26
+ **Shared (12)** — installed everywhere; no sub-agents required:
27
27
 
28
28
  | Skill | Role |
29
29
  |-------|------|
@@ -36,13 +36,15 @@ 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-synthesizer` | Verify specialist findings against code, dedupe, classify, calibrate severity. |
39
+ | `thatch-review-context` | Gather project/feature context (PR descriptions, git archaeology, ticket references, memory) before fan-out. Prevents false positives about intentionally deferred work. |
40
+ | `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. |
39
41
  | `thatch-session-reflection` | End-of-session memory recording (project, user, tools, self). |
40
42
 
41
43
  **opencode-only (1)** — the coordinator needs sub-agent support:
42
44
 
43
45
  | Skill | Role |
44
46
  |-------|------|
45
- | `thatch-code-review` | Resolve review target, estimate complexity, partition, dispatch the 5 specialists in parallel, synthesize. |
47
+ | `thatch-code-review` | Resolve review target, gather project context, research affected workflows, estimate complexity, partition, dispatch the 5 specialists in parallel, synthesize. |
46
48
 
47
49
  ## REVIEW_COMMON
48
50
 
@@ -57,6 +59,16 @@ The five review specialists share a framework interpolated via `${REVIEW_COMMON}
57
59
  trigger; "the code allows this" is not enough.
58
60
  - **Intent verification** — trace callers, check git history, and `thatch_memory_recall`
59
61
  for design rationale before flagging a behavior as a bug.
62
+ - **Project context awareness** — if a context brief is provided (from the
63
+ coordinator or from loading `thatch-review-context`), use it to avoid false
64
+ positives about intentionally deferred work.
65
+ - **Workflow context awareness** — if a workflow guide is provided (from the
66
+ coordinator or from loading `thatch-workflow-research`), use it to understand
67
+ the purpose and evolution of the code, distinguishing intentional behavior
68
+ and long-standing design decisions from new issues.
69
+ - **TODO ($ticket) markers** — recognize `TODO ($TICKET-ID): ...` as legitimate
70
+ breadcrumbs for deferred work, not stale artifacts. Flag only if the referenced
71
+ ticket is closed or merged.
60
72
  - **Output format** — `[SEVERITY] [CATEGORY] file:line` with finding, evidence
61
73
  (quoted), trigger, reachability, source of truth, producer chain, provenance.
62
74
 
@@ -66,7 +78,7 @@ The synthesizer reuses the same verification rigor but has its own structure
66
78
  ## The two arrays
67
79
 
68
80
  ```ts
69
- const SHARED_SKILLS: SkillDef[] = [ /* 10 skills above */ ];
81
+ const SHARED_SKILLS: SkillDef[] = [ /* 12 skills above */ ];
70
82
  const OPENCODE_ONLY_SKILLS: SkillDef[] = [ /* code-review coordinator */ ];
71
83
  ```
72
84
 
@@ -100,8 +112,7 @@ and `--cursor` pass only the shared set.
100
112
  ## Memory review skills in practice
101
113
 
102
114
  - **Quick single lens**: load any specialist directly and point it at a branch.
103
- - **Full review on opencode**: load `thatch-code-review` — it dispatches all 5
104
- specialists in parallel, then synthesizes.
115
+ - **Full review on opencode**: load `thatch-code-review` — it gathers project context, researches affected workflows, dispatches all 5 specialists in parallel (with both the context brief and workflow guide injected into each briefing), then synthesizes.
105
116
  - **Full review on Claude Code/Cursor**: run each specialist in sequence, then
106
117
  run `thatch-review-synthesizer` to verify and aggregate.
107
118
 
@@ -26,6 +26,7 @@ file/IPC/CLI contracts ready to graduate into `bun:test` integration tests.
26
26
  | [UC-015](UC-015-env-override-matrix.md) | `THATCH_DB_PATH`, `XDG_CONFIG_HOME`, `CLAUDE_CONFIG_DIR`, `THATCH_QUEUE_DIR`, `THATCH_RECALL_THRESHOLD`, `THATCH_MODEL` |
27
27
  | [UC-016](UC-016-concurrent-session-isolation.md) | Per-session extraction isolation (in-memory + file queue); shared stateless sideband |
28
28
  | [UC-017](UC-017-buffer-tool-vs-buffer-batch.md) | `buffer-batch` (Claude, `tool_calls[]`+`session_id`) vs `buffer-tool` (Cursor, single+`conversation_id`) |
29
+ | [UC-018](UC-018-mcp-startup-setup-detection.md) | MCP startup detects missing/broken setup instructions and warns the agent |
29
30
 
30
31
  ## Template
31
32
 
@@ -17,12 +17,12 @@
17
17
  appends a thatch block to `CLAUDE.md` bracketed by start/end markers (replaced, not
18
18
  duplicated, on re-run), writes `.claude/settings.json` hooks (`SessionStart` -> `thatch reminder`,
19
19
  `PostToolBatch` -> `thatch buffer-batch`, `UserPromptSubmit` -> `thatch flush-tools`), and installs
20
- **10 shared skills** (no code-review coordinator) to `$CLAUDE_CONFIG_DIR/skills/` — user-scoped
20
+ **12 shared skills** (no code-review coordinator) to `$CLAUDE_CONFIG_DIR/skills/` — user-scoped
21
21
  even in project-local mode.
22
22
  - `--cursor` project-local writes `.cursor/mcp.json`, appends to `AGENTS.md`, writes
23
23
  `.cursor/hooks.json` in the **flat format** (`{version:1, hooks:{...}}`): `sessionStart` ->
24
24
  `thatch reminder --json`, `postToolUse` -> `thatch buffer-tool`, `beforeSubmitPrompt` ->
25
- `thatch flush-tools --json`; and installs 10 shared skills to `~/.cursor/skills/`.
25
+ `thatch flush-tools --json`; and installs 12 shared skills to `~/.cursor/skills/`.
26
26
  - Re-run is idempotent: instructions are not duplicated, thatch hooks are replaced (not appended),
27
27
  and non-thatch hooks are preserved. A legacy `thatch echo` hook is replaced with `flush-tools`.
28
28
  - `--global` (Claude) writes `~/.claude/CLAUDE.md` + `~/.claude/settings.json` but **no project
@@ -13,16 +13,16 @@
13
13
  5. Check whether the `thatch-code-review` coordinator skill is present.
14
14
 
15
15
  **Expected**
16
- - Claude Code and Cursor install exactly **10 shared skills** to the skills
16
+ - Claude Code and Cursor install exactly **12 shared skills** to the skills
17
17
  dir — the coordinator (`thatch-code-review`) is **absent** (it needs
18
18
  sub-agents, which those hosts lack).
19
- - opencode installs **11** — the 10 shared plus the coordinator.
19
+ - opencode installs **13** — the 12 shared plus the coordinator.
20
20
  - The locally edited `SKILL.md` is **overwritten** with the canonical content
21
21
  on the next `setup`/init (drift detection: a file is only rewritten when its
22
22
  content differs from the definition). Unrelated skill files are untouched.
23
23
  - Skills never land in the worktree — always under the user-scoped config dir
24
24
  (`~/.claude/skills`, `~/.cursor/skills`, `$XDG_CONFIG_HOME/opencode/skills`).
25
25
 
26
- _Automatable: yes — file presence, count (10 vs 11), content-diff-overwrite, and
26
+ _Automatable: yes — file presence, count (12 vs 13), content-diff-overwrite, and
27
27
  coordinator host-gating are all file assertions (`setup.test.ts` already covers
28
28
  the unit contract)._
@@ -0,0 +1,38 @@
1
+ # UC-018: MCP startup setup detection
2
+
3
+ **Preconditions**
4
+ - Thatch installed and `bun` on PATH
5
+ - MCP server launched by Claude Code (`thatch mcp` with `CLAUDE_PROJECT_DIR` set)
6
+ or Cursor (`thatch mcp` with `CURSOR_PROJECT_DIR` set)
7
+
8
+ **Steps**
9
+ 1. Start a Claude Code session in a project where `thatch setup --claude` was
10
+ never run (no `CLAUDE.md` with thatch markers, neither local nor global).
11
+ 2. Call any thatch tool (e.g. `mcp__thatch__store_list`).
12
+ 3. Repeat in a project where setup was run but `CLAUDE.md` was edited externally
13
+ and the thatch block's end marker was deleted.
14
+ 4. Repeat in a project where setup was run correctly.
15
+ 5. Repeat all steps for Cursor (substituting `--cursor`, `AGENTS.md`,
16
+ `CURSOR_PROJECT_DIR`).
17
+
18
+ **Expected**
19
+ - **Not-installed**: The first `tools/call` response is prepended with a
20
+ warning: "[thatch] Thatch is running as an MCP server but has not been set
21
+ up for Claude Code. ... Tell the user to run: thatch setup --claude". The
22
+ warning also appears on stderr. Subsequent tool responses are clean (warning
23
+ is one-shot).
24
+ - **Markers-broken**: The first `tools/call` response is prepended with a
25
+ warning naming the corrupted file and instructing the user to run
26
+ `thatch setup` (or manually remove the corrupted block and re-run).
27
+ - **Installed**: No warning. Tool responses are clean from the first call.
28
+ - **Cursor**: Same behavior, with "Cursor" substituted for "Claude Code" and
29
+ `thatch setup --cursor` in the message. When both `CURSOR_PROJECT_DIR` and
30
+ `CLAUDE_PROJECT_DIR` are set, Cursor detection takes priority.
31
+ - **No env var**: When neither `CURSOR_PROJECT_DIR` nor `CLAUDE_PROJECT_DIR` is
32
+ set (manual `thatch mcp` invocation), `checkSetup` returns `null` and no
33
+ warning is emitted.
34
+
35
+ _Automatable: yes — `setup.test.ts` already covers the unit contract (10 tests
36
+ in the `checkSetup` describe block: null, local, global, not-installed,
37
+ markers-broken, local priority, Cursor variants, Cursor priority). This is the
38
+ end-to-end runbook version._
@@ -114,6 +114,17 @@ Beyond the tools, thatch hooks into opencode itself:
114
114
  - **Compaction context.** When opencode compacts a long session, thatch injects
115
115
  a reminder so the summarized session still knows memory tools exist.
116
116
 
117
+ ### Setup detection (Claude Code and Cursor)
118
+
119
+ When the MCP server starts (Claude Code or Cursor), it checks whether
120
+ `thatch setup` was run for the current host by looking for the instruction
121
+ markers in `CLAUDE.md` (Claude Code) or `AGENTS.md` (Cursor). It checks local
122
+ first (in the project directory), then global (in the config directory). If
123
+ setup was never run, or if the instruction markers are broken (e.g. the file
124
+ was edited externally and the thatch block was partially modified), the server
125
+ emits a warning to stderr and prepends it to the first tool response so the
126
+ agent can tell the user to run `thatch setup`.
127
+
117
128
  ## Skills
118
129
 
119
130
  On startup thatch installs [skills] into your global opencode config
@@ -143,6 +154,8 @@ Five specialist review lenses, each a self-contained static-analysis pass:
143
154
  | `thatch-review-no-slop` | AI writing anti-patterns: change narration, fourth wall breaks, em dashes, hedging, filler. |
144
155
  | `thatch-review-breadcrumbs` | Comment narrative: do comments form a coherent outline of the code's behavior? |
145
156
  | `thatch-review-synthesizer` | Verifies and synthesizes findings from multiple specialists into a single deduplicated, severity-grouped report. |
157
+ | `thatch-review-context` | Gathers project context (PR descriptions, git archaeology, ticket references, memory) before a review. Prevents false positives about intentionally deferred work. |
158
+ | `thatch-workflow-research` | Researches code workflows and features affected by a change or planned change. Reads code flows, comments, git history, and produces a guide for reviewers or planners. |
146
159
 
147
160
  ### opencode-only skills
148
161
 
@@ -152,12 +165,13 @@ Five specialist review lenses, each a self-contained static-analysis pass:
152
165
 
153
166
  ### Host availability
154
167
 
155
- | Skill | opencode | Claude Code |
156
- |-------|----------|-------------|
157
- | Memory skills (4) | Yes | Yes |
158
- | Review specialists (5) | Yes | Yes |
159
- | Review synthesizer | Yes | Yes |
160
- | Code review coordinator | Yes | No (requires sub-agents) |
168
+ | Skill | opencode | Claude Code | Cursor |
169
+ |-------|----------|-------------|--------|
170
+ | Memory skills (4) | Yes | Yes | Yes |
171
+ | Review specialists (5) | Yes | Yes | Yes |
172
+ | Review synthesizer | Yes | Yes | Yes |
173
+ | Review context + workflow research | Yes | Yes | Yes |
174
+ | Code review coordinator | Yes | No (requires sub-agents) | No (requires sub-agents) |
161
175
 
162
176
  ### Using review skills
163
177
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jeffober/thatch",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
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",
package/src/mcp.ts CHANGED
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  import { ThatchDB } from "./db";
3
3
  import { BgeEmbeddingModel } from "./embeddings";
4
4
  import { detectRepo } from "./git";
5
+ import { checkSetup } from "./setup";
5
6
  import { TOOL_DEFS, type CoreContext, type ToolDef } from "./tool-defs";
6
7
  import { SidebandServer, sidebandSocketPath } from "./sideband";
7
8
 
@@ -99,6 +100,17 @@ export async function runMcpServer(): Promise<void> {
99
100
  const ctx: CoreContext = { db, model, defaultStore: repo };
100
101
  const tools = compileTools();
101
102
 
103
+ // Check whether `thatch setup` was run for the current host. If not, or if
104
+ // markers are broken, surface a warning on the first tools/call response so
105
+ // the agent can tell the user to run setup. Also emit to stderr for
106
+ // visibility in host debug logs.
107
+ let setupWarning: string | null = null;
108
+ const setupStatus = checkSetup(projectDir);
109
+ if (setupStatus && setupStatus.status !== "installed") {
110
+ setupWarning = setupStatus.message;
111
+ console.error(`[thatch] ${setupWarning}`);
112
+ }
113
+
102
114
  // The sideband socket lets one-shot hook processes (flush-tools) ask the
103
115
  // warm MCP server to embed a prompt and search for matches — without
104
116
  // loading the ~34 MB model themselves. If the socket can't be opened
@@ -137,6 +149,17 @@ export async function runMcpServer(): Promise<void> {
137
149
  const isNotification = req.id === null || req.id === undefined;
138
150
  const res = await dispatch(req, tools, ctx);
139
151
  if (res === null || isNotification) continue;
152
+
153
+ // Surface the setup warning on the first tools/call response so the
154
+ // agent sees it and can notify the user. Cleared after one surfacing.
155
+ if (setupWarning && req.method === "tools/call" && !res.error) {
156
+ const content = res.result?.content;
157
+ if (Array.isArray(content) && content[0]?.text != null) {
158
+ content[0].text = `[thatch] ${setupWarning}\n\n${content[0].text}`;
159
+ }
160
+ setupWarning = null;
161
+ }
162
+
140
163
  send(res);
141
164
  }
142
165
  }
package/src/prompts.ts CHANGED
@@ -27,6 +27,19 @@ WIP, PR status). Unscoped memories are project-wide and always included in searc
27
27
  Before diving into code, thatch_memory_recall with a query relevant to the area
28
28
  you're working in. Prior sessions may have already investigated it.
29
29
 
30
+ ## Skills
31
+
32
+ Thatch ships skills for code review, project investigation, and memory
33
+ workflows. The host auto-discovers them, but reach for them proactively:
34
+
35
+ - \`thatch-code-review\` — full multi-agent code review (dispatches 5 specialists + synthesizer). Requires sub-agent support.
36
+ - \`thatch-workflow-research\` — research code workflows affected by a change or planned change, before reviewing or planning.
37
+ - \`thatch-review-context\` — gather project context (PRs, tickets, TODOs, deferred work) before a review.
38
+ - \`thatch-project-primer\` — investigate a new project and write foundational memories.
39
+ - \`thatch-session-reflection\` — record what you learned at end of session.
40
+ - \`thatch-fact-extractor\` — extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
41
+ - \`thatch-dedup-classifier\` — resolve duplicate memory pairs from \`thatch_find_duplicates\`.
42
+
30
43
  ## When to Write
31
44
 
32
45
  **One signal is enough.** Do not wait for confirmation.
@@ -126,6 +139,19 @@ WIP, PR status). Unscoped memories are project-wide and always included in searc
126
139
  Before diving into code, \`memory_recall\` with a query relevant to the area
127
140
  you're working in. Prior sessions may have already investigated it.
128
141
 
142
+ ## Skills
143
+
144
+ Thatch ships skills for code review, project investigation, and memory
145
+ workflows. The host auto-discovers them, but reach for them proactively:
146
+
147
+ - \`thatch-workflow-research\` — research code workflows affected by a change or planned change, before reviewing or planning.
148
+ - \`thatch-review-context\` — gather project context (PRs, tickets, TODOs, deferred work) before a review.
149
+ - \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` — five specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
150
+ - \`thatch-project-primer\` — investigate a new project and write foundational memories.
151
+ - \`thatch-session-reflection\` — record what you learned at end of session.
152
+ - \`thatch-fact-extractor\` — extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
153
+ - \`thatch-dedup-classifier\` — resolve duplicate memory pairs from \`find_duplicates\`.
154
+
129
155
  ## When to Write
130
156
 
131
157
  **One signal is enough.** Do not wait for confirmation.
@@ -241,6 +267,19 @@ WIP, PR status). Unscoped memories are project-wide and always included in searc
241
267
  Before diving into code, \`memory_recall\` with a query relevant to the area
242
268
  you're working in. Prior sessions may have already investigated it.
243
269
 
270
+ ## Skills
271
+
272
+ Thatch ships skills for code review, project investigation, and memory
273
+ workflows. The host auto-discovers them, but reach for them proactively:
274
+
275
+ - \`thatch-workflow-research\` — research code workflows affected by a change or planned change, before reviewing or planning.
276
+ - \`thatch-review-context\` — gather project context (PRs, tickets, TODOs, deferred work) before a review.
277
+ - \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` — five specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
278
+ - \`thatch-project-primer\` — investigate a new project and write foundational memories.
279
+ - \`thatch-session-reflection\` — record what you learned at end of session.
280
+ - \`thatch-fact-extractor\` — extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
281
+ - \`thatch-dedup-classifier\` — resolve duplicate memory pairs from \`find_duplicates\`.
282
+
244
283
  ## When to Write
245
284
 
246
285
  **One signal is enough.** Do not wait for confirmation.
package/src/setup.ts CHANGED
@@ -415,8 +415,120 @@ export function setupCursor(
415
415
  return {
416
416
  mcpConfig: paths.mcpConfigPath,
417
417
  agentsMd: paths.agentsMdPath,
418
- hooks: paths.hooksPath,
419
- skills,
420
- global,
418
+ hooks: paths.hooksPath,
419
+ skills,
420
+ global,
421
+ };
422
+ }
423
+
424
+ // ---------------------------------------------------------------------------
425
+ // Setup detection — check whether setup was completed for the current host
426
+ // ---------------------------------------------------------------------------
427
+
428
+ export type HostKind = "claude" | "cursor";
429
+
430
+ export type SetupStatus =
431
+ | { status: "installed"; scope: "local" | "global"; host: HostKind }
432
+ | { status: "not-installed"; host: HostKind; message: string }
433
+ | { status: "markers-broken"; host: HostKind; file: string; message: string };
434
+
435
+ type FileCheck = "installed" | "absent" | "broken";
436
+
437
+ function checkInstructionsFile(path: string, startMarker: string, endMarker: string): FileCheck {
438
+ if (!existsSync(path)) return "absent";
439
+ const content = readFileSync(path, "utf8");
440
+ const startIdx = content.indexOf(startMarker);
441
+ if (startIdx === -1) return "absent";
442
+ const endIdx = content.indexOf(endMarker, startIdx);
443
+ if (endIdx === -1) return "broken";
444
+ return "installed";
445
+ }
446
+
447
+ /**
448
+ * Detects the host from env vars (CURSOR_PROJECT_DIR for Cursor,
449
+ * CLAUDE_PROJECT_DIR for Claude Code) and checks whether `thatch setup` was
450
+ * run for that host. Checks local instructions (in the project dir) first,
451
+ * then global (in the config dir). Returns null if the host cannot be
452
+ * determined (neither env var is set — e.g. manual `thatch mcp` invocation).
453
+ */
454
+ export function checkSetup(projectDir: string, homeDir?: string): SetupStatus | null {
455
+ const home = homeDir ?? process.env.HOME ?? "/tmp";
456
+ const isCursor = !!process.env.CURSOR_PROJECT_DIR;
457
+ const isClaude = !!process.env.CLAUDE_PROJECT_DIR && !isCursor;
458
+ if (!isCursor && !isClaude) return null;
459
+
460
+ const host: HostKind = isCursor ? "cursor" : "claude";
461
+
462
+ if (host === "claude") {
463
+ return checkClaudeSetup(projectDir, home);
464
+ }
465
+ return checkCursorSetup(projectDir, home);
466
+ }
467
+
468
+ function checkClaudeSetup(projectDir: string, home: string): SetupStatus {
469
+ const configDir = claudeConfigDir(home);
470
+
471
+ const localMd = join(projectDir, "CLAUDE.md");
472
+ const localCheck = checkInstructionsFile(localMd, THATCH_MARKER, THATCH_END_MARKER);
473
+ if (localCheck === "installed") return { status: "installed", scope: "local", host: "claude" };
474
+ if (localCheck === "broken") {
475
+ return {
476
+ status: "markers-broken",
477
+ host: "claude",
478
+ file: localMd,
479
+ message: `Thatch's instructions in ${localMd} have corrupted markers: the start marker was found but the end marker is missing. This usually happens when the file was edited externally and the thatch block was partially modified. Tell the user to fix this by running: thatch setup --claude. If that doesn't resolve it, they may need to manually remove the corrupted thatch block from ${localMd} and re-run setup.`,
480
+ };
481
+ }
482
+
483
+ const globalMd = join(configDir, "CLAUDE.md");
484
+ const globalCheck = checkInstructionsFile(globalMd, THATCH_MARKER, THATCH_END_MARKER);
485
+ if (globalCheck === "installed") return { status: "installed", scope: "global", host: "claude" };
486
+ if (globalCheck === "broken") {
487
+ return {
488
+ status: "markers-broken",
489
+ host: "claude",
490
+ file: globalMd,
491
+ message: `Thatch's instructions in ${globalMd} have corrupted markers: the start marker was found but the end marker is missing. This usually happens when the file was edited externally and the thatch block was partially modified. Tell the user to fix this by running: thatch setup --claude --global. If that doesn't resolve it, they may need to manually remove the corrupted thatch block from ${globalMd} and re-run setup.`,
492
+ };
493
+ }
494
+
495
+ return {
496
+ status: "not-installed",
497
+ host: "claude",
498
+ message: "Thatch is running as an MCP server but has not been set up for Claude Code. The instructions that tell you how to use thatch's memory tools are missing from CLAUDE.md. Tell the user to run: thatch setup --claude",
499
+ };
500
+ }
501
+
502
+ function checkCursorSetup(projectDir: string, home: string): SetupStatus {
503
+ const configDir = cursorConfigDir(home);
504
+
505
+ const localMd = join(projectDir, "AGENTS.md");
506
+ const localCheck = checkInstructionsFile(localMd, CURSOR_MARKER, CURSOR_END_MARKER);
507
+ if (localCheck === "installed") return { status: "installed", scope: "local", host: "cursor" };
508
+ if (localCheck === "broken") {
509
+ return {
510
+ status: "markers-broken",
511
+ host: "cursor",
512
+ file: localMd,
513
+ message: `Thatch's instructions in ${localMd} have corrupted markers: the start marker was found but the end marker is missing. This usually happens when the file was edited externally and the thatch block was partially modified. Tell the user to fix this by running: thatch setup --cursor. If that doesn't resolve it, they may need to manually remove the corrupted thatch block from ${localMd} and re-run setup.`,
514
+ };
515
+ }
516
+
517
+ const globalMd = join(configDir, "AGENTS.md");
518
+ const globalCheck = checkInstructionsFile(globalMd, CURSOR_MARKER, CURSOR_END_MARKER);
519
+ if (globalCheck === "installed") return { status: "installed", scope: "global", host: "cursor" };
520
+ if (globalCheck === "broken") {
521
+ return {
522
+ status: "markers-broken",
523
+ host: "cursor",
524
+ file: globalMd,
525
+ message: `Thatch's instructions in ${globalMd} have corrupted markers: the start marker was found but the end marker is missing. This usually happens when the file was edited externally and the thatch block was partially modified. Tell the user to fix this by running: thatch setup --cursor --global. If that doesn't resolve it, they may need to manually remove the corrupted thatch block from ${globalMd} and re-run setup.`,
526
+ };
527
+ }
528
+
529
+ return {
530
+ status: "not-installed",
531
+ host: "cursor",
532
+ message: "Thatch is running as an MCP server but has not been set up for Cursor. The instructions that tell you how to use thatch's memory tools are missing from AGENTS.md. Tell the user to run: thatch setup --cursor",
421
533
  };
422
534
  }
package/src/skills.ts CHANGED
@@ -82,6 +82,25 @@ Before flagging behavior as a bug, verify intent:
82
82
 
83
83
  If any of these reveals the behavior is intentional, it is not a finding. If you cannot determine intent after all three steps, you may report it — but note that you could not confirm whether the behavior is intentional.
84
84
 
85
+ ## Project context awareness
86
+ If your briefing includes a project context brief (from the coordinator or from loading thatch-review-context), use it to calibrate your findings:
87
+ - **Deferred work** listed in the brief is intentionally excluded from this PR. Do not flag the absence of deferred pieces as bugs, inconsistencies, or missing functionality.
88
+ - **Dependencies** in the brief tell you whether base-branch behavior is expected to be present or not. Do not assert that base-branch behavior exists without verifying it landed.
89
+ - **Relevant constraints** may explain why code is structured a certain way. Consider them before flagging design choices.
90
+
91
+ ## Workflow context awareness
92
+ If your briefing includes a workflow guide (from the coordinator or from loading thatch-workflow-research), use it to understand the purpose and evolution of the code you are reviewing:
93
+ - **Purpose** sections explain why the workflow exists, which helps distinguish intentional behavior from bugs.
94
+ - **Major evolutions** sections explain how the code reached its current state, which helps distinguish recent changes from long-standing design decisions.
95
+ - **Constraints and design decisions** sections explain tradeoffs and intentional choices, which prevents flagging known design decisions as issues.
96
+ - **Current state** sections list known limitations and incomplete work, which prevents flagging known gaps as new bugs.
97
+
98
+ ## TODO ($ticket) markers
99
+ Code may contain \`TODO ($TICKET-ID): description\` comments that mark intentionally deferred work: temporary code, placeholders for future tickets, or planned cleanups. These are legitimate breadcrumbs, not stale artifacts.
100
+ - Do NOT flag a TODO ($ticket) marker as a stale artifact if the ticket it references is still open or future work.
101
+ - DO flag it if you can verify the referenced ticket is closed or merged (the TODO is now stale).
102
+ - If your briefing includes a context brief that lists the deferred work, use it to determine whether the ticket is still pending.
103
+
85
104
  ## Output format
86
105
  Produce findings as markdown. For each finding:
87
106
 
@@ -733,6 +752,219 @@ Findings you verified as real but pre-existing, with a one-line note on the issu
733
752
  Note which files or areas were NOT covered by any specialist.
734
753
  `;
735
754
 
755
+ // ---------------------------------------------------------------------------
756
+ // Review context builder — gathers project/feature context before fan-out
757
+ // ---------------------------------------------------------------------------
758
+
759
+ const REVIEW_CONTEXT = `---
760
+ name: thatch-review-context
761
+ description: Gather project and feature context before a code review. Investigates PR descriptions, git history, ticket references, docs, and memory to build a context brief that prevents false positives about intentionally deferred work. Use before dispatching review specialists or running a solo review.
762
+ ---
763
+
764
+ You are a review context builder. Your job is to gather project context that gives reviewers the background they need to avoid false positives about intentionally deferred work, incomplete features, and multi-ticket dependencies.
765
+
766
+ ## Why this matters
767
+
768
+ A specialist reviewer without project context will flag missing pieces of a feature as bugs or inconsistencies. If the PR is one ticket in a multi-ticket effort, the "missing" piece may be scheduled for the next ticket. Context prevents these false positives.
769
+
770
+ ## Sources to investigate
771
+
772
+ Work through these sources in order. Not every source will yield information for every change. Skip sources that produce nothing rather than forcing a narrative.
773
+
774
+ ### 1. PR description
775
+ If reviewing a PR, read the description:
776
+ - \`gh pr view N --json title,body,labels,milestone\` (or the local branch's PR if detected)
777
+ - Extract: stated scope, what is intentionally excluded, ticket references, linked PRs
778
+
779
+ ### 2. Branch name
780
+ Branch names often contain ticket identifiers. Look for patterns:
781
+ - \`user/ticket-123\`, \`user/plat-122\`, \`feature/PROJ-456\`
782
+ - Extract the ticket ID and use it to search other sources
783
+
784
+ ### 3. Git archaeology
785
+ - \`git log --oneline merge-base..HEAD\` — commit messages may reference tickets, describe scope, or mention future work
786
+ - \`git log --all --oneline --grep="TICKET-ID"\` — find related commits on other branches
787
+ - \`git log -S "TODO (TICKET"\` — find TODO markers that reference this or related tickets
788
+ - \`git branch -a\` — other branches may show planned or in-progress related work
789
+
790
+ ### 4. TODO ($ticket) markers in the diff
791
+ Scan the diff for TODO markers that reference ticket identifiers:
792
+ - Pattern: \`TODO ($TICKET-ID): description\`
793
+ - Example: \`// TODO (PLAT-123): replace this temporary flag with the real config loader\`
794
+ - Example: \`// TODO (PLAT-124): this fallback will be removed when the new API lands\`
795
+ - These mark intentionally deferred work: cleanups, temporary code, or pieces to be introduced later
796
+ - Each marker tells a reviewer "this is known and scheduled, not missing"
797
+ - Extract the ticket IDs and note what is deferred
798
+
799
+ ### 5. Thatch memories (RAG)
800
+ Call \`thatch_memory_recall\` with queries like:
801
+ - The feature or project name (if known from the PR or branch)
802
+ - The ticket identifier
803
+ - "feature status" or "milestone" or "roadmap"
804
+ - Any architectural decisions or design docs related to the changed area
805
+
806
+ ### 6. Project documentation
807
+ - README, docs/, design docs, ADRs
808
+ - CONTRIBUTING.md or equivalent for conventions
809
+ - Any roadmap, milestone, or project plan documents
810
+
811
+ ### 7. Issue tracker (if accessible)
812
+ If ticket IDs were found:
813
+ - \`gh issue list --search "TICKET-ID"\` or \`gh issue view N\`
814
+ - Look for milestone assignments, dependencies, and blocking relationships
815
+ - Check for epic or parent issues that describe the overall feature
816
+
817
+ ## Context brief format
818
+
819
+ Produce a structured brief:
820
+
821
+ ### Project context
822
+ - What larger initiative or feature this change is part of
823
+ - The ticket or milestone this PR implements
824
+
825
+ ### This change's scope
826
+ - What this PR is scoped to deliver (from PR description, commit messages, diff analysis)
827
+ - What is explicitly excluded or deferred
828
+
829
+ ### Deferred work
830
+ List each deferred piece:
831
+ - What is deferred
832
+ - Which ticket will deliver it (if known)
833
+ - Any TODO ($ticket) markers in the code that annotate it
834
+
835
+ ### Dependencies
836
+ - What other tickets or PRs this depends on (must merge first)
837
+ - What tickets or PRs depend on this (are blocked by it)
838
+ - Whether base branches have landed (for stacked PRs)
839
+
840
+ ### Relevant constraints
841
+ - Design decisions or architectural constraints from memories or docs
842
+ - Conventions that reviewers should be aware of
843
+
844
+ ## If context is sparse
845
+
846
+ Not every PR will have rich context. If you find minimal context:
847
+ - State what you looked for and what you found
848
+ - Note that the change appears to be standalone (no multi-ticket dependencies detected)
849
+ - Flag any TODO ($ticket) markers in the diff even if you could not resolve the ticket
850
+
851
+ ## The TODO ($ticket) convention
852
+
853
+ When code is intentionally temporary or incomplete because work is split across tickets, mark it with a TODO that references the ticket that will resolve it:
854
+
855
+ \`\`\`
856
+ // TODO ($TICKET-ID): description of what will be done or removed here
857
+ \`\`\`
858
+
859
+ Examples:
860
+ - \`// TODO (PLAT-123): replace this temporary flag with the real config loader\`
861
+ - \`// TODO (PLAT-124): this fallback will be removed when the new API lands\`
862
+ - \`# TODO (INFRA-456): delete this compatibility shim once all callers migrate\`
863
+
864
+ These markers serve as breadcrumbs for reviewers (human and LLM) who lack project context:
865
+ - They signal "this is known and scheduled, not a bug or oversight"
866
+ - They link the code to the ticket that will resolve it
867
+ - They should NOT be flagged as stale artifacts (the work is not yet completed)
868
+ - They SHOULD be flagged if the referenced ticket is closed or merged (the TODO is now stale)
869
+ `;
870
+
871
+ // ---------------------------------------------------------------------------
872
+ // Workflow research — code archaeology for review or planning
873
+ // ---------------------------------------------------------------------------
874
+
875
+ const WORKFLOW_RESEARCH = `---
876
+ name: thatch-workflow-research
877
+ description: Research the code workflows and features affected by a change or planned change. Identifies affected workflows, reads code flows and comments, traces git history, recalls memories, and produces a guide to the code. Use before reviewing a change or planning new work in an unfamiliar area.
878
+ ---
879
+
880
+ You are a code workflow researcher. Your job is to identify the features and logical workflows affected by a change (or a planned change), do deep code archaeology on them, and produce a guide that gives other agents the context they need to review or plan effectively.
881
+
882
+ ## Why this matters
883
+
884
+ A specialist reviewer without code-level context will misidentify intentional behavior as bugs, miss known design constraints, and duplicate the same code-tracing work across every specialist lens. A planner without code-level context will propose changes that conflict with existing flows. This skill produces the code guide that prevents both.
885
+
886
+ ## Relationship to thatch-review-context
887
+
888
+ These two skills are complementary, not overlapping:
889
+ - **thatch-review-context** gathers project metadata: tickets, PRs, TODO markers, deferred work, issue-tracker context. It answers "what is this change trying to do and what is intentionally left out?"
890
+ - **thatch-workflow-research** (this skill) gathers code-level context: actual code flows, comments, git history, evolutions. It answers "how does the code being changed actually work, and how did it get that way?"
891
+
892
+ Use both before a review. The coordinator runs thatch-review-context in Step 2 and this skill in Step 3.
893
+
894
+ ## Two modes
895
+
896
+ ### Review mode (existing change)
897
+ Given a git range, branch, or PR:
898
+ 1. Run \`git diff --stat\` on the resolved range to identify changed files.
899
+ 2. For each changed file, read the diff to understand what is being modified.
900
+ 3. From the changes, identify which features and business-logic workflows are touched. A single file may participate in multiple workflows; a single workflow may span multiple files.
901
+
902
+ ### Planning mode (new change)
903
+ Given a description of work to be done:
904
+ 1. Identify which areas of the codebase the planned change would affect.
905
+ 2. Use grep/glob to find the files and modules that implement the relevant features.
906
+ 3. From those files, identify which existing workflows the change will interact with or modify.
907
+
908
+ ## Research process
909
+
910
+ For each identified workflow or feature, work through these steps. Not every step will yield information for every workflow. Skip steps that produce nothing rather than forcing a narrative.
911
+
912
+ ### 1. Retrieve memories
913
+ Call \`thatch_memory_recall\` with queries like:
914
+ - The workflow or feature name
915
+ - The primary files or modules involved
916
+ - "architecture" or "design" or "convention" for the area
917
+ - Any gotchas or known issues in the area
918
+
919
+ ### 2. Read documentation
920
+ - README, docs/, design docs, ADRs related to the workflow
921
+ - CLAUDE.md, AGENTS.md, CONTRIBUTING.md for conventions
922
+ - Any inline documentation at the module level
923
+
924
+ ### 3. Read the code flow
925
+ Trace each workflow through the codebase. Do not just read the changed lines; read the full flow:
926
+ - Identify the entry point(s) for the workflow
927
+ - Follow the data path through the functions and modules involved
928
+ - Read the comments in the flow. Comments encode intention, rationale, and design decisions that are invisible from the code alone.
929
+ - Note key contracts: what does each function or module assume about its inputs? What does it guarantee about its outputs?
930
+ - Note implicit state machines: what states can the workflow be in? What transitions are guarded?
931
+
932
+ ### 4. Read git history
933
+ Trace the evolution of the workflow through git:
934
+ - \`git log --oneline -- <key files>\` for the commit history of the files involved
935
+ - \`git log -S "<function name>"\` to find when key functions were introduced or changed
936
+ - \`git blame\` on critical sections to find when and why they were written
937
+ - \`git log --all --oneline --grep="<feature name>"\` to find related work on other branches
938
+ - Look for commit messages that explain design decisions, refactors, or bug fixes that shaped the workflow
939
+
940
+ Focus on *why* the code evolved, not just *when*. Major evolutions are: creation, significant refactors, behavior changes, bug fixes that changed the flow, and additions of new paths or states.
941
+
942
+ ## Output: code guide
943
+
944
+ Produce a guide with one section per affected workflow or feature. Each section should be self-contained enough that a reviewer or planner can understand the workflow without reading the code themselves.
945
+
946
+ ### Workflow: <name>
947
+
948
+ - **Purpose**: What this workflow does and why it exists in the system
949
+ - **Key files**: The primary files and entry points, with file:line references
950
+ - **Data flow**: How data moves through the workflow (high-level, not line-by-line)
951
+ - **Major evolutions**: Key changes from git history. When was it created? What refactors or behavior changes shaped it? What drove those changes? Cite commit hashes or dates.
952
+ - **Constraints and design decisions**: From comments, memories, and docs. Known constraints, tradeoffs, intentional design choices, and gotchas.
953
+ - **Current state**: Any open issues, TODOs, known limitations, or incomplete migrations
954
+
955
+ ## Scope discipline
956
+
957
+ Only research workflows that the change actually touches. Do not research every workflow in the codebase. If a changed file participates in three workflows but the change only affects one, research only that one.
958
+
959
+ If the change is small and touches a single workflow, the guide may be one section. If the change is cross-cutting, the guide may have several sections. Let the change determine the scope.
960
+
961
+ ## What this skill is NOT
962
+
963
+ - It is not a code review. Do not evaluate the quality of the code or flag issues. That is the job of the review specialists.
964
+ - It is not a project context builder. That is the job of thatch-review-context, which gathers project metadata (tickets, PRs, TODOs, deferred work). This skill gathers code-level context (flows, comments, git history, evolutions).
965
+ - It is not a memory writer. Do not call thatch_memory_remember. If you discover durable facts, note them in the guide; the session-reflection or fact-extractor skills will persist them later.
966
+ `;
967
+
736
968
  // ---------------------------------------------------------------------------
737
969
  // Session reflection — end-of-session memory recording guidance
738
970
  // ---------------------------------------------------------------------------
@@ -833,7 +1065,35 @@ Fetch any refs not locally reachable so branches and PRs that were never checked
833
1065
 
834
1066
  Run git diff --stat on the resolved range and git log --oneline to understand the change.
835
1067
 
836
- ## Step 2: Estimate complexity
1068
+ ## Step 2: Gather project context
1069
+
1070
+ Load the thatch-review-context skill and follow its methodology to build a context brief for this change. Investigate:
1071
+ - PR description (if a PR was specified or detected via the branch)
1072
+ - Branch name for ticket identifiers
1073
+ - Git log for commit messages referencing tickets or describing scope
1074
+ - TODO ($ticket) markers in the diff
1075
+ - thatch_memory_recall for feature/project status, design decisions, ticket dependencies
1076
+ - Project docs, READMEs, design docs
1077
+ - Issue tracker (gh issue/view) if ticket IDs are found
1078
+
1079
+ Produce the context brief in the format the skill prescribes (project context, this change's scope, deferred work, dependencies, relevant constraints).
1080
+
1081
+ 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.
1082
+
1083
+ ## Step 3: Research affected workflows
1084
+
1085
+ Dispatch a sub-agent using the Task tool to research the code workflows affected by this change. Pass the sub-agent:
1086
+ - The git range and changed files (from Step 1)
1087
+ - The project context brief (from Step 2)
1088
+ - Instructions to load the thatch-workflow-research skill and follow its methodology
1089
+
1090
+ The sub-agent produces a code guide with one section per affected workflow or feature. Wait for it to complete and collect the guide.
1091
+
1092
+ This guide gives specialists the code-level context (purpose, data flow, evolutions, constraints) they need to avoid false positives about intentional behavior and long-standing design decisions, and reduces duplicate code-tracing across the five specialist lenses.
1093
+
1094
+ For small changes (a single file or trivial diff), you may do this research inline instead of dispatching a sub-agent. Use your judgment: if the workflow research would require reading more than 3-4 files, dispatch a sub-agent to preserve your context for orchestration.
1095
+
1096
+ ## Step 4: Estimate complexity
837
1097
 
838
1098
  Estimate the review effort in scrum points (1-13 scale):
839
1099
  - **1**: Trivial — typo fix, config tweak, single-line change.
@@ -847,7 +1107,7 @@ Points reflect *review complexity*, not implementation effort.
847
1107
 
848
1108
  Identify files to exclude from review: vendored dependencies, generated files, lockfiles, compiled assets.
849
1109
 
850
- ## Step 3: Partition (if > 3 points)
1110
+ ## Step 5: Partition (if > 3 points)
851
1111
 
852
1112
  For changes estimated at more than 3 points, partition into review units of approximately 3 points each:
853
1113
  - Group files by logical component or feature, not by directory.
@@ -857,7 +1117,7 @@ For changes estimated at more than 3 points, partition into review units of appr
857
1117
 
858
1118
  For changes estimated at 3 points or fewer, skip partitioning — dispatch one set of specialists covering the full scope. A single 3-point unit is not large enough to warrant decomposition.
859
1119
 
860
- ## Step 4: Dispatch specialist sub-agents
1120
+ ## Step 6: Dispatch specialist sub-agents
861
1121
 
862
1122
  For each review unit, dispatch sub-agents using the Task tool. Each sub-agent runs one specialist lens on one review unit. The five specialists are:
863
1123
 
@@ -876,7 +1136,7 @@ For the integration review unit (5+ points), dispatch a sub-agent focused on:
876
1136
  - Boundary correctness — race conditions, ordering dependencies, shared state issues at boundaries.
877
1137
  - Top-level coherence — does the overall change make sense as a unit?
878
1138
 
879
- ## Step 5: Synthesize
1139
+ ## Step 7: Synthesize
880
1140
 
881
1141
  After all sub-agents complete, load the thatch-review-synthesizer skill to verify findings, deduplicate across specialists, classify (CONFIRMED/REJECTED/UNVERIFIABLE), and produce the final severity-grouped report.
882
1142
 
@@ -897,10 +1157,13 @@ When dispatching each sub-agent, include in the prompt:
897
1157
  - The specific files in this unit's scope
898
1158
  - The specialist focus (from the five specialists above)
899
1159
  - The diff stat for this unit's files
1160
+ - **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.
1161
+ - **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.
900
1162
  - Any design context or specific concerns
901
1163
  - Explicit scope boundaries ("your scope is X; do NOT review Y")
902
1164
  - Instruction to produce markdown findings with: severity, category, file:line, finding, evidence, trigger scenario, reachability, source of truth, producer chain, provenance
903
1165
  - Instruction to apply the reachability gate (including reading and citing governing constraints for data-state claims) and intent verification before reporting
1166
+ - Instruction to respect the project context brief: do not flag deferred work as bugs or inconsistencies, and recognize TODO ($ticket) markers as intentional breadcrumbs
904
1167
  `;
905
1168
 
906
1169
  // ---------------------------------------------------------------------------
@@ -918,6 +1181,8 @@ const SHARED_SKILLS: SkillDef[] = [
918
1181
  { name: "thatch-review-no-slop", content: REVIEW_NO_SLOP },
919
1182
  { name: "thatch-review-breadcrumbs", content: REVIEW_BREADCRUMBS },
920
1183
  { name: "thatch-review-synthesizer", content: REVIEW_SYNTHESIZER },
1184
+ { name: "thatch-review-context", content: REVIEW_CONTEXT },
1185
+ { name: "thatch-workflow-research", content: WORKFLOW_RESEARCH },
921
1186
  { name: "thatch-session-reflection", content: SESSION_REFLECTION },
922
1187
  ];
923
1188