@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.
Files changed (60) hide show
  1. package/README.md +24 -10
  2. package/artifacts/skills/thatch-code-review.md +9 -7
  3. package/artifacts/skills/thatch-review-economy.md +97 -0
  4. package/artifacts/skills/thatch-review-followup.md +1 -1
  5. package/artifacts/skills/thatch-review-synthesizer.md +15 -5
  6. package/bin/qa-run +38 -0
  7. package/bin/thatch +10 -5
  8. package/docs/dev/README.md +71 -18
  9. package/docs/dev/features/README.md +33 -0
  10. package/docs/dev/features/behavior-engine.md +271 -0
  11. package/docs/dev/features/cicd.md +89 -0
  12. package/docs/dev/features/cli.md +81 -0
  13. package/docs/dev/features/compaction-recovery.md +48 -0
  14. package/docs/dev/features/database.md +244 -0
  15. package/docs/dev/features/deduplication.md +102 -0
  16. package/docs/dev/features/extraction.md +253 -0
  17. package/docs/dev/features/hygiene.md +81 -0
  18. package/docs/dev/features/memory-store.md +154 -0
  19. package/docs/dev/features/multi-host.md +228 -0
  20. package/docs/dev/features/nudge-pipeline.md +282 -0
  21. package/docs/dev/features/prediction-engine.md +253 -0
  22. package/docs/dev/features/qa-system.md +205 -0
  23. package/docs/dev/features/session-lifecycle.md +110 -0
  24. package/docs/dev/features/setup.md +199 -0
  25. package/docs/dev/features/sideband.md +104 -0
  26. package/docs/dev/gotchas.md +3 -3
  27. package/docs/dev/mcp-parity.md +6 -4
  28. package/docs/dev/setup-and-hooks.md +4 -4
  29. package/docs/dev/skills.md +10 -8
  30. package/docs/plans/README.md +2 -2
  31. package/docs/user/README.md +58 -20
  32. package/docs/user/behavior-engine.md +85 -0
  33. package/docs/user/cli.md +98 -0
  34. package/docs/user/code-review.md +73 -0
  35. package/docs/user/deduplication.md +70 -0
  36. package/docs/user/default-behaviors.md +75 -0
  37. package/docs/user/extraction.md +74 -0
  38. package/docs/user/hygiene.md +76 -0
  39. package/docs/user/memory.md +81 -0
  40. package/docs/user/prediction-engine.md +87 -0
  41. package/docs/user/setup.md +110 -0
  42. package/docs/user/skills.md +97 -0
  43. package/package.json +2 -2
  44. package/src/behavior.ts +120 -0
  45. package/src/db.ts +160 -417
  46. package/src/embeddings.ts +0 -41
  47. package/src/extraction.ts +2 -2
  48. package/src/git.ts +3 -1
  49. package/src/index.ts +55 -9
  50. package/src/mcp.ts +30 -1
  51. package/src/prediction.ts +127 -0
  52. package/src/prompts.ts +135 -188
  53. package/src/scoring-engine.ts +374 -0
  54. package/src/seed-behaviors.ts +339 -0
  55. package/src/setup.ts +2 -6
  56. package/src/sideband.ts +36 -8
  57. package/src/skills.ts +1 -0
  58. package/src/tool-defs.ts +172 -25
  59. package/src/vector-math.ts +30 -0
  60. 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 7 specialists + synthesizer). Requires sub-agent support.
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
- export function claudeInstructions(): string {
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 Claude Code sessions. Use it to persist
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 Claude Code: \`mcp__thatch__memory_remember\`,
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\`. Bare names used below for readability.
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\` - seven specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
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
- CLAUDE.md, speculative conclusions.
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
- const dispatch = isOpencode
421
- ? "Dispatch a task with background: true"
422
- : "Spawn a background sub-agent";
423
- const drainTool = isOpencode ? "thatch_extraction_done" : "mcp__thatch__extraction_done";
424
- const fetchTool = isOpencode
425
- ? "thatch_get_extraction_payload"
426
- : "mcp__thatch__get_extraction_payload";
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 `# Persistence
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 === 0 ? "you may prefer" : "you tend to";
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
+ }