hippo-memory 1.62.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 +9 -0
- package/dist/agent-memories/apply.d.ts +2 -0
- package/dist/agent-memories/apply.js +23 -1
- package/dist/agent-memories/claude-code.d.ts +2 -1
- package/dist/agent-memories/claude-code.js +4 -4
- package/dist/agent-memories/report.d.ts +1 -0
- package/dist/agent-memories/report.js +2 -2
- package/dist/agent-memories/sync.js +37 -23
- 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 +7 -12
- 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 +4 -3
- package/dist/api/context-select.js +9 -11
- package/dist/api/context-types.d.ts +12 -17
- package/dist/api/context.d.ts +3 -2
- package/dist/api/context.js +20 -20
- package/dist/api/dormant.js +1 -1
- package/dist/api/drill-down.d.ts +4 -4
- package/dist/api/drill-down.js +22 -10
- 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/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 +7 -18
- package/dist/api/remember.d.ts +2 -2
- package/dist/api/sleep.d.ts +7 -35
- package/dist/api/sleep.js +3 -2
- 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 +1 -1
- package/dist/capture/compact.js +9 -13
- 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/curate.d.ts +1 -1
- package/dist/cli/curate.js +8 -24
- package/dist/cli/dag.js +5 -9
- package/dist/cli/decisions.js +10 -21
- package/dist/cli/explain.js +2 -1
- package/dist/cli/goals.js +1 -1
- package/dist/cli/init.js +1 -1
- package/dist/cli/playbooks.js +4 -9
- package/dist/cli/projects.js +3 -1
- package/dist/cli/recall.js +2 -1
- package/dist/cli/remember.js +6 -18
- package/dist/cli/session-hooks.js +21 -40
- package/dist/cli/setup.d.ts +1 -1
- package/dist/cli/setup.js +2 -6
- 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 +7 -12
- package/dist/cli/transfer.js +8 -13
- 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 -0
- 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 +6 -9
- package/dist/dag.d.ts +10 -21
- package/dist/dag.js +23 -73
- 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 +6 -6
- package/dist/dedupe.js +86 -61
- package/dist/delivery-recorder.js +154 -135
- package/dist/doctor.js +119 -104
- 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 +5 -6
- 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 +1 -1
- 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 +12 -14
- 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 +3 -3
- package/dist/project-briefs.d.ts +2 -3
- package/dist/project-briefs.js +9 -13
- package/dist/project-identity.d.ts +22 -9
- package/dist/project-identity.js +47 -12
- package/dist/project-merge.d.ts +17 -2
- package/dist/project-merge.js +109 -27
- 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 +17 -17
- package/dist/shared.js +93 -97
- package/dist/skills.d.ts +3 -3
- package/dist/skills.js +8 -8
- 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 +31 -59
- 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
package/dist/physics.d.ts
CHANGED
|
@@ -52,7 +52,7 @@ export declare function computeMass(strength: number, retrievalCount: number): n
|
|
|
52
52
|
export declare function computeCharge(valence: EmotionalValence): number;
|
|
53
53
|
export declare function computeTemperature(ageDays: number, temperatureDecay: number): number;
|
|
54
54
|
/**
|
|
55
|
-
*
|
|
55
|
+
* Query gravity (retrieval-time, virtual — does not update position).
|
|
56
56
|
* Returns scalar force magnitude for ranking.
|
|
57
57
|
*
|
|
58
58
|
* F_query(i) = G_Q * mass(i) * max(0, cosine(pos_i, query))^2
|
|
@@ -64,7 +64,7 @@ export declare function queryGravityMagnitude(particle: PhysicsParticle, queryEm
|
|
|
64
64
|
*/
|
|
65
65
|
export declare function velocityAlignmentBonus(particle: PhysicsParticle, queryEmbedding: number[]): number;
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
67
|
+
* Inter-memory attraction force vector (consolidation-time).
|
|
68
68
|
* Attractive force from particle j on particle i.
|
|
69
69
|
*
|
|
70
70
|
* F_attract(i,j) = G_M * m_i * m_j * max(0, cosine(i,j))^3 * direction(j→i in embedding space)
|
|
@@ -74,7 +74,7 @@ export declare function velocityAlignmentBonus(particle: PhysicsParticle, queryE
|
|
|
74
74
|
*/
|
|
75
75
|
export declare function attractionForce(pi: PhysicsParticle, pj: PhysicsParticle, G_memory: number): number[];
|
|
76
76
|
/**
|
|
77
|
-
*
|
|
77
|
+
* Conflict repulsion force vector (consolidation-time).
|
|
78
78
|
* Repulsive force pushing i away from j.
|
|
79
79
|
*
|
|
80
80
|
* F_repel(i,j) = K_R * m_i * m_j / max(0.01, cosine_distance(i,j))^2
|
|
@@ -82,7 +82,7 @@ export declare function attractionForce(pi: PhysicsParticle, pj: PhysicsParticle
|
|
|
82
82
|
*/
|
|
83
83
|
export declare function repulsionForce(pi: PhysicsParticle, pj: PhysicsParticle, K_repulsion: number): number[];
|
|
84
84
|
/**
|
|
85
|
-
*
|
|
85
|
+
* Drag force vector (consolidation-time).
|
|
86
86
|
* F_drag(i) = -drag * velocity(i) / max(1, effective_half_life(i))
|
|
87
87
|
*
|
|
88
88
|
* effectiveHalfLife should be passed in from the memory's current half_life_days.
|
package/dist/physics.js
CHANGED
|
@@ -79,11 +79,9 @@ const CHARGE_MAP = {
|
|
|
79
79
|
critical: -1.0,
|
|
80
80
|
};
|
|
81
81
|
export function computeMass(strength, retrievalCount) {
|
|
82
|
-
// EVAL-ONLY ablation (see ablation.ts): under the recall-boost flag,
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
// arm's physics-pool rankings (codex P2). Covers both the init and refresh
|
|
86
|
-
// callers in physics-state.ts.
|
|
82
|
+
// EVAL-ONLY ablation (see ablation.ts): under the recall-boost flag mass ignores retrieval history, since
|
|
83
|
+
// query gravity ranks by mass and prior counts would leak strengthening into the ablated arm's
|
|
84
|
+
// physics-pool rankings. Covers both the init and refresh callers in physics-state.ts.
|
|
87
85
|
const effectiveCount = isRecallBoostAblated() ? 0 : retrievalCount;
|
|
88
86
|
return Math.max(0.01, strength * (1 + 0.1 * Math.log2(effectiveCount + 1)));
|
|
89
87
|
}
|
|
@@ -97,7 +95,7 @@ export function computeTemperature(ageDays, temperatureDecay) {
|
|
|
97
95
|
// Force computations
|
|
98
96
|
// ---------------------------------------------------------------------------
|
|
99
97
|
/**
|
|
100
|
-
*
|
|
98
|
+
* Query gravity (retrieval-time, virtual — does not update position).
|
|
101
99
|
* Returns scalar force magnitude for ranking.
|
|
102
100
|
*
|
|
103
101
|
* F_query(i) = G_Q * mass(i) * max(0, cosine(pos_i, query))^2
|
|
@@ -121,7 +119,7 @@ export function velocityAlignmentBonus(particle, queryEmbedding) {
|
|
|
121
119
|
return Math.max(0, alignment);
|
|
122
120
|
}
|
|
123
121
|
/**
|
|
124
|
-
*
|
|
122
|
+
* Inter-memory attraction force vector (consolidation-time).
|
|
125
123
|
* Attractive force from particle j on particle i.
|
|
126
124
|
*
|
|
127
125
|
* F_attract(i,j) = G_M * m_i * m_j * max(0, cosine(i,j))^3 * direction(j→i in embedding space)
|
|
@@ -139,7 +137,7 @@ export function attractionForce(pi, pj, G_memory) {
|
|
|
139
137
|
return vecScale(direction, magnitude);
|
|
140
138
|
}
|
|
141
139
|
/**
|
|
142
|
-
*
|
|
140
|
+
* Conflict repulsion force vector (consolidation-time).
|
|
143
141
|
* Repulsive force pushing i away from j.
|
|
144
142
|
*
|
|
145
143
|
* F_repel(i,j) = K_R * m_i * m_j / max(0.01, cosine_distance(i,j))^2
|
|
@@ -154,7 +152,7 @@ export function repulsionForce(pi, pj, K_repulsion) {
|
|
|
154
152
|
return vecScale(direction, magnitude);
|
|
155
153
|
}
|
|
156
154
|
/**
|
|
157
|
-
*
|
|
155
|
+
* Drag force vector (consolidation-time).
|
|
158
156
|
* F_drag(i) = -drag * velocity(i) / max(1, effective_half_life(i))
|
|
159
157
|
*
|
|
160
158
|
* effectiveHalfLife should be passed in from the memory's current half_life_days.
|
package/dist/policies.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Policy first-class object.
|
|
3
3
|
*
|
|
4
4
|
* The "bi-temporal-first" object type: a named rule/statement that is in force
|
|
5
5
|
* over an EFFECTIVE-TIME range and evolves via supersession. Two time axes:
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
* loadPoliciesAsOf's asOfDate) is normalized to canonical ISO-8601 datetime
|
|
31
31
|
* (`toISOString`) at the store boundary BEFORE any persist or compare, so the
|
|
32
32
|
* fixed-width values sort lexically and the half-open [valid_from, valid_to)
|
|
33
|
-
* comparison is correct (
|
|
34
|
-
*
|
|
33
|
+
* comparison is correct (a date-only asOf vs a datetime valid_from would
|
|
34
|
+
* otherwise make a same-day policy invisible).
|
|
35
35
|
*
|
|
36
36
|
* Dual-write atomicity: `savePolicy` writes the memory + policies row (and, on
|
|
37
37
|
* supersede, the predecessor's UPDATE) inside writeEntry's SAVEPOINT.
|
|
@@ -129,21 +129,20 @@ export declare function loadActivePolicies(hippoRoot: string, tenantId: string,
|
|
|
129
129
|
* - `superseded` rows that cover T BUT whose successor was not yet effective at T
|
|
130
130
|
* (successor.valid_from > asOf) - i.e. an earlier version that was genuinely in
|
|
131
131
|
* force then. This is the core valid-time correctness: a Jan-Jun policy
|
|
132
|
-
* superseded in May is still the answer for `asof March`.
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
* successor-aware filter mirrors the existing recall-history.ts asOf pattern.)
|
|
132
|
+
* superseded in May is still the answer for `asof March`. Filtering on
|
|
133
|
+
* status='active' alone would conflate transaction-time with valid-time; the
|
|
134
|
+
* successor-aware filter mirrors the existing recall-history.ts asOf pattern.
|
|
136
135
|
*
|
|
137
136
|
* `closed` rows are EXCLUDED: closing is a deliberate transaction-time retirement,
|
|
138
137
|
* and resurrecting closed policies for a historical valid-time is full
|
|
139
138
|
* transaction-time-travel (deferred). Returns an ARRAY (overlapping same-name
|
|
140
139
|
* ranges are allowed in v1). Optionally filtered to one policy_name.
|
|
141
140
|
*
|
|
142
|
-
* Date-only `asOfDate` (
|
|
141
|
+
* Date-only `asOfDate` (YYYY-MM-DD, no time component) resolves to the END
|
|
143
142
|
* of that UTC day (23:59:59.999Z), so "as of [day D]" includes a policy that
|
|
144
143
|
* became effective at any instant during D - this is the read-side fix for the
|
|
145
|
-
* common create-then-asof-today workflow, keeping the stored valid_from honest
|
|
146
|
-
*
|
|
144
|
+
* common create-then-asof-today workflow, keeping the stored valid_from honest.
|
|
145
|
+
* A full datetime asOf is used as the precise instant.
|
|
147
146
|
*/
|
|
148
147
|
export declare function loadPoliciesAsOf(hippoRoot: string, tenantId: string, asOfDate: string, opts?: {
|
|
149
148
|
name?: string;
|
package/dist/policies.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Policy first-class object.
|
|
3
3
|
*
|
|
4
4
|
* The "bi-temporal-first" object type: a named rule/statement that is in force
|
|
5
5
|
* over an EFFECTIVE-TIME range and evolves via supersession. Two time axes:
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
* loadPoliciesAsOf's asOfDate) is normalized to canonical ISO-8601 datetime
|
|
31
31
|
* (`toISOString`) at the store boundary BEFORE any persist or compare, so the
|
|
32
32
|
* fixed-width values sort lexically and the half-open [valid_from, valid_to)
|
|
33
|
-
* comparison is correct (
|
|
34
|
-
*
|
|
33
|
+
* comparison is correct (a date-only asOf vs a datetime valid_from would
|
|
34
|
+
* otherwise make a same-day policy invisible).
|
|
35
35
|
*
|
|
36
36
|
* Dual-write atomicity: `savePolicy` writes the memory + policies row (and, on
|
|
37
37
|
* supersede, the predecessor's UPDATE) inside writeEntry's SAVEPOINT.
|
|
@@ -114,7 +114,7 @@ function buildPolicyContent(policyName, policyText, validFrom, validTo) {
|
|
|
114
114
|
// Preflight the supersede target BEFORE inserting the new row (so the new
|
|
115
115
|
// autoincrement id can never be its own supersede target); read the
|
|
116
116
|
// predecessor version in the same SELECT for server-derived versioning.
|
|
117
|
-
// Mirrors saveProcess / saveDecision
|
|
117
|
+
// Mirrors saveProcess / saveDecision.
|
|
118
118
|
function preflightPolicySupersede(db, tenantId, supersedesId) {
|
|
119
119
|
// SAFETY: SELECT projects exactly status, version; .get() returns that
|
|
120
120
|
// shape for the matching row, or undefined when no policy/tenant pair matches.
|
|
@@ -206,8 +206,7 @@ export function savePolicy(hippoRoot, tenantId, opts, actor = 'cli') {
|
|
|
206
206
|
// (a date-only asOf resolves to end-of-day in loadPoliciesAsOf), NOT by
|
|
207
207
|
// backdating the stored valid_from - backdating to midnight would make an
|
|
208
208
|
// earlier-same-day as-of wrongly report the policy already in force and would
|
|
209
|
-
// hide a superseded predecessor for that earlier time
|
|
210
|
-
// 2026-05-30 round 2). An explicit --from is honored as-is.
|
|
209
|
+
// hide a superseded predecessor for that earlier time. An explicit --from is honored as-is.
|
|
211
210
|
const { validFrom, validTo } = validatePolicyDates(opts.validFrom, opts.validTo, now);
|
|
212
211
|
const isSupersede = opts.supersedesPolicyId !== undefined;
|
|
213
212
|
const changeSummary = isSupersede ? (opts.changeSummary ?? null) : null;
|
|
@@ -290,7 +289,7 @@ export function closePolicy(hippoRoot, tenantId, id, actor = 'cli') {
|
|
|
290
289
|
// Closing removes the object from the graph. Remove its rows DIRECTLY (deterministic),
|
|
291
290
|
// not only via an enqueued rebuild whose queue item is lost if the mirror is later
|
|
292
291
|
// forgotten (the queue row cascade-deletes with the memory), which would leave the closed
|
|
293
|
-
// object stale and could block that forget
|
|
292
|
+
// object stale and could block that forget. Still enqueue when a mirror exists
|
|
294
293
|
// so a concurrent rebuild re-derives consistently (harmless if it also runs).
|
|
295
294
|
removeGraphEntitiesForObject(hippoRoot, tenantId, 'policy', closed.id);
|
|
296
295
|
if (closed.memoryId) {
|
|
@@ -376,21 +375,20 @@ export function loadActivePolicies(hippoRoot, tenantId, opts = {}) {
|
|
|
376
375
|
* - `superseded` rows that cover T BUT whose successor was not yet effective at T
|
|
377
376
|
* (successor.valid_from > asOf) - i.e. an earlier version that was genuinely in
|
|
378
377
|
* force then. This is the core valid-time correctness: a Jan-Jun policy
|
|
379
|
-
* superseded in May is still the answer for `asof March`.
|
|
380
|
-
*
|
|
381
|
-
*
|
|
382
|
-
* successor-aware filter mirrors the existing recall-history.ts asOf pattern.)
|
|
378
|
+
* superseded in May is still the answer for `asof March`. Filtering on
|
|
379
|
+
* status='active' alone would conflate transaction-time with valid-time; the
|
|
380
|
+
* successor-aware filter mirrors the existing recall-history.ts asOf pattern.
|
|
383
381
|
*
|
|
384
382
|
* `closed` rows are EXCLUDED: closing is a deliberate transaction-time retirement,
|
|
385
383
|
* and resurrecting closed policies for a historical valid-time is full
|
|
386
384
|
* transaction-time-travel (deferred). Returns an ARRAY (overlapping same-name
|
|
387
385
|
* ranges are allowed in v1). Optionally filtered to one policy_name.
|
|
388
386
|
*
|
|
389
|
-
* Date-only `asOfDate` (
|
|
387
|
+
* Date-only `asOfDate` (YYYY-MM-DD, no time component) resolves to the END
|
|
390
388
|
* of that UTC day (23:59:59.999Z), so "as of [day D]" includes a policy that
|
|
391
389
|
* became effective at any instant during D - this is the read-side fix for the
|
|
392
|
-
* common create-then-asof-today workflow, keeping the stored valid_from honest
|
|
393
|
-
*
|
|
390
|
+
* common create-then-asof-today workflow, keeping the stored valid_from honest.
|
|
391
|
+
* A full datetime asOf is used as the precise instant.
|
|
394
392
|
*/
|
|
395
393
|
export function loadPoliciesAsOf(hippoRoot, tenantId, asOfDate, opts = {}) {
|
|
396
394
|
assertTenantId('loadPoliciesAsOf', tenantId);
|
package/dist/postinstall.js
CHANGED
|
@@ -7,12 +7,9 @@ function main() {
|
|
|
7
7
|
if (envSkipPostinstall())
|
|
8
8
|
return;
|
|
9
9
|
try {
|
|
10
|
-
// Repair-only
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
// postinstall is a consent violation and reads as binary hijacking to
|
|
14
|
-
// supply-chain scanners (issue #133). First install is `hippo hook
|
|
15
|
-
// install codex` only.
|
|
10
|
+
// Repair-only, for users who opted in (a Codex update can restore the real binary over our shim).
|
|
11
|
+
// Swapping the binary from postinstall is a consent violation that supply-chain scanners read as
|
|
12
|
+
// hijacking, so first install is `hippo hook install codex` only.
|
|
16
13
|
repairCodexWrapperIfInstalled();
|
|
17
14
|
}
|
|
18
15
|
catch {
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Surface delivered on `RecallResult.planningFallacyHint` when an
|
|
3
3
|
* agent's recall query carries a forward-prediction phrase AND the closest
|
|
4
4
|
* matching prediction class has closed historical data.
|
|
5
5
|
*
|
|
6
6
|
* The agent sees its track record at the moment of forecasting, anchoring
|
|
7
7
|
* on the outside view (Lovallo-Kahneman 2003) rather than the inside-view
|
|
8
8
|
* inside the planning fallacy.
|
|
9
|
-
*
|
|
10
|
-
* Plan: docs/plans/2026-05-26-j32-auto-injection.md.
|
|
11
9
|
*/
|
|
12
10
|
export interface PlanningFallacyHint {
|
|
13
11
|
classTag: string;
|
|
@@ -25,13 +23,11 @@ export interface PlanningFallacyHint {
|
|
|
25
23
|
meanRatio: number | null;
|
|
26
24
|
}
|
|
27
25
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* Trial 2a confirmed the pre-v1.13.4 silent paths were the most common
|
|
32
|
-
* real-world J3.2 failure mode: a natural-language query carries a
|
|
26
|
+
* "Watching" variant emitted when the forward-claim regex matched but no
|
|
27
|
+
* PlanningFallacyHint baserate was returned. Silence was the most common
|
|
28
|
+
* real-world failure: a natural-language query carries a
|
|
33
29
|
* forward-claim phrase but its non-stopword tokens don't overlap with
|
|
34
|
-
* any prediction class tag, so hippo
|
|
30
|
+
* any prediction class tag, so hippo emitted nothing despite
|
|
35
31
|
* the regex match. The watching variant surfaces the detection event
|
|
36
32
|
* + a one-line suggestion so the agent can either re-tag the prediction
|
|
37
33
|
* or pass the suggestion through to the user.
|
|
@@ -48,7 +44,7 @@ export interface PlanningFallacyWatching {
|
|
|
48
44
|
suggestion: string;
|
|
49
45
|
}
|
|
50
46
|
/**
|
|
51
|
-
*
|
|
47
|
+
* Richer return type for
|
|
52
48
|
* `computePlanningFallacyOutput`. Carries EITHER `hint` (baserate
|
|
53
49
|
* available) OR `watching` (regex fired, no baserate), or NEITHER (mode=off,
|
|
54
50
|
* no queryText, no regex match, or nClosed=0 silent path). Never both.
|
|
@@ -71,7 +67,7 @@ export interface ComputePlanningFallacyHintOpts {
|
|
|
71
67
|
actor?: string;
|
|
72
68
|
}
|
|
73
69
|
/**
|
|
74
|
-
*
|
|
70
|
+
* Planning-fallacy orchestrator.
|
|
75
71
|
*
|
|
76
72
|
* Composes the forward-claim detector + class resolver + baserate compute,
|
|
77
73
|
* with telemetry-grade audit emission at every decision point (success,
|
|
@@ -83,7 +79,7 @@ export interface ComputePlanningFallacyHintOpts {
|
|
|
83
79
|
* - no forward-claim regex match
|
|
84
80
|
* - resolved class has nClosed=0 (no historical data yet; silent)
|
|
85
81
|
*
|
|
86
|
-
* Returns `{ watching: ... }` on
|
|
82
|
+
* Returns `{ watching: ... }` on:
|
|
87
83
|
* - resolver returns no class (no overlap ≥ 1; emits no_class_match audit)
|
|
88
84
|
* - resolver returns tiebreak (≥2 classes tied at best; emits tiebreak audit)
|
|
89
85
|
*
|
|
@@ -93,8 +89,7 @@ export interface ComputePlanningFallacyHintOpts {
|
|
|
93
89
|
* audit carries n_closed + mean_ratio in metadata so no telemetry is lost),
|
|
94
90
|
* then emits recall_autodebias_hint audit + returns the hint.
|
|
95
91
|
*
|
|
96
|
-
* Latency budget
|
|
97
|
-
* on full match+resolve+baserate path. Well under 50ms target.
|
|
92
|
+
* Latency budget: well under 50ms; a miss pays only the regex.
|
|
98
93
|
*/
|
|
99
94
|
export declare function computePlanningFallacyOutput(hippoRoot: string, tenantId: string, queryText: string, opts?: ComputePlanningFallacyHintOpts): PlanningFallacyOutput;
|
|
100
95
|
//# sourceMappingURL=planning-fallacy.d.ts.map
|
|
@@ -11,8 +11,8 @@ import { computePredictionBaserate } from './store.js';
|
|
|
11
11
|
* Indexed via idx_predictions_tenant_class (db.ts:1015) → O(log n) seek
|
|
12
12
|
* plus a small DISTINCT scan over the per-tenant class-tag set.
|
|
13
13
|
*
|
|
14
|
-
* Scope behaviour (
|
|
15
|
-
*
|
|
14
|
+
* Scope behaviour (deliberate): class_tag selection is TENANT-GLOBAL,
|
|
15
|
+
* NOT scope-filtered against
|
|
16
16
|
* the recall's opts.scope. The class_tag is an aggregator label across
|
|
17
17
|
* historical predictions in the class, not a per-memory scope-bound
|
|
18
18
|
* property. A no-scope recall CAN surface a class_tag from a privately-
|
|
@@ -75,7 +75,7 @@ function resolveClassFromTokens(hippoRoot, tenantId, queryTokens) {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
78
|
+
* Planning-fallacy orchestrator.
|
|
79
79
|
*
|
|
80
80
|
* Composes the forward-claim detector + class resolver + baserate compute,
|
|
81
81
|
* with telemetry-grade audit emission at every decision point (success,
|
|
@@ -87,7 +87,7 @@ function resolveClassFromTokens(hippoRoot, tenantId, queryTokens) {
|
|
|
87
87
|
* - no forward-claim regex match
|
|
88
88
|
* - resolved class has nClosed=0 (no historical data yet; silent)
|
|
89
89
|
*
|
|
90
|
-
* Returns `{ watching: ... }` on
|
|
90
|
+
* Returns `{ watching: ... }` on:
|
|
91
91
|
* - resolver returns no class (no overlap ≥ 1; emits no_class_match audit)
|
|
92
92
|
* - resolver returns tiebreak (≥2 classes tied at best; emits tiebreak audit)
|
|
93
93
|
*
|
|
@@ -97,8 +97,7 @@ function resolveClassFromTokens(hippoRoot, tenantId, queryTokens) {
|
|
|
97
97
|
* audit carries n_closed + mean_ratio in metadata so no telemetry is lost),
|
|
98
98
|
* then emits recall_autodebias_hint audit + returns the hint.
|
|
99
99
|
*
|
|
100
|
-
* Latency budget
|
|
101
|
-
* on full match+resolve+baserate path. Well under 50ms target.
|
|
100
|
+
* Latency budget: well under 50ms; a miss pays only the regex.
|
|
102
101
|
*/
|
|
103
102
|
export function computePlanningFallacyOutput(hippoRoot, tenantId, queryText, opts = {}) {
|
|
104
103
|
// Env read FIRST so AUTODEBIAS=off pays zero regex cost. Per-call read
|
|
@@ -115,19 +114,14 @@ export function computePlanningFallacyOutput(hippoRoot, tenantId, queryText, opt
|
|
|
115
114
|
const actor = opts.actor ?? 'recall';
|
|
116
115
|
const resolution = resolveClassFromTokens(hippoRoot, tenantId, match.classQueryTokens);
|
|
117
116
|
if (resolution.tiebreak) {
|
|
118
|
-
// Telemetry: forward-claim detected, ≥2 classes tied at best overlap.
|
|
119
|
-
//
|
|
120
|
-
// can render a "watching but no baserate (tiebreak)" line. Audit emission
|
|
121
|
-
// unchanged (the audit channel is the telemetry-grade source of truth).
|
|
117
|
+
// Telemetry: forward-claim detected, ≥2 classes tied at best overlap. The watching variant lets the
|
|
118
|
+
// caller render "watching but no baserate (tiebreak)"; the audit channel stays the source of truth.
|
|
122
119
|
return watchingWithAudit(hippoRoot, tenantId, actor, match, 'tiebreak', TIEBREAK_SUGGESTION);
|
|
123
120
|
}
|
|
124
121
|
if (!resolution.classTag) {
|
|
125
|
-
// Telemetry: forward-claim detected, no class scored ≥ 1.
|
|
126
|
-
//
|
|
127
|
-
//
|
|
128
|
-
// legitimate forward-claims that have NO obvious class signal.
|
|
129
|
-
// v1.13.4: now ALSO returns a watching variant so the caller surface
|
|
130
|
-
// can render a "watching but no baserate (no class match)" line.
|
|
122
|
+
// Telemetry: forward-claim detected, no class scored ≥ 1. High volume here means regex+token-overlap
|
|
123
|
+
// misses real forward-claims with no class signal, the case for an embedding fallback.
|
|
124
|
+
// The watching variant lets the caller render "watching but no baserate (no class match)".
|
|
131
125
|
return watchingWithAudit(hippoRoot, tenantId, actor, match, 'no_class_match', NO_CLASS_MATCH_SUGGESTION);
|
|
132
126
|
}
|
|
133
127
|
// emitAudit=false: avoid double-write to predict_baserate channel.
|
|
@@ -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 { type KeysetPosition } from '../keyset.js';
|
|
28
26
|
export type ClosureState = 'open' | 'closed' | 'closed-unknown';
|
|
@@ -71,18 +69,22 @@ export interface ListPredictionsOpts {
|
|
|
71
69
|
* The memory is tagged `['prediction', classTag]` with `source='prediction'`
|
|
72
70
|
* and `kind='distilled'`. It surfaces in `hippo recall` so the agent can
|
|
73
71
|
* see open predictions naturally; the predictions table is the canonical
|
|
74
|
-
* structured store used by
|
|
72
|
+
* structured store used by the planning-fallacy detector.
|
|
75
73
|
*/
|
|
76
74
|
export declare function savePrediction(hippoRoot: string, tenantId: string, opts: SavePredictionOpts, actor?: string): Prediction;
|
|
77
75
|
/**
|
|
78
76
|
* Close an existing open prediction. Updates the predictions row only;
|
|
79
77
|
* the memory mirror is NOT mutated in v1 (predictions table is canonical).
|
|
80
|
-
*
|
|
81
|
-
* actualValue) at query time.
|
|
78
|
+
* Accuracy is computed from (estimateValue, actualValue) at query time.
|
|
82
79
|
*/
|
|
83
80
|
export declare function closePrediction(hippoRoot: string, tenantId: string, id: number, opts: ClosePredictionOpts, actor?: string): Prediction;
|
|
84
81
|
export declare function loadPredictionById(hippoRoot: string, tenantId: string, id: number): Prediction | null;
|
|
85
82
|
export declare function loadPredictionsByClass(hippoRoot: string, tenantId: string, classTag: string, opts?: ListPredictionsOpts): Prediction[];
|
|
83
|
+
/** Every prediction in the tenant, open and closed, across all classes: the `status=all` list without a class. */
|
|
84
|
+
export declare function loadAllPredictions(hippoRoot: string, tenantId: string, opts?: {
|
|
85
|
+
limit?: number;
|
|
86
|
+
after?: KeysetPosition;
|
|
87
|
+
}): Prediction[];
|
|
86
88
|
export interface PredictionBaserate {
|
|
87
89
|
classTag: string;
|
|
88
90
|
/** Count of closed predictions with a numeric actual_value (excludes
|
|
@@ -105,28 +107,18 @@ export interface PredictionBaserate {
|
|
|
105
107
|
summary: string;
|
|
106
108
|
}
|
|
107
109
|
/**
|
|
108
|
-
* Compute base-rate stats for closed predictions in a class
|
|
109
|
-
*
|
|
110
|
-
* Lovallo-Kahneman (2003) inside-vs-outside view.
|
|
110
|
+
* Compute base-rate stats for closed predictions in a class for the
|
|
111
|
+
* planning-fallacy detector: Lovallo-Kahneman (2003) inside-vs-outside view.
|
|
111
112
|
*
|
|
112
113
|
* Filter: closure_state='closed' AND estimate_value IS NOT NULL AND
|
|
113
114
|
* actual_value IS NOT NULL. Excludes closed-unknown (no actual to
|
|
114
115
|
* compare against) and open (not yet resolved).
|
|
115
116
|
*
|
|
116
|
-
* Audit-emit is
|
|
117
|
-
* drift risk). Plan-eng-critic round 1 HIGH recommendation: emit inside
|
|
118
|
-
* helper, not at 3 call sites.
|
|
117
|
+
* Audit-emit is built in here, not at the 3 call sites, so callers cannot drift.
|
|
119
118
|
*/
|
|
120
119
|
export declare function computePredictionBaserate(hippoRoot: string, tenantId: string, classTag: string, actor?: string,
|
|
121
|
-
/**
|
|
122
|
-
*
|
|
123
|
-
* emitAudit=false and emits its own `recall_autodebias_hint` audit row
|
|
124
|
-
* instead, so the predict_baserate channel stays scoped to deliberate
|
|
125
|
-
* CLI / HTTP / MCP predict-baserate calls and does NOT pollute on every
|
|
126
|
-
* recall containing a forward-claim phrase. Default true preserves the
|
|
127
|
-
* v1.13.0 J3 audit semantics for the 3 direct callers (cmdPredict
|
|
128
|
-
* baserate, /v1/predictions/stats route, hippo_predict_baserate MCP
|
|
129
|
-
* handler) — none of them pass this argument. */
|
|
120
|
+
/** False skips the predict_baserate audit so that channel only records deliberate
|
|
121
|
+
* baserate calls, not every recall the planning-fallacy orchestrator inspects. */
|
|
130
122
|
emitAudit?: boolean): PredictionBaserate;
|
|
131
123
|
export declare function loadOpenPredictions(hippoRoot: string, tenantId: string, opts?: {
|
|
132
124
|
classTag?: string;
|
|
@@ -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),
|
|
@@ -134,8 +134,8 @@ function buildProcessContent(processName, steps, description) {
|
|
|
134
134
|
// row's autoincrement id could otherwise collide with a non-existent
|
|
135
135
|
// supersedesProcessId (e.g. superseding id 1 on an empty store), making
|
|
136
136
|
// the row supersede itself. Validating first means the new row is never a
|
|
137
|
-
// candidate for its own supersede UPDATE. Mirrors saveDecision
|
|
138
|
-
//
|
|
137
|
+
// candidate for its own supersede UPDATE. Mirrors saveDecision.
|
|
138
|
+
// The same SELECT reads the predecessor version so the
|
|
139
139
|
// successor's version is server-derived, never client-supplied.
|
|
140
140
|
function preflightProcessSupersede(db, tenantId, supersedesId) {
|
|
141
141
|
// SAFETY: SELECT status, version FROM processes; row shape matches
|
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
|
/**
|