@gamaze/hicortex 0.20.7 → 0.20.9

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.
Files changed (61) hide show
  1. package/README.md +10 -41
  2. package/dist/calibration.d.ts +174 -0
  3. package/dist/calibration.js +231 -0
  4. package/dist/capture.d.ts +15 -3
  5. package/dist/capture.js +10 -1
  6. package/dist/classify-domains.d.ts +6 -0
  7. package/dist/classify-domains.js +7 -1
  8. package/dist/cli.js +2 -3
  9. package/dist/config-read.d.ts +1 -1
  10. package/dist/config-read.js +96 -9
  11. package/dist/consolidate.d.ts +79 -68
  12. package/dist/consolidate.js +218 -174
  13. package/dist/dashboard.d.ts +4 -3
  14. package/dist/dedup.d.ts +34 -26
  15. package/dist/dedup.js +91 -57
  16. package/dist/distiller.js +1 -1
  17. package/dist/domain-classify.d.ts +7 -6
  18. package/dist/domain-classify.js +12 -10
  19. package/dist/eval/decay-eval.d.ts +3 -3
  20. package/dist/eval/decay-eval.js +4 -4
  21. package/dist/eval/planted-eval.d.ts +26 -0
  22. package/dist/eval/planted-eval.js +97 -0
  23. package/dist/eval/planted-fixtures.d.ts +107 -0
  24. package/dist/eval/planted-fixtures.js +283 -0
  25. package/dist/eval/planted-harness.d.ts +176 -0
  26. package/dist/eval/planted-harness.js +649 -0
  27. package/dist/index.js +4 -3
  28. package/dist/init.d.ts +9 -3
  29. package/dist/init.js +52 -9
  30. package/dist/llm.d.ts +43 -58
  31. package/dist/llm.js +87 -101
  32. package/dist/mcp-server.js +29 -29
  33. package/dist/nightly.js +105 -103
  34. package/dist/nofit.d.ts +4 -11
  35. package/dist/nofit.js +6 -23
  36. package/dist/recall-index.d.ts +30 -28
  37. package/dist/recall-index.js +21 -18
  38. package/dist/recall-registry.d.ts +2 -1
  39. package/dist/recall-registry.js +35 -1
  40. package/dist/reconsolidation.d.ts +124 -72
  41. package/dist/reconsolidation.js +359 -148
  42. package/dist/relink.js +3 -4
  43. package/dist/retrieval.d.ts +68 -35
  44. package/dist/retrieval.js +292 -104
  45. package/dist/run-deadline.d.ts +62 -0
  46. package/dist/run-deadline.js +73 -0
  47. package/dist/schema-prototypes.d.ts +3 -3
  48. package/dist/schema-prototypes.js +3 -3
  49. package/dist/state.d.ts +2 -3
  50. package/dist/storage.d.ts +16 -16
  51. package/dist/storage.js +62 -24
  52. package/dist/telemetry.d.ts +8 -7
  53. package/dist/token-budget.js +3 -4
  54. package/dist/type-classify.js +4 -4
  55. package/dist/types.d.ts +95 -155
  56. package/domains.example.json +4 -5
  57. package/hermes-plugin/hicortex/README.md +2 -2
  58. package/openclaw.plugin.json +1 -1
  59. package/package.json +2 -1
  60. package/pi-extension/hicortex/README.md +1 -1
  61. package/server.json +3 -3
package/dist/relink.js CHANGED
@@ -134,7 +134,6 @@ async function runRelink(options = {}) {
134
134
  `This machine is a client of ${config.serverUrl ?? "a remote server"} — run relink on the server.`);
135
135
  }
136
136
  // Classification is heuristic-only — no LLM client, no budget cap.
137
- const budget = new consolidate_js_1.BudgetTracker(Number.MAX_SAFE_INTEGER);
138
137
  const dbPath = (0, db_js_1.resolveDbPath)(options.dbPath);
139
138
  const db = (0, db_js_1.initDb)(dbPath);
