Staleness clock penalises memories that compiled into skills — inverted signal #34

Closed
opened 2026-09-08 13:30:11 +00:00 by ric · 1 comment
Owner

Observed on: 6.7.0

Observation

Every entry in the briefing() stale list is at 179 days, and they are all durable preference facts:

  • Preferred git forge (Forgejo over GitHub)
  • Preferred email provider
  • Preferred messaging platform
  • Discourse as forum platform of choice
  • Writing style preferences (humanised, conversational, em-dash rules)
  • OmniMem's own architecture note

These are among the most reliable facts in the store. They're stale precisely because they graduated: they were compiled into preferences-local, so they get loaded as a skill and never surface through direct recall. The staleness clock measures last access, and compilation removed the reason to access them.

Why it matters

The signal is inverted. A fact that recurs often enough to earn a place in a compiled skill is, by the system's own reinforcement logic, more durable than average — and the staleness metric then flags it as a cleanup candidate. Anything that acts on that list (maintenance, archival, an agent reading the briefing and deprioritising) is being pointed at the wrong end of the distribution.

There's a second-order version too: if a compiled fact eventually gets archived for staleness while the skill it fed stays live, the skill outlives its evidence. promote_knowledge() already solves exactly this for RSS articles by clearing expires_at on skill-eligible items — the reasoning in its docstring ("an article feeding a skill must not auto-archive underneath it") applies identically to episodic and preference memories that compiled into a skill, but the exemption doesn't seem to extend to them.

Suggested fix

Exempt any memory that contributed to a compiled skill from the staleness clock, mirroring what promote_knowledge() does for knowledge items. The compiler already knows its source keys at compile time, so it could mark them.

Alternative if a blanket exemption is too strong: count a skill load as an access for its source memories, so the clock reflects actual use rather than direct-recall use. More faithful, more bookkeeping.

Either way it's worth confirming what currently consumes the stale list, and whether anything archives on it automatically — that determines whether this is cosmetic or is quietly eroding the best memories in the store.

**Observed on:** 6.7.0 ## Observation Every entry in the `briefing()` stale list is at 179 days, and they are all durable preference facts: - Preferred git forge (Forgejo over GitHub) - Preferred email provider - Preferred messaging platform - Discourse as forum platform of choice - Writing style preferences (humanised, conversational, em-dash rules) - OmniMem's own architecture note These are among the most reliable facts in the store. They're stale precisely *because* they graduated: they were compiled into `preferences-local`, so they get loaded as a skill and never surface through direct recall. The staleness clock measures last access, and compilation removed the reason to access them. ## Why it matters The signal is inverted. A fact that recurs often enough to earn a place in a compiled skill is, by the system's own reinforcement logic, more durable than average — and the staleness metric then flags it as a cleanup candidate. Anything that acts on that list (maintenance, archival, an agent reading the briefing and deprioritising) is being pointed at the wrong end of the distribution. There's a second-order version too: if a compiled fact eventually gets archived for staleness while the skill it fed stays live, the skill outlives its evidence. `promote_knowledge()` already solves exactly this for RSS articles by clearing `expires_at` on skill-eligible items — the reasoning in its docstring ("an article feeding a skill must not auto-archive underneath it") applies identically to episodic and preference memories that compiled into a skill, but the exemption doesn't seem to extend to them. ## Suggested fix Exempt any memory that contributed to a compiled skill from the staleness clock, mirroring what `promote_knowledge()` does for knowledge items. The compiler already knows its source keys at compile time, so it could mark them. Alternative if a blanket exemption is too strong: count a skill load as an access for its source memories, so the clock reflects actual use rather than direct-recall use. More faithful, more bookkeeping. Either way it's worth confirming what currently consumes the stale list, and whether anything archives on it automatically — that determines whether this is cosmetic or is quietly eroding the best memories in the store.
Author
Owner

Fixed in 6.7.1 (b4822f3 on v6.7.x).

Memories listed in a compiled skill's source_manifest are now exempt from the staleness clock. Your diagnosis was exactly right: they stop being touched because they graduated — they reach sessions as part of the skill rather than through direct recall — so the metric inverted and pointed maintenance at the material the system's own reinforcement logic rates most durable.

To answer the severity question you closed on: nothing archives on the stale list today. Auto-archive covers duplicate clusters and expired RSS articles only. So this was misdirection — of maintenance, and of any agent reading the briefing and acting on it — rather than active erosion. Worth knowing that the second-order failure you describe (a skill outliving its evidence) was not yet happening, but would have been one auto-archive feature away.

One design choice worth recording. I took the blanket exemption rather than the count-a-skill-load-as-an-access alternative, and read it live from each skill's source_manifest rather than stamping a marker onto the memories at compile time. That means deleting or recompiling a skill takes the exemption with it automatically, and no marker can outlive the skill it refers to — which the stamped version would have needed bookkeeping to guarantee. promote_knowledge() solves the same problem for articles by clearing expires_at; this is the same principle applied where the compiler already knows its sources.

Fixed in 6.7.1 (`b4822f3` on `v6.7.x`). Memories listed in a compiled skill's `source_manifest` are now exempt from the staleness clock. Your diagnosis was exactly right: they stop being touched *because* they graduated — they reach sessions as part of the skill rather than through direct recall — so the metric inverted and pointed maintenance at the material the system's own reinforcement logic rates most durable. **To answer the severity question you closed on: nothing archives on the stale list today.** Auto-archive covers duplicate clusters and expired RSS articles only. So this was misdirection — of maintenance, and of any agent reading the briefing and acting on it — rather than active erosion. Worth knowing that the second-order failure you describe (a skill outliving its evidence) was not yet happening, but would have been one auto-archive feature away. **One design choice worth recording.** I took the blanket exemption rather than the count-a-skill-load-as-an-access alternative, and read it live from each skill's `source_manifest` rather than stamping a marker onto the memories at compile time. That means deleting or recompiling a skill takes the exemption with it automatically, and no marker can outlive the skill it refers to — which the stamped version would have needed bookkeeping to guarantee. `promote_knowledge()` solves the same problem for articles by clearing `expires_at`; this is the same principle applied where the compiler already knows its sources.
ric closed this issue 2026-09-08 15:12:52 +00:00
Sign in to join this conversation.
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ric/omnimem#34
No description provided.