v2.4.10
Third slice of the 2026-04-19 audit fix wave. Focuses on long-tail
correctness + hygiene; the larger 2.5.0 items (root init_schema.sql
sync, CE warmup off the latency deque, top-heavy MCP exposure, competitor
bench rerun) are still outstanding and will land in a coordinated 2.5.0
release.
Fixed
datetime.utcnow()removed everywhere it was being called. Three
sites inhippocampus.py,mcp_server.py,mcp_tools_health.py
switched todatetime.now(timezone.utc). Themcp_tools_healthcutoff
foraccess_logpruning was also producing naive ISO strings that
sorted incorrectly against Z-suffixedcreated_atrows — under-deletes
fixed.decision_lookupintent now actually queries thedecisions
table. The pre-2.5.0 guard checked"decisions" not in results
(resultsis pre-initialized with that key — guard always False), and
the body's set union didn't include"decisions"either. Two-bug fix
on a single line. Source-locked by regression test.config.load()no longer silently swallows permission errors.
Bareexcept Exception: passreplaced withtomllib.TOMLDecodeErrorOSErrorbranches that log a warning then fall back to defaults.
CLI still boots whenconfig.tomlis unreadable; the user sees the
reason in stderr instead of stale defaults.
federated_memory_search/federated_searchnow expose
returned_countalongsidetotal_resultsso callers can branch on
the slice without inferring fromlen(results).total_results
semantics unchanged (full pre-slice match pool).
Changed — performance + hygiene
code_ingest.Extraction.add_node_if_new()replaces three O(n²)
set-comprehension dedup sites in the python / typescript / go
extractors. Indistinguishable on small trees, real difference on a
100-file ingest._cached_scorelru_cache shim removed fromrerank.py— it had no
callers and always returnedNone. Real cache (_score_cache
dict + eviction list) untouched.- Subprocess
stdout=open(...)replaced withwith open(...)at the
two backup sites (_impl.py,mcp_tools_health.py) so the fd
closes on every exit path, not just success. bin/quiet-hours-{start,end}.shcd into the script dir before
invoking the python sibling so cron (which sets CWD=$HOME) finds
the file.
CI
- New
tests/test_datetime_hygiene.pyregex-asserts nodatetime.utcnow()
calls remain anywhere insrc/agentmemory/. The earlier draft of this
gate also tracked baredatetime.now()against an allowlist; that
half was dropped because line-numbered allowlists drift on every PR
that touches a long file. Naked-now()cleanup will follow as part
of the coordinated local→UTC timestamp migration.
Testing
1874 passed, 28 skipped, 2 xfailed locally. Three new regression
tests at tests/test_audit_2_5_0_regressions.py lock I25, I29, I31.