Problem
MemOS crystallizes candidate skills from policies, but the agent is expected to call memos_skill_get to trigger skill trials. In practice (especially Hermes adapters) this call never happens. Result: candidate skills with 0 trials, 0 active.
Root cause: the trial loop requires agent participation (memos_skill_get + reward.updated), creating a deadlock when the agent ignores candidate skills.
Solution
Non-repair candidate skills already carry a quality signal — eta encodes the gain/support of source policies. Skip the trial loop and promote directly when eta >= minEtaForRetrieval (default 0.1).
Repair-origin skills still require a trial pass.
Changes (3 files, ~30 lines)
- core/skill/lifecycle.ts — add shouldPromoteCandidate()
- core/skill/subscriber.ts — add lifecycleTick()
- core/pipeline/orchestrator.ts — call lifecycleTick() after skills.flush()
Each flush() (per episode close) scans candidates and promotes eligible ones. No DB schema changes, no config changes.
Problem
MemOS crystallizes candidate skills from policies, but the agent is expected to call memos_skill_get to trigger skill trials. In practice (especially Hermes adapters) this call never happens. Result: candidate skills with 0 trials, 0 active.
Root cause: the trial loop requires agent participation (memos_skill_get + reward.updated), creating a deadlock when the agent ignores candidate skills.
Solution
Non-repair candidate skills already carry a quality signal — eta encodes the gain/support of source policies. Skip the trial loop and promote directly when eta >= minEtaForRetrieval (default 0.1).
Repair-origin skills still require a trial pass.
Changes (3 files, ~30 lines)
Each flush() (per episode close) scans candidates and promotes eligible ones. No DB schema changes, no config changes.