@jeffober/thatch 0.1.28 → 0.1.30
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 +24 -10
- package/artifacts/skills/thatch-code-review.md +9 -7
- package/artifacts/skills/thatch-review-economy.md +97 -0
- package/artifacts/skills/thatch-review-followup.md +1 -1
- package/artifacts/skills/thatch-review-synthesizer.md +15 -5
- package/bin/qa-run +38 -0
- package/bin/release +21 -0
- package/bin/thatch +17 -5
- package/docs/dev/README.md +71 -18
- package/docs/dev/features/README.md +33 -0
- package/docs/dev/features/behavior-engine.md +271 -0
- package/docs/dev/features/cicd.md +89 -0
- package/docs/dev/features/cli.md +81 -0
- package/docs/dev/features/compaction-recovery.md +48 -0
- package/docs/dev/features/database.md +244 -0
- package/docs/dev/features/deduplication.md +102 -0
- package/docs/dev/features/extraction.md +253 -0
- package/docs/dev/features/hygiene.md +81 -0
- package/docs/dev/features/memory-store.md +154 -0
- package/docs/dev/features/multi-host.md +228 -0
- package/docs/dev/features/nudge-pipeline.md +282 -0
- package/docs/dev/features/prediction-engine.md +253 -0
- package/docs/dev/features/qa-system.md +205 -0
- package/docs/dev/features/session-lifecycle.md +110 -0
- package/docs/dev/features/setup.md +199 -0
- package/docs/dev/features/sideband.md +104 -0
- package/docs/dev/gotchas.md +3 -3
- package/docs/dev/mcp-parity.md +6 -4
- package/docs/dev/setup-and-hooks.md +4 -4
- package/docs/dev/skills.md +10 -8
- package/docs/plans/README.md +2 -2
- package/docs/user/README.md +58 -20
- package/docs/user/behavior-engine.md +85 -0
- package/docs/user/cli.md +98 -0
- package/docs/user/code-review.md +73 -0
- package/docs/user/deduplication.md +70 -0
- package/docs/user/default-behaviors.md +75 -0
- package/docs/user/extraction.md +74 -0
- package/docs/user/hygiene.md +76 -0
- package/docs/user/memory.md +81 -0
- package/docs/user/prediction-engine.md +87 -0
- package/docs/user/setup.md +110 -0
- package/docs/user/skills.md +97 -0
- package/package.json +2 -2
- package/src/behavior.ts +120 -0
- package/src/db.ts +160 -417
- package/src/embeddings.ts +0 -41
- package/src/extraction.ts +2 -2
- package/src/git.ts +3 -1
- package/src/index.ts +55 -9
- package/src/mcp.ts +30 -1
- package/src/prediction.ts +127 -0
- package/src/prompts.ts +135 -188
- package/src/scoring-engine.ts +374 -0
- package/src/seed-behaviors.ts +339 -0
- package/src/setup.ts +2 -6
- package/src/sideband.ts +36 -8
- package/src/skills.ts +1 -0
- package/src/tool-defs.ts +172 -25
- package/src/vector-math.ts +30 -0
- package/docs/qa/README.md +0 -175
package/docs/user/README.md
CHANGED
|
@@ -5,6 +5,22 @@ remember information across sessions using local embeddings and SQLite. It
|
|
|
5
5
|
works with **OpenCode** (as a plugin), **Claude Code** (as an MCP server), and
|
|
6
6
|
**Cursor** (as an MCP server).
|
|
7
7
|
|
|
8
|
+
## Feature docs
|
|
9
|
+
|
|
10
|
+
This README is the overview. Each feature has its own guide:
|
|
11
|
+
|
|
12
|
+
- [memory.md](memory.md): persistent memory store
|
|
13
|
+
- [extraction.md](extraction.md): automatic fact extraction from tool calls
|
|
14
|
+
- [prediction-engine.md](prediction-engine.md): user decision model
|
|
15
|
+
- [behavior-engine.md](behavior-engine.md): agent self-discipline rules
|
|
16
|
+
- [default-behaviors.md](default-behaviors.md): what ships automatically
|
|
17
|
+
- [hygiene.md](hygiene.md): store maintenance signals
|
|
18
|
+
- [deduplication.md](deduplication.md): duplicate detection and resolution
|
|
19
|
+
- [skills.md](skills.md): structured workflow skills
|
|
20
|
+
- [code-review.md](code-review.md): multi-agent code review pipeline
|
|
21
|
+
- [setup.md](setup.md): installation and configuration
|
|
22
|
+
- [cli.md](cli.md): command-line tool reference
|
|
23
|
+
|
|
8
24
|
## Installation
|
|
9
25
|
|
|
10
26
|
### OpenCode
|
|
@@ -26,7 +42,7 @@ For async extraction (child sessions run in the background):
|
|
|
26
42
|
export OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true
|
|
27
43
|
```
|
|
28
44
|
|
|
29
|
-
Without this env var, extraction still works
|
|
45
|
+
Without this env var, extraction still works. The child session runs
|
|
30
46
|
fire-and-forget instead of asynchronously. Put it in your shell rc,
|
|
31
47
|
`mise.toml` `[env]`, or `.envrc`.
|
|
32
48
|
|
|
@@ -47,8 +63,8 @@ thatch setup --claude # project-local (writes .mcp.json, CLAUDE.md, .
|
|
|
47
63
|
thatch setup --claude --global # user-scoped (~/.claude/)
|
|
48
64
|
```
|
|
49
65
|
|
|
50
|
-
`bun` must be on PATH (the thatch binary runs under bun). `setup` is idempotent
|
|
51
|
-
|
|
66
|
+
`bun` must be on PATH (the thatch binary runs under bun). `setup` is idempotent.
|
|
67
|
+
Re-running it updates drifted content without clobbering unrelated config.
|
|
52
68
|
For a global install, `setup` prints the `claude mcp add --scope user` command
|
|
53
69
|
to run instead of writing a project `.mcp.json`.
|
|
54
70
|
|
|
@@ -59,7 +75,7 @@ thatch setup --cursor # project-local (.cursor/mcp.json, AGENTS.md, .
|
|
|
59
75
|
thatch setup --cursor --global # user-scoped (~/.cursor/)
|
|
60
76
|
```
|
|
61
77
|
|
|
62
|
-
Cursor has no `claude mcp add` equivalent
|
|
78
|
+
Cursor has no `claude mcp add` equivalent. `setup` writes `~/.cursor/mcp.json`
|
|
63
79
|
directly. Hook output is JSON-wrapped (`--json`) so Cursor injects it as
|
|
64
80
|
`additional_context`.
|
|
65
81
|
|
|
@@ -76,7 +92,7 @@ Every git repo gets its own store, named after the repo's remote identity
|
|
|
76
92
|
(e.g., `sysread/thatch`). There is also a shared `global` store for
|
|
77
93
|
information that applies across all projects.
|
|
78
94
|
|
|
79
|
-
Stores are created automatically
|
|
95
|
+
Stores are created automatically. No setup required.
|
|
80
96
|
|
|
81
97
|
### Memory tools
|
|
82
98
|
|
|
@@ -106,6 +122,7 @@ Stores are created automatically — no setup required.
|
|
|
106
122
|
| Tool | What it does |
|
|
107
123
|
|------|-------------|
|
|
108
124
|
| `thatch_extraction_done` | Acknowledge extraction buffer work. In the nudge fallback path, quiets the nudge while holding entries until the extractor completes. In a child extractor session, marks entries complete. Called by the model after dispatching the fact-extractor skill. |
|
|
125
|
+
| `thatch_get_extraction_payload` | Retrieve the queued tool interactions for the fact-extractor sub-agent. Fetches by session ID so the full payload stays out of the main session's context window. |
|
|
109
126
|
|
|
110
127
|
### Prediction tools
|
|
111
128
|
|
|
@@ -116,6 +133,15 @@ Stores are created automatically — no setup required.
|
|
|
116
133
|
| `thatch_prediction_list` | List all predictions in a store with matchers, confidence, and provenance. |
|
|
117
134
|
| `thatch_prediction_delete` | Delete a prediction by semantic match. Edges and provenance are cascade-deleted. |
|
|
118
135
|
|
|
136
|
+
### Behavior tools
|
|
137
|
+
|
|
138
|
+
| Tool | What it does |
|
|
139
|
+
|------|-------------|
|
|
140
|
+
| `thatch_behavior_codify` | Codify a self-discipline rule: when situation X arises, the agent should do Y. For the agent's own operational discipline, not user preferences. |
|
|
141
|
+
| `thatch_behavior_feedback` | Record ham/spam feedback on a surfaced behavior. `relevant: true` (ham) confirms the rule applies; `relevant: false` (spam) disconfirms. Trains the classifier. |
|
|
142
|
+
| `thatch_behavior_list` | List all codified behaviors with matchers, confidence, and provenance. |
|
|
143
|
+
| `thatch_behavior_delete` | Delete a behavior by semantic match. Edges and provenance are cascade-deleted. |
|
|
144
|
+
|
|
119
145
|
## Automatic behaviors
|
|
120
146
|
|
|
121
147
|
Beyond the tools, thatch hooks into opencode itself:
|
|
@@ -128,33 +154,42 @@ Beyond the tools, thatch hooks into opencode itself:
|
|
|
128
154
|
maintenance signals when there are any: duplicate candidates pending review,
|
|
129
155
|
memories neither updated nor recalled in 90+ days, and memories scoped to
|
|
130
156
|
git branches that no longer exist. The agent is asked to tend the store when
|
|
131
|
-
convenient
|
|
157
|
+
convenient. Thatch never deletes memories on its own.
|
|
132
158
|
- **Write-time similarity warning.** Saving a memory that closely resembles an
|
|
133
159
|
existing one succeeds, but the response warns the agent and lists the
|
|
134
160
|
similar entries so it can merge them or record that they're distinct.
|
|
135
161
|
- **Fact extraction.** Thatch buffers the session's recent tool calls (up
|
|
136
162
|
to 20, per session). When the session goes idle, the plugin creates a
|
|
137
|
-
child session and prompts it to run the fact-extractor skill directly
|
|
138
|
-
|
|
163
|
+
child session and prompts it to run the fact-extractor skill directly. No
|
|
164
|
+
nudge text in your conversation. The child writes memories via
|
|
139
165
|
`thatch_memory_remember` and is cleaned up when it finishes. A toast
|
|
140
166
|
notification shows the results (`[thatch] new: 2, updated: 1`). If the
|
|
141
167
|
direct path fails, a nudge is injected into the next message as a
|
|
142
168
|
fallback. On Claude Code and Cursor, the nudge-and-acknowledge path is
|
|
143
169
|
the only mechanism (no SDK client to create child sessions). The agent
|
|
144
|
-
does the writing
|
|
145
|
-
- **Recall and
|
|
146
|
-
memories
|
|
147
|
-
(invisible to you, visible to the agent) and fires a toast
|
|
148
|
-
(`[thatch] recalled 3 memories
|
|
149
|
-
|
|
170
|
+
does the writing. Thatch never saves memories on its own.
|
|
171
|
+
- **Recall, prediction, and behavior toasts.** When your prompt matches stored
|
|
172
|
+
memories, learned decision patterns, or codified behaviors, thatch injects a
|
|
173
|
+
synthetic nudge (invisible to you, visible to the agent) and fires a toast
|
|
174
|
+
notification (`[thatch] recalled 3 memories`, `[thatch] 2 predictions
|
|
175
|
+
surfaced`, or `[thatch] 1 behavior surfaced`). The toast is ephemeral. It
|
|
176
|
+
fades after a few seconds.
|
|
150
177
|
- **Compaction context.** When opencode compacts a long session, thatch injects
|
|
151
178
|
a reminder so the summarized session still knows memory tools exist.
|
|
152
179
|
- **Prediction auto-fire.** When a prompt matches learned contexts, thatch
|
|
153
180
|
injects a `User decision model` block alongside the recall nudge. The block
|
|
154
181
|
lists scored predictions (confidence, evidence count) that the agent can
|
|
155
182
|
follow silently (strong prediction), surface to the user (ambiguous), or
|
|
156
|
-
use to update the model after the user responds. No extra model call
|
|
157
|
-
|
|
183
|
+
use to update the model after the user responds. No extra model call. The
|
|
184
|
+
prediction search reuses the same prompt embedding as the recall nudge.
|
|
185
|
+
- **Behavior auto-fire.** When a prompt matches codified behavior matchers,
|
|
186
|
+
thatch injects a `Situational behaviors` block listing scored rules
|
|
187
|
+
(confidence, evidence count). The agent evaluates each rule against the
|
|
188
|
+
current situation: if relevant (ham), it follows the rule and calls
|
|
189
|
+
`behavior_feedback` with `relevant: true`; if not relevant (spam), it calls
|
|
190
|
+
`behavior_feedback` with `relevant: false`. This trains the classifier so
|
|
191
|
+
future nudges are more accurate. No extra model call. It reuses the same
|
|
192
|
+
embedding as recall and prediction.
|
|
158
193
|
|
|
159
194
|
### Setup detection (Claude Code and Cursor)
|
|
160
195
|
|
|
@@ -186,13 +221,15 @@ With `thatch setup --claude`, skills install to `~/.claude/skills/` (or
|
|
|
186
221
|
|
|
187
222
|
### Code review skills
|
|
188
223
|
|
|
189
|
-
|
|
224
|
+
Eight specialist review lenses, plus the synthesizer, context, followup,
|
|
225
|
+
response, walkthrough, and workflow skills that support the review pipeline:
|
|
190
226
|
|
|
191
227
|
| Skill | Focus |
|
|
192
228
|
|-------|-------|
|
|
193
229
|
| `thatch-review-pedantic` | Mechanical correctness: spelling, naming, doc accuracy, specs, guidelines, stale artifacts. |
|
|
194
230
|
| `thatch-review-acceptance` | Behavioral/product review: UX coherency, behavioral delta, integration effects, user assumptions. |
|
|
195
231
|
| `thatch-review-state-flow` | Data flow and contracts: module boundaries, implicit state machines, error propagation, separation of concerns. |
|
|
232
|
+
| `thatch-review-economy` | Design simplicity and maintainability: is the complexity earned? Evaluates both the overall change design (forest) and individual touch points (trees) for unnecessary complexity, redundancy, and simpler available alternatives. |
|
|
196
233
|
| `thatch-review-no-slop` | AI writing anti-patterns: change narration, fourth wall breaks, em dashes, hedging, filler. |
|
|
197
234
|
| `thatch-review-breadcrumbs` | Comment narrative: do comments form a coherent outline of the code's behavior? |
|
|
198
235
|
| `thatch-review-mark-and-sweep` | Mechanical change completeness: whole-repo sweep for stragglers after renames, flag removals, API substitutions. |
|
|
@@ -204,6 +241,7 @@ Seven specialist review lenses, each a self-contained static-analysis pass:
|
|
|
204
241
|
| `thatch-review-response` | Author-side review response: triage findings on your own PR, fix bugs one by one, reply on each thread, post a top-level summary comment. |
|
|
205
242
|
| `thatch-change-walkthrough` | Explains a change to the user as a teaching walkthrough: researches each affected workflow at the merge-base, teaches current behavior, then overlays the modifications with file:line citations. |
|
|
206
243
|
| `thatch-code-walkthrough` | Explains a feature, module, or workflow to the user as a teaching walkthrough with file:line citations. Also used to draft high-level docs for new or undocumented features. |
|
|
244
|
+
| `thatch-coding-workflow` | Plans and executes code changes with a task-list-driven workflow: complexity triage, milestone planning, research before coding, post-coding verification. Pairs with `thatch-code-archaeology` (research first, then plan). |
|
|
207
245
|
|
|
208
246
|
### Writing skills
|
|
209
247
|
|
|
@@ -224,7 +262,7 @@ Seven specialist review lenses, each a self-contained static-analysis pass:
|
|
|
224
262
|
| Skill | opencode | Claude Code | Cursor |
|
|
225
263
|
|-------|----------|-------------|--------|
|
|
226
264
|
| Memory skills (4) | Yes | Yes | Yes |
|
|
227
|
-
| Review specialists (
|
|
265
|
+
| Review specialists (8) | Yes | Yes | Yes |
|
|
228
266
|
| Review synthesizer | Yes | Yes | Yes |
|
|
229
267
|
| Review context + code archaeology | Yes | Yes | Yes |
|
|
230
268
|
| Review followup | Yes | Yes | Yes |
|
|
@@ -333,11 +371,11 @@ No configuration needed. The default behavior:
|
|
|
333
371
|
|
|
334
372
|
**Changing `THATCH_MODEL` on an existing database:** memories embedded by a
|
|
335
373
|
model with a different vector dimension are skipped by search (not corrupted,
|
|
336
|
-
not deleted
|
|
374
|
+
not deleted, just invisible) until re-saved. There is no automatic
|
|
337
375
|
re-embedding.
|
|
338
376
|
|
|
339
377
|
## Privacy
|
|
340
378
|
|
|
341
379
|
- All data stays on your machine. No network calls for embeddings or storage.
|
|
342
380
|
- The embedding model is downloaded once from Hugging Face Hub on first use, then cached locally.
|
|
343
|
-
- Your memories are stored in a local SQLite database
|
|
381
|
+
- Your memories are stored in a local SQLite database. Nothing is sent to any service.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Behavior Engine
|
|
2
|
+
|
|
3
|
+
Thatch lets your agent codify self-discipline rules: "when situation X
|
|
4
|
+
arises, I should do Y." These are the agent's own operational rules,
|
|
5
|
+
not your preferences (those are predictions). The agent grades its own
|
|
6
|
+
rules with ham/spam feedback.
|
|
7
|
+
|
|
8
|
+
## How it works
|
|
9
|
+
|
|
10
|
+
Each behavior has two parts:
|
|
11
|
+
|
|
12
|
+
- **Matcher**: a description of the situation that triggers the
|
|
13
|
+
rule ("about to commit changes to the repo"). Embedded and matched
|
|
14
|
+
against your prompt.
|
|
15
|
+
- **Behavior**: the rule itself ("run mise run check before
|
|
16
|
+
committing"). What the agent reads and follows.
|
|
17
|
+
|
|
18
|
+
When your prompt matches a behavior matcher above the threshold
|
|
19
|
+
(default 0.60), thatch injects a `Situational behaviors` block into
|
|
20
|
+
the agent's context. The block looks like:
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
[thatch] Situational behaviors
|
|
24
|
+
- [0.58 conf, 1 tests] When about to commit changes to the repo:
|
|
25
|
+
do Run mise run check (tsc + bun test + markdownlint) before
|
|
26
|
+
committing. Never commit code that fails the quality gate.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The agent evaluates each surfaced rule against the current situation.
|
|
30
|
+
If relevant (ham), it follows the rule and calls `behavior_feedback`
|
|
31
|
+
with `relevant: true`. If not relevant (spam), it calls
|
|
32
|
+
`behavior_feedback` with `relevant: false`. This trains the classifier
|
|
33
|
+
so future nudges are more accurate.
|
|
34
|
+
|
|
35
|
+
## Default behaviors
|
|
36
|
+
|
|
37
|
+
Thatch auto-seeds a set of default behaviors into the global store on
|
|
38
|
+
first run. These fire across all projects without manual setup:
|
|
39
|
+
|
|
40
|
+
| Rule | Fires on | What it does |
|
|
41
|
+
|------|----------|-------------|
|
|
42
|
+
| Session wrap-up | "wrapping up," "loose ends," "signing off" | Check git status, untracked files, stale artifacts before the session ends. Read-only. |
|
|
43
|
+
| Work finalization | "committing," "merging," "closing out," "ready to merge" | Check git status, branch memory consolidation, follow-up TODOs. Read-only. |
|
|
44
|
+
| Research new project | "new project," "unfamiliar codebase," "new ticket" | Check coverage, naming drift, migration evidence, load archaeology skill. |
|
|
45
|
+
| Day turnover (coding) | "continuing from yesterday," "picking up where I left off" | Check how far origin/main moved since merge-base, suggest rebase. |
|
|
46
|
+
| Day turnover (PR) | "continuing the PR," "picking up the branch" | Check for new upstream review comments on the open PR. |
|
|
47
|
+
| Day turnover (review) | "continuing the review," "picking up the review" | Check for new upstream comments and responses to our comments. |
|
|
48
|
+
| Snag or dead end | "dead end," "red herring," "that did not work" | Save a memory about the wrong path so future sessions skip it. Save-only. |
|
|
49
|
+
| Debugging archaeology | "debugging," "why is this broken," "what changed" | Git archaeology before proposing a fix, look for orphaned code from removed behavior. |
|
|
50
|
+
| Planning archaeology | "planning a change," "how should we approach" | Git archaeology to understand design intent before proposing changes. |
|
|
51
|
+
|
|
52
|
+
Default behaviors are plugin-owned. The agent can ham/spam them
|
|
53
|
+
(adjust confidence, controls whether they fire) but cannot change the
|
|
54
|
+
behavior text or trigger. When thatch updates a default behavior in a
|
|
55
|
+
new release, the old version is automatically replaced on next startup.
|
|
56
|
+
|
|
57
|
+
## Tools
|
|
58
|
+
|
|
59
|
+
| Tool | What it does |
|
|
60
|
+
|------|-------------|
|
|
61
|
+
| `thatch_behavior_codify` | Create a self-discipline rule: situation, behavior, rationale. |
|
|
62
|
+
| `thatch_behavior_feedback` | Record ham/spam feedback on a surfaced behavior. `relevant: true` confirms; `relevant: false` disconfirms. |
|
|
63
|
+
| `thatch_behavior_list` | List all codified behaviors with matchers, confidence, and provenance. |
|
|
64
|
+
| `thatch_behavior_delete` | Delete a behavior by semantic match. Edges and provenance are cascade-deleted. |
|
|
65
|
+
|
|
66
|
+
## Configuration
|
|
67
|
+
|
|
68
|
+
- `THATCH_BEHAVIOR_THRESHOLD`: cosine score threshold for behavior
|
|
69
|
+
auto-fire. Defaults to 0.60. Same rationale as prediction threshold.
|
|
70
|
+
|
|
71
|
+
## Limitations
|
|
72
|
+
|
|
73
|
+
- Behaviors are the agent's own rules, not your preferences. Use
|
|
74
|
+
`thatch_prediction_update` for user preferences instead.
|
|
75
|
+
- The agent creates behaviors based on its own judgment. Thatch never
|
|
76
|
+
creates behaviors on its own (except the default seeds).
|
|
77
|
+
- Ham/spam feedback adjusts confidence but never reaches 0 or 1.
|
|
78
|
+
Delete a wrong behavior with `thatch_behavior_delete`.
|
|
79
|
+
- Behaviors are per-store. The default behaviors live in the global
|
|
80
|
+
store (shared across projects). Agent-codified behaviors default to
|
|
81
|
+
the project store.
|
|
82
|
+
|
|
83
|
+
See [memory.md](memory.md) for the base memory system and
|
|
84
|
+
[prediction-engine.md](prediction-engine.md) for the user decision
|
|
85
|
+
model.
|
package/docs/user/cli.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# CLI
|
|
2
|
+
|
|
3
|
+
Thatch ships with a command-line tool for inspecting memories and
|
|
4
|
+
running maintenance tasks outside the agent. It requires `bun` on your
|
|
5
|
+
PATH.
|
|
6
|
+
|
|
7
|
+
## Memory inspection
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
thatch stores # list all stores
|
|
11
|
+
thatch list [store] # list memory labels in a store
|
|
12
|
+
thatch show <label> [store] # display one memory by label
|
|
13
|
+
thatch forget <label> [store] # delete one memory by label
|
|
14
|
+
thatch search <query> [store] # semantic search (cosine similarity)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Store defaults to your current git repo (detected from `git remote
|
|
18
|
+
get-url origin`). Use `global` for the shared global store. Use `all`
|
|
19
|
+
with `search` to search the project store and `global` together.
|
|
20
|
+
|
|
21
|
+
`search` uses the same cosine-similarity search as
|
|
22
|
+
`thatch_memory_recall`. Results include a similarity score for each
|
|
23
|
+
match. Limited to 10 results.
|
|
24
|
+
|
|
25
|
+
## Maintenance
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
thatch hygiene # print the hygiene report
|
|
29
|
+
thatch reminder [--json] # print the session-start reminder
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`hygiene` prints the standalone hygiene report (duplicate candidates,
|
|
33
|
+
stale entries, orphaned branch memories). See
|
|
34
|
+
[hygiene.md](hygiene.md).
|
|
35
|
+
|
|
36
|
+
`reminder` prints the full session-start reminder including the
|
|
37
|
+
hygiene report. The `--json` flag wraps the output as
|
|
38
|
+
`{"additional_context": "..."}` for Cursor's hook format. These
|
|
39
|
+
commands are normally called by hooks, not by hand, but you can run
|
|
40
|
+
them to see what the agent sees at session start.
|
|
41
|
+
|
|
42
|
+
## Priming a new project
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
thatch prime
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Runs the `thatch-project-primer` skill via an external CLI. Thatch
|
|
49
|
+
searches your PATH for `opencode`, `agent` (Cursor CLI), or `claude`
|
|
50
|
+
in that order. The first one found is used to run the primer, which
|
|
51
|
+
investigates the codebase from multiple angles and writes foundational
|
|
52
|
+
memories.
|
|
53
|
+
|
|
54
|
+
This is the same skill the agent can load manually, but `thatch prime`
|
|
55
|
+
runs it in a dedicated session focused on project investigation.
|
|
56
|
+
|
|
57
|
+
## Infrastructure commands
|
|
58
|
+
|
|
59
|
+
These commands are called by hooks installed by `thatch setup`. You
|
|
60
|
+
should not need to run them by hand.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
thatch mcp # start the stdio MCP server
|
|
64
|
+
thatch buffer-batch # append tool batch to queue (Claude Code hook)
|
|
65
|
+
thatch buffer-tool # append single tool to queue (Cursor hook)
|
|
66
|
+
thatch flush-tools [--json] # peek queue + print nudges (hook)
|
|
67
|
+
thatch flush-predictions [--json] # prediction-only nudge (hook)
|
|
68
|
+
thatch setup --claude [--cursor] [--global] # install config + hooks + skills
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Environment variables
|
|
72
|
+
|
|
73
|
+
| Variable | Default | What it controls |
|
|
74
|
+
|----------|---------|-----------------|
|
|
75
|
+
| `THATCH_DB_PATH` | `~/.config/thatch/thatch.db` | SQLite database path |
|
|
76
|
+
| `THATCH_MODEL` | `Xenova/bge-small-en-v1.5` | Embedding model name |
|
|
77
|
+
| `THATCH_RECALL_THRESHOLD` | `0.55` | Cosine threshold for recall nudge |
|
|
78
|
+
| `THATCH_PREDICTION_THRESHOLD` | `0.60` | Cosine threshold for prediction auto-fire |
|
|
79
|
+
| `THATCH_BEHAVIOR_THRESHOLD` | `0.60` | Cosine threshold for behavior auto-fire |
|
|
80
|
+
| `CLAUDE_PROJECT_DIR` | `process.cwd()` | Claude Code project directory |
|
|
81
|
+
| `CURSOR_PROJECT_DIR` | (falls through) | Cursor project directory |
|
|
82
|
+
| `CLAUDE_CONFIG_DIR` | `~/.claude` | Claude Code config directory |
|
|
83
|
+
| `CURSOR_CONFIG_DIR` | `~/.cursor` | Cursor config directory |
|
|
84
|
+
|
|
85
|
+
## Limitations
|
|
86
|
+
|
|
87
|
+
- Requires `bun` on PATH. Thatch does not bundle its own runtime.
|
|
88
|
+
- `search` is limited to 10 results. There is no pagination.
|
|
89
|
+
- `prime` requires an external CLI (`opencode`, `agent`, or `claude`)
|
|
90
|
+
on PATH. If none is found, it exits with an error.
|
|
91
|
+
- Infrastructure commands (`mcp`, `buffer-batch`, `buffer-tool`,
|
|
92
|
+
`flush-tools`, `flush-predictions`) are meant for hooks, not manual
|
|
93
|
+
use. Running them by hand can produce confusing output.
|
|
94
|
+
- There is no web UI or dashboard. All inspection is through the CLI
|
|
95
|
+
or the agent's tool calls.
|
|
96
|
+
|
|
97
|
+
See [setup.md](setup.md) for installation and [memory.md](memory.md)
|
|
98
|
+
for the memory system.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Code Review
|
|
2
|
+
|
|
3
|
+
Thatch ships a multi-agent code review pipeline. Eight specialist
|
|
4
|
+
review lenses run in parallel, then a synthesizer verifies and
|
|
5
|
+
deduplicates their findings into a single report.
|
|
6
|
+
|
|
7
|
+
## How it works
|
|
8
|
+
|
|
9
|
+
The coordinator skill (`thatch-code-review`, opencode-only) orchestrates
|
|
10
|
+
the review:
|
|
11
|
+
|
|
12
|
+
1. **Resolve the target**: fetch origin, compute merge-base against
|
|
13
|
+
`origin/main`, support branch/PR/explicit range.
|
|
14
|
+
2. **Gather project context**: PR descriptions, git archaeology,
|
|
15
|
+
ticket references, TODO markers, prior reviews, project memory.
|
|
16
|
+
3. **Research affected workflows**: load `thatch-code-archaeology`,
|
|
17
|
+
trace the code paths the change touches.
|
|
18
|
+
4. **Estimate complexity**: partition the diff into review units.
|
|
19
|
+
5. **Dispatch specialists**: fan out the eight specialists as
|
|
20
|
+
parallel sub-agents, each with the context brief.
|
|
21
|
+
6. **Synthesize**: the synthesizer reads all specialist output,
|
|
22
|
+
verifies each finding (cited text exists, claim is accurate,
|
|
23
|
+
severity is justified), deduplicates by root cause, and produces
|
|
24
|
+
the final report.
|
|
25
|
+
|
|
26
|
+
## The eight specialists
|
|
27
|
+
|
|
28
|
+
| Skill | What it checks |
|
|
29
|
+
|-------|-------------|
|
|
30
|
+
| `thatch-review-pedantic` | Spelling, naming, doc accuracy, specs, guidelines, stale artifacts, structural conventions (file/directory placement). |
|
|
31
|
+
| `thatch-review-acceptance` | UX coherency, behavioral delta, integration effects, user assumptions. |
|
|
32
|
+
| `thatch-review-state-flow` | Module boundaries, implicit state machines, error propagation, separation of concerns. |
|
|
33
|
+
| `thatch-review-economy` | Design simplicity and maintainability: is the complexity earned? Evaluates both the overall change design (forest) and individual touch points (trees) for unnecessary complexity, redundancy, and simpler available alternatives. |
|
|
34
|
+
| `thatch-review-no-slop` | AI writing anti-patterns: change narration, fourth wall breaks, em dashes, hedging, filler. |
|
|
35
|
+
| `thatch-review-breadcrumbs` | Comment narrative: do comments form a coherent outline of the code's behavior? |
|
|
36
|
+
| `thatch-review-mark-and-sweep` | Mechanical change completeness: whole-repo sweep for stragglers after renames, flag removals, API substitutions. |
|
|
37
|
+
| `thatch-review-highlights` | Positive finding detection: clever solutions, cleanup done along the way, documentation that helps. Medium-high bar. |
|
|
38
|
+
|
|
39
|
+
Each specialist is a self-contained static-analysis pass. They can run
|
|
40
|
+
individually or as part of the coordinated review.
|
|
41
|
+
|
|
42
|
+
## Follow-up rounds
|
|
43
|
+
|
|
44
|
+
After the author responds or pushes changes, `thatch-review-followup`
|
|
45
|
+
verifies whether prior findings were adequately addressed before
|
|
46
|
+
deciding whether to re-run the full review. The author must either
|
|
47
|
+
fix the code, prove the finding is not a concern with a checkable
|
|
48
|
+
argument, or file a follow-up ticket with a risk explanation.
|
|
49
|
+
|
|
50
|
+
## Author-side response
|
|
51
|
+
|
|
52
|
+
When you receive review comments on your own PR,
|
|
53
|
+
`thatch-review-response` helps you triage findings (legitimate,
|
|
54
|
+
intentional, false positive, unlikely edge case), fix bugs one by
|
|
55
|
+
one, reply on each thread, and post a top-level summary comment.
|
|
56
|
+
|
|
57
|
+
## Limitations
|
|
58
|
+
|
|
59
|
+
- The coordinator (`thatch-code-review`) is opencode-only. It
|
|
60
|
+
requires sub-agent support to dispatch parallel specialists. On
|
|
61
|
+
Claude Code or Cursor, run specialists individually instead.
|
|
62
|
+
- The review quality depends on the model. Weak models may
|
|
63
|
+
hallucinate findings or miss subtle issues.
|
|
64
|
+
- The synthesizer verifies cited text exists, but it does not
|
|
65
|
+
re-run the specialist's analysis. A specialist that cites
|
|
66
|
+
correctly but reasons incorrectly will pass verification.
|
|
67
|
+
- The review covers the diff (merge-base..HEAD). It does not
|
|
68
|
+
review the entire codebase. Pre-existing bugs are only found
|
|
69
|
+
if the change makes them more reachable.
|
|
70
|
+
|
|
71
|
+
See [skills.md](skills.md) for the full skill list and
|
|
72
|
+
[default-behaviors.md](default-behaviors.md) for the review-adjacent
|
|
73
|
+
behavior rules (day-turnover-review, planning-git-archaeology).
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Deduplication
|
|
2
|
+
|
|
3
|
+
When two memories are very similar, thatch surfaces them as duplicate
|
|
4
|
+
candidates. The agent decides whether to merge, keep both, or mark
|
|
5
|
+
them as distinct. Thatch never merges or deletes memories on its own.
|
|
6
|
+
|
|
7
|
+
## How it works
|
|
8
|
+
|
|
9
|
+
The dedup cycle is agent-driven:
|
|
10
|
+
|
|
11
|
+
1. **Find pairs.** `thatch_find_duplicates` searches for memory pairs
|
|
12
|
+
whose cosine similarity exceeds the threshold (default 0.85). Pairs
|
|
13
|
+
already reviewed via `thatch_dedup_mark_checked` are skipped. Related
|
|
14
|
+
pairs are grouped into clusters: a cluster of 3+ labels usually
|
|
15
|
+
means one topic fragmented across entries that should be consolidated.
|
|
16
|
+
|
|
17
|
+
2. **Classify.** The agent loads the `thatch-dedup-classifier` skill,
|
|
18
|
+
reads both memories, and decides the relationship:
|
|
19
|
+
- **Duplicate**: same information, merge into one.
|
|
20
|
+
- **Supplement**: related but distinct, keep both.
|
|
21
|
+
- **Contradiction**: conflicting information, resolve.
|
|
22
|
+
- **Unrelated**: similar wording, different topic, mark and ignore.
|
|
23
|
+
|
|
24
|
+
3. **Reconcile.** For duplicates, the agent merges by updating one
|
|
25
|
+
memory with `overwrite: true` and deleting the other with
|
|
26
|
+
`thatch_memory_forget`. For contradictions, the agent resolves the
|
|
27
|
+
conflict and updates. For supplements and unrelated pairs, no
|
|
28
|
+
changes needed.
|
|
29
|
+
|
|
30
|
+
4. **Record verdict.** The agent calls `thatch_dedup_mark_checked` with
|
|
31
|
+
the pair labels and the verdict. This stops `find_duplicates` from
|
|
32
|
+
re-reporting the pair.
|
|
33
|
+
|
|
34
|
+
## Verdict lifecycle
|
|
35
|
+
|
|
36
|
+
Verdicts are not permanent. Overwriting either memory with
|
|
37
|
+
`overwrite: true` clears all verdicts involving that memory.
|
|
38
|
+
Deleting a memory with `thatch_memory_forget` also clears its
|
|
39
|
+
verdicts. This means a merged pair can re-flag if the merge creates
|
|
40
|
+
a new similarity with a different memory.
|
|
41
|
+
|
|
42
|
+
This is intended. A merge changes the content, which may create new
|
|
43
|
+
duplicate relationships that should be reviewed.
|
|
44
|
+
|
|
45
|
+
## When it fires
|
|
46
|
+
|
|
47
|
+
The dedup cycle is not automatic. It fires when:
|
|
48
|
+
|
|
49
|
+
- The agent calls `thatch_find_duplicates` directly (you ask, or the
|
|
50
|
+
hygiene report motivates it).
|
|
51
|
+
- The hygiene report at session start shows duplicate candidates,
|
|
52
|
+
prompting the agent to run `find_duplicates` and work through them.
|
|
53
|
+
- The write-time similarity warning fires on `thatch_memory_remember`,
|
|
54
|
+
alerting the agent to near-duplicate entries.
|
|
55
|
+
|
|
56
|
+
## Limitations
|
|
57
|
+
|
|
58
|
+
- Similarity is cosine only. Two memories can say the same thing in
|
|
59
|
+
different words and not be flagged. Two memories with similar wording
|
|
60
|
+
but different meaning can false-flag.
|
|
61
|
+
- The 0.85 threshold is hardcoded. There is no configuration for it.
|
|
62
|
+
- The agent drives the cycle. Thatch never merges or deletes memories
|
|
63
|
+
on its own. If the agent does not call `thatch_find_duplicates`,
|
|
64
|
+
duplicates accumulate.
|
|
65
|
+
- Verdicts are cleared when either memory is updated. A merged pair can
|
|
66
|
+
re-flag if the merge creates a new similarity with a different memory.
|
|
67
|
+
This is intended, but it means dedup is not a one-time fix.
|
|
68
|
+
|
|
69
|
+
See [hygiene.md](hygiene.md) for the hygiene report and
|
|
70
|
+
[memory.md](memory.md) for the memory tools.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Default Behaviors
|
|
2
|
+
|
|
3
|
+
Thatch auto-seeds a set of default behaviors into the global store on
|
|
4
|
+
first run. These are self-discipline rules the agent follows when your
|
|
5
|
+
prompt matches the trigger context. They fire across all projects
|
|
6
|
+
without manual setup.
|
|
7
|
+
|
|
8
|
+
## How it works
|
|
9
|
+
|
|
10
|
+
Default behaviors use the behavior engine (see
|
|
11
|
+
[behavior-engine.md](behavior-engine.md)). On every prompt, thatch
|
|
12
|
+
embeds the text and searches for matching behavior matchers. If a
|
|
13
|
+
matcher scores above the threshold (default 0.60), the behavior is
|
|
14
|
+
injected as a `Situational behaviors` nudge.
|
|
15
|
+
|
|
16
|
+
The rules are plugin-owned. The agent can ham/spam them (adjust
|
|
17
|
+
confidence, controls whether they fire) but cannot change the behavior
|
|
18
|
+
text or trigger. When thatch updates a default behavior in a new
|
|
19
|
+
release, the old version is automatically replaced on next startup.
|
|
20
|
+
|
|
21
|
+
## What ships
|
|
22
|
+
|
|
23
|
+
| Rule | Fires on | What it does |
|
|
24
|
+
|------|----------|-------------|
|
|
25
|
+
| Session wrap-up | "wrapping up," "loose ends," "signing off," "clean up" | Check git status, untracked files, stale artifacts before the session ends. Read-only. |
|
|
26
|
+
| Work finalization | "committing," "merging," "closing out," "ready to merge," "shipping" | Check git status, branch memory consolidation, follow-up TODOs. Read-only. |
|
|
27
|
+
| Research new project | "new project," "unfamiliar codebase," "new ticket" | Check coverage, naming drift, migration evidence. Load archaeology skill. |
|
|
28
|
+
| Day turnover (coding) | "continuing from yesterday," "picking up where I left off" | Check how far origin/main moved since merge-base, suggest rebase. |
|
|
29
|
+
| Day turnover (PR) | "continuing the PR," "picking up the branch" | Check for new upstream review comments on the open PR. |
|
|
30
|
+
| Day turnover (review) | "continuing the review," "picking up the review" | Check for new upstream comments and responses to our comments. |
|
|
31
|
+
| Snag or dead end | "dead end," "red herring," "that did not work" | Save a memory about the wrong path so future sessions skip it. Save-only. |
|
|
32
|
+
| Debugging archaeology | "debugging," "why is this broken," "what changed" | Git archaeology before proposing a fix. Look for orphaned code from removed behavior. |
|
|
33
|
+
| Planning archaeology | "planning a change," "how should we approach" | Git archaeology to understand design intent before proposing changes. |
|
|
34
|
+
|
|
35
|
+
## Version-gated updates
|
|
36
|
+
|
|
37
|
+
Each default behavior carries a version stamp in its rationale text.
|
|
38
|
+
On startup, thatch compares the stored stamp against the current
|
|
39
|
+
package version. If they differ (the behavior was seeded by an older
|
|
40
|
+
release), the old behavior is deleted and the new one is created
|
|
41
|
+
with the updated content. This mirrors how stale skill cleanup
|
|
42
|
+
works: updating a behavior in a new release automatically replaces
|
|
43
|
+
the old version on every install.
|
|
44
|
+
|
|
45
|
+
## Customizing
|
|
46
|
+
|
|
47
|
+
You cannot edit the default behaviors directly (they are
|
|
48
|
+
plugin-managed). But you can:
|
|
49
|
+
|
|
50
|
+
- **Ham/spam them**: Call `thatch_behavior_feedback` with
|
|
51
|
+
`relevant: true` or `relevant: false` when a default behavior
|
|
52
|
+
surfaces. This adjusts confidence and controls whether it fires
|
|
53
|
+
in future sessions.
|
|
54
|
+
- **Add your own**: Call `thatch_behavior_codify` to add custom
|
|
55
|
+
rules for situations the defaults don't cover. Custom behaviors
|
|
56
|
+
coexist with the defaults.
|
|
57
|
+
- **Delete a default**: Call `thatch_behavior_delete` with the
|
|
58
|
+
behavior statement text. This removes it, but it will re-seed on
|
|
59
|
+
next startup if it's still in the defaults list. To permanently
|
|
60
|
+
remove a default, it must be removed from the thatch source code.
|
|
61
|
+
|
|
62
|
+
## Limitations
|
|
63
|
+
|
|
64
|
+
- Default behaviors live in the global store. They fire across all
|
|
65
|
+
projects. There is no per-project default behavior.
|
|
66
|
+
- The trigger is semantic (cosine on the situation text), not keyword
|
|
67
|
+
matching. A prompt that means the same thing but uses different
|
|
68
|
+
words will still match. A prompt that uses the same words but means
|
|
69
|
+
something different may false-fire.
|
|
70
|
+
- The 0.60 threshold is tuned to reduce false fires. If you see
|
|
71
|
+
unwanted behavior nudges, ham them (relevant: false) to lower
|
|
72
|
+
confidence. If you see missing nudges, check the threshold.
|
|
73
|
+
|
|
74
|
+
See [behavior-engine.md](behavior-engine.md) for the full engine
|
|
75
|
+
documentation and [skills.md](skills.md) for the skill system.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Fact Extraction
|
|
2
|
+
|
|
3
|
+
Thatch buffers your session's tool calls and extracts durable facts from
|
|
4
|
+
them into memories. This happens automatically, without any prompt from
|
|
5
|
+
you.
|
|
6
|
+
|
|
7
|
+
## How it works
|
|
8
|
+
|
|
9
|
+
1. **Buffering**: As the session runs, thatch records tool calls (read,
|
|
10
|
+
edit, bash, grep, etc.) in an in-memory ring buffer (up to 20 per
|
|
11
|
+
session). The buffer is a parallel data structure, not derived from
|
|
12
|
+
conversation history.
|
|
13
|
+
|
|
14
|
+
2. **Extraction**: When the session goes idle (after the agent's turn
|
|
15
|
+
completes), the plugin creates a child session and prompts it to run
|
|
16
|
+
the `thatch-fact-extractor` skill. The child fetches the buffered
|
|
17
|
+
tool interactions via `thatch_get_extraction_payload`, extracts
|
|
18
|
+
durable facts, and writes them as memories via
|
|
19
|
+
`thatch_memory_remember`.
|
|
20
|
+
|
|
21
|
+
3. **Cleanup**: When the child finishes, the parent's buffer is
|
|
22
|
+
drained and a toast notification shows the results (`[thatch] new: 2,
|
|
23
|
+
updated: 1`). The child session is deleted.
|
|
24
|
+
|
|
25
|
+
You see the toast. You do not see the nudge or the child session. The
|
|
26
|
+
extraction runs in the background and does not interrupt your
|
|
27
|
+
conversation.
|
|
28
|
+
|
|
29
|
+
## Fallback path (Claude Code and Cursor)
|
|
30
|
+
|
|
31
|
+
On MCP hosts (Claude Code, Cursor), there is no SDK client to create
|
|
32
|
+
child sessions. The extraction nudge is injected into the next user
|
|
33
|
+
message instead. The agent dispatches a sub-agent to run the
|
|
34
|
+
fact-extractor skill, then calls `thatch_extraction_done` to acknowledge.
|
|
35
|
+
|
|
36
|
+
## What gets extracted
|
|
37
|
+
|
|
38
|
+
The fact-extractor skill decides what is worth saving. It looks for:
|
|
39
|
+
|
|
40
|
+
- Durable project facts (architecture, conventions, design decisions)
|
|
41
|
+
- Non-obvious gotchas and footguns
|
|
42
|
+
- Data model relationships
|
|
43
|
+
- User preferences and corrections
|
|
44
|
+
|
|
45
|
+
It does NOT save:
|
|
46
|
+
|
|
47
|
+
- Point-in-time facts (current file locations, line numbers, function
|
|
48
|
+
names)
|
|
49
|
+
- Commit hashes or branch-specific history
|
|
50
|
+
- Anything re-derivable from the codebase faster than recalling it
|
|
51
|
+
|
|
52
|
+
## Configuration
|
|
53
|
+
|
|
54
|
+
- `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true`: enables async
|
|
55
|
+
extraction (child sessions run in the background, fire-and-forget).
|
|
56
|
+
Without this, extraction still works but the child session runs
|
|
57
|
+
synchronously (blocking the turn briefly). Put it in your shell rc,
|
|
58
|
+
`mise.toml [env]`, or `.envrc`. OpenCode only; not needed for
|
|
59
|
+
Claude Code or Cursor.
|
|
60
|
+
|
|
61
|
+
## Limitations
|
|
62
|
+
|
|
63
|
+
- The buffer caps at 20 tool interactions per session. If the session
|
|
64
|
+
runs long, older interactions are dropped before the extraction fires.
|
|
65
|
+
- Extraction only runs when the session goes idle. If the agent is
|
|
66
|
+
continuously active, the buffer grows until 20 and then stops
|
|
67
|
+
recording.
|
|
68
|
+
- The fact-extractor is an LLM. Its quality depends on the model.
|
|
69
|
+
Weak models may miss durable facts or save point-in-time noise.
|
|
70
|
+
- Compaction does not affect the buffer. The buffer is a parallel
|
|
71
|
+
data structure that survives conversation compaction.
|
|
72
|
+
|
|
73
|
+
See [memory.md](memory.md) for the memory system the extractor
|
|
74
|
+
writes to.
|