mirror of
https://github.com/proffesor-for-testing/agentic-qe.git
synced 2026-09-19 08:45:47 +08:00
b62eb83ad4
#493 was not the last instance of the kv-Date hazard — it was the most reachable. Audit of the rest of the learning pipeline found 11 more unprotected kv-read sites where TypeScript declares `Date` but JSON round-trip through `memory.get` yields an ISO string at runtime. Two failure modes, both already documented at learning-coordinator.ts:898-904 (#491 Bug 3): 1. THROW — `record.someDate.getTime()` raises TypeError. Surfaces immediately on the first invocation once any record exists. 2. SILENT — `timeRange.contains(record.someDate)` or `new Date() > record.expiresAt` coerces string vs Date to NaN; all comparisons return false; records are silently filtered out or expiry is never recognised. No error, just empty/stale analytics. The silent variant is the worse one — #491 Bug 3 was the same class and shipped for a release cycle undetected. Strategic fix: a single `rehydrateDates<T>(record, dateFields[])` helper at `src/shared/utils/kv-date-rehydrate.ts` applied at every kv-read seam that touches Date-bearing types. Shallow-copies the record and coerces named string fields back to Date; pass-through for already-Date, null, undefined. Sites patched (11 total): src/domains/learning-optimization/services/ production-intel.ts — 4 sites (HIGH #2-#5 throw, MEDIUM #8 silent) getMetricsHistory, getRecentIncidents (×2), resolveIncident, getRecentMilestones metrics-optimizer.ts — 1 site (HIGH #1 throw) getMetricsHistory.sort learning-coordinator.ts — 1 site (HIGH #6 throw) getReplayBuffer.sort transfer-specialist.ts — 4 sites (HIGH #7 throw, MEDIUM #9 silent) queryKnowledge (×2), getKnowledgeById, bulkTransfer src/domains/learning-optimization/ coordinator-helpers.ts — 1 site (SILENT) getExperiencesForDomain coordinator.ts — 1 site (SILENT, duplicate of above) getExperiencesForDomain (private) Sites verified SAFE (kv-read but only access non-Date fields): - coordinator.ts:1045/1134/1175 — uses .domain/.confidence/.version - metrics-optimizer.ts:676 — uses .metrics map - learning-coordinator.ts:379/438/483/547/830/842 — uses .confidence/.successRate/.domain/.usageCount - learning-coordinator.ts:901 — already has #491 Bug 3 inline rehydration with instanceof guard - experience-capture.ts:520/563 — TaskExperience uses number timestamps, not Date Sites NOT patched (deferred per scope): - coordination/protocols/learning-consolidation.ts — defined but never imported anywhere. Dead code; would resurrect the bug if reactivated. Documented in the audit but not fixed. Regression tests (29 new, 6 files): tests/unit/shared/utils/kv-date-rehydrate.test.ts (10) tests/unit/domains/learning-optimization/ production-intel-date-coercion.test.ts (5) metrics-optimizer-date-coercion.test.ts (2) learning-coordinator-date-coercion.test.ts (2) transfer-specialist-date-coercion.test.ts (5) coordinator-helpers-date-coercion.test.ts (2) Each service test seeds its mock memory backend with kv-shape records (ISO strings instead of Date instances — matching the post-JSON.parse shape that better-sqlite3-backed memory yields in production) and exercises the kv-read → consumer path that would fail pre-fix. Both throw and silent failure modes are pinned: throws are asserted not to fire, silent failures are caught by behavioural assertions (e.g. the expired-knowledge test asserts `expired.score < live.score * 0.5 ±`, which would fail pre-fix because the 0.5 penalty never triggered). Verification: - 29/29 new regression tests green - 135/135 existing tests for patched services green (production-intel, metrics-optimizer, transfer-specialist, learning-coordinator, learning-consolidation, learning-consolidation-mining, learning-consolidation-liveness) - `tsc --noEmit` clean - `npm run build` produces dist with rehydrateDates at all 17 expected call sites across the 6 patched files Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>