hippo-memory 1.61.0 → 1.63.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 +37 -53
- package/dist/agent-memories/apply.d.ts +3 -1
- package/dist/agent-memories/apply.js +23 -1
- package/dist/agent-memories/claude-code.d.ts +4 -1
- package/dist/agent-memories/claude-code.js +53 -9
- package/dist/agent-memories/report.d.ts +1 -0
- package/dist/agent-memories/report.js +2 -2
- package/dist/agent-memories/sync.d.ts +3 -3
- package/dist/agent-memories/sync.js +46 -24
- package/dist/agent-memories/types.d.ts +0 -2
- package/dist/ambient-store.d.ts +4 -4
- package/dist/ambient-store.js +4 -3
- package/dist/api/assemble.d.ts +7 -10
- package/dist/api/assemble.js +62 -66
- package/dist/api/audit.d.ts +2 -2
- package/dist/api/audit.js +2 -2
- package/dist/api/auth.d.ts +6 -6
- package/dist/api/auth.js +5 -7
- package/dist/api/context-select.d.ts +50 -0
- package/dist/api/context-select.js +342 -0
- package/dist/api/context-types.d.ts +12 -17
- package/dist/api/context.d.ts +5 -4
- package/dist/api/context.js +208 -535
- package/dist/api/dormant.js +1 -1
- package/dist/api/drill-down.d.ts +4 -4
- package/dist/api/drill-down.js +56 -41
- package/dist/api/outcome.d.ts +8 -13
- package/dist/api/outcome.js +13 -17
- package/dist/api/promote.d.ts +5 -8
- package/dist/api/promote.js +55 -66
- package/dist/api/quarantine.js +3 -2
- package/dist/api/recall-types.d.ts +43 -55
- package/dist/api/recall.d.ts +3 -3
- package/dist/api/recall.js +310 -456
- package/dist/api/remember.d.ts +2 -2
- package/dist/api/sleep.d.ts +7 -35
- package/dist/api/sleep.js +206 -220
- package/dist/api/tokens.d.ts +2 -2
- package/dist/api/tokens.js +2 -2
- package/dist/api/types.d.ts +6 -10
- package/dist/api/types.js +2 -4
- package/dist/audit-prune.d.ts +4 -6
- package/dist/audit-prune.js +3 -5
- package/dist/audit.js +11 -33
- package/dist/auth.d.ts +8 -9
- package/dist/auth.js +5 -7
- package/dist/autolearn.d.ts +1 -1
- package/dist/autolearn.js +1 -1
- package/dist/availability.js +3 -5
- package/dist/capture/command.d.ts +5 -4
- package/dist/capture/command.js +8 -22
- package/dist/capture/compact.d.ts +2 -2
- package/dist/capture/compact.js +11 -15
- package/dist/capture/extract.js +37 -115
- package/dist/capture-error.d.ts +1 -1
- package/dist/capture-error.js +1 -1
- package/dist/churn-git.d.ts +1 -1
- package/dist/churn-git.js +1 -1
- package/dist/cli/audit.js +3 -4
- package/dist/cli/auth.js +3 -6
- package/dist/cli/briefs.js +324 -306
- package/dist/cli/context.js +44 -34
- package/dist/cli/continuity.js +283 -271
- package/dist/cli/curate.d.ts +1 -1
- package/dist/cli/curate.js +43 -58
- package/dist/cli/dag.js +5 -9
- package/dist/cli/decisions.js +334 -345
- package/dist/cli/explain.js +68 -61
- package/dist/cli/goals.js +1 -1
- package/dist/cli/init.js +1 -1
- package/dist/cli/maintenance.js +62 -51
- package/dist/cli/playbooks.js +391 -379
- package/dist/cli/projects.js +11 -6
- package/dist/cli/recall.js +30 -44
- package/dist/cli/remember.js +118 -87
- package/dist/cli/session-hooks.js +106 -115
- package/dist/cli/setup.d.ts +1 -1
- package/dist/cli/setup.js +267 -250
- package/dist/cli/shared.js +3 -3
- package/dist/cli/slack.js +1 -1
- package/dist/cli/sleep.js +27 -1
- package/dist/cli/status.d.ts +4 -4
- package/dist/cli/status.js +80 -76
- package/dist/cli/transfer.js +88 -107
- package/dist/cli/usage.js +9 -6
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +4 -9
- package/dist/compaction-record.d.ts +2 -2
- package/dist/compaction-record.js +89 -68
- package/dist/compare.d.ts +11 -16
- package/dist/compare.js +11 -16
- package/dist/config.d.ts +19 -18
- package/dist/config.js +90 -67
- package/dist/connectors/github/backfill.d.ts +2 -2
- package/dist/connectors/github/backfill.js +8 -15
- package/dist/connectors/github/cli-impl.js +3 -8
- package/dist/connectors/github/deletion.d.ts +5 -12
- package/dist/connectors/github/deletion.js +5 -12
- package/dist/connectors/github/dlq.d.ts +6 -9
- package/dist/connectors/github/dlq.js +2 -3
- package/dist/connectors/github/ingest.d.ts +5 -7
- package/dist/connectors/github/ingest.js +8 -12
- package/dist/connectors/github/octokit-client.d.ts +3 -5
- package/dist/connectors/github/octokit-client.js +5 -6
- package/dist/connectors/github/signature.d.ts +9 -39
- package/dist/connectors/github/signature.js +9 -39
- package/dist/connectors/github/tenant-routing.d.ts +1 -1
- package/dist/connectors/github/tenant-routing.js +1 -1
- package/dist/connectors/github/transform.js +2 -2
- package/dist/connectors/github/types.d.ts +2 -10
- package/dist/connectors/github/types.js +1 -3
- package/dist/connectors/slack/deletion.d.ts +3 -8
- package/dist/connectors/slack/deletion.js +3 -8
- package/dist/connectors/slack/dlq.d.ts +1 -1
- package/dist/connectors/slack/ingest.d.ts +1 -1
- package/dist/connectors/slack/ingest.js +7 -16
- package/dist/connectors/slack/signature.d.ts +1 -1
- package/dist/connectors/slack/tenant-routing.d.ts +3 -5
- package/dist/connectors/slack/tenant-routing.js +3 -5
- package/dist/connectors/slack/transform.d.ts +5 -6
- package/dist/connectors/slack/transform.js +5 -6
- package/dist/connectors/slack/types.d.ts +2 -6
- package/dist/connectors/slack/types.js +1 -3
- package/dist/connectors/slack/web-client.js +10 -3
- package/dist/connectors/slack/workspaces.d.ts +3 -5
- package/dist/connectors/slack/workspaces.js +3 -5
- package/dist/consolidate/conflicts.js +3 -14
- package/dist/consolidate/decay.js +9 -29
- package/dist/consolidate/llm-passes.js +4 -5
- package/dist/consolidate/merge.js +8 -23
- package/dist/consolidate/run.d.ts +1 -8
- package/dist/consolidate/run.js +3 -25
- package/dist/consolidate/sleep.js +5 -17
- package/dist/consolidate/traces.js +9 -21
- package/dist/customer-notes.d.ts +5 -7
- package/dist/customer-notes.js +82 -76
- package/dist/dag.d.ts +10 -21
- package/dist/dag.js +189 -203
- package/dist/db/continuity.js +2 -2
- package/dist/db/migrations/v14.js +1 -1
- package/dist/db/migrations/v15.js +1 -2
- package/dist/db/migrations/v16.js +3 -4
- package/dist/db/migrations/v17.js +2 -3
- package/dist/db/migrations/v19.js +1 -1
- package/dist/db/migrations/v20.js +1 -1
- package/dist/db/migrations/v21.js +2 -6
- package/dist/db/migrations/v22.js +2 -4
- package/dist/db/migrations/v23.js +1 -1
- package/dist/db/migrations/v24.js +4 -6
- package/dist/db/migrations/v25.js +2 -3
- package/dist/db/migrations/v26.js +3 -3
- package/dist/db/migrations/v27.js +2 -10
- package/dist/db/migrations/v28.js +5 -8
- package/dist/db/migrations/v29.js +3 -4
- package/dist/db/migrations/v30.js +2 -2
- package/dist/db/migrations/v31.js +1 -1
- package/dist/db/migrations/v32.js +1 -1
- package/dist/db/migrations/v33.js +3 -3
- package/dist/db/migrations/v34.js +1 -1
- package/dist/db/migrations/v35.js +3 -4
- package/dist/db/migrations/v36.js +3 -4
- package/dist/db/migrations/v37.js +5 -5
- package/dist/db/migrations/v38.js +7 -8
- package/dist/db/migrations/v39.js +1 -1
- package/dist/db/migrations/v40.js +4 -16
- package/dist/db/migrations/v41.js +3 -4
- package/dist/db/migrations/v42.js +3 -4
- package/dist/db/migrations/v45.js +1 -1
- package/dist/db/migrations/v46.js +1 -1
- package/dist/db/migrations/v47.js +1 -1
- package/dist/db/migrations/v48.js +1 -1
- package/dist/decisions.d.ts +2 -2
- package/dist/decisions.js +97 -80
- package/dist/dedupe.js +86 -61
- package/dist/delivery-recorder.js +154 -135
- package/dist/doctor.js +129 -110
- package/dist/dormant.js +1 -4
- package/dist/embedding-provider.d.ts +4 -8
- package/dist/embedding-provider.js +4 -8
- package/dist/embeddings.js +55 -47
- package/dist/env.d.ts +1 -1
- package/dist/env.js +12 -12
- package/dist/escape.d.ts +5 -0
- package/dist/escape.js +10 -0
- package/dist/eval-stats.d.ts +1 -2
- package/dist/eval-stats.js +1 -2
- package/dist/eval-suite.js +27 -21
- package/dist/extract.js +4 -9
- package/dist/failure-log.d.ts +3 -3
- package/dist/failure-log.js +1 -1
- package/dist/forward-claim-detector.d.ts +2 -4
- package/dist/forward-claim-detector.js +6 -11
- package/dist/goals.d.ts +3 -3
- package/dist/goals.js +103 -91
- package/dist/graph/read.d.ts +2 -2
- package/dist/graph/read.js +5 -6
- package/dist/graph/types.d.ts +8 -8
- package/dist/graph/write.d.ts +7 -14
- package/dist/graph/write.js +16 -23
- package/dist/graph-extract.d.ts +7 -8
- package/dist/graph-extract.js +62 -72
- package/dist/graph-recall.d.ts +2 -2
- package/dist/graph-recall.js +55 -49
- package/dist/graph-stream.d.ts +5 -6
- package/dist/graph-stream.js +66 -57
- package/dist/graph-view.d.ts +2 -2
- package/dist/graph-view.js +7 -7
- package/dist/half-life-migration.d.ts +1 -2
- package/dist/half-life-migration.js +2 -3
- package/dist/hooks/codex-session.js +1 -1
- package/dist/hooks/codex-wrapper.d.ts +1 -1
- package/dist/hooks/codex-wrapper.js +3 -2
- package/dist/hooks/json-hooks.d.ts +2 -2
- package/dist/hooks/json-hooks.js +5 -4
- package/dist/hooks/opencode.d.ts +1 -1
- package/dist/hooks/opencode.js +5 -4
- package/dist/hooks/shared.d.ts +3 -7
- package/dist/hooks/shared.js +1 -8
- package/dist/http-util.d.ts +2 -3
- package/dist/http-util.js +3 -0
- package/dist/importers/core.d.ts +2 -9
- package/dist/importers/core.js +15 -30
- package/dist/importers/sources.js +2 -1
- package/dist/importers/vault.js +2 -20
- package/dist/incidents.d.ts +1 -1
- package/dist/incidents.js +46 -39
- package/dist/instruction-detect.d.ts +1 -1
- package/dist/instruction-detect.js +1 -1
- package/dist/invalidation.d.ts +3 -0
- package/dist/invalidation.js +160 -114
- package/dist/json.d.ts +5 -0
- package/dist/json.js +4 -0
- package/dist/judgment.js +1 -2
- package/dist/local-embedding.js +1 -1
- package/dist/mcp/admin-tools.js +7 -17
- package/dist/mcp/format.js +1 -1
- package/dist/mcp/framing.js +3 -6
- package/dist/mcp/protocol.d.ts +2 -5
- package/dist/mcp/protocol.js +1 -3
- package/dist/mcp/recall-tools.js +12 -15
- package/dist/mcp/request.js +4 -3
- package/dist/mcp/session-state.js +2 -3
- package/dist/mcp/stdio.js +2 -1
- package/dist/mcp/tools.js +9 -6
- package/dist/memory-value-weights.d.ts +5 -8
- package/dist/memory-value-weights.js +5 -8
- package/dist/memory-value.d.ts +13 -13
- package/dist/memory-value.js +26 -37
- package/dist/memory.d.ts +20 -22
- package/dist/memory.js +24 -48
- package/dist/multihop.d.ts +1 -1
- package/dist/multihop.js +3 -2
- package/dist/owner-validation.d.ts +4 -5
- package/dist/owner-validation.js +4 -5
- package/dist/physics.d.ts +4 -4
- package/dist/physics.js +7 -9
- package/dist/policies.d.ts +9 -10
- package/dist/policies.js +96 -81
- package/dist/postinstall.js +3 -6
- package/dist/predictions/planning-fallacy.d.ts +9 -14
- package/dist/predictions/planning-fallacy.js +10 -16
- package/dist/predictions/store.d.ts +15 -23
- package/dist/predictions/store.js +36 -33
- package/dist/processes.d.ts +2 -7
- package/dist/processes.js +88 -72
- package/dist/project-briefs.d.ts +2 -3
- package/dist/project-briefs.js +141 -118
- package/dist/project-identity.d.ts +22 -9
- package/dist/project-identity.js +47 -12
- package/dist/project-merge.d.ts +28 -5
- package/dist/project-merge.js +213 -46
- package/dist/project-remote.d.ts +12 -0
- package/dist/project-remote.js +138 -0
- package/dist/prompt-recall.js +1 -2
- package/dist/rate-limit.d.ts +1 -1
- package/dist/rate-limit.js +1 -1
- package/dist/raw-archive.d.ts +9 -0
- package/dist/raw-archive.js +70 -53
- package/dist/recall-history.d.ts +19 -20
- package/dist/recall-history.js +24 -42
- package/dist/recall-pipeline.js +4 -28
- package/dist/recall-scope.d.ts +7 -8
- package/dist/recall-scope.js +7 -8
- package/dist/recall-trace.d.ts +5 -9
- package/dist/recall-trace.js +6 -10
- package/dist/refine-llm.d.ts +1 -1
- package/dist/refine-llm.js +2 -2
- package/dist/reject-flow.d.ts +3 -4
- package/dist/reject-flow.js +122 -117
- package/dist/rejection.d.ts +5 -6
- package/dist/rejection.js +7 -15
- package/dist/rerankers/clef.d.ts +1 -1
- package/dist/rerankers/jev.d.ts +1 -2
- package/dist/rerankers/jev.js +4 -5
- package/dist/rerankers/llm.d.ts +1 -2
- package/dist/rerankers/llm.js +1 -2
- package/dist/rerankers/types.d.ts +1 -2
- package/dist/rrf.d.ts +2 -2
- package/dist/rrf.js +2 -2
- package/dist/search/bm25-search.d.ts +1 -1
- package/dist/search/bm25-search.js +2 -1
- package/dist/search/boosts.js +2 -1
- package/dist/search/hybrid.d.ts +1 -1
- package/dist/search/hybrid.js +2 -1
- package/dist/search/physics-search.d.ts +1 -1
- package/dist/search/physics-search.js +2 -1
- package/dist/search/types.d.ts +2 -0
- package/dist/search/types.js +3 -1
- package/dist/secret-detect.d.ts +4 -5
- package/dist/secret-detect.js +6 -10
- package/dist/server/auth.js +5 -5
- package/dist/server/client-ip.js +1 -1
- package/dist/server/cursor.js +2 -1
- package/dist/server/mcp-http.js +4 -4
- package/dist/server/request.d.ts +3 -6
- package/dist/server/request.js +6 -7
- package/dist/server/routes/admin.js +5 -4
- package/dist/server/routes/customer-notes.js +6 -5
- package/dist/server/routes/decisions.js +4 -3
- package/dist/server/routes/incidents.js +7 -5
- package/dist/server/routes/memories.js +7 -7
- package/dist/server/routes/policies.js +3 -2
- package/dist/server/routes/predictions.js +12 -15
- package/dist/server/routes/processes.js +3 -2
- package/dist/server/routes/project-briefs.js +8 -7
- package/dist/server/routes/recall.js +95 -93
- package/dist/server/routes/skills.js +6 -5
- package/dist/server/types.d.ts +1 -1
- package/dist/server/validation.d.ts +1 -2
- package/dist/server/validation.js +7 -14
- package/dist/server-detect.js +72 -58
- package/dist/server.d.ts +2 -2
- package/dist/server.js +131 -117
- package/dist/shared.d.ts +26 -17
- package/dist/shared.js +102 -104
- package/dist/skills.d.ts +3 -3
- package/dist/skills.js +88 -72
- package/dist/store/audit-event.d.ts +2 -2
- package/dist/store/audit-event.js +1 -1
- package/dist/store/candidates.d.ts +2 -2
- package/dist/store/candidates.js +4 -3
- package/dist/store/conflicts.js +30 -22
- package/dist/store/delete-and-batch.d.ts +11 -14
- package/dist/store/delete-and-batch.js +40 -91
- package/dist/store/entry-reads.d.ts +17 -25
- package/dist/store/entry-reads.js +59 -40
- package/dist/store/entry-row.d.ts +6 -24
- package/dist/store/entry-row.js +6 -24
- package/dist/store/entry-writes.d.ts +6 -7
- package/dist/store/entry-writes.js +13 -11
- package/dist/store/handoffs.d.ts +1 -1
- package/dist/store/handoffs.js +7 -10
- package/dist/store/index-and-stats.d.ts +2 -6
- package/dist/store/index-and-stats.js +4 -10
- package/dist/store/mirrors.d.ts +6 -19
- package/dist/store/mirrors.js +14 -39
- package/dist/store/open.js +9 -31
- package/dist/store/rows.d.ts +5 -11
- package/dist/store/rows.js +6 -11
- package/dist/store/search-rows.d.ts +17 -34
- package/dist/store/search-rows.js +34 -56
- package/dist/store/sessions.d.ts +4 -5
- package/dist/store/sessions.js +5 -6
- package/dist/store/summaries.d.ts +13 -17
- package/dist/store/summaries.js +26 -70
- package/dist/support-bundle.js +4 -8
- package/dist/tenant.d.ts +1 -5
- package/dist/token-ledger.d.ts +1 -1
- package/dist/token-ledger.js +3 -5
- package/dist/trace.js +1 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/working-memory.d.ts +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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Prediction first-class object.
|
|
3
3
|
*
|
|
4
4
|
* Canonical store for ex-ante claims that can be closed against ex-post
|
|
5
5
|
* outcomes. The `predictions` table holds every field (including
|
|
@@ -19,10 +19,8 @@
|
|
|
19
19
|
* a failure in either step rolls back both. Pattern matches supersede
|
|
20
20
|
* (api.ts:1486) and the Slack/GitHub connectors.
|
|
21
21
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* (estimate_value, actual_value) at query time. J3 is a follow-up episode;
|
|
25
|
-
* this module ships the data layer.
|
|
22
|
+
* The planning-fallacy detector reads `loadPredictionsByClass` and computes
|
|
23
|
+
* per-class base rates from (estimate_value, actual_value) at query time.
|
|
26
24
|
*/
|
|
27
25
|
import { BadRequestError, NotFoundError } from '../api-errors.js';
|
|
28
26
|
import { openHippoDb, closeHippoDb } from '../db.js';
|
|
@@ -68,7 +66,7 @@ function rowToPrediction(row) {
|
|
|
68
66
|
* The memory is tagged `['prediction', classTag]` with `source='prediction'`
|
|
69
67
|
* and `kind='distilled'`. It surfaces in `hippo recall` so the agent can
|
|
70
68
|
* see open predictions naturally; the predictions table is the canonical
|
|
71
|
-
* structured store used by
|
|
69
|
+
* structured store used by the planning-fallacy detector.
|
|
72
70
|
*/
|
|
73
71
|
export function savePrediction(hippoRoot, tenantId, opts, actor = 'cli') {
|
|
74
72
|
assertTenantId('savePrediction', tenantId);
|
|
@@ -142,8 +140,7 @@ function insertPredictionRow(db, memoryId, tenantId, opts, now, actor) {
|
|
|
142
140
|
/**
|
|
143
141
|
* Close an existing open prediction. Updates the predictions row only;
|
|
144
142
|
* the memory mirror is NOT mutated in v1 (predictions table is canonical).
|
|
145
|
-
*
|
|
146
|
-
* actualValue) at query time.
|
|
143
|
+
* Accuracy is computed from (estimateValue, actualValue) at query time.
|
|
147
144
|
*/
|
|
148
145
|
export function closePrediction(hippoRoot, tenantId, id, opts, actor = 'cli') {
|
|
149
146
|
assertTenantId('closePrediction', tenantId);
|
|
@@ -175,13 +172,8 @@ export function closePrediction(hippoRoot, tenantId, id, opts, actor = 'cli') {
|
|
|
175
172
|
}
|
|
176
173
|
/** Closes the row, reloads it and audits the close; the caller owns the transaction. */
|
|
177
174
|
function closeOpenPredictionRow(db, tenantId, id, opts, now, actor) {
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
// an already-closed prediction return a clear error instead of
|
|
181
|
-
// silently overwriting actual_value + emitting a duplicate
|
|
182
|
-
// predict_close audit row. Zero changed rows → caller decides
|
|
183
|
-
// whether it's a "not found" or "already closed" case based on the
|
|
184
|
-
// load-then-close pattern.
|
|
175
|
+
// closure_state='open' in the WHERE stops a retried close from overwriting
|
|
176
|
+
// actual_value and auditing twice; zero changed rows means not found or already closed.
|
|
185
177
|
const updateResult = db.prepare(`
|
|
186
178
|
UPDATE predictions
|
|
187
179
|
SET actual_value = ?, closure_state = ?, closed_at = ?, closure_note = ?
|
|
@@ -283,29 +275,41 @@ export function loadPredictionsByClass(hippoRoot, tenantId, classTag, opts = {})
|
|
|
283
275
|
closeHippoDb(db);
|
|
284
276
|
}
|
|
285
277
|
}
|
|
278
|
+
/** Every prediction in the tenant, open and closed, across all classes: the `status=all` list without a class. */
|
|
279
|
+
export function loadAllPredictions(hippoRoot, tenantId, opts = {}) {
|
|
280
|
+
assertTenantId('loadAllPredictions', tenantId);
|
|
281
|
+
const after = keysetAfter('created_at', 'id', opts.after);
|
|
282
|
+
const db = openHippoDb(hippoRoot);
|
|
283
|
+
try {
|
|
284
|
+
// SAFETY: rows' shape matches the columns named in the SELECT.
|
|
285
|
+
const rows = db.prepare(`
|
|
286
|
+
SELECT id, memory_id, tenant_id, class_tag, claim_text,
|
|
287
|
+
estimate_value, estimate_unit, target_date,
|
|
288
|
+
actual_value, closure_state, closed_at, closure_note, created_at
|
|
289
|
+
FROM predictions
|
|
290
|
+
WHERE tenant_id = ?${after.sql}
|
|
291
|
+
ORDER BY created_at DESC, id DESC
|
|
292
|
+
LIMIT ?
|
|
293
|
+
`).all(tenantId, ...after.params, opts.limit ?? 100);
|
|
294
|
+
return rows.map(rowToPrediction);
|
|
295
|
+
}
|
|
296
|
+
finally {
|
|
297
|
+
closeHippoDb(db);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
286
300
|
/**
|
|
287
|
-
* Compute base-rate stats for closed predictions in a class
|
|
288
|
-
*
|
|
289
|
-
* Lovallo-Kahneman (2003) inside-vs-outside view.
|
|
301
|
+
* Compute base-rate stats for closed predictions in a class for the
|
|
302
|
+
* planning-fallacy detector: Lovallo-Kahneman (2003) inside-vs-outside view.
|
|
290
303
|
*
|
|
291
304
|
* Filter: closure_state='closed' AND estimate_value IS NOT NULL AND
|
|
292
305
|
* actual_value IS NOT NULL. Excludes closed-unknown (no actual to
|
|
293
306
|
* compare against) and open (not yet resolved).
|
|
294
307
|
*
|
|
295
|
-
* Audit-emit is
|
|
296
|
-
* drift risk). Plan-eng-critic round 1 HIGH recommendation: emit inside
|
|
297
|
-
* helper, not at 3 call sites.
|
|
308
|
+
* Audit-emit is built in here, not at the 3 call sites, so callers cannot drift.
|
|
298
309
|
*/
|
|
299
310
|
export function computePredictionBaserate(hippoRoot, tenantId, classTag, actor = 'cli',
|
|
300
|
-
/**
|
|
301
|
-
*
|
|
302
|
-
* emitAudit=false and emits its own `recall_autodebias_hint` audit row
|
|
303
|
-
* instead, so the predict_baserate channel stays scoped to deliberate
|
|
304
|
-
* CLI / HTTP / MCP predict-baserate calls and does NOT pollute on every
|
|
305
|
-
* recall containing a forward-claim phrase. Default true preserves the
|
|
306
|
-
* v1.13.0 J3 audit semantics for the 3 direct callers (cmdPredict
|
|
307
|
-
* baserate, /v1/predictions/stats route, hippo_predict_baserate MCP
|
|
308
|
-
* handler) — none of them pass this argument. */
|
|
311
|
+
/** False skips the predict_baserate audit so that channel only records deliberate
|
|
312
|
+
* baserate calls, not every recall the planning-fallacy orchestrator inspects. */
|
|
309
313
|
emitAudit = true) {
|
|
310
314
|
assertTenantId('computePredictionBaserate', tenantId);
|
|
311
315
|
if (!classTag)
|
|
@@ -325,9 +329,8 @@ emitAudit = true) {
|
|
|
325
329
|
const nClosed = rows.length;
|
|
326
330
|
if (nClosed === 0) {
|
|
327
331
|
// Audit zero-result reads too — agents probing empty classes is
|
|
328
|
-
// a signal worth recording. Skipped when emitAudit=false
|
|
329
|
-
//
|
|
330
|
-
// only when nClosed > 0 anyway, so no signal is lost).
|
|
332
|
+
// a signal worth recording. Skipped when emitAudit=false: the orchestrator's own
|
|
333
|
+
// recall_autodebias_hint audit fires only when nClosed > 0, so no signal is lost.
|
|
331
334
|
if (emitAudit)
|
|
332
335
|
auditBaserateRead(db, tenantId, actor, classTag, 0);
|
|
333
336
|
return {
|
package/dist/processes.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Process first-class object.
|
|
3
3
|
*
|
|
4
4
|
* A `process` is a "living process map": a named, ordered list of steps that
|
|
5
5
|
* evolves over time. Unlike `incident` (open->resolved->closed, no supersede),
|
|
@@ -31,13 +31,9 @@
|
|
|
31
31
|
* them back. Pattern matches saveDecision (decisions.ts).
|
|
32
32
|
*/
|
|
33
33
|
import { type KeysetPosition } from './keyset.js';
|
|
34
|
+
import type { JsonValue } from './json.js';
|
|
34
35
|
export type ProcessStatus = 'active' | 'superseded' | 'closed';
|
|
35
36
|
export declare const VALID_PROCESS_STATES: ReadonlySet<ProcessStatus>;
|
|
36
|
-
/** Arbitrary JSON-shaped value; the domain type for untrusted input at the
|
|
37
|
-
* steps I/O boundary (validateProcessSteps parses this into string[]). */
|
|
38
|
-
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
39
|
-
[key: string]: JsonValue;
|
|
40
|
-
};
|
|
41
37
|
/** DoS / abuse caps on the steps body (untrusted at the HTTP/SDK boundary). */
|
|
42
38
|
export declare const MAX_PROCESS_STEPS = 200;
|
|
43
39
|
export declare const MAX_PROCESS_STEP_LEN = 2000;
|
|
@@ -109,5 +105,4 @@ export declare function loadProcesses(hippoRoot: string, tenantId: string, opts?
|
|
|
109
105
|
export declare function loadActiveProcesses(hippoRoot: string, tenantId: string, opts?: {
|
|
110
106
|
limit?: number;
|
|
111
107
|
}): Process[];
|
|
112
|
-
export {};
|
|
113
108
|
//# sourceMappingURL=processes.d.ts.map
|
package/dist/processes.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Process first-class object.
|
|
3
3
|
*
|
|
4
4
|
* A `process` is a "living process map": a named, ordered list of steps that
|
|
5
5
|
* evolves over time. Unlike `incident` (open->resolved->closed, no supersede),
|
|
@@ -130,9 +130,82 @@ function buildProcessContent(processName, steps, description) {
|
|
|
130
130
|
content += `\n\nDescription: ${description}`;
|
|
131
131
|
return content;
|
|
132
132
|
}
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
133
|
+
// Preflight the supersede target BEFORE inserting the new row. The new
|
|
134
|
+
// row's autoincrement id could otherwise collide with a non-existent
|
|
135
|
+
// supersedesProcessId (e.g. superseding id 1 on an empty store), making
|
|
136
|
+
// the row supersede itself. Validating first means the new row is never a
|
|
137
|
+
// candidate for its own supersede UPDATE. Mirrors saveDecision.
|
|
138
|
+
// The same SELECT reads the predecessor version so the
|
|
139
|
+
// successor's version is server-derived, never client-supplied.
|
|
140
|
+
function preflightProcessSupersede(db, tenantId, supersedesId) {
|
|
141
|
+
// SAFETY: SELECT status, version FROM processes; row shape matches
|
|
142
|
+
// the two selected columns 1:1.
|
|
143
|
+
const pred = db.prepare(`SELECT status, version FROM processes WHERE id = ? AND tenant_id = ?`).get(supersedesId, tenantId);
|
|
144
|
+
if (!pred) {
|
|
145
|
+
throw new NotFoundError(`saveProcess: process ${supersedesId} to supersede not found for tenant ${tenantId}`);
|
|
146
|
+
}
|
|
147
|
+
if (pred.status !== 'active') {
|
|
148
|
+
throw new ConflictError(`saveProcess: process ${supersedesId} is not active (status='${pred.status}'); only active processes can be superseded.`);
|
|
149
|
+
}
|
|
150
|
+
return pred.version + 1;
|
|
151
|
+
}
|
|
152
|
+
function insertProcessRow(db, memoryId, w, version) {
|
|
153
|
+
const result = db.prepare(`
|
|
154
|
+
INSERT INTO processes(
|
|
155
|
+
memory_id, tenant_id, process_name, description, steps, version,
|
|
156
|
+
status, superseded_by, superseded_at, change_summary, closed_at, created_at
|
|
157
|
+
) VALUES (?, ?, ?, ?, ?, ?, 'active', NULL, NULL, ?, NULL, ?)
|
|
158
|
+
`).run(memoryId, w.tenantId, w.processName, w.description ?? null, JSON.stringify(w.steps), version, w.changeSummary, w.now);
|
|
159
|
+
return Number(result.lastInsertRowid ?? 0);
|
|
160
|
+
}
|
|
161
|
+
function supersedeProcessRow(db, w, supersedesId, processId, version) {
|
|
162
|
+
const sup = db.prepare(`
|
|
163
|
+
UPDATE processes
|
|
164
|
+
SET status = 'superseded', superseded_by = ?, superseded_at = ?
|
|
165
|
+
WHERE id = ? AND tenant_id = ? AND status = 'active' AND id != ?
|
|
166
|
+
`).run(processId, w.now, supersedesId, w.tenantId, processId);
|
|
167
|
+
if (sup.changes === 0) {
|
|
168
|
+
throw new ConflictError(`saveProcess: process ${supersedesId} could not be superseded (no longer active or self-reference).`);
|
|
169
|
+
}
|
|
170
|
+
appendAuditEvent(db, {
|
|
171
|
+
tenantId: w.tenantId,
|
|
172
|
+
actor: w.actor,
|
|
173
|
+
op: 'process_supersede',
|
|
174
|
+
targetId: String(supersedesId),
|
|
175
|
+
metadata: {
|
|
176
|
+
process_id: supersedesId,
|
|
177
|
+
superseded_by: processId,
|
|
178
|
+
new_version: version,
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/** The afterWrite body: preflight, INSERT, supersede, reload, create audit, all in one SAVEPOINT. */
|
|
183
|
+
function writeProcessRow(db, memoryId, w) {
|
|
184
|
+
const version = w.supersedesId !== undefined ? preflightProcessSupersede(db, w.tenantId, w.supersedesId) : 1;
|
|
185
|
+
const processId = insertProcessRow(db, memoryId, w, version);
|
|
186
|
+
if (w.supersedesId !== undefined)
|
|
187
|
+
supersedeProcessRow(db, w, w.supersedesId, processId, version);
|
|
188
|
+
// SAFETY: SELECT ${PROCESS_COLS} enumerates every ProcessRow field
|
|
189
|
+
// 1:1 (see PROCESS_COLS above).
|
|
190
|
+
const row = db.prepare(`SELECT ${PROCESS_COLS} FROM processes WHERE id = ?`)
|
|
191
|
+
.get(processId);
|
|
192
|
+
if (!row)
|
|
193
|
+
throw new Error('saveProcess: failed to reload saved process row');
|
|
194
|
+
// GDPR-light metadata: ids + counts only, no process_name / step text.
|
|
195
|
+
appendAuditEvent(db, {
|
|
196
|
+
tenantId: w.tenantId,
|
|
197
|
+
actor: w.actor,
|
|
198
|
+
op: 'process_create',
|
|
199
|
+
targetId: String(processId),
|
|
200
|
+
metadata: {
|
|
201
|
+
process_id: processId,
|
|
202
|
+
version,
|
|
203
|
+
step_count: w.steps.length,
|
|
204
|
+
has_description: w.description !== undefined && w.description !== null && w.description !== '',
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
return row;
|
|
208
|
+
}
|
|
136
209
|
/**
|
|
137
210
|
* Create a process (or a new version that supersedes an existing one). Writes
|
|
138
211
|
* the memory mirror + the processes row atomically inside writeEntry's SAVEPOINT
|
|
@@ -163,78 +236,21 @@ export function saveProcess(hippoRoot, tenantId, opts, actor = 'cli') {
|
|
|
163
236
|
baseHalfLifeDays: objectHalfLifeDays(hippoRoot),
|
|
164
237
|
tenantId,
|
|
165
238
|
});
|
|
239
|
+
const w = {
|
|
240
|
+
tenantId,
|
|
241
|
+
actor,
|
|
242
|
+
processName: opts.processName,
|
|
243
|
+
description: opts.description,
|
|
244
|
+
steps,
|
|
245
|
+
changeSummary,
|
|
246
|
+
supersedesId: opts.supersedesProcessId,
|
|
247
|
+
now,
|
|
248
|
+
};
|
|
166
249
|
let savedRow;
|
|
167
250
|
writeEntry(hippoRoot, mem, {
|
|
168
251
|
actor,
|
|
169
252
|
afterWrite: (db, memoryId) => {
|
|
170
|
-
|
|
171
|
-
// row's autoincrement id could otherwise collide with a non-existent
|
|
172
|
-
// supersedesProcessId (e.g. superseding id 1 on an empty store), making
|
|
173
|
-
// the row supersede itself. Validating first means the new row is never a
|
|
174
|
-
// candidate for its own supersede UPDATE. Mirrors saveDecision (codex P1
|
|
175
|
-
// 2026-05-28). The same SELECT reads the predecessor version so the
|
|
176
|
-
// successor's version is server-derived, never client-supplied.
|
|
177
|
-
let version = 1;
|
|
178
|
-
if (opts.supersedesProcessId !== undefined) {
|
|
179
|
-
// SAFETY: SELECT status, version FROM processes; row shape matches
|
|
180
|
-
// the two selected columns 1:1.
|
|
181
|
-
const pred = db.prepare(`SELECT status, version FROM processes WHERE id = ? AND tenant_id = ?`).get(opts.supersedesProcessId, tenantId);
|
|
182
|
-
if (!pred) {
|
|
183
|
-
throw new NotFoundError(`saveProcess: process ${opts.supersedesProcessId} to supersede not found for tenant ${tenantId}`);
|
|
184
|
-
}
|
|
185
|
-
if (pred.status !== 'active') {
|
|
186
|
-
throw new ConflictError(`saveProcess: process ${opts.supersedesProcessId} is not active (status='${pred.status}'); only active processes can be superseded.`);
|
|
187
|
-
}
|
|
188
|
-
version = pred.version + 1;
|
|
189
|
-
}
|
|
190
|
-
const result = db.prepare(`
|
|
191
|
-
INSERT INTO processes(
|
|
192
|
-
memory_id, tenant_id, process_name, description, steps, version,
|
|
193
|
-
status, superseded_by, superseded_at, change_summary, closed_at, created_at
|
|
194
|
-
) VALUES (?, ?, ?, ?, ?, ?, 'active', NULL, NULL, ?, NULL, ?)
|
|
195
|
-
`).run(memoryId, tenantId, opts.processName, opts.description ?? null, JSON.stringify(steps), version, changeSummary, now);
|
|
196
|
-
const processId = Number(result.lastInsertRowid ?? 0);
|
|
197
|
-
if (opts.supersedesProcessId !== undefined) {
|
|
198
|
-
const sup = db.prepare(`
|
|
199
|
-
UPDATE processes
|
|
200
|
-
SET status = 'superseded', superseded_by = ?, superseded_at = ?
|
|
201
|
-
WHERE id = ? AND tenant_id = ? AND status = 'active' AND id != ?
|
|
202
|
-
`).run(processId, now, opts.supersedesProcessId, tenantId, processId);
|
|
203
|
-
if (sup.changes === 0) {
|
|
204
|
-
throw new ConflictError(`saveProcess: process ${opts.supersedesProcessId} could not be superseded (no longer active or self-reference).`);
|
|
205
|
-
}
|
|
206
|
-
appendAuditEvent(db, {
|
|
207
|
-
tenantId,
|
|
208
|
-
actor,
|
|
209
|
-
op: 'process_supersede',
|
|
210
|
-
targetId: String(opts.supersedesProcessId),
|
|
211
|
-
metadata: {
|
|
212
|
-
process_id: opts.supersedesProcessId,
|
|
213
|
-
superseded_by: processId,
|
|
214
|
-
new_version: version,
|
|
215
|
-
},
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
// SAFETY: SELECT ${PROCESS_COLS} enumerates every ProcessRow field
|
|
219
|
-
// 1:1 (see PROCESS_COLS above).
|
|
220
|
-
const row = db.prepare(`SELECT ${PROCESS_COLS} FROM processes WHERE id = ?`)
|
|
221
|
-
.get(processId);
|
|
222
|
-
if (!row)
|
|
223
|
-
throw new Error('saveProcess: failed to reload saved process row');
|
|
224
|
-
savedRow = row;
|
|
225
|
-
// GDPR-light metadata: ids + counts only, no process_name / step text.
|
|
226
|
-
appendAuditEvent(db, {
|
|
227
|
-
tenantId,
|
|
228
|
-
actor,
|
|
229
|
-
op: 'process_create',
|
|
230
|
-
targetId: String(processId),
|
|
231
|
-
metadata: {
|
|
232
|
-
process_id: processId,
|
|
233
|
-
version,
|
|
234
|
-
step_count: steps.length,
|
|
235
|
-
has_description: opts.description !== undefined && opts.description !== null && opts.description !== '',
|
|
236
|
-
},
|
|
237
|
-
});
|
|
253
|
+
savedRow = writeProcessRow(db, memoryId, w);
|
|
238
254
|
},
|
|
239
255
|
});
|
|
240
256
|
if (!savedRow) {
|
package/dist/project-briefs.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* (docs/plans/2026-05-30-e2-project-brief-object.md).
|
|
2
|
+
* Project_brief first-class object.
|
|
4
3
|
*
|
|
5
4
|
* A `project_brief` is the living, repo-scoped summary of a repository's state: a
|
|
6
5
|
* `summary` body scoped to a `repo`, evolving via the supersede delta lifecycle.
|
|
@@ -94,7 +93,7 @@ export declare function loadProjectBriefs(hippoRoot: string, tenantId: string, o
|
|
|
94
93
|
/**
|
|
95
94
|
* The repo's CURRENT active brief, or null. By convention there is one active brief
|
|
96
95
|
* per (tenant, repo); if an operator created more than one (the DB does not prevent
|
|
97
|
-
* it, consistent with every other
|
|
96
|
+
* it, consistent with every other first-class object), the MOST-RECENT active row wins.
|
|
98
97
|
*/
|
|
99
98
|
export declare function loadActiveBriefForRepo(hippoRoot: string, tenantId: string, repo: string): ProjectBrief | null;
|
|
100
99
|
/**
|