gitmem-mcp 1.6.5 → 1.6.6
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/CHANGELOG.md +5 -0
- package/dist/tools/recall.d.ts +10 -0
- package/dist/tools/recall.js +64 -48
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.6.6] - 2026-06-27
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **`recall` stubs low-confidence scars to cut wasted tokens**: scars scoring below the `0.55` similarity threshold (already flagged `[low confidence]`, ~66% N/A rate in that band) now render as a one-line stub — title, severity, score, short id, and the `[low confidence]` tag — instead of hydrating their full body (description, counter-arguments, applies-when, why-this-matters, action-protocol, self-check, related triples). High-confidence scars (≥ 0.55) are unchanged, and blocking-verification scars always render in full regardless of score. The `0.55` cutoff is now a single named constant (`LOW_CONFIDENCE_THRESHOLD`) shared by the tag and the stub so they can't drift apart. The scar's id stays visible, so an agent can still pull detail on demand. (GIT-49)
|
|
14
|
+
|
|
10
15
|
## [1.6.5] - 2026-06-27
|
|
11
16
|
|
|
12
17
|
### Fixed
|
package/dist/tools/recall.d.ts
CHANGED
|
@@ -15,6 +15,16 @@
|
|
|
15
15
|
import type { KnowledgeTriple } from "../services/supabase-client.js";
|
|
16
16
|
import { type ScarWithVariant } from "../services/variant-assignment.js";
|
|
17
17
|
import type { Project, PerformanceData } from "../types/index.js";
|
|
18
|
+
/**
|
|
19
|
+
* Confidence cutoff for scar rendering.
|
|
20
|
+
*
|
|
21
|
+
* Matches below this similarity are flagged `[low confidence]` and, per the
|
|
22
|
+
* 1.5.0 UX-audit calibration, are N/A ~66% of the time. They pass the pro-tier
|
|
23
|
+
* 0.45 inclusion filter but are rendered as stubs (header only) rather than full
|
|
24
|
+
* bodies — the tag boundary and the stub boundary share this constant so they
|
|
25
|
+
* can never drift apart.
|
|
26
|
+
*/
|
|
27
|
+
export declare const LOW_CONFIDENCE_THRESHOLD = 0.55;
|
|
18
28
|
/**
|
|
19
29
|
* Parameters for recall tool
|
|
20
30
|
*/
|
package/dist/tools/recall.js
CHANGED
|
@@ -27,6 +27,16 @@ import { getSessionPath } from "../services/gitmem-dir.js";
|
|
|
27
27
|
import { wrapDisplay, SEV, dimText, ANSI } from "../services/display-protocol.js";
|
|
28
28
|
import { formatNudgeHeader } from "../services/nudge-variants.js";
|
|
29
29
|
import { fetchDismissalCounts } from "../services/behavioral-decay.js";
|
|
30
|
+
/**
|
|
31
|
+
* Confidence cutoff for scar rendering.
|
|
32
|
+
*
|
|
33
|
+
* Matches below this similarity are flagged `[low confidence]` and, per the
|
|
34
|
+
* 1.5.0 UX-audit calibration, are N/A ~66% of the time. They pass the pro-tier
|
|
35
|
+
* 0.45 inclusion filter but are rendered as stubs (header only) rather than full
|
|
36
|
+
* bodies — the tag boundary and the stub boundary share this constant so they
|
|
37
|
+
* can never drift apart.
|
|
38
|
+
*/
|
|
39
|
+
export const LOW_CONFIDENCE_THRESHOLD = 0.55;
|
|
30
40
|
/**
|
|
31
41
|
* Format scars into a readable response for Claude
|
|
32
42
|
*/
|
|
@@ -80,8 +90,8 @@ No past lessons match this plan closely enough. Scars accumulate as you work —
|
|
|
80
90
|
for (const scar of scars) {
|
|
81
91
|
const sev = SEV[scar.severity] || "[?]";
|
|
82
92
|
const starterTag = scar.is_starter ? ` ${dimText("[starter]")}` : "";
|
|
83
|
-
// Confidence tier: marginal matches
|
|
84
|
-
const confidenceTag = scar.similarity <
|
|
93
|
+
// Confidence tier: marginal matches get flagged — 66% N/A rate below the threshold
|
|
94
|
+
const confidenceTag = scar.similarity < LOW_CONFIDENCE_THRESHOLD ? ` ${dimText("[low confidence]")}` : "";
|
|
85
95
|
// Pro: decay tag for scars with reduced behavioral relevance
|
|
86
96
|
const decayTag = hasProInsights() && scar.decay_multiplier !== undefined && scar.decay_multiplier < 0.8
|
|
87
97
|
? ` ${dimText(`[decay: ${Math.round(scar.decay_multiplier * 100)}%]`)}`
|
|
@@ -94,55 +104,61 @@ No past lessons match this plan closely enough. Scars accumulate as you work —
|
|
|
94
104
|
lines.push(` _[dismissed ${counts.dismissed}/${counts.surfaced} times — re-evaluate whether this still applies]_`);
|
|
95
105
|
}
|
|
96
106
|
}
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (scar.counter_arguments.length > 0) {
|
|
107
|
-
lines.push("");
|
|
108
|
-
lines.push("*You might think:*");
|
|
109
|
-
for (const counter of scar.counter_arguments.slice(0, 2)) {
|
|
110
|
-
lines.push(` - ${counter}`);
|
|
107
|
+
// Stub low-confidence scars: render header only, skip the heavy body.
|
|
108
|
+
// ~66% of sub-threshold matches are N/A, so their full bodies are wasted
|
|
109
|
+
// tokens. Blocking-verification scars always render full regardless of score.
|
|
110
|
+
const isStub = scar.similarity < LOW_CONFIDENCE_THRESHOLD && !scar.required_verification?.blocking;
|
|
111
|
+
if (!isStub) {
|
|
112
|
+
// Use variant enforcement text if available (blind to variant name)
|
|
113
|
+
if (scar.variant_info?.has_variants && scar.variant_info.variant) {
|
|
114
|
+
const variantText = formatVariantEnforcement(scar.variant_info.variant, scar.title);
|
|
115
|
+
lines.push(variantText);
|
|
111
116
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
lines.push("*Applies when:* " + scar.applies_when.slice(0, 3).join(", "));
|
|
116
|
-
}
|
|
117
|
-
// Render LLM-cooperative enforcement fields
|
|
118
|
-
if (scar.why_this_matters) {
|
|
119
|
-
lines.push("");
|
|
120
|
-
lines.push(`**Why this matters:** ${scar.why_this_matters}`);
|
|
121
|
-
}
|
|
122
|
-
if (scar.action_protocol && scar.action_protocol.length > 0) {
|
|
123
|
-
lines.push("");
|
|
124
|
-
lines.push("**Action Protocol:**");
|
|
125
|
-
scar.action_protocol.forEach((step, i) => {
|
|
126
|
-
lines.push(` ${i + 1}. ${step}`);
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
if (scar.self_check_criteria && scar.self_check_criteria.length > 0) {
|
|
130
|
-
lines.push("");
|
|
131
|
-
lines.push("**Self-Check:**");
|
|
132
|
-
for (const criterion of scar.self_check_criteria) {
|
|
133
|
-
lines.push(` - [ ] ${criterion}`);
|
|
117
|
+
else {
|
|
118
|
+
// Legacy path: use original scar description
|
|
119
|
+
lines.push(scar.description);
|
|
134
120
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
121
|
+
if (scar.counter_arguments.length > 0) {
|
|
122
|
+
lines.push("");
|
|
123
|
+
lines.push("*You might think:*");
|
|
124
|
+
for (const counter of scar.counter_arguments.slice(0, 2)) {
|
|
125
|
+
lines.push(` - ${counter}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (scar.applies_when.length > 0) {
|
|
129
|
+
lines.push("");
|
|
130
|
+
lines.push("*Applies when:* " + scar.applies_when.slice(0, 3).join(", "));
|
|
131
|
+
}
|
|
132
|
+
// Render LLM-cooperative enforcement fields
|
|
133
|
+
if (scar.why_this_matters) {
|
|
134
|
+
lines.push("");
|
|
135
|
+
lines.push(`**Why this matters:** ${scar.why_this_matters}`);
|
|
136
|
+
}
|
|
137
|
+
if (scar.action_protocol && scar.action_protocol.length > 0) {
|
|
138
|
+
lines.push("");
|
|
139
|
+
lines.push("**Action Protocol:**");
|
|
140
|
+
scar.action_protocol.forEach((step, i) => {
|
|
141
|
+
lines.push(` ${i + 1}. ${step}`);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (scar.self_check_criteria && scar.self_check_criteria.length > 0) {
|
|
145
|
+
lines.push("");
|
|
146
|
+
lines.push("**Self-Check:**");
|
|
147
|
+
for (const criterion of scar.self_check_criteria) {
|
|
148
|
+
lines.push(` - [ ] ${criterion}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Render related knowledge triples
|
|
152
|
+
if (scar.related_triples && scar.related_triples.length > 0) {
|
|
153
|
+
lines.push("");
|
|
154
|
+
lines.push("*Related knowledge:*");
|
|
155
|
+
for (const triple of scar.related_triples) {
|
|
156
|
+
lines.push(` - ${triple.subject} **${triple.predicate}** ${triple.object}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (scar.source_issue) {
|
|
160
|
+
lines.push(`*Source:* ${scar.source_issue}`);
|
|
142
161
|
}
|
|
143
|
-
}
|
|
144
|
-
if (scar.source_issue) {
|
|
145
|
-
lines.push(`*Source:* ${scar.source_issue}`);
|
|
146
162
|
}
|
|
147
163
|
lines.push("");
|
|
148
164
|
lines.push("---");
|