Skip to content

Mixed-version OME queue can feed an empty approach into skill extraction #395

Description

@Kendrick-Song

PR #393 extended AgentCaseExtracted and SkillClusterUpdated with case-body fields, all defaulted so pending pre-1.2.3 events in OME's SQLite run_record queue still deserialize on upgrade.

The pure back-compat path is safe: a 1.2.2 SkillClusterUpdated deserializes with quality_score = 0.0, and everalgo short-circuits at agent_memory/skill.py:189-199 (case.quality_score < skip_quality_threshold = 0.2) returning [] with no LLM call.

The leak is one event upstream. A pending 1.2.2 AgentCaseExtracted deserializes with approach = "" / key_insight = None but a real quality_score. trigger_skill_clustering then emits a fully 1.2.3-shaped SkillClusterUpdated carrying approach = "" alongside e.g. quality_score = 0.8, which clears the 0.2 floor. The LLM is asked to distil a skill from a task_intent with an empty approach; if it responds update, _persist_skillwrite_main full-replaces the SKILL.md body — the corruption class #393 exists to prevent.

Window is narrow (upgrade with queued work) and approach = "" is not a reliable sentinel: AgentCase.approach is a required str with no normalization (memory/models.py:291), unlike key_insight which from_algo normalizes falsy → None (:321-322). So a legitimately-empty approach is indistinguishable from a back-compat default.

Options: a logger.warning + early return in extract_agent_skill when not event.approach; a schema-version field on the event; or drain the OME queue as an upgrade step. The first is cheap but carries a false-positive risk worth weighing.

Found by the whole-branch review of #393.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions