linksee-memory 0.15.0 → 0.15.1
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/dist/lib/truth-engine.d.ts +8 -0
- package/dist/lib/truth-engine.js +10 -5
- package/dist/mcp/server.js +3 -1
- package/package.json +1 -1
|
@@ -95,6 +95,14 @@ export type ResolutionAction = 'fix' | 'supersede' | 'acknowledge' | 'dismiss';
|
|
|
95
95
|
export interface ResolveInput {
|
|
96
96
|
/** For dismiss: silence only this match term. Omitted → silence the anchor at the gate. */
|
|
97
97
|
hit_term?: string;
|
|
98
|
+
/**
|
|
99
|
+
* For dismiss: false = close these drift edges as false positives but leave the gate
|
|
100
|
+
* watching. The default (true) also stops the gate. Two different verdicts hide behind
|
|
101
|
+
* "dismiss": "this detection was wrong" and "stop detecting this". Anchor #2 ("no destructive
|
|
102
|
+
* migrations") had a false positive from migrate.ts — the right answer was to close the edge
|
|
103
|
+
* and keep the gate, since "ALTER TABLE memories DROP" is exactly what it exists to catch.
|
|
104
|
+
*/
|
|
105
|
+
gate?: boolean;
|
|
98
106
|
anchor_id: number;
|
|
99
107
|
action: ResolutionAction;
|
|
100
108
|
rationale?: string;
|
package/dist/lib/truth-engine.js
CHANGED
|
@@ -543,12 +543,17 @@ export function resolveDrift(db, input) {
|
|
|
543
543
|
// real detections survive.
|
|
544
544
|
if (input.action === 'dismiss') {
|
|
545
545
|
db.prepare("UPDATE drift_edges SET status = 'dismissed' WHERE anchor_id = ? AND status = 'open'").run(input.anchor_id);
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
resolution.gate_dismissed = input.hit_term ? input.hit_term.toLowerCase() : 'all matches';
|
|
546
|
+
if (input.gate === false) {
|
|
547
|
+
resolution.gate_dismissed = 'none (edges closed; gate still watching)';
|
|
548
|
+
resolution.gate = false;
|
|
550
549
|
}
|
|
551
|
-
|
|
550
|
+
else
|
|
551
|
+
try {
|
|
552
|
+
db.prepare(`INSERT INTO gate_dismissals (anchor_id, hit_term, rationale) VALUES (?, ?, ?)
|
|
553
|
+
ON CONFLICT(anchor_id, COALESCE(hit_term, '')) DO UPDATE SET rationale = excluded.rationale`).run(input.anchor_id, input.hit_term ? input.hit_term.toLowerCase() : null, input.rationale ?? null);
|
|
554
|
+
resolution.gate_dismissed = input.hit_term ? input.hit_term.toLowerCase() : 'all matches';
|
|
555
|
+
}
|
|
556
|
+
catch { /* pre-v16 DB → edges-only dismiss, as before */ }
|
|
552
557
|
}
|
|
553
558
|
// If action is 'fix', mark open edges as resolved
|
|
554
559
|
if (input.action === 'fix') {
|
package/dist/mcp/server.js
CHANGED
|
@@ -280,13 +280,14 @@ const TOOLS = [
|
|
|
280
280
|
},
|
|
281
281
|
{
|
|
282
282
|
name: 'resolve_drift',
|
|
283
|
-
description: 'Record a resolution for a drifting anchor — the human feedback loop.\n\n6 actions:\n• fix — "we fixed the code/reality to match intent" → state becomes aligned\n• supersede — "intent evolved, this is the new direction" → state becomes aligned\n• acknowledge — "we know, parking it for now" → state becomes held (with optional review date)\n• dismiss — "false positive, not actually drifting" → edges dismissed AND the gate stops firing on it (
|
|
283
|
+
description: 'Record a resolution for a drifting anchor — the human feedback loop.\n\n6 actions:\n• fix — "we fixed the code/reality to match intent" → state becomes aligned\n• supersede — "intent evolved, this is the new direction" → state becomes aligned\n• acknowledge — "we know, parking it for now" → state becomes held (with optional review date)\n• dismiss — "false positive, not actually drifting" → edges dismissed AND the gate stops firing on it (hit_term: just that word; gate:false: close the edges but keep the gate watching)\n• harden — "re-injected but still violated, enforce it" → card_policy.gate_mode=hard (PreToolUse will BLOCK)\n• soften — "back off to a warning" → gate_mode=soft\n\nWHEN TO CALL:\n• After drift_status shows 🔴 drift or 🟡 review items\n• When the user says "that\'s fixed" / "ignore that" / "we changed direction"\n• When acknowledging a known gap with a review date',
|
|
284
284
|
inputSchema: {
|
|
285
285
|
type: 'object',
|
|
286
286
|
properties: {
|
|
287
287
|
anchor_id: { type: 'number', description: 'The drift_anchor ID to resolve' },
|
|
288
288
|
action: { type: 'string', enum: ['fix', 'supersede', 'acknowledge', 'dismiss', 'harden', 'soften', 'surface'], description: "Resolution action. With candidate_id (an orphaned proposal): 'surface' keeps it visible for the human, 'dismiss' retires it." },
|
|
289
289
|
candidate_id: { type: 'number', description: 'Resolve an orphaned proposal (from recall({ dream: true })) instead of an anchor: pass its candidate_id with action surface | dismiss and a rationale that references the North Star. (Absorbs resolve_proposal.)' },
|
|
290
|
+
gate: { type: 'boolean', default: true, description: "For dismiss: false = these detections were false positives, close them, but KEEP the gate watching this anchor (its signals still fire). Use when the anchor's rule is right and only this evidence was wrong — e.g. a lexical hit in a file that is not what the rule is about. Default true also silences the gate (whole anchor, or just hit_term)." },
|
|
290
291
|
rationale: { type: 'string', description: 'Why this resolution (recorded for audit trail)' },
|
|
291
292
|
review_after: { type: 'string', description: 'For acknowledge: ISO date to re-check (e.g. "2026-07-04")' },
|
|
292
293
|
superseded_by: { type: 'number', description: 'For supersede: the new anchor ID that replaces this one' },
|
|
@@ -1751,6 +1752,7 @@ function handleResolveDrift(args) {
|
|
|
1751
1752
|
review_after: args.review_after,
|
|
1752
1753
|
superseded_by: args.superseded_by,
|
|
1753
1754
|
hit_term: args.hit_term,
|
|
1755
|
+
gate: args.gate,
|
|
1754
1756
|
});
|
|
1755
1757
|
return JSON.stringify(result);
|
|
1756
1758
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linksee-memory",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"mcpName": "io.github.michielinksee/linksee-memory",
|
|
5
5
|
"description": "Local-first agent memory MCP — cross-agent brain with drift detection, 6-layer structured memory + token-saving file diff cache",
|
|
6
6
|
"type": "module",
|