@xdarkicex/openclaw-memory-libravdb 1.4.3 → 1.4.5

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.
@@ -1,1879 +0,0 @@
1
- # Mathematical Reference
2
-
3
- This document is the formal reference for the scoring and optimization math used
4
- by the plugin. The gating scalar is documented separately in
5
- [gating.md](./gating.md). The continuity model and recent-tail preservation
6
- layer are documented in [continuity.md](./continuity.md). The authored
7
- invariant/variant partitioning rules are documented in
8
- [ast-v2.md](./ast-v2.md). The protected-shadow-rule Tier 1.5 model is
9
- documented in [elevated-guidance.md](./elevated-guidance.md). Earlier
10
- non-versioned math docs are preserved for
11
- historical context, but the reviewed `*-v*` documents are authoritative when
12
- both forms exist.
13
-
14
- Every formula below points at the file that currently implements it. If the code
15
- changes first, this document must change with it.
16
-
17
- This revision (3.3) merges the complete section set from `mathematics.md` with
18
- the formal corrections introduced in `mathematics-3-2.md`. All sections are now
19
- present and carry the 3.2 corrections:
20
-
21
- - explicit domain and startup invariants where later proofs depend on them
22
- - removal of self-referential set definitions in the planned two-pass model
23
- - disambiguation of decay symbols with different units and meanings
24
- - explicit convex-combination proof obligations for bounded scores
25
- - regularized Matryoshka normalization with $\varepsilon$-guarded denominators
26
- and explicit early-exit threshold values
27
- - division-by-zero guards in compaction clustering ($n = 0$ and $k = 0$ cases)
28
- - clamped confidence formula with per-backend range proofs
29
- - cold-start smoothing in the authority-weight frequency term $f(d)$
30
- - separated coarse-candidate raw set from filtered set in Pass 1
31
- - $\eta_{\mathrm{hop}}$ symbol replacing bare $\lambda$ for hop attenuation
32
- - startup invariant $\tau_{\mathcal{I}} \le \tau$ made explicit
33
- - edge-case safety and quality-multiplier boundedness added as runtime invariants
34
- - Unicode code-point correction in sidecar token estimator
35
- - $\chi$ calibration notice tied to tokenizer validation
36
-
37
- ## 1. Hybrid Scoring
38
-
39
- Each candidate returned by the vector store starts with a cosine similarity score
40
- $\cos(q,d) \in [0,1]$ from embedding retrieval. The host then applies a hybrid
41
- ranker:
42
-
43
- $$
44
- \mathrm{base}(d) =
45
- \alpha \cdot \cos(q,d) +
46
- \beta \cdot R(d) +
47
- \gamma \cdot S(d)
48
- $$
49
-
50
- $$
51
- \mathrm{score}(d) = \mathrm{base}(d) \cdot Q(d)
52
- $$
53
-
54
- where:
55
-
56
- $$
57
- R(d) = e^{-\lambda_s(d)\,\Delta t_d}
58
- $$
59
-
60
- $$
61
- S(d)=
62
- \begin{cases}
63
- 1.0 & \text{if } d \text{ is from the active session} \\
64
- 0.6 & \text{if } d \text{ is from durable namespace memory} \\
65
- 0.3 & \text{if } d \text{ is from global memory}
66
- \end{cases}
67
- $$
68
-
69
- $$
70
- Q(d)=
71
- \begin{cases}
72
- 1 - \delta \cdot \mathrm{decay\_rate}(d) & \text{if } d \text{ is a summary} \\
73
- 1 & \text{otherwise}
74
- \end{cases}
75
- $$
76
-
77
- Implemented in [`src/scoring.ts`](../src/scoring.ts).
78
-
79
- The current implementation defaults are:
80
-
81
- - $\alpha = 0.7$
82
- - $\beta = 0.2$
83
- - $\gamma = 0.1$
84
- - $\delta = 0.5$
85
-
86
- The runtime enforces this convex-mixture contract by clamping weights into
87
- $[0,1]$ and re-normalizing them onto a unit sum before scoring. This keeps the
88
- base score on a stable scale and makes tuning interpretable: increasing one
89
- weight means explicitly decreasing another.
90
-
91
- **Note on retrieval similarity.** The term $\cos(q,d) \in [0,1]$ represents the
92
- similarity score as bounded at the host ranking boundary. If the retrieval layer
93
- surfaces a negative cosine-style score, the host clamps it to $0$ before applying
94
- the section-1 hybrid ranker. The planned two-pass system in Section 7 uses raw
95
- cosine similarity spanning $[-1,1]$ with negatives clipped explicitly. These are
96
- described separately to avoid conflating current implementation with planned
97
- architecture.
98
-
99
- ### 1.1 Domain Constraints
100
-
101
- The following parameter domains are required for all formulas in this section:
102
-
103
- $$
104
- \alpha, \beta, \gamma \in [0,1], \qquad \alpha + \beta + \gamma = 1
105
- $$
106
-
107
- $$
108
- \delta \in [0,1]
109
- $$
110
-
111
- $$
112
- \cos(q,d) \in [0,1], \qquad R(d) \in (0,1], \qquad S(d) \in \{0.3, 0.6, 1.0\}
113
- $$
114
-
115
- $$
116
- \mathrm{decay\_rate}(d) \in [0,1]
117
- $$
118
-
119
- Under these assumptions, $\mathrm{base}(d)$ is a convex combination of
120
- quantities in $[0,1]$, so:
121
-
122
- $$
123
- \mathrm{base}(d) \in [0,1]
124
- $$
125
-
126
- And since $\delta \in [0,1]$ and the decay rate is in $[0,1]$:
127
-
128
- $$
129
- Q(d) \in [1-\delta,\, 1] \subseteq [0,1]
130
- $$
131
-
132
- Therefore:
133
-
134
- $$
135
- \mathrm{score}(d) \in [0,1]
136
- $$
137
-
138
- ### 1.2 Boundary Cases
139
-
140
- - $\alpha = 1$ collapses to semantic retrieval only.
141
- - $\beta = 1$ collapses to pure recency preference.
142
- - $\gamma = 1$ collapses to scope-only ranking and is almost always wrong
143
- because it ignores content.
144
- - $\delta = 0$ ignores summary quality completely.
145
- - $\delta = 1$ applies the maximum configured penalty to low-confidence
146
- summaries while preserving nonnegativity, because
147
- the decay rate is in $[0,1]$, which guarantees $Q(d) \ge 0$.
148
-
149
- ### 1.3 Note on $S(d)$ Values
150
-
151
- The scope weights $\{1.0, 0.6, 0.3\}$ are empirically tuned constants, not
152
- values derived from a normalized probability model. They are intentionally
153
- stable across query types. At the default $\gamma = 0.1$, the maximum
154
- contribution of $S(d)$ to $\mathrm{base}(d)$ is $0.1$, so miscalibration of
155
- these values has bounded impact on the final score. Future work may replace
156
- this step function with access-frequency priors derived from retrieval
157
- telemetry.
158
-
159
- ## 2. Recency Decay
160
-
161
- Recency uses exponential decay:
162
-
163
- $$
164
- R(d) = e^{-\lambda_s \Delta t_d}
165
- $$
166
-
167
- where $\Delta t_d$ is the age of the record in seconds and $\lambda_s$ is the
168
- scope-specific decay constant.
169
-
170
- Implemented in [`src/scoring.ts`](../src/scoring.ts).
171
-
172
- In the current implementation, $\Delta t_d$ is measured in **seconds**, not
173
- milliseconds:
174
-
175
- $$
176
- \Delta t_d = \frac{\mathrm{Date.now()} - ts_d}{1000}
177
- $$
178
-
179
- and the $\lambda_s$ values are therefore **per-second** decay constants. The
180
- product $\lambda_s \Delta t_d$ is dimensionless, as required by the exponential.
181
-
182
- The current implementation uses different constants by scope:
183
-
184
- - active session: $\lambda_s = 0.0001$
185
- - durable namespace memory: $\lambda_s = 0.00001$
186
- - global memory: $\lambda_s = 0.000002$
187
-
188
- The implied half-lives make the decay constants auditable at a glance:
189
-
190
- | Scope | $\lambda_s$ | Half-life |
191
- |---|---|---|
192
- | Session | $0.0001$ | $\approx 1.9\ \text{hours}$ |
193
- | User | $0.00001$ | $\approx 19\ \text{hours}$ |
194
- | Global | $0.000002$ | $\approx 4\ \text{days}$ |
195
-
196
- $$
197
- t_{1/2} = \frac{\ln 2}{\lambda_s}
198
- $$
199
-
200
- If those half-lives feel wrong for a given deployment, adjust $\lambda_s$ via
201
- config — do not change the decay formula itself.
202
-
203
- This makes session context fade fastest, durable namespace memory fade more slowly, and
204
- global memory remain the most stable.
205
-
206
- When the host supplies an explicit `userId`, the durable namespace matches that
207
- `userId`. When the host does not provide a `userId`, the plugin derives a stable
208
- durable namespace from the session key, or falls back to `session:${sessionId}`
209
- when both `userId` and `sessionKey` are absent, so the retrieval math and scope
210
- weighting stay unchanged even when the host does not expose a separate user principal.
211
-
212
- **Note on symbol disambiguation.** The symbol $\lambda_s$ here denotes the
213
- scope-specific recency decay constant with units $\mathrm{s}^{-1}$. Section 7.3
214
- uses $\lambda_r$ for a separate recency constant in the planned authority weight.
215
- Section 7.7 uses $\eta_{\mathrm{hop}}$ for a dimensionless hop attenuation
216
- factor. These three parameters are distinct and must not be substituted for each
217
- other.
218
-
219
- Why exponential instead of linear:
220
-
221
- - exponential decay preserves ordering smoothly across many time scales
222
- - it never goes negative
223
- - it gives a natural "fast drop then long tail" shape for conversational relevance
224
-
225
- Linear decay has a hard cutoff or requires arbitrary clipping. Exponential decay
226
- decays old memories continuously without inventing a discontinuity.
227
-
228
- ## 3. Token Budget Fitting
229
-
230
- After ranking, the system performs greedy prompt packing.
231
-
232
- Implemented in [`src/tokens.ts`](../src/tokens.ts).
233
-
234
- Let candidates be sorted by final hybrid score:
235
-
236
- $$
237
- \mathrm{score}(d_1) \ge \mathrm{score}(d_2) \ge \dots \ge \mathrm{score}(d_n)
238
- $$
239
-
240
- and let $c_i$ be the estimated token cost of candidate $d_i$. The current host
241
- token estimator is:
242
-
243
- $$
244
- \mathrm{estimateTokens}(t)=\left\lceil\frac{|t|}{\chi(t)}\right\rceil
245
- $$
246
-
247
- where:
248
-
249
- $$
250
- \chi(t)=
251
- \begin{cases}
252
- 1.6 & \text{for CJK scripts} \\
253
- 2.5 & \text{for Cyrillic, Arabic, or Hebrew scripts} \\
254
- 4.0 & \text{otherwise}
255
- \end{cases}
256
- $$
257
-
258
- Given prompt budget $B$, the system selects the longest ranked prefix whose
259
- cumulative cost fits:
260
-
261
- $$
262
- S = [d_1, d_2, \dots, d_m]
263
- $$
264
-
265
- such that:
266
-
267
- $$
268
- \sum_{i=1}^{m} c_i \le B
269
- $$
270
-
271
- and either $m=n$ or $\sum_{i=1}^{m+1} c_i > B$.
272
-
273
- Greedy is optimal for this implementation because the ranking is already fixed.
274
- The problem is not "find the best weighted subset under a knapsack objective";
275
- it is "preserve rank order while honoring a hard prompt cap." Once rank order
276
- is fixed, prefix acceptance is the correct policy.
277
-
278
- **Note on estimator divergence.** The host estimator
279
- ([`src/tokens.ts`](../src/tokens.ts)) is script-aware and is used for prompt
280
- budget fitting. The sidecar estimator
281
- ([`sidecar/compact/tokens.go`](../sidecar/compact/tokens.go)) uses a fixed
282
- normalization rule:
283
-
284
- $$
285
- \widehat{T}_{sidecar}(t)=\max\!\left(\left\lfloor\frac{C(t)}{4}\right\rfloor,\, 1\right)
286
- $$
287
-
288
- where $C(t)$ is the Unicode code-point count of the string. The sidecar uses
289
- `utf8.RuneCountInString()` rather than `len()`, because Go's `len()` returns
290
- the UTF-8 byte length, not the code-point count; a CJK character occupies 3
291
- bytes, so `len()` would produce a systematic over-count relative to the host
292
- estimator's character-based ratios. The remaining divergence is bounded in
293
- impact because the sidecar value appears only as a normalization denominator
294
- in $P(t)$, never in prompt-budget arithmetic.
295
-
296
- The two estimators are intentionally different. The host estimator optimizes
297
- prompt-budget accuracy. The sidecar estimator is used only as a stable
298
- normalization denominator in the technical specificity signal $P(t)$ of the
299
- gating scalar. They must not be substituted for each other.
300
-
301
- **Note on $\chi$ calibration.** The ratios $\{1.6, 2.5, 4.0\}$ are validated
302
- against GPT-4 family tokenizers. They should be re-validated against the
303
- deployment tokenizer on a representative corpus sample whenever the tokenizer
304
- changes; the validation script and its results should be committed alongside
305
- this document.
306
-
307
- ## 4. Matryoshka Cascade
308
-
309
- For Nomic embeddings, one full vector $\vec{v} \in \mathbb{R}^{768}$ produces
310
- three tiers via regularized normalization:
311
-
312
- $$
313
- \vec{u}_{64} = \frac{\vec{v}_{1:64}}{\sqrt{\lVert \vec{v}_{1:64} \rVert_2^2 + \varepsilon^2}}, \quad
314
- \vec{u}_{256} = \frac{\vec{v}_{1:256}}{\sqrt{\lVert \vec{v}_{1:256} \rVert_2^2 + \varepsilon^2}}, \quad
315
- \vec{u}_{768} = \frac{\vec{v}_{1:768}}{\sqrt{\lVert \vec{v}_{1:768} \rVert_2^2 + \varepsilon^2}}
316
- $$
317
-
318
- where $\varepsilon = 10^{-8}$.
319
-
320
- Re-normalization is required after truncation because a prefix of a unit vector
321
- is not itself a unit vector in general. The regularized denominator
322
- $\sqrt{\lVert \vec{v}_{1:k} \rVert_2^2 + \varepsilon^2}$ is numerically
323
- identical to the plain $L_2$ norm when the norm is large, and smoothly forces
324
- $\vec{u}_k \to \vec{0}$ when the norm approaches zero rather than producing NaN
325
- or amplifying floating-point noise. A near-zero-norm tier vector yields a cosine
326
- score near zero, which falls below both early-exit thresholds and produces
327
- automatic fall-through to the next tier.
328
-
329
- **Note on approximate unit normalization.** For any nonzero prefix with
330
- $\varepsilon > 0$:
331
-
332
- $$
333
- \lVert \vec{u}_k \rVert_2
334
- = \frac{\lVert \vec{v}_{1:k} \rVert_2}{\sqrt{\lVert \vec{v}_{1:k} \rVert_2^2 + \varepsilon^2}}
335
- < 1
336
- $$
337
-
338
- So regularized prefix vectors are **approximately** unit-normalized. The
339
- approximation becomes negligible when the prefix norm is large relative to
340
- $\varepsilon$; with $\varepsilon = 10^{-8}$ and ordinary float32 prefix norms
341
- this difference is not operationally significant, but the distinction matters
342
- for formal correctness.
343
-
344
- Implemented in [`sidecar/embed/matryoshka.go`](../sidecar/embed/matryoshka.go)
345
- and [`sidecar/store/libravdb.go`](../sidecar/store/libravdb.go).
346
-
347
- Cascade search uses:
348
-
349
- - L1: `64d` with early-exit threshold $\theta_{L1} = 0.65$
350
- - L2: `256d` with early-exit threshold $\theta_{L2} = 0.75$
351
- - L3: `768d`
352
-
353
- These thresholds are calibrated on held-out cosine rank correlation with the
354
- 768d ground truth for the chosen embedding model. They control the
355
- precision/recall tradeoff of the cascade and are not required to preserve exact
356
- ranking — rank preservation at reduced dimension is approximate by design of
357
- Matryoshka prefix embeddings, not a mathematical guarantee. The L1 and L2 tiers
358
- function as recall-oriented coarse filters; the false-positive rate at each tier
359
- is an explicit design parameter controlled by $\theta_{L1}$ and $\theta_{L2}$.
360
- If the embedding model changes, both thresholds must be re-derived from the new
361
- model's ROC curve against 768d ground truth.
362
-
363
- The search exits early when a tier's best score exceeds the configured threshold;
364
- otherwise it falls through to the next tier. Empty lower-tier collections
365
- degrade gracefully because:
366
-
367
- $$
368
- \max(\emptyset) = 0
369
- $$
370
-
371
- and $0$ is below both early-exit thresholds by design.
372
-
373
- Backfill condition:
374
-
375
- - L3 is the source of truth
376
- - L1 and L2 are derived caches
377
- - if an L1 or L2 insert fails, a dirty-tier marker is recorded
378
- - startup backfill reconstructs the missing tier vector from L3
379
-
380
- **Note on $\varepsilon$ calibration.** The value $\varepsilon = 10^{-8}$ is
381
- appropriate for float32 embeddings where pathological near-zero norms are
382
- numerical artifacts. If the embedding model changes, verify that near-zero norms
383
- in the new model are indeed artifacts and not meaningful signal before retaining
384
- this value.
385
-
386
- ## 5. Compaction Clustering
387
-
388
- Compaction groups raw session turns into deterministic chronological clusters
389
- and replaces each cluster with one summary record. The intent is to turn many
390
- highly local turns into fewer retrieval-worthy summaries.
391
-
392
- Implemented in [`sidecar/compact/summarize.go`](../sidecar/compact/summarize.go).
393
-
394
- The current algorithm is not semantic k-means. It is deterministic chronological
395
- partitioning:
396
-
397
- 1. collect eligible non-summary turns
398
- 2. sort them by `(ts, id)`
399
- 3. choose target cluster size $k$
400
- 4. normalize the requested target cluster size:
401
-
402
- Non-positive runtime inputs are normalized to the shipped default
403
- $k = 20$ before clustering. After normalization, the effective target size must
404
- satisfy $k \ge 1$.
405
-
406
- 5. derive cluster count:
407
-
408
- Let $n$ be the number of eligible turns. The cluster count is:
409
-
410
- $$
411
- c = \left\lceil \frac{\max(n,\,1)}{k} \right\rceil
412
- $$
413
-
414
- 6. assign turn $i$ to cluster:
415
-
416
- $$
417
- \mathrm{clusterIndex}(i) = \left\lfloor \frac{i \cdot c}{\max(n,\,1)} \right\rfloor
418
- $$
419
-
420
- The $\max(n, 1)$ guards prevent division by zero when $n = 0$. When $n \ge 1$,
421
- these are identical to the unguarded forms $\lceil n/k \rceil$ and
422
- $\lfloor (i \cdot c)/n \rfloor$.
423
-
424
- When $n < k$, the formula produces $c = 1$ and all turns map to cluster 0: a
425
- single cluster containing fewer turns than the target size. Single-member
426
- clusters should be tagged with method `trivial` so that downstream consumers can
427
- apply a different quality interpretation if needed.
428
-
429
- This yields contiguous chronological buckets of roughly equal size while
430
- avoiding nondeterministic clustering behavior.
431
-
432
- The summarizer input for cluster $C_j$ is the ordered turn sequence:
433
-
434
- $$
435
- C_j = [t_1, t_2, \dots, t_m]
436
- $$
437
-
438
- with each element carrying turn id and text.
439
-
440
- The output is a summary record $s(C_j)$ with:
441
-
442
- - summary text
443
- - source ids
444
- - confidence
445
- - method
446
- - `decay_rate = 1 - confidence`
447
-
448
- Implemented across [`sidecar/compact/summarize.go`](../sidecar/compact/summarize.go),
449
- [`sidecar/summarize/engine.go`](../sidecar/summarize/engine.go), and
450
- [`sidecar/summarize/onnx_local.go`](../sidecar/summarize/onnx_local.go).
451
-
452
- For the first real-model benchmark pass comparing raw T5 confidence against
453
- Nomic-space preservation metrics and the hard preservation gate, see
454
- [`compaction-evaluation.md`](./compaction-evaluation.md).
455
-
456
- ### 5.1 Semiotic Mismatch
457
-
458
- The system uses:
459
-
460
- - T5-small as an optional local abstractive decoder
461
- - Nomic `nomic-embed-text-v1.5` as the canonical retrieval embedding space
462
-
463
- Those models do not measure the same thing.
464
-
465
- The raw T5 confidence term is:
466
-
467
- $$
468
- \mathrm{conf}_{\mathrm{t5}}(s, C_j) =
469
- \exp\!\left(\frac{1}{m}\sum_{i=1}^{m}\log p(x_i \mid x_{<i}, C_j)\right)
470
- $$
471
-
472
- where $x_i$ are generated summary tokens. This measures decoder
473
- self-consistency, not geometric preservation in the vector space used later for
474
- retrieval.
475
-
476
- So a T5 summary can be locally confident while still drifting away from the
477
- source cluster in Nomic space.
478
-
479
- ### 5.2 Nomic-Space Preservation
480
-
481
- Let the embedding function be:
482
-
483
- $$
484
- E : \text{text} \to \mathbb{R}^d
485
- $$
486
-
487
- For a source cluster $C_j = \langle t_1, \dots, t_n \rangle$, define:
488
-
489
- $$
490
- v_i = E(t_i)
491
- $$
492
-
493
- $$
494
- \mu_C = \frac{1}{n}\sum_{i=1}^{n} v_i
495
- $$
496
-
497
- $$
498
- v_s = E(s)
499
- $$
500
-
501
- where cosine similarity renormalizes vectors at comparison time, so $\mu_C$
502
- does not need separate unit normalization in the definition below.
503
-
504
- The primary preservation term is centroid alignment:
505
-
506
- $$
507
- Q_{\mathrm{align}}(s, C_j) = \cos(v_s, \mu_C)
508
- $$
509
-
510
- The secondary preservation term is average positive source coverage:
511
-
512
- $$
513
- Q_{\mathrm{cover}}(s, C_j) =
514
- \frac{1}{n}\sum_{i=1}^{n}\max(0, \cos(v_s, v_i))
515
- $$
516
-
517
- The Nomic-space confidence term is then:
518
-
519
- $$
520
- \mathrm{conf}_{\mathrm{nomic}}(s, C_j) =
521
- \max\!\left(0,\;\min\!\left(1,\;\frac{Q_{\mathrm{align}} + Q_{\mathrm{cover}}}{2}\right)\right)
522
- $$
523
-
524
- This is the canonical compaction quality signal because it is defined in the
525
- same geometric space the vector store uses at retrieval time.
526
-
527
- ### 5.3 Preservation Gate
528
-
529
- Before an abstractive T5 summary is accepted, it must pass a hard preservation
530
- gate:
531
-
532
- $$
533
- Q_{\mathrm{align}}(s, C_j) \ge \tau_{\mathrm{preserve}}
534
- $$
535
-
536
- with the shipped default:
537
-
538
- $$
539
- \tau_{\mathrm{preserve}} = 0.65
540
- $$
541
-
542
- If the abstractive summary fails this test, the system rejects it and falls back
543
- to deterministic extractive compaction.
544
-
545
- This means the decoder may propose a summary, but Nomic-space preservation
546
- decides whether it is faithful enough to become memory.
547
-
548
- ### 5.4 Final Confidence
549
-
550
- For extractive summaries, the final stored confidence is:
551
-
552
- $$
553
- \mathrm{confidence}(s) = \mathrm{conf}_{\mathrm{nomic}}(s, C_j)
554
- $$
555
-
556
- For accepted abstractive T5 summaries, the final stored confidence is a
557
- Nomic-heavy hybrid:
558
-
559
- $$
560
- \mathrm{confidence}(s) =
561
- \lambda \cdot \mathrm{conf}_{\mathrm{nomic}}(s, C_j)
562
- + (1-\lambda)\cdot \mathrm{conf}_{\mathrm{t5}}(s, C_j)
563
- $$
564
-
565
- with the shipped default:
566
-
567
- $$
568
- \lambda = 0.8
569
- $$
570
-
571
- So Nomic-space preservation remains the dominant term, while T5 decoder
572
- confidence contributes only auxiliary stability information.
573
-
574
- Therefore:
575
-
576
- $$
577
- \mathrm{confidence}(s) \in [0,1]
578
- $$
579
-
580
- for all valid inputs, because both $\mathrm{conf}_{\mathrm{nomic}}$ and
581
- $\mathrm{conf}_{\mathrm{t5}}$ are bounded in $[0,1]$ and the hybrid is a convex
582
- combination.
583
-
584
- ### 5.5 Retrieval Decay Multiplier
585
-
586
- The retrieval decay metadata is then:
587
-
588
- $$
589
- \mathrm{decay\_rate}(s) = 1 - \mathrm{confidence}(s)
590
- $$
591
-
592
- and the retrieval quality multiplier from Section 1 becomes:
593
-
594
- $$
595
- Q(s) = 1 - \delta \cdot \mathrm{decay\_rate}(s)
596
- $$
597
-
598
- Given $\delta \in [0,1]$ and $\mathrm{confidence}(s) \in [0,1]$, the decay rate
599
- is in $[0,1]$ and therefore:
600
-
601
- $$
602
- Q(s) \in [1-\delta,\, 1] \subseteq [0,1]
603
- $$
604
-
605
- At the shipped default $\delta = 0.5$, this constrains summary quality weights
606
- to:
607
-
608
- $$
609
- Q(s) \in [0.5,\, 1.0]
610
- $$
611
-
612
- This makes compaction load-bearing in retrieval rather than archival only.
613
-
614
- ### 5.6 Optional Lossless Compaction Extension
615
-
616
- The current implementation replaces compacted session turns in the searchable
617
- session collection after summary insertion succeeds. A stronger future variant
618
- is to preserve compacted raw turns in an immutable session-history layer and
619
- treat summary records as derived view nodes over that history. This extension is
620
- inspired by the immutable-store and expandable-summary architecture in the LCM
621
- paper ([Ehrlich and Blackman, 2026](https://papers.voltropy.com/LCM)), but the
622
- formalization here is adapted to this repository's existing compaction and
623
- continuity math.
624
-
625
- Let:
626
-
627
- $$
628
- \mathcal{R}_{\mathrm{session}}=\langle r_1,\dots,r_n\rangle
629
- $$
630
-
631
- be the immutable raw session history, and let:
632
-
633
- $$
634
- \mathbf{S}=\{s_1,s_2,\dots\}
635
- $$
636
-
637
- be the set of compacted summary nodes. Define the summary-coverage DAG:
638
-
639
- $$
640
- \mathcal{G}_{\mathrm{cont}}=(\mathbf{S}\cup\mathcal{R}_{\mathrm{session}}, E_{\triangleleft})
641
- $$
642
-
643
- with:
644
-
645
- $$
646
- E_{\triangleleft}\subseteq (\mathbf{S}\times\mathbf{S})\cup(\mathbf{S}\times\mathcal{R}_{\mathrm{session}})
647
- $$
648
-
649
- Recursive raw expansion is:
650
-
651
- $$
652
- \mathrm{Expand}^{*}(x)=
653
- \begin{cases}
654
- \{x\} & \text{if } x\in\mathcal{R}_{\mathrm{session}} \\
655
- \bigcup_{y:(x,y)\in E_{\triangleleft}} \mathrm{Expand}^{*}(y) & \text{if } x\in\mathbf{S}
656
- \end{cases}
657
- $$
658
-
659
- The continuity contract for this extension is:
660
-
661
- $$
662
- \forall s\in\mathbf{S},\ \mathrm{Expand}^{*}(s)\neq\emptyset
663
- $$
664
-
665
- and:
666
-
667
- $$
668
- \forall r\in\mathcal{R}_{\mathrm{session}},\ \exists x\in \mathbf{S}\cup T_{\mathrm{recent}} \text{ such that } r\in\mathrm{Expand}^{*}(x)
669
- $$
670
-
671
- Under this extension, compaction changes the active retrievable view and the
672
- assembly surface, but not the existence of raw historical evidence. This is
673
- compatible with the section-1 through section-5 retrieval math because the
674
- hybrid score still applies to the injected/searchable nodes; the extension only
675
- strengthens the recoverability contract beneath those nodes.
676
-
677
- ## 6. Why These Pieces Compose
678
-
679
- The full quality loop is:
680
-
681
- $$
682
- \text{high-value turns}
683
- \rightarrow \text{better clusters}
684
- \rightarrow \text{higher summary confidence}
685
- \rightarrow \text{lower decay rate}
686
- \rightarrow \text{higher retrieval score}
687
- $$
688
-
689
- That is the system-level reason the math is distributed across ingestion,
690
- compaction, and retrieval instead of existing only in one scoring function.
691
-
692
- For rigor, this section should be read in two parts:
693
-
694
- - The upstream step
695
- `high-value turns -> better clusters -> higher summary confidence`
696
- is an engineering hypothesis supported by preservation metrics and empirical
697
- calibration evidence. It is not a pure algebraic proof obligation because it
698
- depends on learned-model behavior.
699
- - The downstream step
700
- `higher summary confidence -> lower decay rate -> higher retrieval score`
701
- is a formal and implementation-correspondence obligation. It follows from:
702
-
703
- $$
704
- \mathrm{decay\_rate}(s) = 1 - \mathrm{confidence}(s)
705
- $$
706
-
707
- and
708
-
709
- $$
710
- Q(s) = 1 - \delta \cdot \mathrm{decay\_rate}(s),
711
- \qquad
712
- S_{\mathrm{final}}(s) = S_{\mathrm{base}}(s) \cdot Q(s)
713
- $$
714
-
715
- Under equal base score $S_{\mathrm{base}}$ and fixed $\delta \in [0,1]$,
716
- higher confidence implies lower decay, larger $Q(s)$, and therefore a larger
717
- final retrieval score. This downstream monotonic composition is the part that
718
- must be locked by exact code-level tests before later retrieval architecture
719
- work proceeds.
720
-
721
- ## 7. Two-Pass Discovery Scoring
722
-
723
- This section documents the reviewed scoring and assembly model for the
724
- two-pass retrieval system. Parts of this section are now implemented in
725
- [`src/scoring.ts`](../src/scoring.ts),
726
- [`src/context-engine.ts`](../src/context-engine.ts),
727
- [`src/continuity.ts`](../src/continuity.ts), and the sidecar store/RPC
728
- adapter. Remaining unimplemented or approximate pieces should be treated as
729
- explicit follow-on work, not as permission to relax the mathematical contract.
730
-
731
- The design goal is to separate:
732
-
733
- 1. invariant documents that must always be present
734
- 2. cheap discovery over variant documents
735
- 3. selective second-pass expansion under a hard prompt budget
736
-
737
- ### 7.1 Foundational Definitions
738
-
739
- Let the retrievable document corpus be:
740
-
741
- $$
742
- \mathbf{D}=\{d_1, d_2, \ldots, d_n\}
743
- $$
744
-
745
- and let the query space be $\mathbf{Q}$.
746
-
747
- Let the embedding function:
748
-
749
- $$
750
- \varphi : \mathbf{D}\cup\mathbf{Q}\rightarrow \mathbb{R}^m
751
- $$
752
-
753
- map documents and queries to unit vectors:
754
-
755
- $$
756
- \lVert \varphi(x) \rVert_2 = 1 \qquad \forall x \in \mathbf{D}\cup\mathbf{Q}
757
- $$
758
-
759
- The gating function is:
760
-
761
- $$
762
- G : \mathbf{Q}\times\mathbf{D}\rightarrow \{0,1\}
763
- $$
764
-
765
- and determines whether a document is injected for a query.
766
-
767
- ### 7.2 Corpus Decomposition
768
-
769
- The reviewed AST partitioning model in [`ast-v2.md`](./ast-v2.md) refines the
770
- older binary invariant-or-variant split into three authored tiers plus a
771
- continuity carve-out inside the retrievable variant corpus.
772
-
773
- The authored corpus is partitioned into hard invariants, soft invariants, and
774
- variant memory:
775
-
776
- $$
777
- \mathbf{D} = \mathcal{I}_1\cup\mathcal{I}_2\cup\mathcal{V},
778
- \qquad
779
- \mathcal{I}_1\cap\mathcal{I}_2=\mathcal{I}_1\cap\mathcal{V}=\mathcal{I}_2\cap\mathcal{V}=\emptyset
780
- $$
781
-
782
- The tier membership predicate is:
783
-
784
- $$
785
- \iota : \mathbf{D}\rightarrow \{0,1,2\}
786
- $$
787
-
788
- with:
789
-
790
- $$
791
- \mathcal{I}_1 = \{d\in\mathbf{D}\mid \iota(d)=1\}
792
- $$
793
-
794
- and:
795
-
796
- $$
797
- \mathcal{I}_2 = \{d\in\mathbf{D}\mid \iota(d)=2\}
798
- \qquad
799
- \mathcal{V} = \{d\in\mathbf{D}\mid \iota(d)=0\}
800
- $$
801
-
802
- Here:
803
-
804
- - $\mathcal{I}_1$ is the hard invariant set, injected exactly and never
805
- truncated
806
- - $\mathcal{I}_2$ is the soft invariant sequence, injected by longest-prefix
807
- truncation in authored order
808
- - $\mathcal{V}$ is the retrievable variant corpus
809
-
810
- For OpenClaw, the intended implementation is that authored documents such as
811
- `AGENTS.md` and `souls.md` are compiled into $\mathcal{I}_1$, $\mathcal{I}_2$,
812
- and $\mathcal{V}$ at load time rather than discovered monolithically at query
813
- time.
814
-
815
- The hard authored guarantee is:
816
-
817
- $$
818
- \iota(d)=1 \Rightarrow G(q,d)=1 \qquad \forall q\in\mathbf{Q}
819
- $$
820
-
821
- Soft invariants are also authored constants, but unlike $\mathcal{I}_1$ they
822
- are budget-elastic. Let the authored order on $\mathcal{I}_2$ be:
823
-
824
- $$
825
- \mathcal{I}_2=\langle d^{(2)}_1,d^{(2)}_2,\dots,d^{(2)}_m\rangle
826
- $$
827
-
828
- and define the longest-prefix operator:
829
-
830
- $$
831
- \mathrm{Pref}(\mathcal{I}_2;\,b)=\langle d^{(2)}_1,\dots,d^{(2)}_j\rangle
832
- $$
833
-
834
- where:
835
-
836
- $$
837
- j=\max\left\{r\in\{0,\dots,m\}\ \middle|\ \sum_{i=1}^{r}\mathrm{toks}(d^{(2)}_i)\le b\right\}
838
- $$
839
-
840
- When continuity is enabled, the runtime further refines the variant corpus into
841
- an exact recent raw suffix and the remaining retrievable variant set:
842
-
843
- $$
844
- \mathcal{V}=T_{\mathrm{recent}}\cup\mathcal{V}_{\mathrm{rest}},
845
- \qquad
846
- T_{\mathrm{recent}}\cap\mathcal{V}_{\mathrm{rest}}=\emptyset
847
- $$
848
-
849
- Only $\mathcal{V}_{\mathrm{rest}}$ participates in semantic retrieval. The
850
- recent tail is preserved exactly and budgeted separately.
851
-
852
- ### 7.3 Document Authority Weight
853
-
854
- Each retrievable variant document carries a precomputed authority weight:
855
-
856
- $$
857
- \omega(d)=\alpha_r\cdot r(d)+\alpha_f\cdot f(d)+\alpha_a\cdot a(d)
858
- $$
859
-
860
- with:
861
-
862
- $$
863
- \alpha_r+\alpha_f+\alpha_a=1, \qquad \alpha_r,\alpha_f,\alpha_a \in [0,1]
864
- $$
865
-
866
- where:
867
-
868
- $$
869
- r(d)=\exp\!\left(-\lambda_r\cdot \Delta t(d)\right)
870
- $$
871
-
872
- $$
873
- f(d)=\frac{\log(1+\mathrm{acc}(d))}{\log\!\left(1+\max_{d'\in\mathcal{V}_{\mathrm{rest}}}\mathrm{acc}(d')+1\right)}
874
- $$
875
-
876
- $$
877
- a(d)\in[0,1]
878
- $$
879
-
880
- Here $\lambda_r > 0$ is the recency decay constant with units $\mathrm{s}^{-1}$,
881
- and $\Delta t(d) \ge 0$ is document age in seconds.
882
-
883
- The $+1$ in the denominator of $f(d)$, but not the numerator, implements minimal
884
- additive smoothing that guarantees a defined value at cold start. The asymmetry
885
- is deliberate: a document with zero accesses should score $f(d) = 0$ exactly,
886
- which the unsmoothed numerator preserves. When
887
- $\max_{d'\in\mathcal{V}_{\mathrm{rest}}}\mathrm{acc}(d') = 0$, the denominator equals $\log 2$
888
- and:
889
-
890
- $$
891
- f(d) = 0 \qquad \forall d\in\mathcal{V}_{\mathrm{rest}}
892
- $$
893
-
894
- cleanly deferring frequency weight to $r(d)$ and $a(d)$ until access history
895
- accumulates.
896
-
897
- Because $r(d)\in(0,1]$, $f(d)\in[0,1]$, and $a(d)\in[0,1]$, and $\omega(d)$
898
- is a convex combination of these terms:
899
-
900
- $$
901
- \omega(d)\in[0,1]
902
- $$
903
-
904
- For variant nodes extracted from core authored identity documents,
905
- [`ast-v2.md`](./ast-v2.md) sets $a(d)=1.0$. This lets the planned discovery
906
- score incorporate recency, access frequency, and authored authority without
907
- baking those concerns into the raw cosine term.
908
-
909
- ### 7.4 Pass 1: Coarse Semantic Filtering
910
-
911
- Pass 1 computes cosine similarity:
912
-
913
- $$
914
- \mathrm{sim}(q,d)=\varphi(q)^\top \varphi(d) \in [-1,1]
915
- $$
916
-
917
- The raw top-$k_1$ candidate set is:
918
-
919
- $$
920
- \mathcal{C}_1^{\mathrm{raw}}(q)=\mathrm{TopK}_{d\in\mathcal{V}_{\mathrm{rest}}}\!\left(k_1,\,\mathrm{sim}(q,d)\right)
921
- $$
922
-
923
- with filtered coarse set:
924
-
925
- $$
926
- \mathcal{C}_1(q)=\left\{d\in\mathcal{C}_1^{\mathrm{raw}}(q)\mid \mathrm{sim}(q,d)\ge \theta_1\right\}
927
- $$
928
-
929
- where $\theta_1\in[-1,1]$.
930
-
931
- The purpose of this pass is breadth with cheap semantic recall. Documents below
932
- $\theta_1$ are rejected even if they land in the top-$k_1$ set, because the
933
- first pass must not admit semantically orthogonal noise into second-pass work.
934
-
935
- ### 7.5 Pass 2: Normalized Hybrid Scoring
936
-
937
- Let the query keyword extractor return:
938
-
939
- $$
940
- K = \mathrm{KeyExt}(q)
941
- $$
942
-
943
- and define normalized keyword coverage:
944
-
945
- $$
946
- M_{norm}(K,d)=\frac{|K\cap \mathrm{terms}(d)|}{\max(|K|,\,1)}\in[0,1]
947
- $$
948
-
949
- When $|K| > 0$ this is identical to $|K\cap \mathrm{terms}(d)| / |K|$. When
950
- $|K| = 0$ (the query yields no extractable keywords), the numerator is zero and
951
- $M_{norm} = 0$ exactly, collapsing the second-pass score to pure semantic
952
- retrieval — the correct degenerate behavior.
953
-
954
- The proposed normalized second-pass score is:
955
-
956
- $$
957
- S_{final}(d)=
958
- \frac{
959
- \omega(d)\cdot\max(\mathrm{sim}(q,d),\,0)\cdot\left(1+\kappa\cdot M_{norm}(K,d)\right)
960
- }{
961
- 1+\kappa
962
- }
963
- $$
964
-
965
- where $\kappa\in[0,\infty)$.
966
-
967
- The normalized second-pass score form above was suggested during design review
968
- by GitHub contributor [@JuanHuaXu](https://github.com/JuanHuaXu). The broader
969
- two-pass architecture in this section remains project-authored.
970
-
971
- This form is preferred over a hard clamp such as $\min(\mathrm{term},1)$
972
- because clamping discards ranking information at the high end of the score
973
- distribution. The denominator $(1+\kappa)$ gives an analytic bound instead of
974
- truncating the result.
975
-
976
- The second-pass candidate set is:
977
-
978
- $$
979
- \mathcal{C}_2(q)=\mathrm{TopK}_{d\in\mathcal{C}_1(q)}\!\left(k_2,\,S_{final}(d)\right)
980
- $$
981
-
982
- with $k_2 \le k_1$ and $k_1, k_2 \in \mathbb{Z}_{>0}$.
983
-
984
- ### 7.6 Bounded Range and Interpretation of $\kappa$
985
-
986
- Let:
987
-
988
- $$
989
- s=\max(\mathrm{sim}(q,d),\,0)\in[0,1]
990
- $$
991
-
992
- Then:
993
-
994
- $$
995
- S_{final}(d)=\frac{\omega(d)\cdot s\cdot(1+\kappa M_{norm}(K,d))}{1+\kappa}
996
- $$
997
-
998
- Because $M_{norm}(K,d)\in[0,1]$ and $\kappa\ge 0$:
999
-
1000
- $$
1001
- 1 \le 1+\kappa M_{norm}(K,d) \le 1+\kappa
1002
- $$
1003
-
1004
- so:
1005
-
1006
- $$
1007
- 0 \le \frac{1+\kappa M_{norm}(K,d)}{1+\kappa} \le 1
1008
- $$
1009
-
1010
- Combining with $s\in[0,1]$ and $\omega(d)\in[0,1]$:
1011
-
1012
- $$
1013
- 0 \le S_{final}(d)\le \omega(d)\le 1
1014
- $$
1015
-
1016
- This yields a clean interpretation of $\kappa$:
1017
-
1018
- - $\kappa = 0$ gives pure semantic retrieval
1019
- - $\kappa = 0.5$ allows keyword coverage to provide up to a one-third relative
1020
- boost before normalization
1021
- - $\kappa = 1.0$ makes full lexical support restore the pure semantic ceiling
1022
- while penalizing semantic-only matches with no keyword support
1023
-
1024
- A reasonable initial experiment value is:
1025
-
1026
- $$
1027
- \kappa = 0.3
1028
- $$
1029
-
1030
- ### 7.7 Multi-Hop Expansion
1031
-
1032
- Let the authored hop graph be:
1033
-
1034
- $$
1035
- \mathcal{G}=(\mathbf{D},\, E)
1036
- $$
1037
-
1038
- where edges are registered in document metadata at authorship time.
1039
-
1040
- For a document $d$, define its hop neighborhood:
1041
-
1042
- $$
1043
- H(d)=\{d'\in\mathbf{D}\mid (d,d')\in E\}
1044
- $$
1045
-
1046
- The hop expansion set is:
1047
-
1048
- $$
1049
- \mathcal{C}_{hop}(q)=\bigcup_{d\in\mathcal{C}_2(q)} H(d)\setminus\mathcal{C}_2(q)
1050
- $$
1051
-
1052
- Each hop candidate inherits a decayed score from its best parent:
1053
-
1054
- $$
1055
- S_{hop}(d')=
1056
- \eta_{\mathrm{hop}}\cdot
1057
- \max_{d\in\mathcal{C}_2(q),\; d'\in H(d)} S_{final}(d)
1058
- $$
1059
-
1060
- with hop decay factor $\eta_{\mathrm{hop}}\in(0,1)$.
1061
-
1062
- **Note on symbol disambiguation.** The symbol $\eta_{\mathrm{hop}}$ is used
1063
- here deliberately to avoid collision with $\lambda_s$ (scope recency, Section 2)
1064
- and $\lambda_r$ (authority-weight recency, Section 7.3). The parameters have
1065
- different semantics and units: $\lambda_r$ has units $\mathrm{s}^{-1}$, while
1066
- $\eta_{\mathrm{hop}}$ is a dimensionless attenuation factor in $(0,1)$.
1067
-
1068
- The filtered hop set is:
1069
-
1070
- $$
1071
- \mathcal{C}_{hop}^{*}(q)=\{d'\in\mathcal{C}_{hop}(q)\mid S_{hop}(d')\ge\theta_{hop}\}
1072
- $$
1073
-
1074
- with $\theta_{hop}\in[0,1]$.
1075
-
1076
- Since $S_{final}(d)\in[0,1]$ and $\eta_{\mathrm{hop}}\in(0,1)$:
1077
-
1078
- $$
1079
- S_{hop}(d')\in[0,\,1)
1080
- $$
1081
-
1082
- ### 7.8 Final Assembly Under a Token Budget
1083
-
1084
- Variant projection is:
1085
-
1086
- $$
1087
- \mathrm{Proj}(\mathcal{V}_{\mathrm{rest}},\, q)=\mathcal{C}_2(q)\cup\mathcal{C}_{hop}^{*}(q)
1088
- $$
1089
-
1090
- The final injected context is:
1091
-
1092
- $$
1093
- C_{\mathrm{total}}(q)=\mathcal{I}_1\cup \mathcal{I}_2^{*}\cup T_{\mathrm{recent}}\cup \mathrm{Proj}(\mathcal{V}_{\mathrm{rest}},\, q)
1094
- $$
1095
-
1096
- Let the total prompt budget be $\tau$, and let the reserve fractions satisfy:
1097
-
1098
- $$
1099
- \alpha_1,\alpha_2,\beta\in[0,1],
1100
- \qquad
1101
- \alpha_1+\alpha_2+\beta\le 1
1102
- $$
1103
-
1104
- where:
1105
-
1106
- - $\alpha_1$ reserves hard authored budget
1107
- - $\alpha_2$ reserves soft authored budget
1108
- - $\beta$ is the target recent-tail budget fraction
1109
-
1110
- Define the hard authored token mass:
1111
-
1112
- $$
1113
- \tau_{\mathcal{I}_1}=\sum_{d\in\mathcal{I}_1}\mathrm{toks}(d)
1114
- $$
1115
-
1116
- **Required startup hard authored invariant:**
1117
-
1118
- $$
1119
- \tau_{\mathcal{I}_1}\le \alpha_1\tau
1120
- $$
1121
-
1122
- This must be enforced at startup or configuration validation time. If violated,
1123
- the system cannot simultaneously satisfy "the hard invariant set is never
1124
- truncated" and "total injected tokens do not exceed the total budget."
1125
- Initialization must fail or the deployment must be reconfigured.
1126
-
1127
- Let $T_{\mathrm{base}}$ be the mandatory recent-tail base suffix defined in
1128
- [`continuity.md`](./continuity.md): the shortest raw suffix of the active
1129
- session containing at least the most recent $m$ turns. The mandatory continuity
1130
- fit requirement is:
1131
-
1132
- $$
1133
- \tau_{\mathcal{I}_1} + \sum_{d\in T_{\mathrm{base}}}\mathrm{toks}(d)\le \tau
1134
- $$
1135
-
1136
- Otherwise no legal assembly exists that preserves both hard invariants and the
1137
- minimum continuity tail. The runtime must surface degraded mode explicitly; it
1138
- must not silently truncate $\mathcal{I}_1$ or split the mandatory recent tail.
1139
-
1140
- The effective soft authored budget is:
1141
-
1142
- $$
1143
- \tau_{\mathcal{I}_2}^{\mathrm{eff}}
1144
- =
1145
- \min\!\left(
1146
- \alpha_2\tau,\,
1147
- \tau-\tau_{\mathcal{I}_1}-\sum_{d\in T_{\mathrm{base}}}\mathrm{toks}(d)
1148
- \right)
1149
- $$
1150
-
1151
- and the injected soft invariant prefix is:
1152
-
1153
- $$
1154
- \mathcal{I}_2^{*}=\mathrm{Pref}(\mathcal{I}_2;\,\tau_{\mathcal{I}_2}^{\mathrm{eff}})
1155
- $$
1156
-
1157
- Define the recent-tail target:
1158
-
1159
- $$
1160
- \tau_{\mathrm{tail}}^{\mathrm{target}}=\beta\tau
1161
- $$
1162
-
1163
- The exact recent-tail selector is the longest bundle-safe raw suffix containing
1164
- $T_{\mathrm{base}}$ and satisfying:
1165
-
1166
- $$
1167
- \sum_{d\in T_{\mathrm{recent}}}\mathrm{toks}(d)
1168
- \le
1169
- \min\!\left(
1170
- \max\!\left(\tau_{\mathrm{tail}}^{\mathrm{target}},\,
1171
- \sum_{d\in T_{\mathrm{base}}}\mathrm{toks}(d)\right),\,
1172
- \tau-\tau_{\mathcal{I}_1}-\sum_{d\in\mathcal{I}_2^{*}}\mathrm{toks}(d)
1173
- \right)
1174
- $$
1175
-
1176
- This preserves the continuity rule that the mandatory recent suffix wins over
1177
- the nominal tail target when they conflict, while still respecting the total
1178
- prompt budget.
1179
-
1180
- The residual retrievable variant budget is:
1181
-
1182
- $$
1183
- \tau_{\mathcal{V}}(q)
1184
- =
1185
- \tau-\tau_{\mathcal{I}_1}
1186
- -\sum_{d\in\mathcal{I}_2^{*}}\mathrm{toks}(d)
1187
- -\sum_{d\in T_{\mathrm{recent}}}\mathrm{toks}(d)
1188
- $$
1189
-
1190
- which must satisfy:
1191
-
1192
- $$
1193
- \tau_{\mathcal{V}}(q)\ge 0
1194
- $$
1195
-
1196
- Documents in $\mathrm{Proj}(\mathcal{V}_{\mathrm{rest}}, q)$ are injected in descending
1197
- score order until:
1198
-
1199
- $$
1200
- \sum_{d\in \text{injected}} \mathrm{toks}(d)\le\tau_{\mathcal{V}}
1201
- $$
1202
-
1203
- The merged score sequence is:
1204
-
1205
- $$
1206
- \sigma(d)=
1207
- \begin{cases}
1208
- S_{final}(d) & d\in\mathcal{C}_2(q) \\
1209
- S_{hop}(d) & d\in\mathcal{C}_{hop}^{*}(q)
1210
- \end{cases}
1211
- $$
1212
-
1213
- ### 7.9 Complete Gating Definition
1214
-
1215
- $$
1216
- G(q,d)=
1217
- \begin{cases}
1218
- 1 & \text{if } d\in\mathcal{I}_1\cup\mathcal{I}_2^{*}\cup T_{\mathrm{recent}} \\
1219
- \mathbf{1}[d\in\mathcal{C}_2(q)\cup\mathcal{C}_{hop}^{*}(q)] & \text{if } d\in\mathcal{V}_{\mathrm{rest}}
1220
- \end{cases}
1221
- $$
1222
-
1223
- ### 7.10 Required Runtime Invariants
1224
-
1225
- The implementation must preserve these properties:
1226
-
1227
- 1. Invariant completeness:
1228
-
1229
- $$
1230
- \forall d\in\mathcal{I}_1,\; \forall q\in\mathbf{Q}: d\in C_{\mathrm{total}}(q)
1231
- $$
1232
-
1233
- 2. Soft invariant order preservation:
1234
-
1235
- $$
1236
- \mathcal{I}_2^{*}\text{ is a prefix of }\mathcal{I}_2
1237
- $$
1238
-
1239
- 3. Partition integrity:
1240
-
1241
- $$
1242
- \mathcal{I}_1\cap\mathcal{I}_2=\mathcal{I}_1\cap\mathcal{V}=\mathcal{I}_2\cap\mathcal{V}=\emptyset,
1243
- \qquad
1244
- T_{\mathrm{recent}}\cap\mathcal{V}_{\mathrm{rest}}=\emptyset
1245
- $$
1246
-
1247
- 4. Mandatory recent-tail completeness:
1248
-
1249
- $$
1250
- T_{\mathrm{base}}\subseteq T_{\mathrm{recent}}
1251
- $$
1252
-
1253
- 5. Score boundedness:
1254
-
1255
- $$
1256
- S_{final}(d)\in[0,1]
1257
- $$
1258
-
1259
- 6. Token budget respect:
1260
-
1261
- $$
1262
- \sum_{d\in C_{\mathrm{total}}(q)} \mathrm{toks}(d)\le\tau
1263
- $$
1264
-
1265
- with $\mathcal{I}_1$ never truncated, $\mathcal{I}_2$ truncated only by
1266
- longest-prefix selection, and the recent-tail base never silently dropped.
1267
-
1268
- 7. Compaction boundary safety:
1269
-
1270
- Compaction may operate only on $\mathcal{V}_{\mathrm{rest}}$, never on
1271
- $T_{\mathrm{recent}}$.
1272
-
1273
- 8. Hop termination:
1274
-
1275
- The authored hop graph should be acyclic, or the runtime must cap hop depth at
1276
- one to guarantee termination.
1277
-
1278
- 9. Edge-case safety:
1279
-
1280
- No valid input in the declared domain may produce a NaN, a negative score, or a
1281
- division-by-zero. This includes at minimum:
1282
-
1283
- - cold-start corpus with $\max \mathrm{acc}=0$
1284
- - empty extracted keyword set with $|K|=0$
1285
- - zero eligible clustering turns with $n=0$
1286
- - near-zero-norm Matryoshka prefix vectors
1287
- - empty hop neighborhoods
1288
- - empty or zero-residual $\tau_{\mathcal{V}}(q)$ after invariant and
1289
- continuity reservation
1290
-
1291
- 7. Quality multiplier boundedness:
1292
-
1293
- $$
1294
- \mathrm{confidence}(s)\in[0,1],
1295
- \qquad
1296
- Q(d)\in[1-\delta,\,1]\subseteq[0,1]
1297
- $$
1298
-
1299
- for all valid inputs with $\delta\in[0,1]$.
1300
-
1301
- ## 8. Theory Boundary And Future Refinement
1302
-
1303
- Cross-review of this document and [`continuity.md`](./continuity.md) surfaced a
1304
- useful mathematical boundary that this reference should keep explicit:
1305
-
1306
- 1. storage and continuity axioms
1307
- 2. primary retrieval and assembly math
1308
- 3. optional recoverability policy
1309
-
1310
- ### 8.1 What Is Core Math
1311
-
1312
- The core retrieval theorem in this document is the scored, budgeted selection
1313
- of retrievable nodes from $\mathcal{V}_{\mathrm{rest}}$ together with authored
1314
- invariants and the exact recent tail. In other words, the primary law remains:
1315
-
1316
- $$
1317
- C_{\mathrm{total}}(q)=\mathcal{I}_1\cup \mathcal{I}_2^{*}\cup T_{\mathrm{recent}}\cup \mathrm{Proj}(\mathcal{V}_{\mathrm{rest}}, q)
1318
- $$
1319
-
1320
- with the retrieval side governed by:
1321
-
1322
- $$
1323
- S_{\mathrm{final}}(d)=S_{\mathrm{base}}(d)\cdot Q(d)
1324
- $$
1325
-
1326
- and the budget side governed by the residual variant budget
1327
- $\tau_{\mathcal{V}}(q)$ defined in Section 7.8.
1328
-
1329
- ### 8.2 What Is Not Core Math
1330
-
1331
- The following should be treated as policy or heuristic unless they are derived
1332
- from the governing score equations and budget laws:
1333
-
1334
- - automatic query-time summary expansion
1335
- - fixed expansion penalties
1336
- - fixed expansion token sub-budgets
1337
- - confidence thresholds for expansion eligibility
1338
- - recursion-depth limits for summary expansion
1339
-
1340
- These controls may be useful in runtime experiments, but they are not theorem
1341
- terms by default. They should not be mistaken for new axioms of the scoring
1342
- model.
1343
-
1344
- ### 8.3 Lossless Does Not Mean Always Expand
1345
-
1346
- The lossless extension in Section 5.6 strengthens the storage and
1347
- recoverability contract. It does not imply that every relevant summary should be
1348
- expanded into raw turns during ordinary retrieval.
1349
-
1350
- The mathematically safe reading is:
1351
-
1352
- - raw immutability is an axiom
1353
- - $\mathrm{Expand}^{*}$ is a recoverability theorem over the summary DAG
1354
- - query-time expansion is **explicit recovery/audit only** — it was removed from
1355
- the hot retrieval path and is not the default behavior; any expansion beyond
1356
- the core $C_{\mathrm{total}}(q)$ assembly must be triggered deliberately, not
1357
- applied silently to ranked candidates
1358
-
1359
- This distinction preserves the design goal that continuity and recoverability
1360
- support retrieval without silently replacing it.
1361
-
1362
- ### 8.4 Preferred Direction For Future Refinement
1363
-
1364
- If a future version wants query-time expansion inside the main retrieval path,
1365
- the preferred direction is to re-derive it from the existing two-pass and
1366
- multi-hop framework rather than introduce standalone penalties and thresholds
1367
- that float outside the score model.
1368
-
1369
- In practical terms, future refinement should prefer one of two paths:
1370
-
1371
- 1. keep summary expansion as a separate recovery or audit layer
1372
- 2. formally unify summary expansion with the existing hop-expansion math
1373
-
1374
- What this document should avoid is an in-between state where recoverability
1375
- logic behaves like a second retrieval theorem without being derived as one.
1376
-
1377
- ### 8.5 Preserved Research Ideas
1378
-
1379
- The review process also surfaced several strong theoretical ideas that are worth
1380
- retaining for future work:
1381
-
1382
- - rate-distortion views of compaction quality
1383
- - information-adaptive clustering instead of equal-size chronological buckets
1384
- - hot-spot preservation tiers driven by access concentration
1385
- - causal-centrality-aware compaction penalties or vetoes
1386
- - entropy-based tail selection
1387
- - retrieval-failure-triggered raw-history recovery (the specific observable
1388
- signals S1/S2/S3 are defined in the vNext spec slice; this entry refers to the
1389
- general concept, not the current implementation)
1390
- - closed-loop compaction tuning driven by observed retrieval quality
1391
-
1392
- These ideas are intentionally preserved as future mathematics rather than
1393
- current contract. The present document remains normative only for the formulas
1394
- and invariants already defined above.
1395
-
1396
- ## 9. Temporal-Compositional Retrieval Extension
1397
-
1398
- This section defines a narrow, mathematically principled extension to the
1399
- $\mathrm{Proj}()$ operator that corrects the single-turn-centric failure mode on
1400
- temporal-compositional queries such as "how many days before $X$ did $Y$
1401
- happen."
1402
-
1403
- The extension is self-contained. Every formula in this section is bounded and
1404
- correct under the existing parameter domains. The assembly law
1405
- $C_{\mathrm{total}}(q)$, the budget hierarchy, and the runtime invariants in
1406
- Section 7.10 and [`continuity.md`](./continuity.md) are unchanged. Only the
1407
- internal definition of $\mathrm{Proj}(\mathcal{V}_{\mathrm{rest}}, q)$ is
1408
- refined.
1409
-
1410
- Implemented in: `src/temporal.ts` (planned).
1411
-
1412
- ### 9.1 Motivation: The Set-Scoring Gap
1413
-
1414
- The standard Pass-2 score $S_{\mathrm{final}}(d)$ maximizes over individual
1415
- candidates:
1416
-
1417
- $$
1418
- \mathcal{C}_2(q)
1419
- =
1420
- \mathrm{TopK}_{d \in \mathcal{C}_1(q)}
1421
- \left(k_2,\, S_{\mathrm{final}}(d)\right)
1422
- $$
1423
-
1424
- This is optimal when the query is answerable from a single best document. It
1425
- fails when the query requires two complementary date-bearing turns to be
1426
- jointly present, neither of which is individually the best semantic match.
1427
-
1428
- The failure pattern is:
1429
-
1430
- - Turn $A$ covers the query topic broadly, so it earns a high
1431
- $S_{\mathrm{final}}$ and wins alone.
1432
- - Turn $B$ contains the missing date anchor, but earns only a moderate
1433
- $S_{\mathrm{final}}$ and is evicted.
1434
- - Neither $A$ alone nor $B$ alone answers the question.
1435
-
1436
- The fix is to move from
1437
- $\underset{d}{\arg\max}\; S_{\mathrm{final}}(d)$ to a coverage-aware set
1438
- selector that rewards a set of candidates for jointly maximizing semantic
1439
- relevance, temporal anchor density, and event-slot coverage while penalizing
1440
- redundancy automatically via marginal scoring.
1441
-
1442
- ### 9.2 Temporal Query Indicator $\xi(q)\in[0,1]$
1443
-
1444
- To avoid mutating the retrieval contract for normal queries, the extension
1445
- activates only when the query is detected to be temporal-compositional.
1446
- Define the temporal query indicator using the same saturating-sum pattern as
1447
- $T(t)$ in [`gating.md`](./gating.md):
1448
-
1449
- $$
1450
- \xi(q)
1451
- =
1452
- \min\!\left(
1453
- \frac{\displaystyle\sum_i s_i \cdot \mathbf{1}[\mathrm{tpat}_i(q)]}
1454
- {\theta_{\xi}^{\mathrm{norm}}},
1455
- 1
1456
- \right)
1457
- $$
1458
-
1459
- where the shipped temporal patterns $\mathrm{tpat}_i$ are zero-allocation
1460
- byte-lexer matches over the query text, including but not limited to
1461
- "how many days", "how long", "before", "after", "since", "first", "earlier",
1462
- "which came first", "when did", and "between".
1463
-
1464
- Each pattern carries a weight $s_i > 0$. The default normalization constant is
1465
- $\theta_{\xi}^{\mathrm{norm}} = 1.5$, so two strong temporal signals saturate
1466
- $\xi(q)=1$.
1467
-
1468
- By construction, the $\min(\cdot, 1)$ clamp and non-negative numerator
1469
- guarantee:
1470
-
1471
- $$
1472
- \xi(q)\in[0,1]
1473
- $$
1474
-
1475
- If no temporal patterns match, $\xi(q)=0$ and the extension contributes
1476
- nothing to the scoring formula.
1477
-
1478
- The extension activates only when $\xi(q)\ge\theta_\xi$, with shipped default
1479
- $\theta_\xi = 0.3$. Below that threshold, the standard $\mathrm{Proj}$ path
1480
- executes without modification.
1481
-
1482
- ### 9.3 Temporal Anchor Density $A(d)\in[0,1]$
1483
-
1484
- A document's temporal anchor density measures how many explicit date or time
1485
- expressions it contains, normalized by a bounded saturation constant.
1486
- Define the anchor count over a lightweight anchor pattern set $\mathcal{P}_A$
1487
- (ISO dates, relative day expressions, clock times, calendar words, Unix
1488
- timestamps):
1489
-
1490
- $$
1491
- A(d)
1492
- =
1493
- \min\!\left(
1494
- \frac{\displaystyle\sum_j \mathbf{1}[\mathrm{anch}_j(d)]}
1495
- {\theta_A^{\mathrm{norm}}},
1496
- 1
1497
- \right)
1498
- $$
1499
-
1500
- The default $\theta_A^{\mathrm{norm}} = 3$, so three or more distinct anchor
1501
- expressions saturate $A(d)=1$.
1502
-
1503
- Again, the clamp guarantees:
1504
-
1505
- $$
1506
- A(d)\in[0,1]
1507
- $$
1508
-
1509
- $A(d)$ is a precomputed document-level scalar. It does not depend on the query
1510
- and should be cached in the same document-addressed cache $\Psi$ defined in
1511
- [`ast-v2.md`](./ast-v2.md) Section 7 alongside tier partition and budget
1512
- metadata. The value must be recomputed whenever a stored document is created,
1513
- updated, or regenerated by compaction.
1514
-
1515
- ### 9.4 Event-Slot Extraction and Marginal Coverage $\Delta\Phi$
1516
-
1517
- #### 9.4.1 Event-Slot Extraction
1518
-
1519
- For a temporal-compositional query $q$, define the event-slot set:
1520
-
1521
- $$
1522
- E(q)=\langle e_1, e_2, \dots, e_m \rangle
1523
- $$
1524
-
1525
- where each $e_j$ is a short noun-phrase span extracted from $q$ by a
1526
- lightweight span extractor: named entities plus the main noun phrase preceding
1527
- and following any detected temporal-pattern word. The extractor returns at
1528
- most $m_{\max}=4$ slots to bound cost.
1529
-
1530
- When $|E(q)|=0$, all coverage terms evaluate to zero and the formula degrades
1531
- cleanly.
1532
-
1533
- #### 9.4.2 Per-Slot Coverage Indicator
1534
-
1535
- For each slot $e_j$ and candidate document $d$, define the binary slot-match
1536
- indicator:
1537
-
1538
- $$
1539
- \phi_j(d)
1540
- =
1541
- \mathbf{1}\!\left[\varphi(e_j)^\top \varphi(d) \ge \theta_e\right]
1542
- \in \{0,1\}
1543
- $$
1544
-
1545
- where $\varphi(\cdot)$ is the same unit-normalized embedding function defined
1546
- in Section 7.1, and $\theta_e \in [-1,1]$ is the slot-match similarity
1547
- threshold, default $\theta_e = 0.50$.
1548
-
1549
- #### 9.4.3 Marginal Coverage
1550
-
1551
- For a set $\mathcal{S}$ of already-selected documents, define the marginal
1552
- coverage of adding $d$:
1553
-
1554
- $$
1555
- \Delta\Phi(d, \mathcal{S}, q)
1556
- =
1557
- \frac{1}{\max(|E(q)|, 1)}
1558
- \sum_{j=1}^{|E(q)|}
1559
- \phi_j(d)
1560
- \cdot
1561
- \mathbf{1}\!\left[\nexists d' \in \mathcal{S} : \phi_j(d') = 1\right]
1562
- $$
1563
-
1564
- This is the fraction of uncovered event slots that $d$ newly covers.
1565
-
1566
- The outer factor is in $(0,1]$, the sum counts at most $|E(q)|$ binary terms,
1567
- and therefore:
1568
-
1569
- $$
1570
- \Delta\Phi(d, \mathcal{S}, q)\in[0,1]
1571
- $$
1572
-
1573
- The indicator
1574
- $\mathbf{1}\!\left[\nexists d' \in \mathcal{S} : \phi_j(d') = 1\right]$
1575
- ensures that slots already covered by a previously selected document
1576
- contribute zero marginal gain, automatically penalizing redundant anchor turns
1577
- without a separate explicit penalty term.
1578
-
1579
- As $|\mathcal{S}|$ grows, $\Delta\Phi(d,\mathcal{S},q)$ is monotone
1580
- non-increasing: new selections can only cover more slots, leaving fewer
1581
- uncovered slots for later candidates to gain credit for.
1582
-
1583
- ### 9.5 Coverage-Augmented Blended Score
1584
- $S_{\mathrm{proj}}(d,\mathcal{S},q)\in[0,1]$
1585
-
1586
- Define the coverage-augmented score for candidate $d$ given already-selected
1587
- set $\mathcal{S}$ and query $q$:
1588
-
1589
- $$
1590
- S_{\mathrm{cov}}(d, \mathcal{S}, q)
1591
- =
1592
- \mu \cdot S_{\mathrm{final}}(d)
1593
- + \nu \cdot A(d)
1594
- + \rho \cdot \Delta\Phi(d, \mathcal{S}, q)
1595
- $$
1596
-
1597
- where:
1598
-
1599
- $$
1600
- \mu,\nu,\rho\in[0,1],
1601
- \qquad
1602
- \mu+\nu+\rho=1
1603
- $$
1604
-
1605
- The default shipped weights are $\mu=0.60$, $\nu=0.20$, and $\rho=0.20$.
1606
-
1607
- Blend this with the standard score using $\xi(q)$ as an interpolation scalar:
1608
-
1609
- $$
1610
- S_{\mathrm{proj}}(d, \mathcal{S}, q)
1611
- =
1612
- (1 - \xi(q)) \cdot S_{\mathrm{final}}(d)
1613
- + \xi(q) \cdot S_{\mathrm{cov}}(d, \mathcal{S}, q)
1614
- $$
1615
-
1616
- Substituting $S_{\mathrm{cov}}$ yields:
1617
-
1618
- $$
1619
- S_{\mathrm{proj}}
1620
- =
1621
- \bigl(1 - \xi(1-\mu)\bigr)\cdot S_{\mathrm{final}}
1622
- + \xi\nu \cdot A
1623
- + \xi\rho \cdot \Delta\Phi
1624
- $$
1625
-
1626
- All coefficients are non-negative, and they sum to one:
1627
-
1628
- $$
1629
- \bigl(1 - \xi(1-\mu)\bigr) + \xi\nu + \xi\rho
1630
- =
1631
- 1 - \xi + \xi\mu + \xi\nu + \xi\rho
1632
- =
1633
- 1 - \xi + \xi(\mu+\nu+\rho)
1634
- =
1635
- 1
1636
- $$
1637
-
1638
- Because $S_{\mathrm{final}}(d)$, $A(d)$, and
1639
- $\Delta\Phi(d,\mathcal{S},q)$ all lie in $[0,1]$, this is a proper convex
1640
- combination, so:
1641
-
1642
- $$
1643
- S_{\mathrm{proj}}(d,\mathcal{S},q)\in[0,1]
1644
- $$
1645
-
1646
- Degeneracy cases:
1647
-
1648
- | Condition | Behavior |
1649
- | --- | --- |
1650
- | $\xi(q)=0$ | $S_{\mathrm{proj}} = S_{\mathrm{final}}(d)$; standard retrieval unchanged |
1651
- | $\xi(q)=1$, $\nu=\rho=0$, $\mu=1$ | Explicit no-op configuration; still $S_{\mathrm{proj}} = S_{\mathrm{final}}(d)$ |
1652
- | $|E(q)|=0$ | $\Delta\Phi=0$ for all $d$; the $\rho$ term vanishes |
1653
- | $\mathcal{S}=\emptyset$ | $\Delta\Phi$ equals full slot-coverage fraction |
1654
- | all slots already covered by $\mathcal{S}$ | $\Delta\Phi=0$ for all remaining $d$ |
1655
-
1656
- Note: the greedy selector below optimizes a submodular coverage term
1657
- $\Delta\Phi$ augmented with fixed document priors $S_{\mathrm{final}}(d)$ and
1658
- $A(d)$. The classic $(1-1/e)$ approximation guarantee applies strictly to the
1659
- coverage component; in practice the blended score preserves greedy usefulness
1660
- for temporal anchor selection.
1661
-
1662
- ### 9.6 Temporal Recovery Candidate Set
1663
- $\mathcal{C}_{\mathrm{rec}}(q)$
1664
-
1665
- The root cause of the observed benchmark failure is not only that documents are
1666
- scored incorrectly; it is also that the necessary complementary anchor turn may
1667
- never enter $\mathcal{C}_2(q)$ because its semantic similarity to the
1668
- whole-query embedding is too low.
1669
-
1670
- A bounded recovery pass admits anchor-rich documents below the normal Pass-1
1671
- threshold:
1672
-
1673
- $$
1674
- \mathcal{C}_{\mathrm{rec}}(q)
1675
- =
1676
- \mathrm{TopK}_{d \in
1677
- \left\{d' \in \mathcal{V}_{\mathrm{rest}} :
1678
- \mathrm{sim}(q,d') \ge \theta_{\mathrm{rec}}\right\}}
1679
- \left(k_{\mathrm{rec}},\, A(d)\right)
1680
- \setminus \mathcal{C}_2(q)
1681
- $$
1682
-
1683
- where:
1684
-
1685
- - $\theta_{\mathrm{rec}} < \theta_1$ is a looser semantic floor, default
1686
- $\theta_{\mathrm{rec}} = 0.15$, preventing pure noise while still admitting
1687
- anchor-heavy but semantically distant turns.
1688
- - $k_{\mathrm{rec}}$ is a small cap, default $k_{\mathrm{rec}} = 10$, bounding
1689
- recovery cost to $O(k_{\mathrm{rec}})$.
1690
-
1691
- The combined candidate pool for the greedy selector is:
1692
-
1693
- $$
1694
- \mathcal{C}_{\mathrm{pool}}(q)
1695
- =
1696
- \mathcal{C}_2(q)\cup\mathcal{C}_{\mathrm{rec}}(q)
1697
- $$
1698
-
1699
- By construction,
1700
- $\mathcal{C}_{\mathrm{pool}}(q)\subseteq\mathcal{V}_{\mathrm{rest}}$, so
1701
- partition integrity is preserved.
1702
-
1703
- ### 9.7 Greedy Coverage-Aware Selector
1704
-
1705
- Given $\mathcal{C}_{\mathrm{pool}}(q)$, the selector builds the final chosen
1706
- set greedily, using the same rank-then-prefix-accept spirit as the existing
1707
- token-budget packing in Section 7.8.
1708
-
1709
- Let $k_{\mathrm{cov}}\le k_2$ be the maximum number of anchor turns to select,
1710
- default $k_{\mathrm{cov}}=3$.
1711
-
1712
- Initialize:
1713
-
1714
- $$
1715
- \mathcal{S}_0 = \emptyset
1716
- $$
1717
-
1718
- For $i = 0, 1, \dots, k_{\mathrm{cov}}-1$:
1719
-
1720
- $$
1721
- d_i^*
1722
- =
1723
- \underset{d \in \mathcal{C}_{\mathrm{pool}}(q)\setminus\mathcal{S}_i}{\arg\max}
1724
- \;
1725
- S_{\mathrm{proj}}(d, \mathcal{S}_i, q)
1726
- $$
1727
-
1728
- Early stop if:
1729
-
1730
- $$
1731
- S_{\mathrm{proj}}(d_i^*, \mathcal{S}_i, q) < \theta_{\mathrm{stop}}
1732
- $$
1733
-
1734
- with default $\theta_{\mathrm{stop}}=0.10$. Otherwise:
1735
-
1736
- $$
1737
- \mathcal{S}_{i+1} = \mathcal{S}_i \cup \{d_i^*\}
1738
- $$
1739
-
1740
- The final selected set is $\mathcal{S}^*(q)$, or the earlier set at which
1741
- early stopping triggered.
1742
-
1743
- Each greedy step scans at most
1744
- $|\mathcal{C}_{\mathrm{pool}}(q)| \le k_2 + k_{\mathrm{rec}}$ candidates.
1745
- Total complexity is therefore:
1746
-
1747
- $$
1748
- O\!\left(k_{\mathrm{cov}} \cdot (k_2 + k_{\mathrm{rec}})\right)
1749
- $$
1750
-
1751
- which is negligible relative to embedding and vector-search cost.
1752
-
1753
- ### 9.8 Modified Projection Operator
1754
-
1755
- The temporal extension redefines $\mathrm{Proj}$ conditionally:
1756
-
1757
- $$
1758
- \mathrm{Proj}(\mathcal{V}_{\mathrm{rest}}, q)
1759
- =
1760
- \begin{cases}
1761
- \mathcal{S}^*(q)\cup\mathcal{C}_{hop}^{*}(q)
1762
- & \text{if } \xi(q) \ge \theta_\xi \\[4pt]
1763
- \mathcal{C}_2(q)\cup\mathcal{C}_{hop}^{*}(q)
1764
- & \text{otherwise}
1765
- \end{cases}
1766
- $$
1767
-
1768
- The assembly law and budget equations remain unchanged:
1769
-
1770
- $$
1771
- C_{\mathrm{total}}(q)=\mathcal{I}_1\cup\mathcal{I}_2^{*}\cup T_{\mathrm{recent}}\cup \mathrm{Proj}(\mathcal{V}_{\mathrm{rest}}, q)
1772
- $$
1773
-
1774
- $$
1775
- \tau_{\mathcal{V}}(q)
1776
- =
1777
- \tau-\tau_{\mathcal{I}_1}
1778
- -\sum_{d\in\mathcal{I}_2^{*}}\mathrm{toks}(d)
1779
- -\sum_{d\in T_{\mathrm{recent}}}\mathrm{toks}(d)
1780
- $$
1781
-
1782
- Documents in $\mathrm{Proj}(\mathcal{V}_{\mathrm{rest}}, q)$ are injected in
1783
- descending $\sigma(d)$ order until $\tau_{\mathcal{V}}(q)$ is exhausted.
1784
-
1785
- For documents entering through the temporal selector, the merged score sequence
1786
- is extended:
1787
-
1788
- $$
1789
- \sigma(d)=
1790
- \begin{cases}
1791
- S_{\mathrm{proj}}(d, \mathcal{S}^*\setminus\{d\}, q)
1792
- & d\in\mathcal{S}^*(q) \\
1793
- S_{hop}(d)
1794
- & d\in\mathcal{C}_{hop}^{*}(q)
1795
- \end{cases}
1796
- $$
1797
-
1798
- For documents that were already present in $\mathcal{C}_2(q)$, the standard
1799
- $S_{\mathrm{final}}(d)$ path remains authoritative and duplicates are excluded
1800
- by construction.
1801
-
1802
- ### 9.9 Preservation of Section 7.10 Runtime Invariants
1803
-
1804
- All runtime invariants from Section 7.10 remain preserved:
1805
-
1806
- 1. Invariant completeness is unaffected because $\mathcal{I}_1$ injection is
1807
- independent of $\mathrm{Proj}$.
1808
- 2. Soft invariant order preservation is unaffected because
1809
- $\mathcal{I}_2^{*}$ is unchanged.
1810
- 3. Partition integrity is preserved because
1811
- $\mathcal{C}_{\mathrm{rec}}\subseteq\mathcal{V}_{\mathrm{rest}}$ and
1812
- $\mathcal{S}^*\subseteq\mathcal{C}_{\mathrm{pool}}
1813
- \subseteq\mathcal{V}_{\mathrm{rest}}$.
1814
- 4. Mandatory recent-tail completeness is unaffected because
1815
- $T_{\mathrm{base}}\subseteq T_{\mathrm{recent}}$ remains independent of
1816
- $\mathrm{Proj}$.
1817
- 5. Score boundedness is preserved because
1818
- $S_{\mathrm{proj}}(d,\mathcal{S},q)\in[0,1]$.
1819
- 6. Token budget respect is preserved because the result still flows through the
1820
- same residual variant budget and greedy token packing contract.
1821
- 7. Compaction boundary safety is preserved because
1822
- $\mathcal{S}^*\subseteq\mathcal{V}_{\mathrm{rest}}$.
1823
- 8. Hop termination is unchanged because $\mathcal{C}_{hop}^{*}(q)$ is defined
1824
- identically.
1825
- 9. Edge-case safety is preserved by the guards below.
1826
-
1827
- Edge-case additions:
1828
-
1829
- - $\mathcal{C}_{\mathrm{pool}}(q)=\emptyset$: the greedy selector returns
1830
- $\mathcal{S}^*=\emptyset$ and $\mathrm{Proj}$ reduces to
1831
- $\mathcal{C}_{hop}^{*}(q)$ only.
1832
- - $|E(q)|=0$: the denominator in $\Delta\Phi$ uses $\max(|E(q)|,1)$, so no
1833
- division by zero is possible.
1834
- - $\xi(q)<\theta_\xi$: the conditional routes directly to the existing
1835
- $\mathcal{C}_2(q)\cup\mathcal{C}_{hop}^{*}(q)$ behavior.
1836
- - $\tau_{\mathcal{V}}(q)=0$: the selector may compute $\mathcal{S}^*$, but
1837
- packing injects zero documents and the budget invariant still holds.
1838
-
1839
- ### 9.10 Symbol Table (Section 9 Additions)
1840
-
1841
- | Symbol | Domain | Meaning |
1842
- | --- | --- | --- |
1843
- | $\xi(q)$ | $[0,1]$ | Temporal-compositional query indicator |
1844
- | $\theta_\xi$ | $(0,1)$ | Activation threshold for temporal mode |
1845
- | $\theta_{\xi}^{\mathrm{norm}}$ | $(0,\infty)$ | Saturation normalization for $\xi$ |
1846
- | $A(d)$ | $[0,1]$ | Temporal anchor density of document $d$ |
1847
- | $\theta_A^{\mathrm{norm}}$ | $(0,\infty)$ | Saturation normalization for $A$ |
1848
- | $E(q)$ | ordered tuple set | Event-slot sequence extracted from $q$ |
1849
- | $\phi_j(d)$ | $\{0,1\}$ | Binary slot-match indicator |
1850
- | $\theta_e$ | $[-1,1]$ | Slot-match similarity threshold |
1851
- | $\Delta\Phi(d,\mathcal{S},q)$ | $[0,1]$ | Marginal event-slot coverage |
1852
- | $\mu,\nu,\rho$ | $[0,1]$, sum to 1 | Coverage score weights |
1853
- | $S_{\mathrm{cov}}(d,\mathcal{S},q)$ | $[0,1]$ | Coverage-augmented score |
1854
- | $S_{\mathrm{proj}}(d,\mathcal{S},q)$ | $[0,1]$ | Final blended projection score |
1855
- | $\mathcal{C}_{\mathrm{rec}}(q)$ | $\subseteq\mathcal{V}_{\mathrm{rest}}$ | Recovery candidate set |
1856
- | $\theta_{\mathrm{rec}}$ | $[-1,1]$ | Semantic floor for recovery pass |
1857
- | $k_{\mathrm{rec}}$ | $\mathbb{Z}_{>0}$ | Recovery set size cap |
1858
- | $\mathcal{C}_{\mathrm{pool}}(q)$ | $\subseteq\mathcal{V}_{\mathrm{rest}}$ | Combined greedy input pool |
1859
- | $k_{\mathrm{cov}}$ | $\mathbb{Z}_{>0}, \le k_2$ | Maximum anchor turns to select |
1860
- | $\theta_{\mathrm{stop}}$ | $[0,1]$ | Early-stop floor for greedy selector |
1861
- | $\mathcal{S}^*(q)$ | $\subseteq\mathcal{C}_{\mathrm{pool}}$ | Greedy-selected coverage-aware anchor set |
1862
-
1863
- ### 9.11 Relationship to Existing Sections
1864
-
1865
- This section is an extension, not a replacement:
1866
-
1867
- - Section 1 hybrid score $\mathrm{score}(d)$ is unchanged and still feeds
1868
- $S_{\mathrm{final}}(d)$ as before.
1869
- - Section 7.5 $S_{\mathrm{final}}(d)$ is the first input to
1870
- $S_{\mathrm{proj}}$; when $\xi(q)=0$, the two are identical.
1871
- - Section 7.7 hop expansion $\mathcal{C}_{hop}^{*}$ is unchanged and is
1872
- unioned with $\mathcal{S}^*$ exactly as before.
1873
- - Section 7.8 budget arithmetic is unchanged; $\mathrm{Proj}$ is still bounded
1874
- by $\tau_{\mathcal{V}}(q)$ and still greedy-packed.
1875
- - [`gating.md`](./gating.md) inspired the saturating-sum pattern for $\xi(q)$,
1876
- but the two operate on different objects and at different pipeline stages.
1877
- - [`ast-v2.md`](./ast-v2.md) Section 7's document-addressed cache $\Psi$ should
1878
- be extended to store the precomputed $A(d)$ value alongside existing tier and
1879
- budget metadata.