| name | myco:operate-skill-lifecycle-pipeline |
| description | Use this skill when working with Myco's skill lifecycle system — whether generating a new skill from an approved candidate, reviewing the candidate queue, updating a stale skill, retiring an outdated one, or debugging why a skill wasn't triggered. Activates whenever you touch vault_skill_candidates, vault_skill_records, or vault_write_skill — or whenever the user asks about skills, the Skills dashboard, skill generation tasks, or the .agents/skills/ directory. Apply this skill even if the user doesn't explicitly say "skill lifecycle" — any time a task involves producing or updating a SKILL.md file, evaluating candidates, or managing skill status, this procedure applies. |
| managed_by | myco |
| user-invocable | true |
| allowed-tools | ["Read","Edit","Write","Bash","Grep","Glob"] |
Operating the Myco Skill Lifecycle Pipeline
Hands-on reference for managing skill candidates, skill records, and SKILL.md files using Myco's agent tools and Skills dashboard.
Pipeline Architecture and Scheduling
Asymmetric scheduling defaults reflect a deliberate progressive disclosure model:
skill-survey is enabled: true (auto-runs during idle, discovers candidates without user intervention)
skill-generate and skill-evolve are enabled: false (require explicit opt-in)
This prevents runaway generation costs while ensuring candidate discovery happens automatically.
Survey quality transformation: The survey pipeline now runs cluster-first (grouping related spores before proposing candidates), producing 5 domain-scoped candidates vs the old pipeline's 102 candidates with 74.5% dismissed. This dramatically improves signal-to-noise ratio.
Tool Reference
vault_skill_candidates
Manages skill candidates — knowledge clusters identified as potential skills.
// List by status
vault_skill_candidates(action: "list", status: "identified"|"approved"|"dismissed"|"generated")
// Get single candidate
vault_skill_candidates(action: "get", id: "<uuid>")
// Approve a candidate
vault_skill_candidates(action: "update", id: "<uuid>", status: "approved", rationale: "...")
// Create a candidate manually
vault_skill_candidates(action: "create", topic: "...", rationale: "...")
Status lifecycle: identified → approved → generated. Dismiss with status: "dismissed".
UI Labels: In the Skills dashboard, "Approved" status is labeled "Awaiting generation" for clarity. Use the combined "Approved & generated" filter to see the full pipeline progress.
vault_skill_records
Manages materialized skill records (the DB representation of files on disk).
// List active/stale/retired skills
vault_skill_records(action: "list", status: "active"|"stale"|"retired")
// Get a specific skill (by name or UUID)
vault_skill_records(action: "get", id: "<name-or-uuid>")
// Retire a skill
vault_skill_records(action: "update", id: "<uuid>", status: "retired")
vault_write_skill
Staging-based workflow: vault_write_skill now writes to .myco/staging/skills/<candidate_id>/SKILL.md as a provisional draft. The skill remains in staging until promoted via vault_finalize_skill (human approval required).
vault_write_skill(
name: "kebab-case-name", // directory name — no myco: prefix here
display_name: "Title",
description: "triggering description",
content: "<full SKILL.md with frontmatter>",
source_ids: "id1,id2", // optional: comma-separated spore IDs
rationale: "what changed", // optional: written into lineage
candidate_id: "<uuid>" // required for staging workflow
)
Quality gate enforces at write time:
- YAML frontmatter with all required fields
name: myco:<name> prefix
managed_by: myco
user-invocable field present
allowed-tools containing Claude Code tool names only — vault_* names are rejected
- ≤500 lines total
Security enforcement: Agents cannot self-promote skills from staging to live. The vault_finalize_skill tool requires human review and explicit approval.
vault_finalize_skill
Promotes a staged skill draft to the live .agents/skills/ directory and creates the corresponding skill record.
vault_finalize_skill(candidate_id: "<uuid>")
This tool is human-only — agents cannot call it directly. It provides the final quality gate and audit trail via approved_at timestamps.
Producing a SKILL.md File
From an approved candidate (staging workflow)
- Get the candidate:
vault_skill_candidates(action: "get", id: "<uuid>")
- Search for related spores:
vault_search_semantic(query: "<topic>", limit: 10)
- Write to staging: use
vault_write_skill with candidate_id parameter
- Human review required: The skill remains in
.myco/staging/ until promoted
- After promotion, the candidate status automatically updates to
generated
Updating an existing skill
- Get current record:
vault_skill_records(action: "get", id: "<name>")
- Read the file at the
path field to see current content
- Identify what changed — update only the affected sections
- Write with
rationale describing what was updated
- Direct write to live: Skill updates bypass staging and write directly to
.agents/skills/
Critical when updating: Check allowed-tools in the existing frontmatter before carrying it forward. If it contains vault_* names (vault_create_spore, vault_search_semantic, vault_write_skill, etc.), replace them with Claude Code tools. The gate will reject the write otherwise. See Contamination section below.
Hand-authoring skills in feature PRs
When manually creating or editing skills during development (e.g., in a feature branch), additional symlink setup is required for discoverability in Claude Code and Cursor:
- Create or edit the skill in
.agents/skills/<name>/SKILL.md as usual
- Create symlinks for editor discovery:
mkdir -p .claude/skills/
ln -sf ../../.agents/skills/<name> .claude/skills/<name>
mkdir -p .cursor/skills/
ln -sf ../../.agents/skills/<name> .cursor/skills/<name>
- Commit both the skill and the symlinks to your feature branch
- The symlinks ensure the skill is discoverable during manual authoring sessions
Without these symlinks, hand-authored skills remain invisible to Claude Code and Cursor even though they exist in .agents/skills/. The editors only scan their respective skill directories (.claude/skills/ and .cursor/skills/) during session startup.
Splitting an oversized skill
- Identify distinct procedures in the current skill
- Write each as a new focused skill with its own name and description
- Retire the parent:
vault_skill_records(action: "update", status: "retired")
Retiring a skill
vault_skill_records(action: "update", id: "<uuid>", status: "retired")
Retiring preserves the record and lineage but removes the skill from the active pool. Use when a skill has been superseded by focused replacements or the procedure is no longer applicable.
Frontmatter Requirements
Every SKILL.md must contain all six required fields in its YAML frontmatter:
| Field | Requirement |
|---|
name | myco:<kebab-case-name> — must match directory name |
description | Triggering description — primary matching signal for Claude Code |
managed_by | Always myco |
user-invocable | Always true for developer-facing skills |
allowed-tools | Claude Code tools only: Read, Edit, Write, Bash, Grep, Glob |
Omitting any of these fields causes a vault_write_skill rejection, even if the field was present in a prior version. Mid-session rewrites that regenerate frontmatter from scratch are a common source of silent omissions.
Diagnosing vault_write_skill Rejections
3-gate dedup check runs before any file is written: (1) same-name match routes to the evolve path rather than rejecting outright, (2) fulfilled-candidate guard rejects if the candidate_id already links to a different skill, (3) Jaccard description similarity gate rejects at threshold 0.4. If the DB write fails after the file is created, the file is atomically removed to prevent orphans.
The tool returns a descriptive error identifying the failing constraint:
| Error | Fix |
|---|
allowed-tools contains vault_* names | Replace with Claude Code tools: Read, Edit, Write, Bash, Grep, Glob |
missing managed_by: myco | Add managed_by: myco to frontmatter |
missing user-invocable | Add user-invocable: true to frontmatter |
missing name with myco: prefix | Ensure name: myco:<skill-name> in frontmatter |
name contains path traversal | Remove /, \, or .. from the name parameter |
exceeds 500 lines | Trim content or split into sub-skills |
Candidate ... is already fulfilled by skill "..." | The candidate_id is already linked to a different skill. Write to that skill's name to evolve it, or omit candidate_id. |
Description overlaps with existing active skill "..." (Jaccard X.XX, threshold 0.4) | Proposed description is too similar to an existing skill. Reframe to cover a distinct procedure, or write to the existing skill's name to evolve it. |
allowed-tools Contamination
The vault_write_skill gate was added specifically because of a silent propagation bug: when skill evolution tasks preserve existing frontmatter fields, they faithfully copy vault_* names from a contaminated skill into every subsequent evolution. The preservation rule is not a validator.
Contamination propagation path:
- A skill has vault_* names in
allowed-tools (e.g., generated when the spec was wrong)
- skill-evolve is run; the LLM preserves all frontmatter fields as instructed
- The evolved version carries the bad values forward
- vault_write_skill now rejects at write time — the error surfaces the bug
How to fix a contaminated skill: Read the current allowed-tools in the file, replace any vault_* names with Read, Edit, Write, Bash, Grep, Glob, and rewrite via vault_write_skill.
Structural Enforcement vs Prompt Rules
Security hardening pattern: The pipeline now uses structural gates instead of advisory prompt rules. Three coordinated bug fixes closed gaps between prompt suggestions and actual enforcement:
- Agent self-promotion blocked: Agents cannot call
vault_finalize_skill directly
- Quality gates enforced at write-time: Invalid frontmatter is rejected, not just warned about
- Audit trail required:
approved_at timestamps track human approval events
This follows the principle: Enforce constraints in tools, not prompts. Prompts are suggestions; tools are gates.
Debugging Why a Skill Wasn't Triggered
Skills are loaded by Claude Code when the frontmatter description matches the current session context. Diagnosis checklist:
- File present? Check
.agents/skills/<name>/SKILL.md exists on disk
user-invocable: true? Open the file and verify this field is present and true
- Description broad enough? The description is the only matching signal. Too narrow = fewer matches. Compare it to the actual task context.
- Description degraded? Check if the skill was evolved in the last run — the rewrite may have shortened the description (see Over-Evolution section below). Compare with the previous generation.
- allowed-tools correct? Confirm
allowed-tools lists Claude Code tools only
- Still in staging? Check if the skill is stuck in
.myco/staging/ awaiting promotion
- Symlinks present? For hand-authored skills, verify
.claude/skills/ and .cursor/skills/ symlinks exist
Diagnosing skill-evolve Over-Evolution
Symptom: A skill was classified STALE and rewritten, but the result is worse — shorter description, missing sections, generic phrasing — with no new factual content added.
Root cause: skill-evolve classified STALE on cosmetic phrasing differences rather than a substantive factual change. Without an explicit bias-toward-CURRENT directive, LLM rewrites interpret any new context as justification to refactor. This creates a regression loop:
- Descriptions get shorter → triggering coverage silently degrades
- Detailed sections get consolidated → diagnostic value lost (e.g., machine_id regression steps, budget sizing math)
- Phrasing becomes generic → precision lost
The rewritten skill passes all validation checks but is structurally degraded.
Fix steps:
- Check skill evolution task configuration — it must have an explicit "bias toward CURRENT unless there is a substantive factual change" instruction and a "do NOT restructure sections that are still correct" directive
- Identify the previous generation via vault_skill_records lineage
- Compare the description — if shortened, triggering coverage is degraded
- Rewrite to restore description coverage plus any actual new knowledge
The standard for STALE: A new behavior, a fixed bug, a changed API, or a discovered gotcha that the current skill gets factually wrong. Cosmetic phrasing differences are not sufficient.
skill-evolve Watermark Behavior
Pre-filtering and no-op semantics: The skill-evolve system uses watermark timestamps to optimize runs and prevent redundant processing:
- Run-level deduplication: Skills already assessed in the current run (matching
skill_evolve_last_run timestamp) are automatically excluded from assessment to prevent duplicate analysis within a single execution
- Knowledge watermark filtering: Only skills with new knowledge since their
last_assessed_at timestamp are eligible for evolution, creating an efficient change-detection mechanism
- No-op run detection: When no skills qualify for evolution after pre-filtering (either due to recent assessment or lack of new knowledge), the entire run becomes a no-op — the agent reports completion without making any changes
- Watermark rotation: The
last_assessed_at watermark is updated even when a skill is classified as CURRENT, ensuring proper rotation coverage in subsequent runs and preventing the same skill from being unnecessarily re-assessed
Practical implications: This watermark system explains why skill-evolve runs often complete quickly with "no changes needed" — either all candidate skills have already been assessed, or new vault knowledge doesn't warrant updates. The system is designed to be efficient and avoid redundant work, making frequent skill-evolve runs safe and cost-effective.
Budget Sizing for skill-evolve Runs
skill-evolve runs are multiplicative in agent turn cost. Each STALE skill rewrite costs ~8–10 turns (read + knowledge searches + write). Size the budget for worst-case STALE count:
Assess phase: ~1.5 turns/skill × (number of active skills)
Evolve phase: ~10 turns/rewrite × (number of STALE skills)
Task maxTurns: sum of phase budgets + ~5 turns overhead
Recommended configuration for up to 3 STALE skills:
Task-level configuration pattern follows the standard phased executor structure with maxTurns and timeoutSeconds at the task level, and per-phase budget allocation within individual phase configurations.
Task level: maxTurns: 60, timeoutSeconds: 1800
Assess phase: maxTurns: 20
Evolve phase: maxTurns: 35
Silent failure mode: If maxTurns is too low, the run ends "normally" but stops mid-rewrite with no error message. Always verify that the expected STALE skills were actually updated — check their generation number and updated_at after the run.