@getrift/rift 0.1.0-beta.22 → 0.1.0-beta.23

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 (101) hide show
  1. package/dist/src/capture/recover-quarantine.d.ts +4 -4
  2. package/dist/src/cli/commands/capture.d.ts.map +1 -1
  3. package/dist/src/cli/commands/capture.js +7 -0
  4. package/dist/src/cli/commands/capture.js.map +1 -1
  5. package/dist/src/cli/commands/menubar.d.ts +3 -1
  6. package/dist/src/cli/commands/menubar.d.ts.map +1 -1
  7. package/dist/src/cli/commands/menubar.js +36 -12
  8. package/dist/src/cli/commands/menubar.js.map +1 -1
  9. package/dist/src/cli/postinstall-menubar.d.ts +20 -13
  10. package/dist/src/cli/postinstall-menubar.d.ts.map +1 -1
  11. package/dist/src/cli/postinstall-menubar.js +56 -1
  12. package/dist/src/cli/postinstall-menubar.js.map +1 -1
  13. package/dist/src/cli/status/friend-header.d.ts +6 -3
  14. package/dist/src/cli/status/friend-header.d.ts.map +1 -1
  15. package/dist/src/cli/status/friend-header.js +75 -16
  16. package/dist/src/cli/status/friend-header.js.map +1 -1
  17. package/dist/src/cli/status/local-signals.d.ts +19 -4
  18. package/dist/src/cli/status/local-signals.d.ts.map +1 -1
  19. package/dist/src/cli/status/local-signals.js +33 -1
  20. package/dist/src/cli/status/local-signals.js.map +1 -1
  21. package/dist/src/diagnostics/claude-preflight.d.ts +3 -2
  22. package/dist/src/diagnostics/claude-preflight.d.ts.map +1 -1
  23. package/dist/src/diagnostics/claude-preflight.js +10 -9
  24. package/dist/src/diagnostics/claude-preflight.js.map +1 -1
  25. package/dist/src/diagnostics/codex-preflight.d.ts +1 -1
  26. package/dist/src/diagnostics/codex-preflight.d.ts.map +1 -1
  27. package/dist/src/diagnostics/codex-preflight.js +10 -0
  28. package/dist/src/diagnostics/codex-preflight.js.map +1 -1
  29. package/dist/src/diagnostics/doctor.d.ts +7 -4
  30. package/dist/src/diagnostics/doctor.d.ts.map +1 -1
  31. package/dist/src/diagnostics/doctor.js +36 -14
  32. package/dist/src/diagnostics/doctor.js.map +1 -1
  33. package/dist/src/diagnostics/memory-coverage.d.ts +54 -0
  34. package/dist/src/diagnostics/memory-coverage.d.ts.map +1 -0
  35. package/dist/src/diagnostics/memory-coverage.js +272 -0
  36. package/dist/src/diagnostics/memory-coverage.js.map +1 -0
  37. package/dist/src/diagnostics/notify.d.ts +20 -3
  38. package/dist/src/diagnostics/notify.d.ts.map +1 -1
  39. package/dist/src/diagnostics/notify.js +54 -14
  40. package/dist/src/diagnostics/notify.js.map +1 -1
  41. package/dist/src/main.js +1 -1
  42. package/dist/src/main.js.map +1 -1
  43. package/dist/src/mcp/capture-diagnostics.d.ts +51 -0
  44. package/dist/src/mcp/capture-diagnostics.d.ts.map +1 -0
  45. package/dist/src/mcp/capture-diagnostics.js +127 -0
  46. package/dist/src/mcp/capture-diagnostics.js.map +1 -0
  47. package/dist/src/mcp/memory-diagnostics.d.ts +6 -0
  48. package/dist/src/mcp/memory-diagnostics.d.ts.map +1 -0
  49. package/dist/src/mcp/memory-diagnostics.js +51 -0
  50. package/dist/src/mcp/memory-diagnostics.js.map +1 -0
  51. package/dist/src/mcp/tools/log-outcome.d.ts +2 -2
  52. package/dist/src/mcp/tools/status.d.ts +15 -1
  53. package/dist/src/mcp/tools/status.d.ts.map +1 -1
  54. package/dist/src/mcp/tools/status.js +53 -2
  55. package/dist/src/mcp/tools/status.js.map +1 -1
  56. package/dist/src/providers/codex-cli-runner.js +1 -1
  57. package/dist/src/providers/codex-cli-runner.js.map +1 -1
  58. package/dist/src/retrieval/canonical-files.d.ts +48 -0
  59. package/dist/src/retrieval/canonical-files.d.ts.map +1 -0
  60. package/dist/src/retrieval/canonical-files.js +210 -0
  61. package/dist/src/retrieval/canonical-files.js.map +1 -0
  62. package/dist/src/retrieval/compact.d.ts +14 -0
  63. package/dist/src/retrieval/compact.d.ts.map +1 -1
  64. package/dist/src/retrieval/compact.js +7 -1
  65. package/dist/src/retrieval/compact.js.map +1 -1
  66. package/dist/src/retrieval/context-pack.d.ts.map +1 -1
  67. package/dist/src/retrieval/context-pack.js +38 -2
  68. package/dist/src/retrieval/context-pack.js.map +1 -1
  69. package/dist/src/retrieval/conversation-dedup.d.ts +40 -0
  70. package/dist/src/retrieval/conversation-dedup.d.ts.map +1 -0
  71. package/dist/src/retrieval/conversation-dedup.js +141 -0
  72. package/dist/src/retrieval/conversation-dedup.js.map +1 -0
  73. package/dist/src/retrieval/feedback-ranking.d.ts +49 -0
  74. package/dist/src/retrieval/feedback-ranking.d.ts.map +1 -0
  75. package/dist/src/retrieval/feedback-ranking.js +138 -0
  76. package/dist/src/retrieval/feedback-ranking.js.map +1 -0
  77. package/dist/src/retrieval/git-state.d.ts +9 -0
  78. package/dist/src/retrieval/git-state.d.ts.map +1 -1
  79. package/dist/src/retrieval/git-state.js +18 -0
  80. package/dist/src/retrieval/git-state.js.map +1 -1
  81. package/dist/src/retrieval/reranker.d.ts +37 -0
  82. package/dist/src/retrieval/reranker.d.ts.map +1 -1
  83. package/dist/src/retrieval/reranker.js +54 -1
  84. package/dist/src/retrieval/reranker.js.map +1 -1
  85. package/dist/src/server/app.d.ts +1 -1
  86. package/dist/src/server/app.d.ts.map +1 -1
  87. package/dist/src/server/app.js +3 -2
  88. package/dist/src/server/app.js.map +1 -1
  89. package/dist/src/server/routes/conversations-search.d.ts.map +1 -1
  90. package/dist/src/server/routes/conversations-search.js +11 -1
  91. package/dist/src/server/routes/conversations-search.js.map +1 -1
  92. package/dist/src/server/routes/friend-status.d.ts +20 -1
  93. package/dist/src/server/routes/friend-status.d.ts.map +1 -1
  94. package/dist/src/server/routes/friend-status.js +40 -12
  95. package/dist/src/server/routes/friend-status.js.map +1 -1
  96. package/dist/src/server/routes/search.d.ts +1 -1
  97. package/dist/src/server/routes/search.d.ts.map +1 -1
  98. package/dist/src/server/routes/search.js +37 -2
  99. package/dist/src/server/routes/search.js.map +1 -1
  100. package/operator/swiftbar/render-menu.py +3 -3
  101. package/package.json +2 -2