140
139
  const report = {
@@ -215,9 +214,9 @@ async function runRelink(options = {}) {
215
214
  report.skippedExisting += batchSkippedExisting;
216
215
  report.skippedDuplicate += batchSkippedDuplicate;
217
216
  // Phase B: classification — shared heuristic-only path (LLM retired).
218
- // classifyLinkCandidates ignores the null LLM/budget and returns each
219
- // candidate's heuristic type (extends/relates_to).
220
- const classified = await (0, consolidate_js_1.classifyLinkCandidates)(candidates, null, budget);
217
+ // classifyLinkCandidates returns each candidate's heuristic type
218
+ // (extends/relates_to); #405 dropped its dead llm/budget params.
219
+ const classified = await (0, consolidate_js_1.classifyLinkCandidates)(candidates);
221
220
  const types = classified.types;
222
221
  report.llmClassified += classified.llmClassified; // always 0
223
222
  report.heuristicFallback += classified.heuristicFallback;
@@ -2,14 +2,15 @@
2
2
  * Retrieval layer with composite scoring, RRF fusion, and graph traversal.
3
3
  * Ported from hicortex/retrieval.py — same scoring model and weights.
4
4
  *
5
- * Scoring model (weights are config-driven since 0.15.2 — see configureScoring):
5
+ * Scoring model (weights are RELEASE-MANAGED since #408 — calibration.ts;
6
+ * configureScoring is the eval/test seam only):
6
7
  * score = similarity * 0.50 + effective_strength * 0.20
7
8
  * + connection_score * 0.15 + recency * 0.15
8
9
  * + fresh-memory bonus (≤ 0.15, linear over the first 7 days)
9
10
  * then × 0.50 if the memory was superseded by a later decision
10
11
  *
11
12
  * Decay model (B+E+D):
12
- * base_decay = derived from decayHalfLifeDays (config; default 365 → ~1-year
13
+ * base_decay = derived from the calibration half-life (365 → ~1-year
13
14
  * half-life at importance 0.5, importance-scaled either way)
14
15
  * decay_rate = 1 - base_decay * (1 - importance)
15
16
  * decay_rate = 1 - (1 - decay_rate) * 0.7^access_count
@@ -19,10 +20,8 @@
19
20
  */
20
21
  import type Database from "better-sqlite3";
21
22
  import type { Memory, MemorySearchResult } from "./types.js";
22
- /** Default decay half-life (days) at importance 0.5. #192: was 0.0005/h
23
- * (~115-day half-life at base 0.5) — aggressive enough to bury the long tail
24
- * in ranking. Long-term remembering is the product; time preference stays,
25
- * but mild. */
23
+ /** Default decay half-life (days) at importance 0.5 — release-managed
24
+ * (#408): the constant lives in calibration.ts with its provenance. */
26
25
  export declare const DEFAULT_DECAY_HALF_LIFE_DAYS = 365;
27
26
  /**
28
27
  * Derive the per-hour base decay constant from a half-life target: for the
@@ -33,26 +32,26 @@ export declare const DEFAULT_DECAY_HALF_LIFE_DAYS = 365;
33
32
  */
34
33
  export declare function decayConstantForHalfLife(days: number): number;
35
34
  /**
36
- * Configure the decay speed from config (`decayHalfLifeDays`). Called at boot
37
- * by the server and the nightly so both processes score with the same clock.
38
- * Invalid/absent values keep the default. Exported value for tests.
35
+ * Configure the decay speed for THIS process (the eval/test seam — #408).
36
+ * Production NEVER passes an argument: every process scores with the
37
+ * calibration half-life (calibration.ts DECAY_HALF_LIFE_DAYS). An
38
+ * invalid/absent value keeps the default. Exported value for tests.
39
39
  */
40
- export declare function configureDecay(options?: {
41
- halfLifeDays?: unknown;
42
- }): number;
43
- interface RecallDefaults {
40
+ export declare function configureDecay(halfLifeDays?: number): number;
41
+ export interface RecallDefaults {
44
42
  searchLimit: number;
45
43
  recentLimit: number;
46
44
  recentWindowDays: number;
47
45
  coldExposureSlots: number;
48
46
  }
49
47
  /**
50
- * Configure recall breadth from config. Called at boot next to
51
- * configureDecay(); invalid/absent values keep the shipped defaults.
52
- * Returns the resolved values (for logging + tests).
48
+ * Configure recall breadth from RESOLVED overrides (the eval/test seam —
49
+ * #408). Production calls this with no argument: the calibration defaults
50
+ * (calibration.ts) apply. Invalid/absent values keep the shipped default per
51
+ * key. Returns the resolved values (for logging + tests).
53
52
  */
54
- export declare function configureRecall(config?: Record<string, unknown> | null): RecallDefaults;
55
- interface ScoringWeights {
53
+ export declare function configureRecall(overrides?: Partial<RecallDefaults> | null): RecallDefaults;
54
+ export interface ScoringWeights {
56
55
  similarity: number;
57
56
  strength: number;
58
57
  connections: number;
@@ -74,29 +73,28 @@ interface ScoringWeights {
74
73
  rrfVectorWeight: number;
75
74
  }
76
75
  /**
77
- * Configure scoring weights + ranking knobs from config. Called at boot by the
78
- * server and the nightly (alongside configureDecay/configureRecall) so
79
- * retrieval and consolidation rank identically. Invalid/absent values keep the
80
- * shipped default per key. Returns the resolved set for logging/tests. Also
81
- * pushes the #205 BM25F field weights into storage (storage.configureBm25Fts)
82
- * so searchFts ranks with the same config — BM25F weights live in storage.ts
83
- * (next to the FTS column declaration they mirror) but are read here from the
84
- * SAME config object for one-place tuning.
76
+ * Configure scoring weights + ranking knobs from RESOLVED overrides (the
77
+ * eval/test seam — #408). Production calls this with no argument: the
78
+ * calibration defaults (calibration.ts) apply, identically in the daemon and
79
+ * the nightly. Invalid/absent values keep the shipped default per key.
80
+ * Returns the resolved set for logging/tests. (The #205 BM25F field weights
81
+ * are NOT touched here — they live in storage.ts and resolve from the same
82
+ * calibration module via storage.configureBm25Fts.)
85
83
  */
86
- export declare function configureScoring(config?: Record<string, unknown> | null): ScoringWeights;
84
+ export declare function configureScoring(overrides?: Partial<ScoringWeights> | null): ScoringWeights;
87
85
  /** Current resolved weights (tests + status output). */
88
86
  export declare function getScoringWeights(): ScoringWeights;
89
87
  /** EMA rate for the session-intent centroid: centroid_new = (1-α)·old + α·prompt. */
90
88
  export declare const SESSION_INTENT_ALPHA = 0.4;
91
89
  /**
92
- * Configure session-intent keying from config. Called at server boot next to
93
- * configureScoring (the nightly does no recall, so it does not need this).
94
- * Reads only `sessionIntentWeight` ([0,1]; 0 = disabled). Invalid/out-of-range
95
- * values keep the shipped default. Returns `{ weight, alpha }` — alpha is the
96
- * fixed constant, surfaced so the recall closure passes it to the registry in
97
- * one call.
90
+ * Configure session-intent keying for THIS process (the eval/test seam —
91
+ * #408). Production calls this with no argument: the calibration weight
92
+ * (calibration.ts SESSION_INTENT_WEIGHT) applies. `weight` is [0,1] (0 =
93
+ * disabled — the eval kill-switch); invalid/out-of-range values keep the
94
+ * shipped default. Returns `{ weight, alpha }` — alpha is the fixed constant,
95
+ * surfaced so the recall closure passes it to the registry in one call.
98
96
  */
99
- export declare function configureSessionIntent(config?: Record<string, unknown> | null): {
97
+ export declare function configureSessionIntent(weight?: number): {
100
98
  weight: number;
101
99
  alpha: number;
102
100
  };
@@ -161,6 +159,32 @@ export declare function findSupersededIds(db: Database.Database, candidateIds: s
161
159
  * (NULL status, no link) — they never match either arm.
162
160
  */
163
161
  export declare function findDemotedIds(db: Database.Database, candidateIds: string[]): Set<string>;
162
+ /**
163
+ * Hop cap for the belief walk (#393 D). Supersession edges advance
164
+ * created_at monotonically (the stage only links old → new), so chains are
165
+ * acyclic by construction and 10 hops is far beyond any real revision depth;
166
+ * the cap is cheap insurance (see beliefWalkTerminal for why it is needed
167
+ * anyway).
168
+ */
169
+ export declare const BELIEF_WALK_MAX_HOPS = 10;
170
+ /**
171
+ * Terminal of the supersession chain starting at `id` (#393 D): follow
172
+ * superseded_by edges transitively until a memory with no outgoing edge and
173
+ * return it — `id` itself when there is nothing to walk, or whichever node
174
+ * the walk stopped on when it aborts. Shared by retrieval (the belief-walk
175
+ * splice in retrieve()/searchRecent()) and the eval harness (the
176
+ * planted-pairs version_chain class probe), so both agree on what "the
177
+ * chain's current truth" is.
178
+ *
179
+ * Edges advance created_at monotonically (acyclic by construction), BUT
180
+ * applyExplicitMark does no age check and created_at is backdatable from
181
+ * session_date — so a cycle or an absurdly long chain is not impossible.
182
+ * The visited set (seeded with `id`) and the BELIEF_WALK_MAX_HOPS cap are
183
+ * cheap insurance against exactly that; the supersededDemotion multiplier
184
+ * in computeScore remains the safety net for rows the walk does not fully
185
+ * resolve (no edge, cycle, cap abort, absorbed terminal).
186
+ */
187
+ export declare function beliefWalkTerminal(db: Database.Database, id: string, maxHops?: number): string;
164
188
  /**
165
189
  * Convert an L2 distance (as returned by sqlite-vec's vec0 `distance`) to
166
190
  * cosine similarity. Valid because our embeddings are L2-normalized
@@ -171,6 +195,16 @@ export declare function findDemotedIds(db: Database.Database, candidateIds: stri
171
195
  * by consolidate.ts so pre-#145 importers keep working.
172
196
  */
173
197
  export declare function l2ToCosine(distance: number): number;
198
+ /**
199
+ * Cosine similarity between two stored embeddings (#393 increment B). The
200
+ * similarity source measures cosines transitively via vec0 L2 distances; the
201
+ * scout source finds its candidates through FTS (no vec0 query), so it
202
+ * measures the pair cosine directly from the stored vectors instead —
203
+ * valid because every embedding we store is L2-normalized (embedder.ts).
204
+ * Used as link strength / a ranker, never as a gate (the scout has no
205
+ * similarity floor — that is the point of the increment).
206
+ */
207
+ export declare function cosineBetweenVectors(a: Float32Array, b: Float32Array): number;
174
208
  /**
175
209
  * Compute decayed strength with adaptive decay (B+E+D model).
176
210
  * Exported for use by consolidation decay/prune stage.
@@ -264,4 +298,3 @@ export declare function searchRecent(db: Database.Database, options?: {
264
298
  project?: string | null;
265
299
  limit?: number;
266
300
  }): MemorySearchResult[];
267
- export {};