1.7 KiB
| id | type | title | tags | importance | confidence | created | updated | relations | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 59268a95-4712-48b4-bccb-6171c7885301 | fix | Fix: Race condition in cognitive-memory _save_state loses last_reflection timestamp when daily+weekly timers collide |
|
0.8 | 0.8 | 2026-02-20T06:47:07.701221+00:00 | 2026-02-20T06:47:17.701728+00:00 |
|
Race Condition in _save_state Corrupts last_reflection Timestamp
Symptom
REFLECTION.md showed "Last reflection: never" despite the weekly reflect timer having run successfully.
Root Cause
Two concurrent issues:
-
Timer collision: The daily timer (decay) and weekly timer (reflect) could fire simultaneously.
OnCalendar=weeklyresolves to Mon midnight, which overlaps withOnCalendar=dailyon Mondays. Both processes load and save_state.jsonconcurrently. -
Non-atomic writes with silent failure:
_save_state()would overwrite_state.jsonwithout first merging existing state, so decay's write could clobber thelast_reflectionkey written by reflect. Additionally,_load_state()silently caughtJSONDecodeErrorand returned an empty default dict, permanently losing the key on any write collision.
Fix
_save_state()now merges with existing on-disk state before writing (read-modify-write pattern).- Writes use atomic
tempfile + os.replace()to prevent partial writes. - Weekly timer changed from
OnCalendar=weeklytoOnCalendar=Sun *-*-* 02:00:00to avoid midnight collision with the daily timer.
Commit
Commit 7f120f8 in the cognitive-memory repo.