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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions