@jeffober/thatch 0.1.28 → 0.1.29
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/thatch +10 -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/src/prompts.ts
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import type { PredictionNudgeItem } from "./db";
|
|
1
|
+
import type { PredictionNudgeItem, BehaviorNudgeItem } from "./db";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared verb selection for prediction formatting. 0-evidence predictions
|
|
5
|
+
* use the hedged "you may prefer"; predictions with any evidence use the
|
|
6
|
+
* confident "you tend to". Used by both the auto-fire nudge and the
|
|
7
|
+
* prediction_query tool output.
|
|
8
|
+
*/
|
|
9
|
+
export function predictionVerb(evidenceCount: number): string {
|
|
10
|
+
return evidenceCount === 0 ? "you may prefer" : "you tend to";
|
|
11
|
+
}
|
|
2
12
|
|
|
3
13
|
export function systemPrompt(repo: string): string {
|
|
4
14
|
return `# Persistence
|
|
@@ -11,7 +21,9 @@ Tools: thatch_memory_remember, thatch_memory_recall, thatch_memory_list,
|
|
|
11
21
|
thatch_find_duplicates, thatch_dedup_mark_checked,
|
|
12
22
|
thatch_extraction_done, thatch_get_extraction_payload,
|
|
13
23
|
thatch_prediction_query, thatch_prediction_update, thatch_prediction_list,
|
|
14
|
-
thatch_prediction_delete
|
|
24
|
+
thatch_prediction_delete,
|
|
25
|
+
thatch_behavior_codify, thatch_behavior_feedback, thatch_behavior_list,
|
|
26
|
+
thatch_behavior_delete
|
|
15
27
|
|
|
16
28
|
## Stores
|
|
17
29
|
|
|
@@ -37,7 +49,7 @@ you're working in. Prior sessions may have already investigated it.
|
|
|
37
49
|
Thatch ships skills for code review, project investigation, and memory
|
|
38
50
|
workflows. The host auto-discovers them, but reach for them proactively:
|
|
39
51
|
|
|
40
|
-
- \`thatch-code-review\` - full multi-agent code review (dispatches
|
|
52
|
+
- \`thatch-code-review\` - full multi-agent code review (dispatches 8 specialists + synthesizer). Requires sub-agent support.
|
|
41
53
|
- \`thatch-review-followup\` - alternate entrypoint for follow-up review rounds. Verifies whether the author's responses and code changes since your last review adequately addressed prior findings, offers to reply on resolved items, then optionally re-runs the full structured review.
|
|
42
54
|
- \`thatch-code-archaeology\` - investigate an existing feature, debug an unfamiliar area, or begin a new ticket. Explores the code base from multiple angles (data model, state flow, git history, sibling features) before proposing changes. The research skill; pair with \`thatch-coding-workflow\`.
|
|
43
55
|
- \`thatch-change-walkthrough\` - produces a teaching walkthrough of a diff with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + change overlay mirroring the same numbers) and calibrated prose rules. Load the skill for the format and prose rules, not just for the research method.
|
|
@@ -112,6 +124,29 @@ reviewing your changes, or asked you to review their changes or another LLM's
|
|
|
112
124
|
changes. Before creating a new prediction, query for an existing one and
|
|
113
125
|
reinforce or adjust it when possible.
|
|
114
126
|
|
|
127
|
+
## Situational Behaviors
|
|
128
|
+
|
|
129
|
+
A model of your own operational rules is maintained by the behavior engine.
|
|
130
|
+
Scored behaviors may appear above as "Situational behaviors" context; these
|
|
131
|
+
are self-discipline rules you codified for situations where you should react
|
|
132
|
+
in a specific, repeatable way.
|
|
133
|
+
|
|
134
|
+
When surfaced behaviors appear, evaluate each against the current situation:
|
|
135
|
+
- If a behavior is relevant (ham), follow it and call thatch_behavior_feedback
|
|
136
|
+
with relevant: true
|
|
137
|
+
- If a behavior is not relevant (spam), call thatch_behavior_feedback with
|
|
138
|
+
relevant: false
|
|
139
|
+
- This trains the classifier so future nudges are more accurate
|
|
140
|
+
|
|
141
|
+
When you recognize a situation you should react to in a specific, repeatable
|
|
142
|
+
way that is about your own operational discipline (not a user preference):
|
|
143
|
+
1. Use thatch_behavior_codify to create the rule
|
|
144
|
+
2. Use thatch_behavior_feedback when surfaced behaviors fire to ham/spam them
|
|
145
|
+
3. Use thatch_behavior_delete to remove a rule created in error
|
|
146
|
+
|
|
147
|
+
Do not codify rules that make you lazier or less thorough. Rules should encode
|
|
148
|
+
discipline, not shortcuts.
|
|
149
|
+
|
|
115
150
|
## What to Store
|
|
116
151
|
|
|
117
152
|
- **Global store**: user observations, agent personality, system environment
|
|
@@ -204,19 +239,25 @@ When convenient this session (not before addressing the user's request), tend th
|
|
|
204
239
|
* Claude Code they're prefixed as mcp__thatch__memory_remember, but the bare
|
|
205
240
|
* names are what the agent searches for and what the instructions reference.
|
|
206
241
|
*/
|
|
207
|
-
|
|
242
|
+
/**
|
|
243
|
+
* Shared MCP host instructions. Claude Code and Cursor use the same prompt
|
|
244
|
+
* body; only the host name and config file reference differ.
|
|
245
|
+
*/
|
|
246
|
+
function mcpInstructions(host: string, configFile: string): string {
|
|
208
247
|
return `# Persistence
|
|
209
248
|
|
|
210
|
-
Thatch provides persistent memory across
|
|
249
|
+
Thatch provides persistent memory across ${host} sessions. Use it to persist
|
|
211
250
|
knowledge so future sessions can build on what you've already learned.
|
|
212
|
-
Tools are prefixed in
|
|
251
|
+
Tools are prefixed in ${host}: \`mcp__thatch__memory_remember\`,
|
|
213
252
|
\`mcp__thatch__memory_recall\`, \`mcp__thatch__memory_list\`,
|
|
214
253
|
\`mcp__thatch__memory_show\`, \`mcp__thatch__memory_forget\`,
|
|
215
254
|
\`mcp__thatch__store_list\`, \`mcp__thatch__find_duplicates\`,
|
|
216
255
|
\`mcp__thatch__dedup_mark_checked\`, \`mcp__thatch__extraction_done\`,
|
|
217
256
|
\`mcp__thatch__get_extraction_payload\`,
|
|
218
257
|
\`mcp__thatch__prediction_query\`, \`mcp__thatch__prediction_update\`,
|
|
219
|
-
\`mcp__thatch__prediction_list\`, \`mcp__thatch__prediction_delete
|
|
258
|
+
\`mcp__thatch__prediction_list\`, \`mcp__thatch__prediction_delete\`,
|
|
259
|
+
\`mcp__thatch__behavior_codify\`, \`mcp__thatch__behavior_feedback\`,
|
|
260
|
+
\`mcp__thatch__behavior_list\`, \`mcp__thatch__behavior_delete\`. Bare names used below for readability.
|
|
220
261
|
|
|
221
262
|
## Stores
|
|
222
263
|
|
|
@@ -247,7 +288,7 @@ workflows. The host auto-discovers them, but reach for them proactively:
|
|
|
247
288
|
- \`thatch-code-walkthrough\` - produces a teaching walkthrough for a feature/workflow as it stands today with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + Key files) and calibrated prose rules. Also use proactively to draft high-level docs for new or undocumented features (suitable for pkg/README.md or docs/features/<name>.md). Load the skill for the format and prose rules, not just for the research method.
|
|
248
289
|
- \`thatch-review-context\` - gather project context (PRs, tickets, TODOs, deferred work) before a review.
|
|
249
290
|
- \`thatch-review-followup\` - alternate entrypoint for follow-up review rounds. Verifies whether the author's responses and code changes since your last review adequately addressed prior findings, offers to reply on resolved items, then optionally re-runs the full structured review.
|
|
250
|
-
- \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` / \`-mark-and-sweep\` / \`-highlights\` -
|
|
291
|
+
- \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-economy\` / \`-no-slop\` / \`-breadcrumbs\` / \`-mark-and-sweep\` / \`-highlights\` - eight specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
|
|
251
292
|
- \`thatch-project-primer\` - investigate a new project and write foundational memories.
|
|
252
293
|
- \`thatch-session-reflection\` - record what you learned at end of session.
|
|
253
294
|
- \`thatch-fact-extractor\` - extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
|
|
@@ -302,6 +343,29 @@ reviewing your changes, or asked you to review their changes or another LLM's
|
|
|
302
343
|
changes. Before creating a new prediction, query for an existing one and
|
|
303
344
|
reinforce or adjust it when possible.
|
|
304
345
|
|
|
346
|
+
## Situational Behaviors
|
|
347
|
+
|
|
348
|
+
A model of your own operational rules is maintained by the behavior engine.
|
|
349
|
+
Scored behaviors may appear above as "Situational behaviors" context; these
|
|
350
|
+
are self-discipline rules you codified for situations where you should react
|
|
351
|
+
in a specific, repeatable way.
|
|
352
|
+
|
|
353
|
+
When surfaced behaviors appear, evaluate each against the current situation:
|
|
354
|
+
- If a behavior is relevant (ham), follow it and call behavior_feedback
|
|
355
|
+
with relevant: true
|
|
356
|
+
- If a behavior is not relevant (spam), call behavior_feedback with
|
|
357
|
+
relevant: false
|
|
358
|
+
- This trains the classifier so future nudges are more accurate
|
|
359
|
+
|
|
360
|
+
When you recognize a situation you should react to in a specific, repeatable
|
|
361
|
+
way that is about your own operational discipline (not a user preference):
|
|
362
|
+
1. Use behavior_codify to create the rule
|
|
363
|
+
2. Use behavior_feedback when surfaced behaviors fire to ham/spam them
|
|
364
|
+
3. Use behavior_delete to remove a rule created in error
|
|
365
|
+
|
|
366
|
+
Do not codify rules that make you lazier or less thorough. Rules should encode
|
|
367
|
+
discipline, not shortcuts.
|
|
368
|
+
|
|
305
369
|
## What to Store
|
|
306
370
|
|
|
307
371
|
- **Global store**: user observations, agent personality, system environment
|
|
@@ -324,7 +388,7 @@ reinforce or adjust it when possible.
|
|
|
324
388
|
## What NOT to Store
|
|
325
389
|
|
|
326
390
|
Session-specific context, incomplete/unverified info, anything already in
|
|
327
|
-
|
|
391
|
+
${configFile}, speculative conclusions.
|
|
328
392
|
|
|
329
393
|
Apply the durability test: will this still be true and useful in a future
|
|
330
394
|
session that knows nothing about this branch, commit, or session? If not,
|
|
@@ -361,6 +425,10 @@ and the tool returns an error. Pass \`archived: true\` to keep it archived,
|
|
|
361
425
|
"Forget X" - \`memory_recall\` to find it, then \`memory_forget\`.`;
|
|
362
426
|
}
|
|
363
427
|
|
|
428
|
+
export function claudeInstructions(): string {
|
|
429
|
+
return mcpInstructions("Claude Code", "CLAUDE.md");
|
|
430
|
+
}
|
|
431
|
+
|
|
364
432
|
/**
|
|
365
433
|
* The SessionStart hook stdout. Claude Code feeds stdout from SessionStart
|
|
366
434
|
* hooks directly into Claude's context as a system reminder. This text tells
|
|
@@ -401,6 +469,10 @@ export function claudeWriteNudge(): string {
|
|
|
401
469
|
* dispatch a sub-agent that calls get_extraction_payload to fetch the queued
|
|
402
470
|
* interactions as a tool response. This keeps the full payload out of the
|
|
403
471
|
* main session's context window.
|
|
472
|
+
*
|
|
473
|
+
* Call extractionNudgeOpencode for the opencode plugin path (task tool with
|
|
474
|
+
* background parameter) or extractionNudgeMcp for the Claude Code/Cursor
|
|
475
|
+
* CLI path (generic sub-agent wording).
|
|
404
476
|
*/
|
|
405
477
|
export function extractionNudge(
|
|
406
478
|
count: number,
|
|
@@ -408,22 +480,45 @@ export function extractionNudge(
|
|
|
408
480
|
toolName: string,
|
|
409
481
|
sessionID: string,
|
|
410
482
|
): string {
|
|
411
|
-
const plural = count === 1 ? "" : "s";
|
|
412
|
-
// opencode's task tool has a `background` parameter (requires
|
|
413
|
-
// OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true) that launches the sub-agent
|
|
414
|
-
// asynchronously - the call returns immediately and the session is notified
|
|
415
|
-
// on completion. Naming the parameter gives the model a direct hit on the tool
|
|
416
|
-
// schema it sees. MCP hosts (Claude Code, Cursor) keep generic sub-agent
|
|
417
|
-
// wording because their background mechanisms differ and are not exposed as a
|
|
418
|
-
// per-call parameter in the same way.
|
|
419
483
|
const isOpencode = toolName.startsWith("thatch_");
|
|
420
|
-
|
|
421
|
-
?
|
|
422
|
-
:
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
484
|
+
return isOpencode
|
|
485
|
+
? extractionNudgeOpencode(count, missedCount, sessionID)
|
|
486
|
+
: extractionNudgeMcp(count, missedCount, sessionID);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function extractionNudgeOpencode(
|
|
490
|
+
count: number,
|
|
491
|
+
missedCount: number,
|
|
492
|
+
sessionID: string,
|
|
493
|
+
): string {
|
|
494
|
+
const plural = count === 1 ? "" : "s";
|
|
495
|
+
const dispatch = "Dispatch a task with background: true";
|
|
496
|
+
const drainTool = "thatch_extraction_done";
|
|
497
|
+
const fetchTool = "thatch_get_extraction_payload";
|
|
498
|
+
return buildExtractionNudge(count, missedCount, plural, dispatch, drainTool, fetchTool, sessionID);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
function extractionNudgeMcp(
|
|
502
|
+
count: number,
|
|
503
|
+
missedCount: number,
|
|
504
|
+
sessionID: string,
|
|
505
|
+
): string {
|
|
506
|
+
const plural = count === 1 ? "" : "s";
|
|
507
|
+
const dispatch = "Spawn a background sub-agent";
|
|
508
|
+
const drainTool = "mcp__thatch__extraction_done";
|
|
509
|
+
const fetchTool = "mcp__thatch__get_extraction_payload";
|
|
510
|
+
return buildExtractionNudge(count, missedCount, plural, dispatch, drainTool, fetchTool, sessionID);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
function buildExtractionNudge(
|
|
514
|
+
count: number,
|
|
515
|
+
missedCount: number,
|
|
516
|
+
plural: string,
|
|
517
|
+
dispatch: string,
|
|
518
|
+
drainTool: string,
|
|
519
|
+
fetchTool: string,
|
|
520
|
+
sessionID: string,
|
|
521
|
+
): string {
|
|
427
522
|
const acknowledge = `After dispatching, call ${drainTool} to acknowledge.`;
|
|
428
523
|
const subAgentPrompt = `Call ${fetchTool} with session_id "${sessionID}" to retrieve the queued tool interactions, then run the thatch-fact-extractor skill to extract durable facts. Call ${drainTool} with session_id "${sessionID}" when finished, even if nothing was worth saving.`;
|
|
429
524
|
|
|
@@ -465,15 +560,6 @@ export function extractionDirectPrompt(count: number, sessionID: string): string
|
|
|
465
560
|
`Call thatch_extraction_done with session_id "${sessionID}" when finished, even if nothing was worth saving.`;
|
|
466
561
|
}
|
|
467
562
|
|
|
468
|
-
/**
|
|
469
|
-
* Backwards-compatible wrapper for the Claude Code/Cursor CLI path.
|
|
470
|
-
* Maintained for any external callers; bin/thatch should use extractionNudge
|
|
471
|
-
* directly with a missedCount from extract-queue.ts.
|
|
472
|
-
*/
|
|
473
|
-
export function claudeExtractionNudge(count: number, sessionID: string): string {
|
|
474
|
-
return extractionNudge(count, 0, "mcp__thatch__memory_remember", sessionID);
|
|
475
|
-
}
|
|
476
|
-
|
|
477
563
|
/**
|
|
478
564
|
* Static instructions for Cursor's AGENTS.md. Same contract as
|
|
479
565
|
* claudeInstructions() - the host loads this at every session start, and the
|
|
@@ -482,160 +568,7 @@ export function claudeExtractionNudge(count: number, sessionID: string): string
|
|
|
482
568
|
* same protocol.
|
|
483
569
|
*/
|
|
484
570
|
export function cursorInstructions(): string {
|
|
485
|
-
return
|
|
486
|
-
|
|
487
|
-
Thatch provides persistent memory across Cursor sessions. Use it to persist
|
|
488
|
-
knowledge so future sessions can build on what you've already learned.
|
|
489
|
-
Tools are prefixed in Cursor: \`mcp__thatch__memory_remember\`,
|
|
490
|
-
\`mcp__thatch__memory_recall\`, \`mcp__thatch__memory_list\`,
|
|
491
|
-
\`mcp__thatch__memory_show\`, \`mcp__thatch__memory_forget\`,
|
|
492
|
-
\`mcp__thatch__store_list\`, \`mcp__thatch__find_duplicates\`,
|
|
493
|
-
\`mcp__thatch__dedup_mark_checked\`, \`mcp__thatch__extraction_done\`,
|
|
494
|
-
\`mcp__thatch__get_extraction_payload\`,
|
|
495
|
-
\`mcp__thatch__prediction_query\`, \`mcp__thatch__prediction_update\`,
|
|
496
|
-
\`mcp__thatch__prediction_list\`, \`mcp__thatch__prediction_delete\`. Bare names used below for readability.
|
|
497
|
-
|
|
498
|
-
## Stores
|
|
499
|
-
|
|
500
|
-
- \`global\`: user preferences, personality, system environment (shared across projects)
|
|
501
|
-
- Per-project stores: project-specific knowledge (auto-detected from git remote)
|
|
502
|
-
- Use \`mcp__thatch__store_list\` to see active stores
|
|
503
|
-
|
|
504
|
-
Memories can be scoped to a git branch via the \`branch\` param (feature design,
|
|
505
|
-
WIP, PR status). Unscoped memories are project-wide and always included in search.
|
|
506
|
-
|
|
507
|
-
## Session Startup
|
|
508
|
-
|
|
509
|
-
1. \`memory_recall\` "user preferences and personality" (global store)
|
|
510
|
-
2. \`memory_recall\` "project architecture and conventions" (project store)
|
|
511
|
-
3. If on a non-main branch, \`memory_recall\` with the branch name
|
|
512
|
-
4. \`memory_list\` and \`store_list\` to see what's available
|
|
513
|
-
|
|
514
|
-
Before diving into code, \`memory_recall\` with a query relevant to the area
|
|
515
|
-
you're working in. Prior sessions may have already investigated it.
|
|
516
|
-
|
|
517
|
-
## Skills
|
|
518
|
-
|
|
519
|
-
Thatch ships skills for code review, project investigation, and memory
|
|
520
|
-
workflows. The host auto-discovers them, but reach for them proactively:
|
|
521
|
-
|
|
522
|
-
- \`thatch-code-archaeology\` - investigate an existing feature, debug an unfamiliar area, or begin a new ticket. Explores the code base from multiple angles (data model, state flow, git history, sibling features) before proposing changes. The research skill; pair with \`thatch-coding-workflow\`.
|
|
523
|
-
- \`thatch-change-walkthrough\` - produces a teaching walkthrough of a diff with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + change overlay mirroring the same numbers) and calibrated prose rules. Load the skill for the format and prose rules, not just for the research method.
|
|
524
|
-
- \`thatch-code-walkthrough\` - produces a teaching walkthrough for a feature/workflow as it stands today with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + Key files) and calibrated prose rules. Also use proactively to draft high-level docs for new or undocumented features (suitable for pkg/README.md or docs/features/<name>.md). Load the skill for the format and prose rules, not just for the research method.
|
|
525
|
-
- \`thatch-review-context\` - gather project context (PRs, tickets, TODOs, deferred work) before a review.
|
|
526
|
-
- \`thatch-review-followup\` - alternate entrypoint for follow-up review rounds. Verifies whether the author's responses and code changes since your last review adequately addressed prior findings, offers to reply on resolved items, then optionally re-runs the full structured review.
|
|
527
|
-
- \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` / \`-mark-and-sweep\` / \`-highlights\` - seven specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
|
|
528
|
-
- \`thatch-project-primer\` - investigate a new project and write foundational memories.
|
|
529
|
-
- \`thatch-session-reflection\` - record what you learned at end of session.
|
|
530
|
-
- \`thatch-fact-extractor\` - extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
|
|
531
|
-
- \`thatch-dedup-classifier\` - resolve duplicate memory pairs from \`find_duplicates\`.
|
|
532
|
-
- \`thatch-pr-description\` - draft a PR description with SYNOPSIS / PURPOSE / DESCRIPTION / WALK-THROUGH / NOTES, using bold and italic emphasis on the phrases that carry the meaning.
|
|
533
|
-
- \`thatch-ticket-description\` - draft a ticket, issue, or work item (Linear or Jira) with clear sections and bold/italic emphasis for scanning.
|
|
534
|
-
- \`thatch-split-overlarge-pr\` - split already-completed work from an overlarge PR into human-reviewable, release-safe PRs targeting main.
|
|
535
|
-
- \`thatch-review-response\` - respond to code review on the user's own PR. Triage findings, fix bugs one by one, reply on each thread, then post a top-level summary comment.
|
|
536
|
-
|
|
537
|
-
## When to Write
|
|
538
|
-
|
|
539
|
-
**One signal is enough.** Do not wait for confirmation.
|
|
540
|
-
Save immediately on: feedback, preferences, corrections, emotional signals,
|
|
541
|
-
new project knowledge, conventions, architectural decisions, investigation
|
|
542
|
-
results that produced durable knowledge (not point-in-time facts about the
|
|
543
|
-
current state of the code).
|
|
544
|
-
|
|
545
|
-
## Before Responding
|
|
546
|
-
|
|
547
|
-
Before composing a final response after substantial work this turn - multiple
|
|
548
|
-
rounds of tool calls for investigation, debugging, or code-writing - check
|
|
549
|
-
whether you've discovered knowledge worth persisting. Use memory_recall to
|
|
550
|
-
check for duplicates, then memory_remember for new findings. Then deliver
|
|
551
|
-
your response.
|
|
552
|
-
|
|
553
|
-
## User Decision Model
|
|
554
|
-
|
|
555
|
-
A statistical model of the user's decision-making preferences is maintained by
|
|
556
|
-
the prediction engine. Scored predictions may appear above as "User decision
|
|
557
|
-
model" context; these are learned patterns about what the user tends to
|
|
558
|
-
prefer in specific situations.
|
|
559
|
-
|
|
560
|
-
When facing a judgment call about scope, appropriateness, or methodology:
|
|
561
|
-
- If a prediction is strong (high confidence, sufficient evidence), follow it
|
|
562
|
-
- If predictions conflict or confidence is thin, surface the uncertainty
|
|
563
|
-
naturally: "I think you usually prefer X here, but I'm not sure; what do
|
|
564
|
-
you want?"
|
|
565
|
-
- When the user responds to a surfaced prediction, use prediction_update
|
|
566
|
-
to reinforce or weaken the model
|
|
567
|
-
|
|
568
|
-
When the user corrects you, answers your question, or provides a clear signal
|
|
569
|
-
about their preferences:
|
|
570
|
-
1. Use prediction_query to check for existing matchers and predictions
|
|
571
|
-
2. Use prediction_update to create, reinforce, or weaken a prediction
|
|
572
|
-
3. Use prediction_delete to remove a prediction created in error
|
|
573
|
-
|
|
574
|
-
Code review discussions are high-signal prediction material. When working
|
|
575
|
-
through potential review comments with the user, watch for preferences about
|
|
576
|
-
review threshold, severity, tone, evidence, scope, false positives, or what is
|
|
577
|
-
worth posting. This applies whether the user invoked a review skill, is
|
|
578
|
-
reviewing your changes, or asked you to review their changes or another LLM's
|
|
579
|
-
changes. Before creating a new prediction, query for an existing one and
|
|
580
|
-
reinforce or adjust it when possible.
|
|
581
|
-
|
|
582
|
-
## What to Store
|
|
583
|
-
|
|
584
|
-
- **Global store**: user observations, agent personality, system environment
|
|
585
|
-
- **Project store**: repo organization, infrastructure, languages/frameworks,
|
|
586
|
-
component relationships, conventions, operational playbooks
|
|
587
|
-
- **Branch-scoped**: branch purpose, feature design decisions, PR status,
|
|
588
|
-
temporary workarounds
|
|
589
|
-
- **Insights**: Save non-obvious gotchas, patterns, and architectural
|
|
590
|
-
lessons discovered during implementation, but only if they remain true
|
|
591
|
-
across sessions. Never prompt the user; just do it.
|
|
592
|
-
|
|
593
|
-
## How to Write
|
|
594
|
-
|
|
595
|
-
- \`memory_recall\` first to check for duplicates. Use overwrite: true to
|
|
596
|
-
update rather than creating a new entry.
|
|
597
|
-
- One topic per memory. Write for a future instance with zero current context.
|
|
598
|
-
- Confidence 1-2: single signal. 5-6: moderate. 9: explicitly stated.
|
|
599
|
-
10: hard constraint.
|
|
600
|
-
|
|
601
|
-
## What NOT to Store
|
|
602
|
-
|
|
603
|
-
Session-specific context, incomplete/unverified info, anything already in
|
|
604
|
-
AGENTS.md, speculative conclusions.
|
|
605
|
-
|
|
606
|
-
Apply the durability test: will this still be true and useful in a future
|
|
607
|
-
session that knows nothing about this branch, commit, or session? If not,
|
|
608
|
-
do not save it. Do not store:
|
|
609
|
-
- Point-in-time values (migration indices, line numbers, file counts) that
|
|
610
|
-
will be stale by next session
|
|
611
|
-
- Commit hashes and branch-specific history narratives. Git is the source
|
|
612
|
-
of truth for this; do not duplicate it in memory
|
|
613
|
-
- Anything re-derivable from the codebase faster than recalling it (current
|
|
614
|
-
file locations, type signatures, function names)
|
|
615
|
-
|
|
616
|
-
## Archived Memories
|
|
617
|
-
|
|
618
|
-
Memories can be marked \`archived\` - a flag for stable, long-term historical
|
|
619
|
-
records that should not trigger hygiene nudges (stale, orphaned, duplicate).
|
|
620
|
-
Archived memories are excluded from search/recall results by default; pass
|
|
621
|
-
\`includeArchived: true\` to surface them for archaeological dives.
|
|
622
|
-
|
|
623
|
-
When a branch is merged or about to be deleted, consolidate its branch-scoped
|
|
624
|
-
memories into a single archived memory scoped to that same branch (preserving
|
|
625
|
-
provenance). Capture intent, design decisions, review back-and-forth, PR
|
|
626
|
-
number, unexpected pivots - the kind of git-archaeology context that explains
|
|
627
|
-
_why_ the code looks the way it does a year from now. Then memory_forget the
|
|
628
|
-
originals. The archived record outlives the branch. Future sessions searching
|
|
629
|
-
with \`includeArchived: true\` can pull it up when investigating ambiguous code.
|
|
630
|
-
|
|
631
|
-
Updating an archived memory requires passing \`archived\` explicitly - omit it
|
|
632
|
-
and the tool returns an error. Pass \`archived: true\` to keep it archived,
|
|
633
|
-
\`archived: false\` to unarchive.
|
|
634
|
-
|
|
635
|
-
## Explicit Requests
|
|
636
|
-
|
|
637
|
-
"Remember X" - save immediately.
|
|
638
|
-
"Forget X" - \`memory_recall\` to find it, then \`memory_forget\`.`;
|
|
571
|
+
return mcpInstructions("Cursor", "AGENTS.md");
|
|
639
572
|
}
|
|
640
573
|
|
|
641
574
|
// ---------------------------------------------------------------------------
|
|
@@ -685,8 +618,22 @@ function formatRecallNudge(matches: NudgeMatch[], toolName: string): string {
|
|
|
685
618
|
|
|
686
619
|
export function predictionNudge(items: PredictionNudgeItem[]): string {
|
|
687
620
|
const lines = items.map((p) => {
|
|
688
|
-
const verb = p.evidence_count
|
|
621
|
+
const verb = predictionVerb(p.evidence_count);
|
|
689
622
|
return `- [${p.confidence.toFixed(2)} conf, ${p.evidence_count} tests] When ${p.matcher_description}: ${verb} ${p.statement}`;
|
|
690
623
|
});
|
|
691
624
|
return `[thatch] User decision model\n${lines.join("\n")}`;
|
|
692
625
|
}
|
|
626
|
+
|
|
627
|
+
// ---------------------------------------------------------------------------
|
|
628
|
+
// Behavior nudge: auto-injected when behavior matchers fire for the user's
|
|
629
|
+
// prompt. Descriptive, not directive: the system prompt instructions govern
|
|
630
|
+
// how to act (follow relevant rules, ham/spam each match via behavior_feedback).
|
|
631
|
+
// ---------------------------------------------------------------------------
|
|
632
|
+
|
|
633
|
+
export function behaviorNudge(items: BehaviorNudgeItem[]): string {
|
|
634
|
+
const lines = items.map((b) => {
|
|
635
|
+
const verb = b.evidence_count === 0 ? "consider" : "do";
|
|
636
|
+
return `- [${b.confidence.toFixed(2)} conf, ${b.evidence_count} tests] When ${b.matcher_description}: ${verb} ${b.statement}`;
|
|
637
|
+
});
|
|
638
|
+
return `[thatch] Situational behaviors\n${lines.join("\n")}`;
|
|
639
|
+
}
|