mirror of
https://github.com/sdwolf4103/opencode-working-memory.git
synced 2026-06-02 06:19:36 +02:00
feat(memory): add retention model test gaps and health diagnostics
Wave 1 - P0 Test Gaps: - Add hard stale prune removed regression test - Add dormant overlap tests (entry created during dormancy) - Add invalid timestamp NaN protection test - Add reinforcement ordering test with reference type - Add dedupe same-session/under-1hr guard tests - Fix NaN handling with Number.isFinite check Wave 2 - Helper Functions: - Add timestampMs() for safe timestamp conversion - Add isSafetyCriticalForDiag() aligned with runtime Wave 3 - Health Output Format: - Fix top rendered candidates sorted by strength (not text length) - Add stored vs rendered counts breakdown - Add type caps and global cap overflow display - Track globalCapped array explicitly - Add dormant status section Wave 4 - Monitoring Metrics: - Add high_importance_ratio (alert > 30%) - Add safety_critical_count (alert > 5) - Add max_reinforced_count (alert > 10% active) Wave 5 - Integration Fixture: - Add 34-entry over-cap test - Add mixed retention regression fixture - Test TYPE_MAX caps, safety-critical exemption, reinforcement ordering Tests: 224 → 237
This commit is contained in:
+10
-3
@@ -67,6 +67,11 @@ export function calculateEffectiveHalfLife(memory: LongTermMemoryEntry): number
|
||||
return BASE_HALF_LIFE_DAYS / factor;
|
||||
}
|
||||
|
||||
function timestampMs(value: unknown, fallback: number): number {
|
||||
const ms = typeof value === "number" ? value : new Date(String(value)).getTime();
|
||||
return Number.isFinite(ms) ? ms : fallback;
|
||||
}
|
||||
|
||||
export function calculateRetentionStrength(
|
||||
memory: LongTermMemoryEntry,
|
||||
now: number,
|
||||
@@ -76,14 +81,16 @@ export function calculateRetentionStrength(
|
||||
const effectiveHalfLife = calculateEffectiveHalfLife(memory);
|
||||
|
||||
// Use retentionClock if available, fallback to updatedAt.
|
||||
const retentionStart = memory.retentionClock ?? memory.updatedAt;
|
||||
const createdAtMs = new Date(retentionStart).getTime();
|
||||
const retentionStart = Number.isFinite(memory.retentionClock)
|
||||
? memory.retentionClock
|
||||
: memory.updatedAt ?? memory.createdAt;
|
||||
const createdAtMs = timestampMs(retentionStart, now);
|
||||
const effectiveAgeDays = calculateEffectiveAgeDays(createdAtMs, now, lastActivityAt);
|
||||
|
||||
// Calculate strength using exponential decay.
|
||||
const strength = initialStrength * Math.pow(2, -effectiveAgeDays / effectiveHalfLife);
|
||||
|
||||
return Math.max(0, strength);
|
||||
return Number.isFinite(strength) ? Math.max(0, strength) : 0;
|
||||
}
|
||||
|
||||
export function calculateDormantDays(store: WorkspaceMemoryStore, now: number): number {
|
||||
|
||||
Reference in New Issue
Block a user