Evolve skill
Runs the §11.2 10-step evolve pipeline on one named skill — snapshot, load evals, dispatch paired subagents (A=current, B=proposed), drafter writes assertions, grader evaluates, benchmark + flip report, shadow mode, promotion gate, description optimizer, commit or archive. NEVER auto-edits a skill without passing the promotion gate; rejected attempts are archived, not deleted. TRIGGER for "evolve guild:<skill-name>", "run the evolve loop on <skill>", "re-tune this skill's description", "promote this reflection into a skill edit". DO NOT TRIGGER for creating/minting a NEW skill from a capability gap (use guild:create-skill), creating a new specialist (use guild:create-specialist), rolling back a skill version (guild:rollback-skill), reviewing runs (guild:review), composing a team (guild:team-compose), or ingesting wiki sources (guild:wiki-ingest).From its SKILL.md
npx -y skills add lookatitude/guild --skill evolve-skillAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 7 stars7 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
19.0 KB, as published. Nobody here has run it
guild:evolve-skill
Implements the self-evolution pipeline (10 steps) with two triggers: automatic when ≥3 reflections accumulate for a skill, and explicit via /guild:evolve <skill>. Runs paired-subagent evals in the skill-creator style with an AgentDevel-style flip-centered promotion gate, then commits the edit only if the gate passes. Rejected attempts are archived under .guild/evolve/<run-id>/archived/ (no destructive operations — rollbacks themselves snapshot as new versions).
This skill is a gatekeeper, not a free-form editor. It refuses to mutate a live skill file without a passed promotion gate. If the gate fails, it stops and surfaces the flip report + shadow-mode output so the user can decide.
Input
Two fields:
-
Skill slug — the target skill to evolve, e.g.
guild:context-assembleorguild:brainstorm. Must resolve to an existing liveSKILL.mdviafindLiveSkillDir(scripts/evolve-loop.ts), which checks project-instance first:.guild/skills/<slug>/(an already-evolved or project-minted instance IS the live version), then the plugin treeskills/<tier>/<slug>/(all six tiers; self-build cwd or the plugin install viaGUILD_PLUGIN_ROOT/CLAUDE_PLUGIN_ROOT). If the slug resolves nowhere, stop and hand off toskill-authorfor authoring a net-new skill instead. -
Proposed-edit description — optional when the automatic trigger fires (in which case this skill synthesizes the edit from the ≥3 accumulated reflections under
.guild/reflections/whose frontmatterproposals.skill_improvementnames the target skill); required when the explicit trigger is a user-supplied description. The edit may touch the skill body, the YAML frontmatterdescription, or both.Reading the ≥3 threshold (§11.1) is deterministic, not in-context recall. Before deciding whether the automatic trigger fires, read the aggregate
/guild:reflectalready refreshed at.guild/evolve/analyze-runs-latest.md(or regenerate it on demand if stale/absent):npx tsx ${GUILD_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-$HOME/.local/share/guild/dist/claude-code}}/scripts/analyze-runs.ts --cwd <repo-root>Its
proposals[]entries name each skill at or above--min-runs(default 3) with the contributing run ids — use that list (not a fresh in-context count over.guild/reflections/*.md) to confirm the threshold and to seed the proposed-edit synthesis with concrete evidence.
Pipeline (§11.2 10 steps)
Ten ordered steps. Each step's input and output is explicit so a later step can re-read the prior artifact without re-executing.
-
Snapshot current skill. Delegates to
scripts/evolve-loop.ts:npx tsx ${GUILD_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-$HOME/.local/share/guild/dist/claude-code}}/scripts/evolve-loop.ts --skill <skill> --run-id <run-id> --cwd <cwd> [--proposed-edit <path>]. The CLI resolves the live dir viafindLiveSkillDir—.guild/skills/<skill>/when a project instance exists, else the plugin treeskills/<tier>/<skill>/(self-build cwd orGUILD_PLUGIN_ROOT/CLAUDE_PLUGIN_ROOT) — copies it to.guild/skill-versions/<skill>/v<N>/(Nincrements monotonically), and writes.guild/evolve/<run-id>/pipeline.md(the 10-step run plan steps 2-10 read from). Exits non-zero if the slug resolves nowhere. Input:--skill/--proposed-edit. Output:.guild/skill-versions/<skill>/v<N>/+.guild/evolve/<run-id>/pipeline.md.Snapshot completeness verification (mandatory, defense-in-depth).
copyDirRecursivedoes copy the whole resolved dir — butfindLiveSkillDircan resolve DIFFERENT dirs (project instance, source tree, or a rendered plugin-install path), and the orchestrator must never assume the resolved dir was the intended one or that the copy captured every companion. Immediately after the CLI runs, diff the snapshot's file list against the intended live skill dir (companions likedispatch.md-siblings included); on any mismatch, stop and reconcile (wrong dir resolved → re-run against the right one; genuinely missing file → supplement from VCS) before step 2 proceeds. The check costs onels; an unverified snapshot silently corrupts every downstream A-variant artifact. (Provenance note: an earlier cycle wrongly asserted the script skips companions — a probe disproved it; the verification stands on the resolution-variance rationale above, not on that withdrawn claim.) -
Load evals. Read
evals.jsonfrom the step-1 live dir. If fewer than 3 positive + 3 negative cases (insufficient for paired evaluation), bootstrap 2–3 additional cases from the accumulated reflections'proposals.skill_improvementevidence snippets (per§11.2step 2). Behavioral scenarios do not belong inevals.json.evals.jsonis trigger-fixture-only — the trigger-fixture runner iterates exclusively over itsshould_trigger/should_not_triggerarrays; ascenariosarray bolted ontoevals.jsonis dead weight the runner never executes (run-20260718-043952-evolve-learn-onboarddid exactly this — appended ascenariosarray toevals.jsonalongside the trigger arrays — and it went unexercised by the runner). Convention: author behavioral scenarios in a sidecarskills/<tier>/<skill>/scenarios.json, carrying an explicit top-level note (e.g."executed_by": "manual/agent judgment only — not the trigger-fixture runner") so a reader never mistakes it for runner-covered. Input:<live-dir>/evals.json+<live-dir>/scenarios.json(if present) +.guild/reflections/*.md. Output:.guild/evolve/<run-id>/evals.json(merged trigger-fixture working set) +.guild/evolve/<run-id>/scenarios.json(merged behavioral-scenario working set) — both carried forward into the evolve dir even though only the former is runner-executed. -
Dispatch paired subagents. Spawn two subagents in the same turn. A = current skill (from the snapshot in step 1), B = proposed edit (from Input #2). For a net-new skill (slug does not yet exist), A = no-skill baseline (skill disabled) and B = proposed. Feed each the merged eval working set from step 2. Dispatches are live, not simulated — real subagent invocations captured with
--output-format jsonto record per-case wall-clock duration and token usage (this feeds step 6'sduration_ms/total_tokensdeltas directly; it is not estimated after the fact). Behavioral-scenario fixtures come from the step-2scenarios.jsonworking set, whose per-scenario answer keys are pre-declared in the sidecar itself, before any dispatch — step 4 converts them (plus the trigger-fixture expectations) intoassertions.json; grading in step 5 runs only against those pre-declared keys, never a post-hoc judgment of what a transcript happened to show. Input: snapshot + proposed edit + the step-2 evals AND scenarios working sets. Output:.guild/evolve/<run-id>/runs/{A,B}/with per-case timed trajectories. -
Drafter writes assertions. In parallel with step 3's runs, a drafter subagent derives per-case assertions from BOTH working sets: trigger expectations from the eval cases, and behavioral expectations transcribed from
scenarios.json's pre-declared answer keys (the keys already exist before dispatch — this step formats them into the assertion schema, it never invents or revises them after trajectories exist). Input: merged evals + merged scenarios. Output:.guild/evolve/<run-id>/assertions.json. -
Grader evaluates. Grader subagent reads
runs/{A,B}/+assertions.jsonand emits a per-case pass/fail with rationale. Variance disclosure. A single-sample A judgment on a body-ambiguous case can vary between samples (run-20260718-145447-evolve-execute-plantook two A samples and they diverged across the case set). B must pass ALL cases in every sample taken, not merely the retained one; any observed A-sample variance is disclosed verbatim ingate.json— never silently averaged into one number. A sample that was overwritten or whose trajectories were not retained is declared unverified ingate.jsonand excluded from promotion claims (that run'ssampling_note, which flags its own overwritten sample-1 as unverified and rests all claims on sample-2 alone, is the reference shape). Input: trajectories + assertions. Output:.guild/evolve/<run-id>/grading.json. -
Benchmark + flip report. Delegates to
scripts/flip-report.ts. Computespass_rate,duration_ms,total_tokens, mean ± stddev, and the delta between A and B. Classifies each case as P→P (stable pass), F→F (stable fail), P→F (regression), or F→P (fix). Input:grading.json. Output:.guild/evolve/<run-id>/flip-report.mdwith structured YAML frontmatter (regressions, fixes, pass_rate, duration_ms, total_tokens deltas) thatguild:statsand the promotion gate can parse.flip-report.mdMUST be generated byscripts/flip-report.tsfrom agrading.jsonin its required schema —{current, proposed}arrays of{case_id, passed, ms, tokens}— never hand-authored. A hand-written flip-report.md is not valid gate evidence, full stop; bothrun-20260718-043952-evolve-learn-onboardandrun-20260718-145447-evolve-execute-planhit and enforced exactly this rule. -
Shadow mode. Delegates to
scripts/shadow-mode.ts. Replays the proposed skill (B) against the prompts recorded in historical run traces under.guild/runs/<id>/events.ndjsonwithout changing live routing — for each historicalUserPromptSubmitprompt it derives B's TRIGGER / DO NOT TRIGGER tokens from the proposed description, decides whether B would fire, and counts divergences against the skill the trace historically routed to, per§11.2step 7. Input: proposed skill +.guild/runs/. Output:.guild/evolve/<run-id>/shadow-report.mdwith YAML frontmatter emitted by the script:skill,proposed_name,historical_runs,total_prompts,total_divergences,divergence_rate.shadow-report.mdMUST likewise be generated byscripts/shadow-mode.ts— the same invalidity rule as step 6'sflip-report.mdapplies; a hand-writtenshadow-report.mdis not valid gate evidence (both cycles above enforced this too). -
Promotion gate. Promote B if ANY of the four conditions holds:
- 0 regressions AND ≥1 fix (pure improvement).
- No flip change AND total_tokens ↓ ≥10% (cost win without behavior change).
- Regressions present AND user approves via review viewer (explicit override — gate surfaces the flip report + shadow-mode output and blocks until the user acknowledges).
- Doc-only fast-path — the proposed edit is classified doc-only: no change to trigger phrasing, no change to body algorithm, no change to
should_trigger/should_not_triggereval cases; only prose, description, comments, or additive clarifying sections that codify existing valid behavior. A doc-only edit produces no observable behavior delta in paired evals (no fixes, no regressions, no token change — the pipeline cannot distinguish silence from a real pass). Such edits MAY promote under explicit user approval, recorded ingate.jsonascondition: doc-only-fast-pathwith the user's acknowledgement timestamp. User approval MUST be obtained before this condition is triggered (a blanket session directive from the operator qualifies; a run-time prompt also qualifies). Scope boundary: this condition applies ONLY when the diff contains zero body-logic changes. If any trigger phrase, algorithm step, or eval case is altered, the full three-condition gate applies — the doc-only path is NOT available as a fallback. This carve-out must NOT become a backdoor for behavior-change promotions. Motivating runs:evolve-doc-clarification-20260528-134115(prior session, three skills post §11.1 threshold) andrun-learn-knowledge-convergence-20260529-094021(this initiative's reflection, §C.2 finding). Both hit the gate because pure documentation clarifications are eval-invisible; archiving them would have discarded valid improvements with no safety benefit.
B-reproducibility invariant (mandatory, gate-time). At gate time, every B-proposed file MUST be byte-identical to the live working-tree file it will replace — including companion files and sidecars introduced by the edit itself (
dispatch.md-style siblings,scenarios.json), not justSKILL.md— with each file's full SHA-256 recorded ingate.jsonunder ab_reproducibilityblock (paired<file>_sha256/live_<file>_sha256keys, one pair per touched file; truncated hashes do not satisfy this). The two 2026-07-18 runs are the motivating precedent (their records evolved toward this shape across codex rounds; this clause is the normative form). Any drift between the recorded B and the live tree invalidates the recorded hashes — the gate never stands on stale hashes. On drift: resync B to the live bytes and re-record every hash pair; a doc-only delta additionally gets a named delta note ingate.json(the gate's behavioral evidence remains valid); a behavioral delta re-runs the paired eval (steps 3-6) before promotion stands. This is the same rule scenarioS2-b-drift-at-gateevaluates: resync-and-re-establish, never proceed on a stale record.Gate result is recorded at
.guild/evolve/<run-id>/gate.jsonwith the triggering condition (condition: doc-only-fast-pathfor the fourth path, plususer_approved_attimestamp), and MUST additionally recordflip_source/shadow_sourcefields naming the generating script (per steps 6-7's real-script requirement) —gate.jsonis the provenance record provingflip-report.md/shadow-report.mdweren't hand-authored, not just the verdict. -
On promote: description optimizer + commit. Delegates to
scripts/description-optimizer.ts— trains on the skill'sshould_trigger/should_not_triggereval cases, fixes under-triggers and false triggers, keeps the final description ≤1024 chars per§11.2step 9. Then writes the edited skill back to the consuming repo's.guild/skills/<skill>/project instance — the v1 write-back toskills/<tier>/<skill>/(plugin install state) is an explicit v2 DH-3 defect being fixed: the plugin install dir is never written at runtime. The promote choke-point is preserved verbatim (step 9 is still the only writer, the gate still the only unlock); only the write target moves under.guild/. Then bumps the version folder in.guild/skill-versions/<skill>/v<N>/(UNCHANGED — already correct under.guild/; the snapshot from step 1 is now the pre-edit record), and updatesevals.json/scenarios.jsonif new cases were added in step 2. The evolved instance retains itsderived_from_template: guild.skill_template.v1stamp — a reflection-driven evolve never strips or rewrites it.Resource-sync-before-review ordering (mandatory). When the edited skill lives under
plugin/skills/**(self-build), runsync:module-resourcesand confirm both its--checkpasses go green — theresources/mirror and any per-hostdist/copy — before any codex adversarial review (G-lane, perplugin/AGENTS.md§Codex adversarial review) runs against the edited skill, and before commit. The tree codex reviews must be the shippable tree; running sync after codex approves invalidates that approval, since codex signed off on a tree that was not what actually ships.run-20260718-145447-evolve-execute-plan's codex gate hit exactly this ordering defect as a BLOCKER at round 1 — sync must precede review, not follow it. Only after sync is green and codex clears does the lead commit. -
On reject: archive attempt. Move the proposed edit (body + frontmatter diff + flip report + shadow-mode output + gate verdict) to
.guild/evolve/<run-id>/archived/for future iterations per§11.2step 10. The live skill is left untouched.
Artifacts
Two directories, by convention:
.guild/skill-versions/<skill>/v<N>/— pre-edit snapshots, one per evolve run. Monotonically versioned per§11.3. Used byguild:rollback-skillto walk back the stack..guild/evolve/<run-id>/— per-run workspace. Containspipeline.md(run plan),evals.json(merged trigger-fixture set),scenarios.json(merged behavioral-scenario set, if any live-dirscenarios.jsonsidecar existed — not runner-executed),assertions.json,runs/{A,B}/(timed trajectories),grading.json,flip-report.md(script-generated, YAML frontmatter + human summary),shadow-report.md(script-generated, YAML frontmatter + human summary),gate.json(verdict +b_reproducibilityhashes +flip_source/shadow_sourceprovenance), and on rejection a fullarchived/subtree.
Non-destructive rule
This skill NEVER edits a live skill file without passing the promotion gate. The gate is the single choke point; step 9 is the only writer to the consuming repo's .guild/skills/<skill>/. Rejected attempts are archived under .guild/evolve/<run-id>/archived/, never deleted — a future iteration can re-open an archived attempt and re-run the pipeline with different inputs. Per §11.3, rollbacks themselves snapshot as new versions, so there is no destructive path through this skill.
If the gate returns "regressions present" and the user declines to approve, stop. Do not re-prompt, do not soft-merge a partial edit, do not suggest "just fix the description." Archive and hand control back.
Handoff
Emit a handoff block naming the evolve run and gate outcome so the orchestrator can route downstream:
- On promote: emits a summary to
/guild:stats(the promoted version + flip report highlights) so the next/guild:statssurfaces the evolved skill. If the user later invokes/guild:rollback <skill>, the snapshot taken in step 1 is the target. - On reject: emits the archived-attempt path + the gate's triggering-condition rationale. The user may re-run with a refined proposed edit; the archived attempt is re-openable.
Payload fields: run_id, skill, gate_outcome (promoted / rejected), flip_summary (regressions: N, fixes: N, token_delta: ±X%), version_path (the .guild/skill-versions/<skill>/v<N>/ snapshot), and archived_path (only on reject).