@@ -0,0 +1,40 @@
1
+ import type { RankedResult } from "./reranker.js";
2
+ /** Token-set Jaccard at or above this collapses two conversations. High by design. */
3
+ export declare const CONV_DEDUP_JACCARD_THRESHOLD = 0.9;
4
+ /** Rows shorter than this never participate (as rep OR candidate) — short text
5
+ * creates false confidence. Conversation captures are normally far longer. */
6
+ export declare const CONV_DEDUP_MIN_CONTENT_CHARS = 400;
7
+ export declare function convDedupEnabled(env?: NodeJS.ProcessEnv): boolean;
8
+ /**
9
+ * The DATA-based companion to {@link convDedupEnabled}: conv dedup must not run on
10
+ * a pool that contains chunk-marked rows, because under chunking `groupByParent`
11
+ * leaves a parent's content as its best CHUNK's text (see module HAZARD). A
12
+ * non-empty `siblingCountById` means ≥1 chunk-marked row is present — `groupByParent`
13
+ * records an entry for every marked row, even a lone surfaced chunk — so callers
14
+ * skip dedup for that request. On a never-chunked dir this is always 0 (markers
15
+ * come only from non-null parent keys), so dedup runs normally.
16
+ */
17
+ export declare function poolHasChunkMarkers(grouped: {
18
+ siblingCountById: ReadonlyMap<string, number>;
19
+ }): boolean;
20
+ /** |A ∩ B| / |A ∪ B| over token sets. 0 when either side is empty. */
21
+ export declare function tokenSetJaccard(a: ReadonlySet<string>, b: ReadonlySet<string>): number;
22
+ export interface ConversationDedupResult {
23
+ /** Collapsed list: best conversation per near-duplicate set, others removed,
24
+ * non-conversation rows untouched, order preserved. */
25
+ ranked: RankedResult[];
26
+ /** {@link rankedKey} of a representative → total conversation rows folded into
27
+ * it (≥ 2 only when something merged; absent for un-merged rows). */
28
+ duplicateCountById: Map<string, number>;
29
+ /** {@link rankedKey} of a representative → the folded duplicate ROWS (excludes
30
+ * the representative itself). Lets a caller recover what was collapsed away —
31
+ * e.g. transfer a label that was attached to a folded near-duplicate onto the
32
+ * surviving representative, since both are the same evidence. Present only for
33
+ * merged sets. */
34
+ foldedMembersById: Map<string, RankedResult[]>;
35
+ }
36
+ export declare function collapseConversationDuplicates(ranked: readonly RankedResult[], opts?: {
37
+ jaccardThreshold?: number;
38
+ minContentChars?: number;
39
+ }): ConversationDedupResult;
40
+ //# sourceMappingURL=conversation-dedup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-dedup.d.ts","sourceRoot":"","sources":["../../../src/retrieval/conversation-dedup.ts"],"names":[],"mappings":"AA+CA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,sFAAsF;AACtF,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD;+EAC+E;AAC/E,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAOhD,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAW9E;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/C,GAAG,OAAO,CAEV;AAWD,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAOtF;AAED,MAAM,WAAW,uBAAuB;IACtC;4DACwD;IACxD,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB;0EACsE;IACtE,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;;;;uBAImB;IACnB,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;CAChD;AAQD,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,IAAI,GAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAO,GACjE,uBAAuB,CA2CzB"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Post-grouping collapse of near-duplicate CONVERSATION captures.
3
+ *
4
+ * The same task captured across several sessions lands as DISTINCT conversation
5
+ * rows (distinct ids → distinct parent keys), so `groupByParent` — which only
6
+ * collapses chunk siblings of ONE conversation — never merges them and the
7
+ * duplicates crowd top-k. This pass collapses conversation rows whose CONTENT is
8
+ * near-identical, keeps the highest-ranked representative, and records how many
9
+ * rows it folded (mirroring `siblingCountById`).
10
+ *
11
+ * Precision-first, by deliberate design (a false positive HIDES real evidence; a
12
+ * false negative only leaves clutter, which is acceptable for v1):
13
+ * - Conversations ONLY. Docs, trackers, digests, and structured rows pass
14
+ * through untouched — they are never merged and never a merge target.
15
+ * - Exact (normalized) OR token-Jaccard ≥ threshold over the FULL content. Using
16
+ * full content (not a prefix) means "same opening, different substance" stays
17
+ * distinct: divergent bodies drop the union overlap below the threshold.
18
+ * - A minimum content size — short snippets never merge (short text gives false
19
+ * confidence), neither as a representative nor as a candidate.
20
+ * - The representative is the best-ranked row; raw data is untouched (only the
21
+ * served/display list collapses — callers still hydrate raw rows for survivors).
22
+ *
23
+ * Flag default: ON as of the dogfood-PASS flip (roll back with
24
+ * `RIFT_CONV_DEDUP=false|0|off|no`). Callers still gate on `convDedupEnabled()`,
25
+ * so with the flag off the collapse pass is never invoked and the served result
26
+ * is byte-identical to the pre-dedup behavior.
27
+ *
28
+ * Input is assumed score-descending (post-rerank / post-groupByParent), so the
29
+ * first row seen for a duplicate set is its best; overall order is preserved.
30
+ *
31
+ * HAZARD (guarded) — dedup compares `RankedResult.content`. When the pool
32
+ * contains chunk-marked rows, after `groupByParent` that content is the best
33
+ * CHUNK's text for a parent, NOT the full conversation. Two DIFFERENT
34
+ * conversations that happen to share a near-identical chunk (e.g. boilerplate, a
35
+ * pasted prompt, a common preamble) could then false-merge — the exact precision
36
+ * failure this module avoids. Two guards, because `RIFT_CHUNKING` only controls
37
+ * whether NEW rows are split, not whether chunked rows ALREADY exist in the data:
38
+ * 1. {@link convDedupEnabled} returns false while `RIFT_CHUNKING` is on (a
39
+ * global kill-switch while chunked rows are actively being produced).
40
+ * 2. {@link poolHasChunkMarkers} — the load-bearing, DATA-based guard: callers
41
+ * skip dedup for any request whose grouped pool contains a chunk marker, so
42
+ * a dir chunked in the past but now served with `RIFT_CHUNKING=0` is still
43
+ * safe. Lifting BOTH requires dedup to compare hydrated full-parent content.
44
+ */
45
+ import { chunkingEnabled } from "../ingestion/chunk-text.js";
46
+ import { tokenize } from "./lexical.js";
47
+ import { rankedKey } from "./group-by-parent.js";
48
+ /** Token-set Jaccard at or above this collapses two conversations. High by design. */
49
+ export const CONV_DEDUP_JACCARD_THRESHOLD = 0.9;
50
+ /** Rows shorter than this never participate (as rep OR candidate) — short text
51
+ * creates false confidence. Conversation captures are normally far longer. */
52
+ export const CONV_DEDUP_MIN_CONTENT_CHARS = 400;
53
+ const CONVERSATION_TABLES = new Set([
54
+ "conversations_hot",
55
+ "conversations_cold",
56
+ ]);
57
+ export function convDedupEnabled(env = process.env) {
58
+ // Global kill-switch while chunking is ACTIVELY producing chunk-text rows. This
59
+ // is necessary but NOT sufficient — RIFT_CHUNKING=0 does not unchunk old data —
60
+ // so callers MUST also gate on poolHasChunkMarkers() (the data-based guard).
61
+ if (chunkingEnabled(env))
62
+ return false;
63
+ // Default ON (dogfood verdict PASS); roll back with RIFT_CONV_DEDUP=false|0|off|no.
64
+ // The per-request poolHasChunkMarkers() guard still protects previously-chunked
65
+ // dirs, so default-on is safe even where old chunked rows linger.
66
+ const v = env["RIFT_CONV_DEDUP"];
67
+ if (v == null)
68
+ return true;
69
+ return !/^(false|0|off|no)$/i.test(v.trim());
70
+ }
71
+ /**
72
+ * The DATA-based companion to {@link convDedupEnabled}: conv dedup must not run on
73
+ * a pool that contains chunk-marked rows, because under chunking `groupByParent`
74
+ * leaves a parent's content as its best CHUNK's text (see module HAZARD). A
75
+ * non-empty `siblingCountById` means ≥1 chunk-marked row is present — `groupByParent`
76
+ * records an entry for every marked row, even a lone surfaced chunk — so callers
77
+ * skip dedup for that request. On a never-chunked dir this is always 0 (markers
78
+ * come only from non-null parent keys), so dedup runs normally.
79
+ */
80
+ export function poolHasChunkMarkers(grouped) {
81
+ return grouped.siblingCountById.size > 0;
82
+ }
83
+ function isConversationRow(r) {
84
+ return CONVERSATION_TABLES.has(r.source_table);
85
+ }
86
+ /** Whitespace/case-normalized content, for the exact-match fast path. */
87
+ function normalizeForExact(content) {
88
+ return content.normalize("NFC").replace(/\s+/g, " ").trim().toLowerCase();
89
+ }
90
+ /** |A ∩ B| / |A ∪ B| over token sets. 0 when either side is empty. */
91
+ export function tokenSetJaccard(a, b) {
92
+ if (a.size === 0 || b.size === 0)
93
+ return 0;
94
+ const [small, large] = a.size <= b.size ? [a, b] : [b, a];
95
+ let inter = 0;
96
+ for (const t of small)
97
+ if (large.has(t))
98
+ inter += 1;
99
+ const union = a.size + b.size - inter;
100
+ return union === 0 ? 0 : inter / union;
101
+ }
102
+ export function collapseConversationDuplicates(ranked, opts = {}) {
103
+ const threshold = opts.jaccardThreshold ?? CONV_DEDUP_JACCARD_THRESHOLD;
104
+ const minChars = opts.minContentChars ?? CONV_DEDUP_MIN_CONTENT_CHARS;
105
+ const kept = [];
106
+ const duplicateCountById = new Map();
107
+ const foldedMembersById = new Map();
108
+ const reps = [];
109
+ for (const r of ranked) {
110
+ // Guardrail 1 (conversations only) + guardrail 3 (min size): anything else is
111
+ // kept verbatim and never participates in matching.
112
+ if (!isConversationRow(r) || r.content.length < minChars) {
113
+ kept.push(r);
114
+ continue;
115
+ }
116
+ const normExact = normalizeForExact(r.content);
117
+ const tokens = new Set(tokenize(r.content));
118
+ let mergedInto;
119
+ for (const rep of reps) {
120
+ if (normExact === rep.normExact || tokenSetJaccard(tokens, rep.tokens) >= threshold) {
121
+ mergedInto = rep;
122
+ break;
123
+ }
124
+ }
125
+ if (mergedInto) {
126
+ const repKey = rankedKey(mergedInto.row);
127
+ // Representative counts as 1; each folded duplicate adds 1 (same semantics
128
+ // as groupByParent's siblingCountById).
129
+ duplicateCountById.set(repKey, (duplicateCountById.get(repKey) ?? 1) + 1);
130
+ const members = foldedMembersById.get(repKey) ?? [];
131
+ members.push(r);
132
+ foldedMembersById.set(repKey, members);
133
+ }
134
+ else {
135
+ kept.push(r);
136
+ reps.push({ row: r, normExact, tokens });
137
+ }
138
+ }
139
+ return { ranked: kept, duplicateCountById, foldedMembersById };
140
+ }
141
+ //# sourceMappingURL=conversation-dedup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-dedup.js","sourceRoot":"","sources":["../../../src/retrieval/conversation-dedup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import type { TableName } from "../storage/tables.js";
2
+ import { type RankedResult } from "./reranker.js";
3
+ import { type FeedbackScope } from "../observability/retrieval-feedback.js";
4
+ /**
5
+ * Whether retrieval-feedback ranking is enabled. Single env flag
6
+ * `RIFT_FEEDBACK_RANKING`, default OFF — mirrors the `RIFT_CHUNKING` /
7
+ * `RIFT_LOCATOR_BOOST` gated-rollout pattern. Only `"1"` enables it.
8
+ */
9
+ export declare function feedbackRankingEnabled(env?: NodeJS.ProcessEnv): boolean;
10
+ /**
11
+ * Resolve each reranked candidate to its stable evidence key via a
12
+ * projection-only query per source table (no `content`, no embedding vector —
13
+ * the same hot-path discipline as {@link fetchParentKeysForRanked}). Returns
14
+ * `rankedKey(r) → stable_evidence_key`, keyed by `(source_table, id)` so a row
15
+ * id shared across cloud/local doc tables can't collide. Ids with no backing
16
+ * row are simply absent (→ treated as neutral by the caller).
17
+ */
18
+ export declare function fetchStableEvidenceKeysForRanked(ranked: readonly RankedResult[]): Promise<Map<string, string>>;
19
+ /** One reranked result that received a positive feedback boost. */
20
+ export interface FeedbackRankingApplied {
21
+ id: string;
22
+ source_table: TableName;
23
+ stable_evidence_key: string;
24
+ B_feed: number;
25
+ weighted_credit: number;
26
+ positive_event_count: number;
27
+ }
28
+ export interface ApplyFeedbackRankingResult {
29
+ ranked: RankedResult[];
30
+ /** Candidates whose B_feed exceeded neutral — the dogfood/explain surface. */
31
+ applied: FeedbackRankingApplied[];
32
+ }
33
+ /**
34
+ * Boost a reranked set by accumulated retrieval feedback. The caller gates this
35
+ * on {@link feedbackRankingEnabled}; here it is unconditional so it can be
36
+ * exercised directly in tests.
37
+ *
38
+ * Two fast no-ops avoid any cost when there is nothing to do: an empty ledger
39
+ * skips the DB projection entirely, and {@link applyFeedbackBoost} preserves the
40
+ * input order when no candidate's boost is non-neutral.
41
+ *
42
+ * @param keyResolver - test seam; defaults to the DB-backed
43
+ * {@link fetchStableEvidenceKeysForRanked}.
44
+ */
45
+ export declare function applyFeedbackRanking(dataDir: string, ranked: RankedResult[], opts?: {
46
+ scope?: FeedbackScope;
47
+ keyResolver?: (ranked: readonly RankedResult[]) => Promise<Map<string, string>>;
48
+ }): Promise<ApplyFeedbackRankingResult>;
49
+ //# sourceMappingURL=feedback-ranking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-ranking.d.ts","sourceRoot":"","sources":["../../../src/retrieval/feedback-ranking.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,wCAAwC,CAAC;AAEhD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAET;AAMD;;;;;;;GAOG;AACH,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,SAAS,YAAY,EAAE,GAC9B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA4C9B;AAED,mEAAmE;AACnE,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,SAAS,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,8EAA8E;IAC9E,OAAO,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,YAAY,EAAE,EACtB,IAAI,GAAE;IACJ,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,WAAW,CAAC,EAAE,CACZ,MAAM,EAAE,SAAS,YAAY,EAAE,KAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC9B,GACL,OAAO,CAAC,0BAA0B,CAAC,CAoCrC"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Retrieval-feedback ranking integration (Slice 16).
3
+ *
4
+ * Slice 15 shipped the rails: agents open/cite evidence via the MCP tools, and
5
+ * positive-only events accrue in an append-only ledger. `computeFeedbackBoosts`
6
+ * turns those events into a bounded `B_feed` per stable evidence key, but until
7
+ * now nothing fed that boost back into live ranking — it was shadow-only,
8
+ * surfaced through `rift why` for inspection.
9
+ *
10
+ * This module is the candidate-boost LOOKUP that closes the loop, behind a
11
+ * default-OFF flag (`RIFT_FEEDBACK_RANKING`). With the flag off (or an empty
12
+ * ledger) it is never invoked / is a guaranteed no-op, so the ship path is
13
+ * unchanged. With it on, a search:
14
+ * 1. resolves each reranked candidate to its stable evidence key (the SAME
15
+ * `stableEvidenceIdentityForRow` the open/cite path keyed events with, so a
16
+ * candidate matches its own recorded feedback);
17
+ * 2. computes the bounded B_feed for those keys from the ledger;
18
+ * 3. applies it via {@link applyFeedbackBoost} (a re-score identical to having
19
+ * reranked with that B_feed).
20
+ *
21
+ * Scope choice (v0): the lookup uses a GLOBAL scope — every positive event for a
22
+ * key counts, regardless of project/intent. `project`/`intent` on events are
23
+ * agent-supplied and optional (see `rift_log_outcome` / `rift_open_evidence`),
24
+ * so they are frequently absent; a narrow `(project, intent)` lookup scope would
25
+ * silently exclude those events and the boost would mysteriously never fire.
26
+ * Global is the conservative correct default for a single-user tool ("this
27
+ * source helped me before" is a meaningful global signal), it is positive-only
28
+ * and bounded (B_feed ≤ 1.25, weight 0.10 → ≤ +0.025 to a candidate's score),
29
+ * and the `applied[]` explain output lets dogfooding SEE whether global is too
30
+ * coarse before any narrowing. Per-scope ranking is a deliberate follow-up.
31
+ */
32
+ import { getTable } from "../storage/tables.js";
33
+ import { inFilter } from "../storage/filter.js";
34
+ import { rankedKey } from "./group-by-parent.js";
35
+ import { applyFeedbackBoost, } from "./reranker.js";
36
+ import { stableEvidenceIdentityForRow } from "./evidence-key.js";
37
+ import { readRetrievalFeedbackEvents, computeFeedbackBoosts, B_FEED_NEUTRAL, } from "../observability/retrieval-feedback.js";
38
+ /**
39
+ * Whether retrieval-feedback ranking is enabled. Single env flag
40
+ * `RIFT_FEEDBACK_RANKING`, default OFF — mirrors the `RIFT_CHUNKING` /
41
+ * `RIFT_LOCATOR_BOOST` gated-rollout pattern. Only `"1"` enables it.
42
+ */
43
+ export function feedbackRankingEnabled(env = process.env) {
44
+ return env["RIFT_FEEDBACK_RANKING"] === "1";
45
+ }
46
+ /** Minimal projections needed to key a candidate the same way the ledger did. */
47
+ const CONV_KEY_COLUMNS = ["id", "parent_id", "source"];
48
+ const DOC_KEY_COLUMNS = ["id", "source_path"];
49
+ /**
50
+ * Resolve each reranked candidate to its stable evidence key via a
51
+ * projection-only query per source table (no `content`, no embedding vector —
52
+ * the same hot-path discipline as {@link fetchParentKeysForRanked}). Returns
53
+ * `rankedKey(r) → stable_evidence_key`, keyed by `(source_table, id)` so a row
54
+ * id shared across cloud/local doc tables can't collide. Ids with no backing
55
+ * row are simply absent (→ treated as neutral by the caller).
56
+ */
57
+ export async function fetchStableEvidenceKeysForRanked(ranked) {
58
+ const byTable = new Map();
59
+ for (const r of ranked) {
60
+ const arr = byTable.get(r.source_table) ?? [];
61
+ arr.push(r.id);
62
+ byTable.set(r.source_table, arr);
63
+ }
64
+ const out = new Map();
65
+ for (const [tableName, ids] of byTable) {
66
+ if (ids.length === 0)
67
+ continue;
68
+ const keyOf = (id) => rankedKey({ source_table: tableName, id });
69
+ // Digests key on their id alone — no projection needed.
70
+ if (tableName === "digests") {
71
+ for (const id of ids) {
72
+ out.set(keyOf(id), stableEvidenceIdentityForRow("digests", { id }).stable_evidence_key);
73
+ }
74
+ continue;
75
+ }
76
+ const columns = tableName === "conversations_hot" || tableName === "conversations_cold"
77
+ ? CONV_KEY_COLUMNS
78
+ : DOC_KEY_COLUMNS;
79
+ const rows = (await getTable(tableName)
80
+ .query()
81
+ .where(inFilter("id", ids, { validateAsRowId: true }))
82
+ .select([...columns])
83
+ .limit(ids.length)
84
+ .toArray());
85
+ for (const row of rows) {
86
+ const id = typeof row["id"] === "string" ? row["id"] : undefined;
87
+ if (!id)
88
+ continue;
89
+ out.set(keyOf(id), stableEvidenceIdentityForRow(tableName, row).stable_evidence_key);
90
+ }
91
+ }
92
+ return out;
93
+ }
94
+ /**
95
+ * Boost a reranked set by accumulated retrieval feedback. The caller gates this
96
+ * on {@link feedbackRankingEnabled}; here it is unconditional so it can be
97
+ * exercised directly in tests.
98
+ *
99
+ * Two fast no-ops avoid any cost when there is nothing to do: an empty ledger
100
+ * skips the DB projection entirely, and {@link applyFeedbackBoost} preserves the
101
+ * input order when no candidate's boost is non-neutral.
102
+ *
103
+ * @param keyResolver - test seam; defaults to the DB-backed
104
+ * {@link fetchStableEvidenceKeysForRanked}.
105
+ */
106
+ export async function applyFeedbackRanking(dataDir, ranked, opts = {}) {
107
+ const events = readRetrievalFeedbackEvents(dataDir);
108
+ if (events.length === 0)
109
+ return { ranked, applied: [] };
110
+ const resolveKeys = opts.keyResolver ?? fetchStableEvidenceKeysForRanked;
111
+ const keyByRanked = await resolveKeys(ranked);
112
+ const uniqueKeys = [...new Set(keyByRanked.values())];
113
+ if (uniqueKeys.length === 0)
114
+ return { ranked, applied: [] };
115
+ const boosts = computeFeedbackBoosts(events, uniqueKeys, opts.scope ?? {});
116
+ const boostOf = (r) => {
117
+ const k = keyByRanked.get(rankedKey(r));
118
+ return k ? boosts.get(k)?.B_feed : undefined;
119
+ };
120
+ const { ranked: rescored } = applyFeedbackBoost(ranked, boostOf);
121
+ const applied = [];
122
+ for (const r of ranked) {
123
+ const k = keyByRanked.get(rankedKey(r));
124
+ const b = k ? boosts.get(k) : undefined;
125
+ if (b && b.B_feed > B_FEED_NEUTRAL) {
126
+ applied.push({
127
+ id: r.id,
128
+ source_table: r.source_table,
129
+ stable_evidence_key: b.stable_evidence_key,
130
+ B_feed: b.B_feed,
131
+ weighted_credit: b.weighted_credit,
132
+ positive_event_count: b.positive_event_count,
133
+ });
134
+ }
135
+ }
136
+ return { ranked: rescored, applied };
137
+ }
138
+ //# sourceMappingURL=feedback-ranking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-ranking.js","sourceRoot":"","sources":["../../../src/retrieval/feedback-ranking.ts"],"names":[],"mappings":"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"}
@@ -50,4 +50,13 @@ export interface ProbeOptions {
50
50
  * - Otherwise classified per {@link GitState} precedence.
51
51
  */
52
52
  export declare function probeGitStates(inputs: readonly GitStateInput[], opts: ProbeOptions): Map<string, GitState>;
53
+ /**
54
+ * Resolve the git top-level for `cwd` via `git rev-parse --show-toplevel`,
55
+ * so callers can locate repo-root files (PROJECT_STATE.md, TODO.md) even when
56
+ * the agent's cwd is a subdirectory (the same problem {@link probeGitStates}
57
+ * solves for path classification). Returns the resolved absolute repo root, or
58
+ * the resolved `cwd` when git is unavailable / `cwd` is not a repo — a safe
59
+ * fallback that simply looks in `cwd`.
60
+ */
61
+ export declare function resolveRepoRoot(cwd: string): string;
53
62
  //# sourceMappingURL=git-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"git-state.d.ts","sourceRoot":"","sources":["../../../src/retrieval/git-state.ts"],"names":[],"mappings":"AA6BA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,QAAQ,GAChB,SAAS,GACT,WAAW,GACX,UAAU,GACV,SAAS,GACT,eAAe,GACf,SAAS,CAAC;AAEd,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;OASG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,IAAI,EAAE,YAAY,GACjB,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CA+BvB"}
1
+ {"version":3,"file":"git-state.d.ts","sourceRoot":"","sources":["../../../src/retrieval/git-state.ts"],"names":[],"mappings":"AA6BA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,QAAQ,GAChB,SAAS,GACT,WAAW,GACX,UAAU,GACV,SAAS,GACT,eAAe,GACf,SAAS,CAAC;AAEd,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;OASG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,IAAI,EAAE,YAAY,GACjB,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CA+BvB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQnD"}
@@ -68,6 +68,24 @@ export function probeGitStates(inputs, opts) {
68
68
  }
69
69
  return out;
70
70
  }
71
+ /**
72
+ * Resolve the git top-level for `cwd` via `git rev-parse --show-toplevel`,
73
+ * so callers can locate repo-root files (PROJECT_STATE.md, TODO.md) even when
74
+ * the agent's cwd is a subdirectory (the same problem {@link probeGitStates}
75
+ * solves for path classification). Returns the resolved absolute repo root, or
76
+ * the resolved `cwd` when git is unavailable / `cwd` is not a repo — a safe
77
+ * fallback that simply looks in `cwd`.
78
+ */
79
+ export function resolveRepoRoot(cwd) {
80
+ const base = path.resolve(cwd);
81
+ try {
82
+ const top = runGit(base, ["rev-parse", "--show-toplevel"]).trim();
83
+ return top ? path.resolve(top) : base;
84
+ }
85
+ catch {
86
+ return base;
87
+ }
88
+ }
71
89
  function runGit(cwd, args) {
72
90
  return execFileSync("git", ["-C", cwd, ...args], {
73
91
  encoding: "utf8",
@@ -1 +1 @@
1
- {"version":3,"file":"git-state.js","sourceRoot":"","sources":["../../../src/retrieval/git-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,IAAI,MAAM,WAAW,CAAC;AAmD7B;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAgC,EAChC,IAAkB;IAElB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;IACxC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAEpC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAE3C,+DAA+D;IAC/D,iEAAiE;IACjE,kEAAkE;IAClE,6CAA6C;IAC7C,IAAI,IAAY,CAAC;IACjB,IAAI,WAAgC,CAAC;IACrC,IAAI,UAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC7C,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAClF,UAAU,GAAG,IAAI,GAAG,CAClB,MAAM,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC;aACvB,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC,CACnB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,MAAM,KAAK,IAAI,MAAM;YAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACjE,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,MAAM,CAAC,GAAW,EAAE,IAAuB;IAClD,OAAO,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE;QAC/C,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;QACnC,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;KAC5B,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAClB,KAAoB,EACpB,IAAY,EACZ,WAAgC,EAChC,UAAuB;IAEvB,qEAAqE;IACrE,mEAAmE;IACnE,iEAAiE;IACjE,2DAA2D;IAC3D,+DAA+D;IAC/D,+DAA+D;IAC/D,mEAAmE;IACnE,oEAAoE;IACpE,8CAA8C;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACvE,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAE3E,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,WAAW,CAAC;QACxC,oEAAoE;QACpE,+DAA+D;QAC/D,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,OAAO,SAAS,CAAC;QAC7D,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAE3C,gEAAgE;IAChE,8DAA8D;IAC9D,oEAAoE;IACpE,sBAAsB;IACtB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAEvC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;gBACtC,2DAA2D;gBAC3D,8DAA8D;gBAC9D,IAAI,OAAO,GAAG,SAAS,GAAG,IAAI;oBAAE,OAAO,eAAe,CAAC;YACzD,CAAC;YAAC,MAAM,CAAC;gBACP,qCAAqC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,CAAS;IAC7B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,iEAAiE;QACjE,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACpD,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"git-state.js","sourceRoot":"","sources":["../../../src/retrieval/git-state.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,13 @@
17
17
  */
18
18
  import type { TableName } from "../storage/tables.js";
19
19
  import type { RetrievalMethod } from "./hybrid.js";
20
+ /**
21
+ * Weight of the B_feed term. Exported so the flag-gated retrieval-feedback
22
+ * post-pass ({@link applyFeedbackBoost}) can re-score by the SAME weight the
23
+ * composite uses — keeping "apply feedback as a post-pass" mathematically
24
+ * identical to "rerank with that B_feed".
25
+ */
26
+ export declare const W_FEED_WEIGHT = 0.1;
20
27
  /** Half-life (in days) of the short-horizon freshness decay. 14d so a row
21
28
  * indexed within a week still carries most of the bump; past ~2 months
22
29
  * B_fresh collapses to near-zero and effectively disappears. */
@@ -79,4 +86,34 @@ export interface ScoreFactors {
79
86
  * @returns results sorted by final score descending
80
87
  */
81
88
  export declare function rerank(candidates: RerankCandidate[], now?: number): RankedResult[];
89
+ export declare function clampFeedbackBoost(boost: number | undefined): number;
90
+ /**
91
+ * Apply retrieval-feedback boosts to an already-reranked set (Slice 16).
92
+ *
93
+ * `rerank()` deliberately uses a FIXED neutral B_feed term (`+ W_FEED`) so the
94
+ * shadow ledger never moves live ranking. This post-pass is how the gated
95
+ * feedback flag actually applies the learned boost — kept as a separate,
96
+ * flag-gated step so `rerank()` and its golden tests stay byte-for-byte the
97
+ * current behaviour.
98
+ *
99
+ * Why a post-pass is exact: the composite score is a SUM and B_feed appears in
100
+ * exactly one term (`B_feed * W_FEED`). Replacing the old factor `B_old` with a
101
+ * new `B_new` shifts the score by exactly `(B_new - B_old) * W_FEED` — identical
102
+ * to having reranked with `B_new` from the start. `B_old` is whatever the prior
103
+ * pass recorded in `factors.B_feed` (1.0 on the live search path, which never
104
+ * populates `feedback_boost`), so a neutral boost is a guaranteed no-op.
105
+ *
106
+ * Determinism / no-op safety: when no candidate's boost differs from its current
107
+ * factor (the cold-start / empty-ledger case), the input order is returned
108
+ * UNCHANGED — no re-score, no re-sort — so "feedback ranking on, no learned
109
+ * signal yet" is provably indistinguishable from "off".
110
+ *
111
+ * @param ranked - results from {@link rerank}, already sorted by score desc
112
+ * @param boostOf - the learned B_feed for a result, or undefined for neutral
113
+ * @returns the (possibly reordered) results + how many were actually boosted
114
+ */
115
+ export declare function applyFeedbackBoost(ranked: readonly RankedResult[], boostOf: (r: Pick<RankedResult, "id" | "source_table">) => number | undefined): {
116
+ ranked: RankedResult[];
117
+ appliedCount: number;
118
+ };
82
119
  //# sourceMappingURL=reranker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reranker.d.ts","sourceRoot":"","sources":["../../../src/retrieval/reranker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAWnD;;iEAEiE;AACjE,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAqBvC,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,SAAS,CAAC;IACxB,gBAAgB,EAAE,eAAe,CAAC;IAClC,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,eAAe,CAAC;IAClC,YAAY,EAAE,SAAS,CAAC;IACxB,sEAAsE;IACtE,OAAO,EAAE,YAAY,CAAC;IACtB;;;;;8BAK0B;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CACpB,UAAU,EAAE,eAAe,EAAE,EAC7B,GAAG,GAAE,MAAmB,GACvB,YAAY,EAAE,CA+BhB"}
1
+ {"version":3,"file":"reranker.d.ts","sourceRoot":"","sources":["../../../src/retrieval/reranker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AASnD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,MAAS,CAAC;AAGpC;;iEAEiE;AACjE,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAqBvC,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,SAAS,CAAC;IACxB,gBAAgB,EAAE,eAAe,CAAC;IAClC,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,eAAe,CAAC;IAClC,YAAY,EAAE,SAAS,CAAC;IACxB,sEAAsE;IACtE,OAAO,EAAE,YAAY,CAAC;IACtB;;;;;8BAK0B;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CACpB,UAAU,EAAE,eAAe,EAAE,EAC7B,GAAG,GAAE,MAAmB,GACvB,YAAY,EAAE,CA+BhB;AAkCD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGpE;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,OAAO,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,cAAc,CAAC,KAAK,MAAM,GAAG,SAAS,GAC5E;IAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAkBlD"}
@@ -5,6 +5,13 @@ const W_QUAL = 0.10;
5
5
  const W_TIER = 0.10;
6
6
  const W_FEED = 0.10;
7
7
  const W_HYB = 0.05;
8
+ /**
9
+ * Weight of the B_feed term. Exported so the flag-gated retrieval-feedback
10
+ * post-pass ({@link applyFeedbackBoost}) can re-score by the SAME weight the
11
+ * composite uses — keeping "apply feedback as a post-pass" mathematically
12
+ * identical to "rerank with that B_feed".
13
+ */
14
+ export const W_FEED_WEIGHT = W_FEED;
8
15
  /** Small additive boost for just-indexed rows; see B_fresh doc below. */
9
16
  const W_FRESH = 0.05;
10
17
  /** Half-life (in days) of the short-horizon freshness decay. 14d so a row
@@ -86,11 +93,57 @@ function computeFactors(c, now, maxBm25) {
86
93
  const B_fresh = computeFreshness(c.indexed_at, now);
87
94
  return { S_sim, S_rec, S_qual, B_tier, B_feed, B_hyb, B_fresh };
88
95
  }
89
- function clampFeedbackBoost(boost) {
96
+ export function clampFeedbackBoost(boost) {
90
97
  if (typeof boost !== "number" || Number.isNaN(boost))
91
98
  return 1.0;
92
99
  return Math.max(FEEDBACK_MIN, Math.min(FEEDBACK_MAX, boost));
93
100
  }
101
+ /**
102
+ * Apply retrieval-feedback boosts to an already-reranked set (Slice 16).
103
+ *
104
+ * `rerank()` deliberately uses a FIXED neutral B_feed term (`+ W_FEED`) so the
105
+ * shadow ledger never moves live ranking. This post-pass is how the gated
106
+ * feedback flag actually applies the learned boost — kept as a separate,
107
+ * flag-gated step so `rerank()` and its golden tests stay byte-for-byte the
108
+ * current behaviour.
109
+ *
110
+ * Why a post-pass is exact: the composite score is a SUM and B_feed appears in
111
+ * exactly one term (`B_feed * W_FEED`). Replacing the old factor `B_old` with a
112
+ * new `B_new` shifts the score by exactly `(B_new - B_old) * W_FEED` — identical
113
+ * to having reranked with `B_new` from the start. `B_old` is whatever the prior
114
+ * pass recorded in `factors.B_feed` (1.0 on the live search path, which never
115
+ * populates `feedback_boost`), so a neutral boost is a guaranteed no-op.
116
+ *
117
+ * Determinism / no-op safety: when no candidate's boost differs from its current
118
+ * factor (the cold-start / empty-ledger case), the input order is returned
119
+ * UNCHANGED — no re-score, no re-sort — so "feedback ranking on, no learned
120
+ * signal yet" is provably indistinguishable from "off".
121
+ *
122
+ * @param ranked - results from {@link rerank}, already sorted by score desc
123
+ * @param boostOf - the learned B_feed for a result, or undefined for neutral
124
+ * @returns the (possibly reordered) results + how many were actually boosted
125
+ */
126
+ export function applyFeedbackBoost(ranked, boostOf) {
127
+ let appliedCount = 0;
128
+ const rescored = ranked.map((r) => {
129
+ const B_new = clampFeedbackBoost(boostOf(r));
130
+ const B_old = r.factors.B_feed;
131
+ if (B_new === B_old)
132
+ return r;
133
+ appliedCount += 1;
134
+ return {
135
+ ...r,
136
+ score: r.score + (B_new - B_old) * W_FEED,
137
+ factors: { ...r.factors, B_feed: B_new },
138
+ };
139
+ });
140
+ // No effective boost → preserve the exact input order (no re-sort), so an
141
+ // empty/neutral ledger can never perturb ranking.
142
+ if (appliedCount === 0)
143
+ return { ranked: rescored, appliedCount };
144
+ rescored.sort((a, b) => b.score - a.score);
145
+ return { ranked: rescored, appliedCount };
146
+ }
94
147
  /**
95
148
  * B_fresh = exp(-daysSince / FRESH_HALF_LIFE_DAYS).
96
149
  *
@@ -1 +1 @@
1
- {"version":3,"file":"reranker.js","sourceRoot":"","sources":["../../../src/retrieval/reranker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reranker.js","sourceRoot":"","sources":["../../../src/retrieval/reranker.ts"],"names":[],"mappings":"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"}
@@ -25,5 +25,5 @@ export interface App {
25
25
  * If omitted (e.g. in non-auth tests), only the test_token bypass
26
26
  * works for authenticated routes; all other tokens are rejected.
27
27
  */
28
- export declare function buildApp(config: Config, tokenManager?: TokenManager, jobQueue?: JobQueue, embeddingProvider?: EmbeddingProvider, watchers?: Watcher[], scanner?: Scanner | null, digestSummarizer?: DigestSummarizer, metadataExtractor?: MetadataExtractor, localEmbeddingProvider?: EmbeddingProvider): Promise<App>;
28
+ export declare function buildApp(config: Config, tokenManager?: TokenManager, jobQueue?: JobQueue, embeddingProvider?: EmbeddingProvider, watchers?: Watcher[], scanner?: Scanner | null, digestSummarizer?: DigestSummarizer, metadataExtractor?: MetadataExtractor, localEmbeddingProvider?: EmbeddingProvider, configPath?: string): Promise<App>;
29
29
  //# sourceMappingURL=app.d.ts.map