hippo-memory 1.28.0 → 1.30.0
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 +15 -0
- package/dist/api.d.ts +25 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +101 -2
- package/dist/api.js.map +1 -1
- package/dist/audit.d.ts +1 -1
- package/dist/audit.d.ts.map +1 -1
- package/dist/audit.js.map +1 -1
- package/dist/capture.d.ts +49 -2
- package/dist/capture.d.ts.map +1 -1
- package/dist/capture.js +464 -1
- package/dist/capture.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +196 -3
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +21 -0
- package/dist/config.js.map +1 -1
- package/dist/consolidate.d.ts.map +1 -1
- package/dist/consolidate.js +195 -22
- package/dist/consolidate.js.map +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +75 -1
- package/dist/db.js.map +1 -1
- package/dist/hooks.d.ts +10 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +64 -1
- package/dist/hooks.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +14 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/memory-value-weights.d.ts +22 -0
- package/dist/memory-value-weights.d.ts.map +1 -0
- package/dist/memory-value-weights.js +31 -0
- package/dist/memory-value-weights.js.map +1 -0
- package/dist/memory-value.d.ts +123 -0
- package/dist/memory-value.d.ts.map +1 -0
- package/dist/memory-value.js +255 -0
- package/dist/memory-value.js.map +1 -0
- package/dist/recall-trace.d.ts +117 -0
- package/dist/recall-trace.d.ts.map +1 -0
- package/dist/recall-trace.js +179 -0
- package/dist/recall-trace.js.map +1 -0
- package/dist/secret-detect.d.ts +8 -0
- package/dist/secret-detect.d.ts.map +1 -1
- package/dist/secret-detect.js +25 -0
- package/dist/secret-detect.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -0
- package/dist/server.js.map +1 -1
- package/dist/src/api.js +101 -2
- package/dist/src/api.js.map +1 -1
- package/dist/src/audit.js.map +1 -1
- package/dist/src/capture.js +464 -1
- package/dist/src/capture.js.map +1 -1
- package/dist/src/cli.js +196 -3
- package/dist/src/cli.js.map +1 -1
- package/dist/src/config.js +21 -0
- package/dist/src/config.js.map +1 -1
- package/dist/src/consolidate.js +195 -22
- package/dist/src/consolidate.js.map +1 -1
- package/dist/src/db.js +75 -1
- package/dist/src/db.js.map +1 -1
- package/dist/src/hooks.js +64 -1
- package/dist/src/hooks.js.map +1 -1
- package/dist/src/mcp/server.js +14 -1
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/memory-value-weights.js +31 -0
- package/dist/src/memory-value-weights.js.map +1 -0
- package/dist/src/memory-value.js +255 -0
- package/dist/src/memory-value.js.map +1 -0
- package/dist/src/recall-trace.js +179 -0
- package/dist/src/recall-trace.js.map +1 -0
- package/dist/src/secret-detect.js +25 -0
- package/dist/src/secret-detect.js.map +1 -1
- package/dist/src/server.js +1 -0
- package/dist/src/server.js.map +1 -1
- package/dist/src/store.js +55 -4
- package/dist/src/store.js.map +1 -1
- package/dist/src/version.js +1 -1
- package/dist/store.d.ts +15 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +55 -4
- package/dist/store.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-value.js","sourceRoot":"","sources":["../src/memory-value.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LC1 — retrieval-trace persistence
|
|
3
|
+
* (docs/plans/2026-08-02-lc1-recall-trace-persistence.md).
|
|
4
|
+
*
|
|
5
|
+
* Single producer for the `recall_traces` / `recall_trace_results` /
|
|
6
|
+
* `recall_trace_outcomes` tables (schema v40). Every recall on the three
|
|
7
|
+
* wired paths (api.recall, api.getContext, CLI cmdRecall) writes a trace
|
|
8
|
+
* row: the ids + ranks + scores actually returned. Outcome events that
|
|
9
|
+
* resolve their targets from last-retrieval state link back to the trace
|
|
10
|
+
* they judge via `recordTraceOutcome`. This is the (query, shown, outcome)
|
|
11
|
+
* training triple every Track LC learned component needs.
|
|
12
|
+
*
|
|
13
|
+
* All writes here are fail-soft: a broken trace write must never break the
|
|
14
|
+
* surrounding recall or outcome call. Failures are logged to stderr and
|
|
15
|
+
* swallowed (matches the api.ts ~2843 "audit emit failed" precedent — no
|
|
16
|
+
* new debug env var).
|
|
17
|
+
*/
|
|
18
|
+
import { type DatabaseSyncLike } from './db.js';
|
|
19
|
+
import type { RerankStep } from './search.js';
|
|
20
|
+
/** One ranked result to persist alongside its trace row. */
|
|
21
|
+
export interface RecallTraceResultInput {
|
|
22
|
+
memoryId: string;
|
|
23
|
+
score: number;
|
|
24
|
+
/** Per-stage rerank steps when the caller ran with explain/--why; omitted
|
|
25
|
+
* (or empty) persists `rerank_json` as NULL. */
|
|
26
|
+
rerankSteps?: RerankStep[];
|
|
27
|
+
}
|
|
28
|
+
/** Input to `writeRecallTrace` / `writeRecallTraceAtRoot`. */
|
|
29
|
+
export interface RecallTraceInput {
|
|
30
|
+
tenantId: string;
|
|
31
|
+
sessionId?: string | null;
|
|
32
|
+
pipeline: 'api' | 'cli' | 'context' | 'mcp';
|
|
33
|
+
/** Raw query text. NEVER persisted — only its sha256/16 hash + length are
|
|
34
|
+
* stored (GDPR Path A / audit convention, cli.ts:1532). */
|
|
35
|
+
query: string;
|
|
36
|
+
/** True when the caller ran with explain/--why (per-result rerank steps
|
|
37
|
+
* may be present). Defaults to false. */
|
|
38
|
+
explainMode?: boolean;
|
|
39
|
+
/** Results in returned rank order (index 0 = rank 1). */
|
|
40
|
+
results: RecallTraceResultInput[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Insert a `recall_traces` row + its `recall_trace_results` rows in ONE
|
|
44
|
+
* transaction, on the connection handed in. Fail-soft: never throws —
|
|
45
|
+
* logs to stderr and returns null on any failure.
|
|
46
|
+
*
|
|
47
|
+
* Connection policy (per the plan): api.recall calls this directly on its
|
|
48
|
+
* own already-open handle. api.getContext and CLI cmdRecall go through
|
|
49
|
+
* `writeRecallTraceAtRoot` instead, since their audit handles are already
|
|
50
|
+
* closed by the time tracing runs.
|
|
51
|
+
*/
|
|
52
|
+
export declare function writeRecallTrace(db: DatabaseSyncLike, input: RecallTraceInput): number | null;
|
|
53
|
+
/**
|
|
54
|
+
* Convenience wrapper: opens a fresh short-lived connection at `root`,
|
|
55
|
+
* writes the trace, and closes. Returns the new trace id, or null on any
|
|
56
|
+
* failure (fail-soft).
|
|
57
|
+
*
|
|
58
|
+
* Used at api.getContext and CLI cmdRecall — sites where the block's own
|
|
59
|
+
* convention is per-call handles (writeEntry, saveIndex) and the earlier
|
|
60
|
+
* audit handles are already closed. NOT used by api.recall, which must
|
|
61
|
+
* reuse the caller's open handle (v1.11.5 no-side-effects contract,
|
|
62
|
+
* tests/api-recall-no-side-effects.test.ts).
|
|
63
|
+
*
|
|
64
|
+
* F1 structural fix (replaces the earlier stamp-then-clear design): this
|
|
65
|
+
* function does NOT touch the `last_trace_id` meta key. Stamping lived here
|
|
66
|
+
* originally, on its own connection, separate from the `last_retrieval_ids`
|
|
67
|
+
* write in `saveIndex` — two connections meant two commits, so a crash or
|
|
68
|
+
* a failed second write could advance one without the other. LOCKSTEP
|
|
69
|
+
* INVARIANT: `last_trace_id` must only ever advance in the SAME write as
|
|
70
|
+
* `last_retrieval_ids`. The caller now does: call this function FIRST, set
|
|
71
|
+
* `localIndex.last_trace_id` from the returned id, THEN call `saveIndex`
|
|
72
|
+
* once — `saveIndex` persists both meta keys in one transaction
|
|
73
|
+
* (store.ts). Call sites that trace WITHOUT advancing `last_retrieval_ids`
|
|
74
|
+
* (CLI cmdRecall's zero-result path, getContext's empty-result path) simply
|
|
75
|
+
* never touch `localIndex` at all — they can't desync by construction.
|
|
76
|
+
*
|
|
77
|
+
* Fail-soft: never throws, including on connection failure.
|
|
78
|
+
*/
|
|
79
|
+
export declare function writeRecallTraceAtRoot(root: string, input: RecallTraceInput): number | null;
|
|
80
|
+
/** Input to `recordTraceOutcome`. */
|
|
81
|
+
export interface RecordTraceOutcomeInput {
|
|
82
|
+
traceId: number;
|
|
83
|
+
tenantId: string;
|
|
84
|
+
outcome: 'positive' | 'negative';
|
|
85
|
+
/** Ids actually credited by this outcome event (post tenant-filtering). */
|
|
86
|
+
memoryIds: string[];
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Record an outcome event against a trace, linking the (query, shown,
|
|
90
|
+
* outcome) triple. Called ONLY where the credited ids actually come from
|
|
91
|
+
* the last-retrieval mechanism (api.outcomeForLastRecall and any outcome
|
|
92
|
+
* flow that resolves its targets from last-retrieval state) or from an
|
|
93
|
+
* SDK caller's explicit `traceId` opt — never unconditionally from
|
|
94
|
+
* api.outcome, which would mislink an explicit-id caller to a stale,
|
|
95
|
+
* unrelated trace.
|
|
96
|
+
*
|
|
97
|
+
* Lives in its own append-only table, not audit_log metadata: audit_log is
|
|
98
|
+
* pruned by `pruneAuditLog`, and pruning must never erase training data.
|
|
99
|
+
*
|
|
100
|
+
* F4 validation (codex cross-model finding): `traceId`/`memoryIds` reach
|
|
101
|
+
* this function from caller-side state (`last_trace_id` / applied outcome
|
|
102
|
+
* ids) that can go stale relative to the trace it names — a forgotten
|
|
103
|
+
* memory, a tenant switch mid-session, or a race between two callers. Two
|
|
104
|
+
* checks run before the insert, both skip silently (console.error one
|
|
105
|
+
* line) rather than throw:
|
|
106
|
+
* 1. The named trace must exist and belong to `input.tenantId` — a
|
|
107
|
+
* tenant mismatch or a dangling id (deleted trace) skips.
|
|
108
|
+
* 2. `input.memoryIds` is intersected against the trace's OWN
|
|
109
|
+
* `recall_trace_results.memory_id` set — only ids that trace actually
|
|
110
|
+
* returned are recorded. An id that was never in this trace's result
|
|
111
|
+
* set (stale caller state) is silently dropped rather than recorded
|
|
112
|
+
* as a false credit. If the intersection is empty, no row is written.
|
|
113
|
+
*
|
|
114
|
+
* Fail-soft: never throws.
|
|
115
|
+
*/
|
|
116
|
+
export declare function recordTraceOutcome(db: DatabaseSyncLike, input: RecordTraceOutcomeInput): void;
|
|
117
|
+
//# sourceMappingURL=recall-trace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recall-trace.d.ts","sourceRoot":"","sources":["../src/recall-trace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAA6B,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,4DAA4D;AAC5D,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd;qDACiD;IACjD,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B;AAED,8DAA8D;AAC9D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,CAAC;IAC5C;gEAC4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd;8CAC0C;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yDAAyD;IACzD,OAAO,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAsBD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAgD7F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAc3F;AAED,qCAAqC;AACrC,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,GAAG,UAAU,CAAC;IACjC,2EAA2E;IAC3E,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,uBAAuB,GAAG,IAAI,CA8B7F"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LC1 — retrieval-trace persistence
|
|
3
|
+
* (docs/plans/2026-08-02-lc1-recall-trace-persistence.md).
|
|
4
|
+
*
|
|
5
|
+
* Single producer for the `recall_traces` / `recall_trace_results` /
|
|
6
|
+
* `recall_trace_outcomes` tables (schema v40). Every recall on the three
|
|
7
|
+
* wired paths (api.recall, api.getContext, CLI cmdRecall) writes a trace
|
|
8
|
+
* row: the ids + ranks + scores actually returned. Outcome events that
|
|
9
|
+
* resolve their targets from last-retrieval state link back to the trace
|
|
10
|
+
* they judge via `recordTraceOutcome`. This is the (query, shown, outcome)
|
|
11
|
+
* training triple every Track LC learned component needs.
|
|
12
|
+
*
|
|
13
|
+
* All writes here are fail-soft: a broken trace write must never break the
|
|
14
|
+
* surrounding recall or outcome call. Failures are logged to stderr and
|
|
15
|
+
* swallowed (matches the api.ts ~2843 "audit emit failed" precedent — no
|
|
16
|
+
* new debug env var).
|
|
17
|
+
*/
|
|
18
|
+
import { createHash } from 'node:crypto';
|
|
19
|
+
import { openHippoDb, closeHippoDb } from './db.js';
|
|
20
|
+
/**
|
|
21
|
+
* Strip a RerankStep down to {stage, multiplier, scoreBefore, scoreAfter}
|
|
22
|
+
* before persisting (F3 privacy fix, codex cross-model finding). `note` is
|
|
23
|
+
* free-form human text — the CLI's goal-boost step embeds matched goal tag
|
|
24
|
+
* text there, so persisting it verbatim would leak raw user content into
|
|
25
|
+
* training data via `rerank_json`. Only the four structured fields survive;
|
|
26
|
+
* any other/future free-form field is dropped by construction (allowlist,
|
|
27
|
+
* not a denylist).
|
|
28
|
+
*/
|
|
29
|
+
function sanitizeRerankSteps(steps) {
|
|
30
|
+
return steps.map((s) => ({
|
|
31
|
+
stage: s.stage,
|
|
32
|
+
multiplier: s.multiplier,
|
|
33
|
+
scoreBefore: s.scoreBefore,
|
|
34
|
+
scoreAfter: s.scoreAfter,
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Insert a `recall_traces` row + its `recall_trace_results` rows in ONE
|
|
39
|
+
* transaction, on the connection handed in. Fail-soft: never throws —
|
|
40
|
+
* logs to stderr and returns null on any failure.
|
|
41
|
+
*
|
|
42
|
+
* Connection policy (per the plan): api.recall calls this directly on its
|
|
43
|
+
* own already-open handle. api.getContext and CLI cmdRecall go through
|
|
44
|
+
* `writeRecallTraceAtRoot` instead, since their audit handles are already
|
|
45
|
+
* closed by the time tracing runs.
|
|
46
|
+
*/
|
|
47
|
+
export function writeRecallTrace(db, input) {
|
|
48
|
+
try {
|
|
49
|
+
const queryHash = createHash('sha256').update(input.query).digest('hex').slice(0, 16);
|
|
50
|
+
const ts = new Date().toISOString();
|
|
51
|
+
db.exec('BEGIN');
|
|
52
|
+
try {
|
|
53
|
+
const insertTrace = db.prepare(`
|
|
54
|
+
INSERT INTO recall_traces (ts, tenant_id, session_id, pipeline, query_hash, query_length, result_count, explain_mode)
|
|
55
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
56
|
+
`);
|
|
57
|
+
const traceResult = insertTrace.run(ts, input.tenantId, input.sessionId ?? null, input.pipeline, queryHash, input.query.length, input.results.length, input.explainMode ? 1 : 0);
|
|
58
|
+
const traceId = Number(traceResult.lastInsertRowid);
|
|
59
|
+
const insertResult = db.prepare(`
|
|
60
|
+
INSERT INTO recall_trace_results (trace_id, tenant_id, memory_id, result_rank, score, rerank_json)
|
|
61
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
62
|
+
`);
|
|
63
|
+
input.results.forEach((r, i) => {
|
|
64
|
+
insertResult.run(traceId, input.tenantId, r.memoryId, i + 1, r.score, r.rerankSteps && r.rerankSteps.length > 0 ? JSON.stringify(sanitizeRerankSteps(r.rerankSteps)) : null);
|
|
65
|
+
});
|
|
66
|
+
db.exec('COMMIT');
|
|
67
|
+
return traceId;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
db.exec('ROLLBACK');
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
// eslint-disable-next-line no-console
|
|
76
|
+
console.error(`[hippo] recall trace write failed: ${error.message}`);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Convenience wrapper: opens a fresh short-lived connection at `root`,
|
|
82
|
+
* writes the trace, and closes. Returns the new trace id, or null on any
|
|
83
|
+
* failure (fail-soft).
|
|
84
|
+
*
|
|
85
|
+
* Used at api.getContext and CLI cmdRecall — sites where the block's own
|
|
86
|
+
* convention is per-call handles (writeEntry, saveIndex) and the earlier
|
|
87
|
+
* audit handles are already closed. NOT used by api.recall, which must
|
|
88
|
+
* reuse the caller's open handle (v1.11.5 no-side-effects contract,
|
|
89
|
+
* tests/api-recall-no-side-effects.test.ts).
|
|
90
|
+
*
|
|
91
|
+
* F1 structural fix (replaces the earlier stamp-then-clear design): this
|
|
92
|
+
* function does NOT touch the `last_trace_id` meta key. Stamping lived here
|
|
93
|
+
* originally, on its own connection, separate from the `last_retrieval_ids`
|
|
94
|
+
* write in `saveIndex` — two connections meant two commits, so a crash or
|
|
95
|
+
* a failed second write could advance one without the other. LOCKSTEP
|
|
96
|
+
* INVARIANT: `last_trace_id` must only ever advance in the SAME write as
|
|
97
|
+
* `last_retrieval_ids`. The caller now does: call this function FIRST, set
|
|
98
|
+
* `localIndex.last_trace_id` from the returned id, THEN call `saveIndex`
|
|
99
|
+
* once — `saveIndex` persists both meta keys in one transaction
|
|
100
|
+
* (store.ts). Call sites that trace WITHOUT advancing `last_retrieval_ids`
|
|
101
|
+
* (CLI cmdRecall's zero-result path, getContext's empty-result path) simply
|
|
102
|
+
* never touch `localIndex` at all — they can't desync by construction.
|
|
103
|
+
*
|
|
104
|
+
* Fail-soft: never throws, including on connection failure.
|
|
105
|
+
*/
|
|
106
|
+
export function writeRecallTraceAtRoot(root, input) {
|
|
107
|
+
let db;
|
|
108
|
+
try {
|
|
109
|
+
db = openHippoDb(root);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
// eslint-disable-next-line no-console
|
|
113
|
+
console.error(`[hippo] recall trace connection failed: ${error.message}`);
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
return writeRecallTrace(db, input);
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
closeHippoDb(db);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Record an outcome event against a trace, linking the (query, shown,
|
|
125
|
+
* outcome) triple. Called ONLY where the credited ids actually come from
|
|
126
|
+
* the last-retrieval mechanism (api.outcomeForLastRecall and any outcome
|
|
127
|
+
* flow that resolves its targets from last-retrieval state) or from an
|
|
128
|
+
* SDK caller's explicit `traceId` opt — never unconditionally from
|
|
129
|
+
* api.outcome, which would mislink an explicit-id caller to a stale,
|
|
130
|
+
* unrelated trace.
|
|
131
|
+
*
|
|
132
|
+
* Lives in its own append-only table, not audit_log metadata: audit_log is
|
|
133
|
+
* pruned by `pruneAuditLog`, and pruning must never erase training data.
|
|
134
|
+
*
|
|
135
|
+
* F4 validation (codex cross-model finding): `traceId`/`memoryIds` reach
|
|
136
|
+
* this function from caller-side state (`last_trace_id` / applied outcome
|
|
137
|
+
* ids) that can go stale relative to the trace it names — a forgotten
|
|
138
|
+
* memory, a tenant switch mid-session, or a race between two callers. Two
|
|
139
|
+
* checks run before the insert, both skip silently (console.error one
|
|
140
|
+
* line) rather than throw:
|
|
141
|
+
* 1. The named trace must exist and belong to `input.tenantId` — a
|
|
142
|
+
* tenant mismatch or a dangling id (deleted trace) skips.
|
|
143
|
+
* 2. `input.memoryIds` is intersected against the trace's OWN
|
|
144
|
+
* `recall_trace_results.memory_id` set — only ids that trace actually
|
|
145
|
+
* returned are recorded. An id that was never in this trace's result
|
|
146
|
+
* set (stale caller state) is silently dropped rather than recorded
|
|
147
|
+
* as a false credit. If the intersection is empty, no row is written.
|
|
148
|
+
*
|
|
149
|
+
* Fail-soft: never throws.
|
|
150
|
+
*/
|
|
151
|
+
export function recordTraceOutcome(db, input) {
|
|
152
|
+
try {
|
|
153
|
+
const trace = db.prepare(`SELECT tenant_id FROM recall_traces WHERE id = ?`).get(input.traceId);
|
|
154
|
+
if (!trace || trace.tenant_id !== input.tenantId) {
|
|
155
|
+
// eslint-disable-next-line no-console
|
|
156
|
+
console.error(`[hippo] recall trace outcome skipped: trace ${input.traceId} missing or tenant mismatch`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const memberRows = db
|
|
160
|
+
.prepare(`SELECT memory_id FROM recall_trace_results WHERE trace_id = ?`)
|
|
161
|
+
.all(input.traceId);
|
|
162
|
+
const members = new Set(memberRows.map((r) => r.memory_id));
|
|
163
|
+
const credited = input.memoryIds.filter((id) => members.has(id));
|
|
164
|
+
if (credited.length === 0) {
|
|
165
|
+
// eslint-disable-next-line no-console
|
|
166
|
+
console.error(`[hippo] recall trace outcome skipped: no credited ids intersect trace ${input.traceId}'s results`);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
db.prepare(`
|
|
170
|
+
INSERT INTO recall_trace_outcomes (trace_id, ts, tenant_id, outcome, memory_ids_json)
|
|
171
|
+
VALUES (?, ?, ?, ?, ?)
|
|
172
|
+
`).run(input.traceId, new Date().toISOString(), input.tenantId, input.outcome, JSON.stringify(credited));
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
// eslint-disable-next-line no-console
|
|
176
|
+
console.error(`[hippo] recall trace outcome write failed: ${error.message}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=recall-trace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recall-trace.js","sourceRoot":"","sources":["../src/recall-trace.ts"],"names":[],"mappings":"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"}
|
package/dist/secret-detect.d.ts
CHANGED
|
@@ -30,4 +30,12 @@ export declare function detectSecret(entry: {
|
|
|
30
30
|
content: string;
|
|
31
31
|
tags: string[];
|
|
32
32
|
}): SecretDetection;
|
|
33
|
+
/**
|
|
34
|
+
* Replace secret-shaped substrings in free text with a redaction marker.
|
|
35
|
+
* Reuses the same `SECRET_PATTERNS` / co-occurrence guard as `detectSecret`
|
|
36
|
+
* (which only flags whole-entry content) so callers that must persist raw
|
|
37
|
+
* text that never passes through the normal capture content gate — e.g. the
|
|
38
|
+
* CS1 pre-compact snapshot fields — can scrub it in place instead.
|
|
39
|
+
*/
|
|
40
|
+
export declare function redactSecrets(text: string): string;
|
|
33
41
|
//# sourceMappingURL=secret-detect.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-detect.d.ts","sourceRoot":"","sources":["../src/secret-detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAoCD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,eAAe,CAYxF"}
|
|
1
|
+
{"version":3,"file":"secret-detect.d.ts","sourceRoot":"","sources":["../src/secret-detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAoCD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,eAAe,CAYxF;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBlD"}
|
package/dist/secret-detect.js
CHANGED
|
@@ -67,4 +67,29 @@ export function detectSecret(entry) {
|
|
|
67
67
|
}
|
|
68
68
|
return { flagged: false, reason: null };
|
|
69
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Replace secret-shaped substrings in free text with a redaction marker.
|
|
72
|
+
* Reuses the same `SECRET_PATTERNS` / co-occurrence guard as `detectSecret`
|
|
73
|
+
* (which only flags whole-entry content) so callers that must persist raw
|
|
74
|
+
* text that never passes through the normal capture content gate — e.g. the
|
|
75
|
+
* CS1 pre-compact snapshot fields — can scrub it in place instead.
|
|
76
|
+
*/
|
|
77
|
+
export function redactSecrets(text) {
|
|
78
|
+
if (!text)
|
|
79
|
+
return text;
|
|
80
|
+
let result = text;
|
|
81
|
+
// PEM/OpenSSH blocks first: the pattern-table entry matches only the
|
|
82
|
+
// BEGIN delimiter, which is fine for detectSecret's flag-or-not decision
|
|
83
|
+
// but would leave the base64 payload behind here. Consume through the
|
|
84
|
+
// matching END delimiter; a truncated block with no END is redacted to
|
|
85
|
+
// the end of the text (codex round 3).
|
|
86
|
+
result = result.replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----(?:[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----|[\s\S]*$)/g, '[REDACTED]');
|
|
87
|
+
for (const { name, re } of SECRET_PATTERNS) {
|
|
88
|
+
if (CO_OCCURRENCE_GUARDED.has(name) && !KEYISH_CONTEXT_RE.test(text))
|
|
89
|
+
continue;
|
|
90
|
+
const flags = re.flags.includes('g') ? re.flags : `${re.flags}g`;
|
|
91
|
+
result = result.replace(new RegExp(re.source, flags), '[REDACTED]');
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
70
95
|
//# sourceMappingURL=secret-detect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-detect.js","sourceRoot":"","sources":["../src/secret-detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IAC1B,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa;IAC1D,OAAO,EAAE,UAAU,EAAE,aAAa;CACnC,CAAC,CAAC;AAEH,MAAM,eAAe,GAAgD;IACnE,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,sBAAsB,EAAE;IACtD,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,6CAA6C,EAAE;IAC3E,EAAE,IAAI,EAAE,yBAAyB,EAAE,EAAE,EAAE,kCAAkC,EAAE;IAC3E,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,kCAAkC,EAAE;IAC/D,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,0CAA0C,EAAE;IACtE,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,2BAA2B,EAAE;IAC3D,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,oCAAoC,EAAE;IACvE,2EAA2E;IAC3E,yEAAyE;IACzE,yEAAyE;IACzE,uEAAuE;IACvE,QAAQ;IACR,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,2BAA2B,EAAE;IACzD,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,sCAAsC,EAAE;IACzE,0EAA0E;IAC1E,oEAAoE;IACpE,wEAAwE;IACxE,oEAAoE;IACpE,wEAAwE;IACxE,yEAAyE;IACzE,kEAAkE;IAClE,mCAAmC;IACnC,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,uGAAuG,EAAE;CAC3I,CAAC;AAEF,MAAM,iBAAiB,GAAG,mDAAmD,CAAC;AAC9E,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAE7E;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAA0C;IACrE,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAG,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC;QAC/D,CAAC;IACH,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,eAAe,EAAE,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YAAE,SAAS;QACtC,IAAI,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YAAE,SAAS;QACxF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,IAAI,EAAE,EAAE,CAAC;IACtD,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1C,CAAC"}
|
|
1
|
+
{"version":3,"file":"secret-detect.js","sourceRoot":"","sources":["../src/secret-detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IAC1B,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa;IAC1D,OAAO,EAAE,UAAU,EAAE,aAAa;CACnC,CAAC,CAAC;AAEH,MAAM,eAAe,GAAgD;IACnE,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,sBAAsB,EAAE;IACtD,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,6CAA6C,EAAE;IAC3E,EAAE,IAAI,EAAE,yBAAyB,EAAE,EAAE,EAAE,kCAAkC,EAAE;IAC3E,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,kCAAkC,EAAE;IAC/D,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,0CAA0C,EAAE;IACtE,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,2BAA2B,EAAE;IAC3D,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,oCAAoC,EAAE;IACvE,2EAA2E;IAC3E,yEAAyE;IACzE,yEAAyE;IACzE,uEAAuE;IACvE,QAAQ;IACR,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,2BAA2B,EAAE;IACzD,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,sCAAsC,EAAE;IACzE,0EAA0E;IAC1E,oEAAoE;IACpE,wEAAwE;IACxE,oEAAoE;IACpE,wEAAwE;IACxE,yEAAyE;IACzE,kEAAkE;IAClE,mCAAmC;IACnC,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,uGAAuG,EAAE;CAC3I,CAAC;AAEF,MAAM,iBAAiB,GAAG,mDAAmD,CAAC;AAC9E,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAE7E;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAA0C;IACrE,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAG,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC;QAC/D,CAAC;IACH,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,eAAe,EAAE,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YAAE,SAAS;QACtC,IAAI,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YAAE,SAAS;QACxF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,IAAI,EAAE,EAAE,CAAC;IACtD,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,qEAAqE;IACrE,yEAAyE;IACzE,sEAAsE;IACtE,uEAAuE;IACvE,uCAAuC;IACvC,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,0FAA0F,EAC1F,YAAY,CACb,CAAC;IACF,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,eAAe,EAAE,CAAC;QAC3C,IAAI,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QAC/E,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,GAAG,CAAC;QACjE,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,YAAY,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAyBA,kFAAkF;AAClF,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAyBA,kFAAkF;AAClF,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD;AA2QD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B;;;8BAG0B;IAC1B,MAAM,CAAC,EAAE,OAAO,WAAW,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA0HD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAMrE;AAmrFD;;;;;;;;;;GAUG;AACH,wBAAsB,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CA0JlE"}
|
package/dist/server.js
CHANGED
|
@@ -108,6 +108,7 @@ const VALID_AUDIT_OPS = new Set([
|
|
|
108
108
|
'customer_note_create', // E2 customer_note first-class object — emitted by saveCustomerNote
|
|
109
109
|
'customer_note_supersede', // E2 — emitted by saveCustomerNote on a supersession
|
|
110
110
|
'customer_note_close', // E2 — emitted by closeCustomerNote
|
|
111
|
+
'mv_rescue', // LC2-E3 — emitted by consolidate() per rescue; lockstep with AuditOp union + cli.ts VALID_AUDIT_OPS
|
|
111
112
|
]);
|
|
112
113
|
// Cap on GET /v1/audit?limit=. Matches docs/api.md (when written) and is large
|
|
113
114
|
// enough to dump a small deployment's full audit log without paginating, but
|