Skip to content

SkillOpt-Sleep: target existing hand-written skills, not just the dedicated managed skill #120

Description

@jcnouwens

Context

The design spec (docs/superpowers/specs/2026-06-07-skillopt-sleep-claude-code-plugin-design.md, open question 4) poses this as an unresolved fork:

Skill target: evolve a new dedicated skillopt-sleep-managed skill, or also edit your existing hand-written skills in ~/.claude/skills?

The shipped engine took the "new dedicated skill" branch by default (config.py's managed_skill_name: skillopt-sleep-learned, always written to regardless of which skills were actually active during the harvested sessions). Question 4 was never actually decided or closed out — it's still open in the doc.

Problem

Today, cycle.py always resolves a single fixed live_skill_path via cfg.managed_skill_path() and consolidates every mined task against that one skill doc. There's no step that:

  1. Detects which existing skills (Skill tool invocations) were actually used in a harvested session, and
  2. Routes the mined tasks + proposed edits to that skill's real SKILL.md instead of (or in addition to) the generic managed skill.

There is a partial building block already in the codebase for manually targeting one existing skill — target_skill_path / target_skill_text in config.py and the keyword-relevance filter in mine.py (filter_tasks_for_target) — but it requires the user to hand-configure a single static path up front. It doesn't auto-discover multiple skills touched across sessions and doesn't fan out edits per-skill.

Proposed change

  1. harvest.py: while walking a transcript, record Skill tool-use invocations (skill name) into SessionDigest.skills_used.
  2. types.py: propagate a skill_hint onto mined TaskRecords from the session(s) they came from.
  3. mine.py: group tasks by skill_hint (tasks with no hint fall into the existing catch-all managed skill).
  4. cycle.py: loop over skill groups instead of a single fixed skill — for each, resolve the real on-disk SKILL.md (~/.claude/skills/<name>/SKILL.md or installed-plugin cache path), read it, consolidate against it independently, and stage a proposal for it.
  5. staging.py: support N staged proposed_SKILL.md files per night (one per touched skill) instead of assuming exactly one skill + one memory file; adopt needs to iterate all of them.
  6. Gate stays per-skill-group so one skill's weak signal doesn't block acceptance for another.

Why

Without this, SkillOpt-Sleep can only ever grow one generic bucket-skill from usage — it can't actually improve the skills people already wrote and use day to day (e.g. code-review, constitution, custom domain skills), which is the more valuable target for most real setups.

Happy to sketch a PR for the harvest + grouping slice (steps 1–3) first as a smaller, testable increment ahead of the staging/adopt fan-out (steps 4–6), if that's a better shape for review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions