Skip to content

feat: context health diagnostics — C_norm, R_compression, time-gap segmentation, recall recency#113

Merged
BYK merged 1 commit intomainfrom
feat/context-health-diagnostics
May 2, 2026
Merged

feat: context health diagnostics — C_norm, R_compression, time-gap segmentation, recall recency#113
BYK merged 1 commit intomainfrom
feat/context-health-diagnostics

Conversation

@BYK
Copy link
Copy Markdown
Owner

@BYK BYK commented May 2, 2026

Summary

Add two computable diagnostic signals and two behavioral improvements for Lore's context management, inspired by D7x7z49/llm-context-idea research notes on temporal clustering and compression boundaries.

Diagnostic signals (Phase 1)

  • temporalCnorm(timestamps, now) in temporal.ts: Normalized variance of relative-existence weights over message timestamps. Returns [0, 1] — 0 means uniform attention distribution, 1 means dominated by distant past. Lightweight (pure arithmetic over created_at values we already store).

  • compressionRatio(distilledTokens, sourceTokens) in distillation.ts: k/√N ratio where k = distilled tokens, N = source tokens. Values < 1.0 signal aggressive/likely-lossy compression. Based on the "square root boundary" heuristic — unvalidated, used as observation-only diagnostic.

Both are logged per-distillation segment under LORE_DEBUG=1:

distill segment: 12 msgs, 4500→320 tokens, R=4.77, C_norm=0.042

Time-gap-aware segmentation (Phase 2)

  • detectSegments() now prefers splitting at the largest inter-message time gap (≥ 3× median gap) instead of purely at count boundaries. Falls back to count-based splitting when timestamps are uniform (existing behavior preserved).
  • Minimum segment size of 3 messages enforced — tiny trailing segments still get merged.

Recall recency biasing (Phase 3)

  • Adds a recency-sorted list of temporal search results to the RRF fusion alongside the existing BM25 list. Messages that are both semantically relevant AND recent get a natural RRF score boost. No new thresholds — RRF handles the balance.

Changes

File What
packages/core/src/temporal.ts Add temporalCnorm() export
packages/core/src/distillation.ts Add compressionRatio() export, diagnostic logging in distillSegment(), time-gap-aware detectSegments() (now exported)
packages/core/src/recall.ts Add recency-sorted RRF list for temporal results
packages/core/test/context-health.test.ts New: 22 tests for temporalCnorm, compressionRatio, and recency RRF behavior
packages/core/test/distillation.test.ts 8 new tests for detectSegments time-gap splitting

Verification

  • 582 tests pass, 0 fail (all existing + 30 new)
  • Build clean across all 3 packages
  • No schema changes, no new LLM calls, no new dependencies

…gmentation, recall recency

Add two computable diagnostic signals for context management quality:

- temporalCnorm(): normalized variance of relative-existence weights over
  message timestamps. Measures attention imbalance [0,1] — 0 is uniform
  distribution, 1 is dominated by distant past. Logged per-distillation
  under LORE_DEBUG=1.

- compressionRatio(): k/√N ratio where k=distilled tokens, N=source tokens.
  Values < 1.0 signal aggressive/likely-lossy compression. Logged
  per-distillation under LORE_DEBUG=1.

Enhance detectSegments() to prefer splitting at the largest inter-message
time gap (≥3x median) when oversized, respecting natural conversation
boundaries instead of arbitrary count-based chunking. Falls back to
count-based splitting when timestamps are uniform.

Add recency-biased RRF list for temporal recall results. Same candidates
re-ranked by created_at (newest first), fused alongside BM25 via existing
RRF — messages that are both semantically relevant AND recent get a
natural score boost.

Inspired by D7x7z49/llm-context-idea research notes on temporal clustering
and compression boundaries.

582 tests pass, 0 fail. Build clean across all 3 packages.
@BYK BYK enabled auto-merge (squash) May 2, 2026 00:56
@BYK BYK merged commit c6497ac into main May 2, 2026
1 check passed
@BYK BYK deleted the feat/context-health-diagnostics branch May 2, 2026 00:57
@craft-deployer craft-deployer Bot mentioned this pull request May 2, 2026
5 tasks
BYK added a commit that referenced this pull request May 2, 2026
…12) (#116)

## Summary

Persist `r_compression` and `c_norm` context health metrics directly in
the `distillations` table, replacing the `LORE_DEBUG=1`-gated log lines
that were invisible by default.

## Why

The diagnostic logging added in #113 used `log.info()` which is
suppressed unless `LORE_DEBUG=1` — making the diagnostics effectively
invisible in normal operation. Storing metrics in the DB makes them
queryable retroactively without env vars or log parsing.

## Changes

- **Schema v12**: Two nullable `REAL` columns (`r_compression`,
`c_norm`) on `distillations`
- **storeDistillation()**: Accepts optional `rCompression` and `cNorm`
params, writes to new columns
- **distillSegment()**: Computes metrics *before* `storeDistillation()`
(was after), passes them in
- **loadForSession() + loadGen0()**: SQL and row types updated to
include new columns
- **Distillation type**: `r_compression: number | null` and `c_norm:
number | null`
- **Tests**: 3 new tests verifying NULL for legacy rows, correct values
for new rows, mixed results
- **opencode test helper**: `restoreDistillationTables()` updated for
schema parity

## Verification

- 586 tests pass, 0 fail
- Build clean across all 3 packages
- Existing rows get NULL (no backfill needed)
- Migration is two `ALTER TABLE ADD COLUMN` statements (idempotent for
new DBs, safe for existing)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant