hippo-memory 1.12.12 → 1.13.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/api.d.ts +110 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +68 -1
- 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/cli.d.ts.map +1 -1
- package/dist/cli.js +321 -2
- package/dist/cli.js.map +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +77 -1
- package/dist/db.js.map +1 -1
- package/dist/forward-claim-detector.d.ts +38 -0
- package/dist/forward-claim-detector.d.ts.map +1 -0
- package/dist/forward-claim-detector.js +117 -0
- package/dist/forward-claim-detector.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +128 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/predictions.d.ts +194 -0
- package/dist/predictions.d.ts.map +1 -0
- package/dist/predictions.js +580 -0
- package/dist/predictions.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +178 -0
- package/dist/server.js.map +1 -1
- package/dist/src/api.js +68 -1
- package/dist/src/api.js.map +1 -1
- package/dist/src/audit.js.map +1 -1
- package/dist/src/cli.js +321 -2
- package/dist/src/cli.js.map +1 -1
- package/dist/src/db.js +77 -1
- package/dist/src/db.js.map +1 -1
- package/dist/src/forward-claim-detector.js +117 -0
- package/dist/src/forward-claim-detector.js.map +1 -0
- package/dist/src/mcp/server.js +128 -2
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/predictions.js +580 -0
- package/dist/src/predictions.js.map +1 -0
- package/dist/src/server.js +178 -0
- package/dist/src/server.js.map +1 -1
- package/dist/src/store.js +1 -1
- package/dist/src/store.js.map +1 -1
- package/dist/store.d.ts +17 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +1 -1
- package/dist/store.js.map +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,580 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2 prediction first-class object (v0.31 / docs/plans/2026-05-26-e2-prediction-object.md).
|
|
3
|
+
*
|
|
4
|
+
* Canonical store for ex-ante claims that can be closed against ex-post
|
|
5
|
+
* outcomes. The `predictions` table holds every field (including
|
|
6
|
+
* `claim_text`); a memory row mirrors the claim for recall/inspect surfaces
|
|
7
|
+
* but is NOT the source of truth — ON DELETE SET NULL on memory_id means
|
|
8
|
+
* memory deletion gracefully orphans the prediction without losing data.
|
|
9
|
+
*
|
|
10
|
+
* Tenant scoping: every helper requires tenantId. The schema's BEFORE INSERT
|
|
11
|
+
* + BEFORE UPDATE triggers (`trg_predictions_tenant_match_*`) enforce that
|
|
12
|
+
* `predictions.tenant_id` matches the referenced memory's tenant_id when
|
|
13
|
+
* `memory_id IS NOT NULL`. Cross-tenant references are unrepresentable at
|
|
14
|
+
* the schema level.
|
|
15
|
+
*
|
|
16
|
+
* Dual-write atomicity: `savePrediction` writes the memory + predictions
|
|
17
|
+
* row inside `writeEntry`'s SAVEPOINT 'write_entry' (store.ts:1196). The
|
|
18
|
+
* afterWrite hook (store.ts:1199-1201) runs inside the same SAVEPOINT, so
|
|
19
|
+
* a failure in either step rolls back both. Pattern matches supersede
|
|
20
|
+
* (api.ts:1486) and the Slack/GitHub connectors.
|
|
21
|
+
*
|
|
22
|
+
* J3 (reference-class / planning-fallacy detector) reads from
|
|
23
|
+
* `loadPredictionsByClass` to compute per-class base rates from
|
|
24
|
+
* (estimate_value, actual_value) at query time. J3 is a follow-up episode;
|
|
25
|
+
* this module ships the data layer.
|
|
26
|
+
*/
|
|
27
|
+
import { openHippoDb, closeHippoDb } from './db.js';
|
|
28
|
+
import { writeEntry, assertTenantId } from './store.js';
|
|
29
|
+
import { createMemory, Layer } from './memory.js';
|
|
30
|
+
import { appendAuditEvent } from './audit.js';
|
|
31
|
+
import { detectForwardClaim } from './forward-claim-detector.js';
|
|
32
|
+
export const VALID_CLOSURE_STATES = new Set([
|
|
33
|
+
'open',
|
|
34
|
+
'closed',
|
|
35
|
+
'closed-unknown',
|
|
36
|
+
]);
|
|
37
|
+
function rowToPrediction(row) {
|
|
38
|
+
return {
|
|
39
|
+
id: row.id,
|
|
40
|
+
memoryId: row.memory_id,
|
|
41
|
+
tenantId: row.tenant_id,
|
|
42
|
+
classTag: row.class_tag,
|
|
43
|
+
claimText: row.claim_text,
|
|
44
|
+
estimateValue: row.estimate_value,
|
|
45
|
+
estimateUnit: row.estimate_unit,
|
|
46
|
+
targetDate: row.target_date,
|
|
47
|
+
actualValue: row.actual_value,
|
|
48
|
+
closureState: row.closure_state,
|
|
49
|
+
closedAt: row.closed_at,
|
|
50
|
+
closureNote: row.closure_note,
|
|
51
|
+
createdAt: row.created_at,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Public API
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
/**
|
|
58
|
+
* Create a new prediction. Writes a memory mirror + a predictions table
|
|
59
|
+
* row atomically inside `writeEntry`'s SAVEPOINT 'write_entry'. On any
|
|
60
|
+
* failure (audit write, predictions INSERT, trigger ABORT), the SAVEPOINT
|
|
61
|
+
* rolls back — neither the memory row nor the predictions row lands.
|
|
62
|
+
*
|
|
63
|
+
* The memory is tagged `['prediction', classTag]` with `source='prediction'`
|
|
64
|
+
* and `kind='distilled'`. It surfaces in `hippo recall` so the agent can
|
|
65
|
+
* see open predictions naturally; the predictions table is the canonical
|
|
66
|
+
* structured store used by J3.
|
|
67
|
+
*/
|
|
68
|
+
export function savePrediction(hippoRoot, tenantId, opts, actor = 'cli') {
|
|
69
|
+
assertTenantId('savePrediction', tenantId);
|
|
70
|
+
if (!opts.classTag)
|
|
71
|
+
throw new Error('savePrediction: classTag is required');
|
|
72
|
+
if (!opts.claimText)
|
|
73
|
+
throw new Error('savePrediction: claimText is required');
|
|
74
|
+
const now = new Date().toISOString();
|
|
75
|
+
const mem = createMemory(opts.claimText, {
|
|
76
|
+
tags: ['prediction', opts.classTag],
|
|
77
|
+
layer: Layer.Semantic,
|
|
78
|
+
confidence: 'observed',
|
|
79
|
+
source: 'prediction',
|
|
80
|
+
kind: 'distilled',
|
|
81
|
+
tenantId,
|
|
82
|
+
});
|
|
83
|
+
// Captured for the return value; populated inside afterWrite hook so the
|
|
84
|
+
// INSERT and the memory write share a SAVEPOINT.
|
|
85
|
+
let savedRow;
|
|
86
|
+
writeEntry(hippoRoot, mem, {
|
|
87
|
+
actor,
|
|
88
|
+
afterWrite: (db, memoryId) => {
|
|
89
|
+
const result = db.prepare(`
|
|
90
|
+
INSERT INTO predictions(
|
|
91
|
+
memory_id, tenant_id, class_tag, claim_text,
|
|
92
|
+
estimate_value, estimate_unit, target_date,
|
|
93
|
+
actual_value, closure_state, closed_at, closure_note, created_at
|
|
94
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'open', NULL, NULL, ?)
|
|
95
|
+
`).run(memoryId, tenantId, opts.classTag, opts.claimText, opts.estimateValue ?? null, opts.estimateUnit ?? null, opts.targetDate ?? null, null, // actual_value — null until close
|
|
96
|
+
now);
|
|
97
|
+
const predictionId = Number(result.lastInsertRowid ?? 0);
|
|
98
|
+
const row = db.prepare(`
|
|
99
|
+
SELECT id, memory_id, tenant_id, class_tag, claim_text,
|
|
100
|
+
estimate_value, estimate_unit, target_date,
|
|
101
|
+
actual_value, closure_state, closed_at, closure_note, created_at
|
|
102
|
+
FROM predictions WHERE id = ?
|
|
103
|
+
`).get(predictionId);
|
|
104
|
+
if (!row) {
|
|
105
|
+
throw new Error('Failed to reload saved prediction row');
|
|
106
|
+
}
|
|
107
|
+
savedRow = row;
|
|
108
|
+
// GDPR-light audit metadata: prediction_id + class_tag + flags only.
|
|
109
|
+
// No claim_text in metadata; the predictions table holds it canonically.
|
|
110
|
+
appendAuditEvent(db, {
|
|
111
|
+
tenantId,
|
|
112
|
+
actor,
|
|
113
|
+
op: 'predict_create',
|
|
114
|
+
targetId: String(predictionId),
|
|
115
|
+
metadata: {
|
|
116
|
+
prediction_id: predictionId,
|
|
117
|
+
class_tag: opts.classTag,
|
|
118
|
+
has_estimate: opts.estimateValue !== undefined && opts.estimateValue !== null,
|
|
119
|
+
target_date: opts.targetDate ?? null,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
if (!savedRow) {
|
|
125
|
+
// Cannot reach here without the afterWrite throwing first; defensive.
|
|
126
|
+
throw new Error('savePrediction: afterWrite did not populate the row');
|
|
127
|
+
}
|
|
128
|
+
return rowToPrediction(savedRow);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Close an existing open prediction. Updates the predictions row only;
|
|
132
|
+
* the memory mirror is NOT mutated in v1 (predictions table is canonical).
|
|
133
|
+
* J3 computes accuracy (clean vs regressed) from (estimateValue,
|
|
134
|
+
* actualValue) at query time.
|
|
135
|
+
*/
|
|
136
|
+
export function closePrediction(hippoRoot, tenantId, id, opts, actor = 'cli') {
|
|
137
|
+
assertTenantId('closePrediction', tenantId);
|
|
138
|
+
if (!VALID_CLOSURE_STATES.has(opts.closureState)) {
|
|
139
|
+
throw new Error(`closePrediction: closureState must be one of ${Array.from(VALID_CLOSURE_STATES).join('|')}; got ${opts.closureState}`);
|
|
140
|
+
}
|
|
141
|
+
const now = new Date().toISOString();
|
|
142
|
+
const db = openHippoDb(hippoRoot);
|
|
143
|
+
try {
|
|
144
|
+
db.exec('BEGIN IMMEDIATE');
|
|
145
|
+
try {
|
|
146
|
+
// Codex review finding 2026-05-26: WHERE clause requires
|
|
147
|
+
// closure_state='open' so duplicate close requests / retries against
|
|
148
|
+
// an already-closed prediction return a clear error instead of
|
|
149
|
+
// silently overwriting actual_value + emitting a duplicate
|
|
150
|
+
// predict_close audit row. Zero changed rows → caller decides
|
|
151
|
+
// whether it's a "not found" or "already closed" case based on the
|
|
152
|
+
// load-then-close pattern.
|
|
153
|
+
const updateResult = db.prepare(`
|
|
154
|
+
UPDATE predictions
|
|
155
|
+
SET actual_value = ?, closure_state = ?, closed_at = ?, closure_note = ?
|
|
156
|
+
WHERE id = ? AND tenant_id = ? AND closure_state = 'open'
|
|
157
|
+
`).run(opts.actualValue ?? null, opts.closureState, now, opts.closureNote ?? null, id, tenantId);
|
|
158
|
+
if (updateResult.changes === 0) {
|
|
159
|
+
// Distinguish "not found" from "already closed" so callers (CLI, HTTP)
|
|
160
|
+
// can surface the right error to the user.
|
|
161
|
+
const existing = db.prepare(`
|
|
162
|
+
SELECT closure_state FROM predictions WHERE id = ? AND tenant_id = ?
|
|
163
|
+
`).get(id, tenantId);
|
|
164
|
+
if (!existing) {
|
|
165
|
+
throw new Error(`closePrediction: prediction ${id} not found for tenant ${tenantId}`);
|
|
166
|
+
}
|
|
167
|
+
throw new Error(`closePrediction: prediction ${id} is already closed (state='${existing.closure_state}'); ` +
|
|
168
|
+
`cannot re-close. Open predictions only.`);
|
|
169
|
+
}
|
|
170
|
+
const row = db.prepare(`
|
|
171
|
+
SELECT id, memory_id, tenant_id, class_tag, claim_text,
|
|
172
|
+
estimate_value, estimate_unit, target_date,
|
|
173
|
+
actual_value, closure_state, closed_at, closure_note, created_at
|
|
174
|
+
FROM predictions WHERE id = ? AND tenant_id = ?
|
|
175
|
+
`).get(id, tenantId);
|
|
176
|
+
if (!row) {
|
|
177
|
+
throw new Error(`closePrediction: prediction ${id} not found after UPDATE`);
|
|
178
|
+
}
|
|
179
|
+
appendAuditEvent(db, {
|
|
180
|
+
tenantId,
|
|
181
|
+
actor,
|
|
182
|
+
op: 'predict_close',
|
|
183
|
+
targetId: String(id),
|
|
184
|
+
metadata: {
|
|
185
|
+
prediction_id: id,
|
|
186
|
+
closure_state: opts.closureState,
|
|
187
|
+
has_actual: opts.actualValue !== undefined && opts.actualValue !== null,
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
db.exec('COMMIT');
|
|
191
|
+
return rowToPrediction(row);
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
try {
|
|
195
|
+
db.exec('ROLLBACK');
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// Ignore rollback failures — the throw below is what matters.
|
|
199
|
+
}
|
|
200
|
+
throw e;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
closeHippoDb(db);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
export function loadPredictionById(hippoRoot, tenantId, id) {
|
|
208
|
+
assertTenantId('loadPredictionById', tenantId);
|
|
209
|
+
const db = openHippoDb(hippoRoot);
|
|
210
|
+
try {
|
|
211
|
+
const row = db.prepare(`
|
|
212
|
+
SELECT id, memory_id, tenant_id, class_tag, claim_text,
|
|
213
|
+
estimate_value, estimate_unit, target_date,
|
|
214
|
+
actual_value, closure_state, closed_at, closure_note, created_at
|
|
215
|
+
FROM predictions WHERE id = ? AND tenant_id = ?
|
|
216
|
+
`).get(id, tenantId);
|
|
217
|
+
return row ? rowToPrediction(row) : null;
|
|
218
|
+
}
|
|
219
|
+
finally {
|
|
220
|
+
closeHippoDb(db);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
export function loadPredictionsByClass(hippoRoot, tenantId, classTag, opts = {}) {
|
|
224
|
+
assertTenantId('loadPredictionsByClass', tenantId);
|
|
225
|
+
const limit = opts.limit ?? 100;
|
|
226
|
+
const db = openHippoDb(hippoRoot);
|
|
227
|
+
try {
|
|
228
|
+
let rows;
|
|
229
|
+
if (opts.closureState) {
|
|
230
|
+
if (!VALID_CLOSURE_STATES.has(opts.closureState)) {
|
|
231
|
+
throw new Error(`loadPredictionsByClass: closureState must be one of ${Array.from(VALID_CLOSURE_STATES).join('|')}; got ${opts.closureState}`);
|
|
232
|
+
}
|
|
233
|
+
rows = db.prepare(`
|
|
234
|
+
SELECT id, memory_id, tenant_id, class_tag, claim_text,
|
|
235
|
+
estimate_value, estimate_unit, target_date,
|
|
236
|
+
actual_value, closure_state, closed_at, closure_note, created_at
|
|
237
|
+
FROM predictions
|
|
238
|
+
WHERE tenant_id = ? AND class_tag = ? AND closure_state = ?
|
|
239
|
+
ORDER BY created_at DESC, id DESC
|
|
240
|
+
LIMIT ?
|
|
241
|
+
`).all(tenantId, classTag, opts.closureState, limit);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
rows = db.prepare(`
|
|
245
|
+
SELECT id, memory_id, tenant_id, class_tag, claim_text,
|
|
246
|
+
estimate_value, estimate_unit, target_date,
|
|
247
|
+
actual_value, closure_state, closed_at, closure_note, created_at
|
|
248
|
+
FROM predictions
|
|
249
|
+
WHERE tenant_id = ? AND class_tag = ?
|
|
250
|
+
ORDER BY created_at DESC, id DESC
|
|
251
|
+
LIMIT ?
|
|
252
|
+
`).all(tenantId, classTag, limit);
|
|
253
|
+
}
|
|
254
|
+
return rows.map(rowToPrediction);
|
|
255
|
+
}
|
|
256
|
+
finally {
|
|
257
|
+
closeHippoDb(db);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Compute base-rate stats for closed predictions in a class. Used by J3
|
|
262
|
+
* reference-class / planning-fallacy detector. Direct application of
|
|
263
|
+
* Lovallo-Kahneman (2003) inside-vs-outside view.
|
|
264
|
+
*
|
|
265
|
+
* Filter: closure_state='closed' AND estimate_value IS NOT NULL AND
|
|
266
|
+
* actual_value IS NOT NULL. Excludes closed-unknown (no actual to
|
|
267
|
+
* compare against) and open (not yet resolved).
|
|
268
|
+
*
|
|
269
|
+
* Audit-emit is BUILT IN here (single source of truth, no caller-site
|
|
270
|
+
* drift risk). Plan-eng-critic round 1 HIGH recommendation: emit inside
|
|
271
|
+
* helper, not at 3 call sites.
|
|
272
|
+
*/
|
|
273
|
+
export function computePredictionBaserate(hippoRoot, tenantId, classTag, actor = 'cli',
|
|
274
|
+
/** v0.32 / J3.2 — when false, skip the predict_baserate audit emit. The
|
|
275
|
+
* J3.2 orchestrator (computePlanningFallacyHint, below) calls this with
|
|
276
|
+
* emitAudit=false and emits its own `recall_autodebias_hint` audit row
|
|
277
|
+
* instead, so the predict_baserate channel stays scoped to deliberate
|
|
278
|
+
* CLI / HTTP / MCP predict-baserate calls and does NOT pollute on every
|
|
279
|
+
* recall containing a forward-claim phrase. Default true preserves the
|
|
280
|
+
* v1.13.0 J3 audit semantics for the 3 direct callers (cmdPredict
|
|
281
|
+
* baserate, /v1/predictions/stats route, hippo_predict_baserate MCP
|
|
282
|
+
* handler) — none of them pass this argument. */
|
|
283
|
+
emitAudit = true) {
|
|
284
|
+
assertTenantId('computePredictionBaserate', tenantId);
|
|
285
|
+
if (!classTag)
|
|
286
|
+
throw new Error('computePredictionBaserate: classTag is required');
|
|
287
|
+
const db = openHippoDb(hippoRoot);
|
|
288
|
+
try {
|
|
289
|
+
const rows = db.prepare(`
|
|
290
|
+
SELECT estimate_value, actual_value
|
|
291
|
+
FROM predictions
|
|
292
|
+
WHERE tenant_id = ?
|
|
293
|
+
AND class_tag = ?
|
|
294
|
+
AND closure_state = 'closed'
|
|
295
|
+
AND estimate_value IS NOT NULL
|
|
296
|
+
AND actual_value IS NOT NULL
|
|
297
|
+
`).all(tenantId, classTag);
|
|
298
|
+
const nClosed = rows.length;
|
|
299
|
+
if (nClosed === 0) {
|
|
300
|
+
// Audit zero-result reads too — agents probing empty classes is
|
|
301
|
+
// a signal worth recording. Skipped when emitAudit=false (J3.2
|
|
302
|
+
// orchestrator path; its own recall_autodebias_hint audit fires
|
|
303
|
+
// only when nClosed > 0 anyway, so no signal is lost).
|
|
304
|
+
if (emitAudit) {
|
|
305
|
+
appendAuditEvent(db, {
|
|
306
|
+
tenantId,
|
|
307
|
+
actor,
|
|
308
|
+
op: 'predict_baserate',
|
|
309
|
+
targetId: classTag,
|
|
310
|
+
metadata: { class_tag: classTag, n_closed: 0 },
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
return {
|
|
314
|
+
classTag,
|
|
315
|
+
nClosed: 0,
|
|
316
|
+
nRatioEligible: 0,
|
|
317
|
+
meanEstimate: null,
|
|
318
|
+
meanActual: null,
|
|
319
|
+
meanRatio: null,
|
|
320
|
+
p50Ratio: null,
|
|
321
|
+
mae: null,
|
|
322
|
+
summary: '',
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
const ratioEligible = rows.filter((r) => r.estimate_value > 0);
|
|
326
|
+
const nRatioEligible = ratioEligible.length;
|
|
327
|
+
const meanEstimate = rows.reduce((s, r) => s + r.estimate_value, 0) / nClosed;
|
|
328
|
+
const meanActual = rows.reduce((s, r) => s + r.actual_value, 0) / nClosed;
|
|
329
|
+
const mae = rows.reduce((s, r) => s + Math.abs(r.actual_value - r.estimate_value), 0) / nClosed;
|
|
330
|
+
let meanRatio = null;
|
|
331
|
+
let p50Ratio = null;
|
|
332
|
+
if (nRatioEligible > 0) {
|
|
333
|
+
const ratios = ratioEligible.map((r) => r.actual_value / r.estimate_value);
|
|
334
|
+
meanRatio = ratios.reduce((s, x) => s + x, 0) / nRatioEligible;
|
|
335
|
+
const sorted = ratios.slice().sort((a, b) => a - b);
|
|
336
|
+
p50Ratio = nRatioEligible % 2 === 1
|
|
337
|
+
? sorted[(nRatioEligible - 1) / 2]
|
|
338
|
+
: (sorted[nRatioEligible / 2 - 1] + sorted[nRatioEligible / 2]) / 2;
|
|
339
|
+
}
|
|
340
|
+
const ratioPart = meanRatio !== null
|
|
341
|
+
? `averaged ${meanRatio.toFixed(2)}x actual`
|
|
342
|
+
: 'no ratio-eligible rows (all estimates were 0)';
|
|
343
|
+
const summary = `Last ${nClosed} estimate${nClosed === 1 ? '' : 's'} in class ${classTag} ${ratioPart} (MAE ${mae.toFixed(2)}).`;
|
|
344
|
+
if (emitAudit) {
|
|
345
|
+
appendAuditEvent(db, {
|
|
346
|
+
tenantId,
|
|
347
|
+
actor,
|
|
348
|
+
op: 'predict_baserate',
|
|
349
|
+
targetId: classTag,
|
|
350
|
+
metadata: { class_tag: classTag, n_closed: nClosed },
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
return {
|
|
354
|
+
classTag,
|
|
355
|
+
nClosed,
|
|
356
|
+
nRatioEligible,
|
|
357
|
+
meanEstimate,
|
|
358
|
+
meanActual,
|
|
359
|
+
meanRatio,
|
|
360
|
+
p50Ratio,
|
|
361
|
+
mae,
|
|
362
|
+
summary,
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
finally {
|
|
366
|
+
closeHippoDb(db);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
export function loadOpenPredictions(hippoRoot, tenantId, opts = {}) {
|
|
370
|
+
assertTenantId('loadOpenPredictions', tenantId);
|
|
371
|
+
const limit = opts.limit ?? 100;
|
|
372
|
+
const db = openHippoDb(hippoRoot);
|
|
373
|
+
try {
|
|
374
|
+
let rows;
|
|
375
|
+
if (opts.classTag) {
|
|
376
|
+
rows = db.prepare(`
|
|
377
|
+
SELECT id, memory_id, tenant_id, class_tag, claim_text,
|
|
378
|
+
estimate_value, estimate_unit, target_date,
|
|
379
|
+
actual_value, closure_state, closed_at, closure_note, created_at
|
|
380
|
+
FROM predictions
|
|
381
|
+
WHERE tenant_id = ? AND class_tag = ? AND closure_state = 'open'
|
|
382
|
+
ORDER BY created_at DESC, id DESC
|
|
383
|
+
LIMIT ?
|
|
384
|
+
`).all(tenantId, opts.classTag, limit);
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
rows = db.prepare(`
|
|
388
|
+
SELECT id, memory_id, tenant_id, class_tag, claim_text,
|
|
389
|
+
estimate_value, estimate_unit, target_date,
|
|
390
|
+
actual_value, closure_state, closed_at, closure_note, created_at
|
|
391
|
+
FROM predictions
|
|
392
|
+
WHERE tenant_id = ? AND closure_state = 'open'
|
|
393
|
+
ORDER BY created_at DESC, id DESC
|
|
394
|
+
LIMIT ?
|
|
395
|
+
`).all(tenantId, limit);
|
|
396
|
+
}
|
|
397
|
+
return rows.map(rowToPrediction);
|
|
398
|
+
}
|
|
399
|
+
finally {
|
|
400
|
+
closeHippoDb(db);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Resolve a query-token set to a unique best-matching class_tag for the
|
|
405
|
+
* tenant. Scores by lower-cased token overlap; requires best score ≥ 1
|
|
406
|
+
* AND strictly greater than the 2nd-best score.
|
|
407
|
+
*
|
|
408
|
+
* Indexed via idx_predictions_tenant_class (db.ts:1015) → O(log n) seek
|
|
409
|
+
* plus a small DISTINCT scan over the per-tenant class-tag set.
|
|
410
|
+
*
|
|
411
|
+
* Scope behaviour (v1 design choice, independent-review-critic round 1
|
|
412
|
+
* MED): class_tag selection is TENANT-GLOBAL, NOT scope-filtered against
|
|
413
|
+
* the recall's opts.scope. The class_tag is an aggregator label across
|
|
414
|
+
* historical predictions in the class, not a per-memory scope-bound
|
|
415
|
+
* property. A no-scope recall CAN surface a class_tag from a privately-
|
|
416
|
+
* scoped prediction's class in PlanningFallacyHint.classTag — by design,
|
|
417
|
+
* because base-rate reasoning needs the full historical sample.
|
|
418
|
+
* Implications:
|
|
419
|
+
* - The hint payload itself carries no memory content (only the aggregate
|
|
420
|
+
* summary string + numeric stats), so memory bodies do not leak.
|
|
421
|
+
* - The class_tag NAME is the side-channel. If sensitive labels are a
|
|
422
|
+
* concern, callers should either use opaque class names (e.g. hashes
|
|
423
|
+
* or numeric tokens) or set HIPPO_AUTODEBIAS=off.
|
|
424
|
+
* - tests/api-recall-autodebias.test.ts locks this with an explicit
|
|
425
|
+
* test asserting that scope-set predictions surface via no-scope
|
|
426
|
+
* recalls (so future "fix" attempts that scope-filter trip CI).
|
|
427
|
+
*/
|
|
428
|
+
function resolveClassFromTokens(hippoRoot, tenantId, queryTokens) {
|
|
429
|
+
if (queryTokens.length === 0)
|
|
430
|
+
return { classTag: null, tiebreak: false };
|
|
431
|
+
const db = openHippoDb(hippoRoot);
|
|
432
|
+
try {
|
|
433
|
+
const rows = db.prepare(`SELECT DISTINCT class_tag FROM predictions WHERE tenant_id = ?`).all(tenantId);
|
|
434
|
+
const querySet = new Set(queryTokens);
|
|
435
|
+
let bestScore = 0;
|
|
436
|
+
let bestClass = null;
|
|
437
|
+
let secondBest = 0;
|
|
438
|
+
for (const { class_tag } of rows) {
|
|
439
|
+
const classTokens = class_tag
|
|
440
|
+
.toLowerCase()
|
|
441
|
+
.split(/[-_\s]+/)
|
|
442
|
+
.filter((t) => t.length >= 3);
|
|
443
|
+
let score = 0;
|
|
444
|
+
for (const t of classTokens)
|
|
445
|
+
if (querySet.has(t))
|
|
446
|
+
score++;
|
|
447
|
+
if (score > bestScore) {
|
|
448
|
+
secondBest = bestScore;
|
|
449
|
+
bestScore = score;
|
|
450
|
+
bestClass = class_tag;
|
|
451
|
+
}
|
|
452
|
+
else if (score === bestScore && score > 0) {
|
|
453
|
+
// Tie at current best — bump secondBest. Do NOT update bestClass
|
|
454
|
+
// (alphabetical tiebreak would pick wrong class on ambiguous query
|
|
455
|
+
// like "migration will take 3 days" between migration-effort vs
|
|
456
|
+
// migration-risk; silent on tie instead).
|
|
457
|
+
secondBest = score;
|
|
458
|
+
}
|
|
459
|
+
else if (score > secondBest) {
|
|
460
|
+
secondBest = score;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (bestScore < 1)
|
|
464
|
+
return { classTag: null, tiebreak: false };
|
|
465
|
+
if (bestScore === secondBest)
|
|
466
|
+
return { classTag: null, tiebreak: true };
|
|
467
|
+
return { classTag: bestClass, tiebreak: false };
|
|
468
|
+
}
|
|
469
|
+
finally {
|
|
470
|
+
closeHippoDb(db);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* J3.2 orchestrator. Composes the forward-claim detector + class resolver +
|
|
475
|
+
* baserate compute, with telemetry-grade audit emission at every decision
|
|
476
|
+
* point (success, no-class-match, tiebreak).
|
|
477
|
+
*
|
|
478
|
+
* Returns null on any of:
|
|
479
|
+
* - mode === 'off' (env-disabled; pays only the env read, skips regex)
|
|
480
|
+
* - empty queryText
|
|
481
|
+
* - no forward-claim regex match
|
|
482
|
+
* - resolver returns no class (no overlap ≥ 1; emits no_class_match audit)
|
|
483
|
+
* - resolver returns tiebreak (≥2 classes tied at best; emits tiebreak audit)
|
|
484
|
+
* - resolved class has nClosed=0 (no historical data yet; silent)
|
|
485
|
+
*
|
|
486
|
+
* On success: calls computePredictionBaserate(..., emitAudit=false) so the
|
|
487
|
+
* predict_baserate audit channel stays scoped to deliberate predict-
|
|
488
|
+
* baserate calls (the orchestrator's own recall_autodebias_hint audit
|
|
489
|
+
* carries n_closed + mean_ratio in metadata so no telemetry is lost), then
|
|
490
|
+
* emits recall_autodebias_hint audit + returns the hint.
|
|
491
|
+
*
|
|
492
|
+
* Latency budget (plan §Latency): ~50us regex-only on miss; ~750-850us
|
|
493
|
+
* on full match+resolve+baserate path. Well under 50ms target.
|
|
494
|
+
*/
|
|
495
|
+
export function computePlanningFallacyHint(hippoRoot, tenantId, queryText, opts = {}) {
|
|
496
|
+
// Env read FIRST so AUTODEBIAS=off pays zero regex cost. Per-call read
|
|
497
|
+
// (rather than module-load cache) is deliberate: tests env-toggle this
|
|
498
|
+
// via process.env mutation without module reload.
|
|
499
|
+
const mode = opts.mode ?? (process.env.HIPPO_AUTODEBIAS === 'off' ? 'off' : 'regex');
|
|
500
|
+
if (mode === 'off')
|
|
501
|
+
return null;
|
|
502
|
+
if (!queryText)
|
|
503
|
+
return null;
|
|
504
|
+
const match = detectForwardClaim(queryText);
|
|
505
|
+
if (!match)
|
|
506
|
+
return null;
|
|
507
|
+
const actor = opts.actor ?? 'recall';
|
|
508
|
+
const resolution = resolveClassFromTokens(hippoRoot, tenantId, match.classQueryTokens);
|
|
509
|
+
if (resolution.tiebreak) {
|
|
510
|
+
// Telemetry: forward-claim detected, ≥2 classes tied at best overlap.
|
|
511
|
+
// Silent to caller; surfaces in audit only.
|
|
512
|
+
const db = openHippoDb(hippoRoot);
|
|
513
|
+
try {
|
|
514
|
+
appendAuditEvent(db, {
|
|
515
|
+
tenantId,
|
|
516
|
+
actor,
|
|
517
|
+
op: 'recall_autodebias_hint_tiebreak',
|
|
518
|
+
targetId: match.phrase.slice(0, 100),
|
|
519
|
+
metadata: { detected_phrase: match.phrase, token_count: match.classQueryTokens.length },
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
finally {
|
|
523
|
+
closeHippoDb(db);
|
|
524
|
+
}
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
if (!resolution.classTag) {
|
|
528
|
+
// Telemetry: forward-claim detected, no class scored ≥ 1.
|
|
529
|
+
// This is the channel that drives the embedding-fallback decision
|
|
530
|
+
// for J3.3 — high volume here = regex+token-overlap is missing
|
|
531
|
+
// legitimate forward-claims that have NO obvious class signal.
|
|
532
|
+
const db = openHippoDb(hippoRoot);
|
|
533
|
+
try {
|
|
534
|
+
appendAuditEvent(db, {
|
|
535
|
+
tenantId,
|
|
536
|
+
actor,
|
|
537
|
+
op: 'recall_autodebias_hint_no_class_match',
|
|
538
|
+
targetId: match.phrase.slice(0, 100),
|
|
539
|
+
metadata: { detected_phrase: match.phrase, token_count: match.classQueryTokens.length },
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
finally {
|
|
543
|
+
closeHippoDb(db);
|
|
544
|
+
}
|
|
545
|
+
return null;
|
|
546
|
+
}
|
|
547
|
+
// emitAudit=false: avoid double-write to predict_baserate channel.
|
|
548
|
+
// The recall_autodebias_hint audit below carries n_closed + mean_ratio.
|
|
549
|
+
const baserate = computePredictionBaserate(hippoRoot, tenantId, resolution.classTag, actor,
|
|
550
|
+
/*emitAudit=*/ false);
|
|
551
|
+
if (baserate.nClosed === 0)
|
|
552
|
+
return null; // Silent — wait for closed data.
|
|
553
|
+
const db = openHippoDb(hippoRoot);
|
|
554
|
+
try {
|
|
555
|
+
appendAuditEvent(db, {
|
|
556
|
+
tenantId,
|
|
557
|
+
actor,
|
|
558
|
+
op: 'recall_autodebias_hint',
|
|
559
|
+
targetId: resolution.classTag,
|
|
560
|
+
metadata: {
|
|
561
|
+
class_tag: resolution.classTag,
|
|
562
|
+
detected_phrase: match.phrase,
|
|
563
|
+
n_closed: baserate.nClosed,
|
|
564
|
+
mean_ratio: baserate.meanRatio,
|
|
565
|
+
},
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
finally {
|
|
569
|
+
closeHippoDb(db);
|
|
570
|
+
}
|
|
571
|
+
return {
|
|
572
|
+
classTag: resolution.classTag,
|
|
573
|
+
baserateSummary: baserate.summary,
|
|
574
|
+
source: 'j3.2-auto',
|
|
575
|
+
detectedPhrase: match.phrase,
|
|
576
|
+
nClosed: baserate.nClosed,
|
|
577
|
+
meanRatio: baserate.meanRatio,
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
//# sourceMappingURL=predictions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predictions.js","sourceRoot":"","sources":["../src/predictions.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AA8HA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;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;AAqgDD;;;;;;;;;;GAUG;AACH,wBAAsB,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CAyIlE"}
|