Autonomous Skill Drafting
Wayland Core observes every completed turn and, when the same task shape succeeds three times in a row, drafts a reusable skill automatically. The resulting draft is written to disk, registered in the running session, and persisted to the PromptStore so the next session’s skill router starts with prior knowledge of it.
This is the in-session self-improvement path, separate from the offline GEPA evolutionary optimizer described in Self-Evolution (GEPA). The two complement each other: drafting crystallizes a new skill from repeated work; GEPA mutates and scores existing skills to find better phrasings.
How the loop works
Section titled “How the loop works”The U6 loop is implemented in crates/wcore-agent/src/auto_skill/ across three files: recorder.rs, bucketer.rs, and drafter.rs. The engine calls into this loop at the end of every AgentEngine::run() call (bootstrap.rs:1642).
Step 1: Turn trajectory recording
Section titled “Step 1: Turn trajectory recording”At the end of each turn, the engine builds a TurnTrajectory value (recorder.rs):
| Field | What it holds |
|---|---|
user_input | The raw text of the user’s request for this turn |
picked_skill | Which skill the SkillRouter chose, if any |
outcome | Success (natural EndTurn or ToolUse) or Failure (MaxTurns, error, abort) |
summary | Short description such as “3 turns”, used later in the draft body |
timestamp | UTC timestamp at turn end |
The struct is cheap to construct: no I/O, no locks. The engine hands it straight to the bucketer.
Step 2: Task-signature bucketing
Section titled “Step 2: Task-signature bucketing”The Bucketer (bucketer.rs) groups trajectories by a normalized signature derived from the user input. The signature algorithm:
- Lowercase the input.
- Tokenize on whitespace and ASCII punctuation.
- Drop tokens shorter than 2 characters and tokens in a fixed English stopword list.
- Deduplicate, preserving first-seen order.
- Take the top 3 tokens by length (ties broken by first-seen order).
- Sort alphabetically and join with
-.
For example, "refactor the code", "code refactor please", and "please refactor the code" all normalize to the same signature because they share the same top-3 content words. This means the streak accumulates across phrasings of the same underlying task.
An empty signature (all stopwords, very short input) is ignored silently.
A Failure outcome drops the bucket for that signature entirely, resetting the streak to zero.
Step 3: Draft trigger at N=3
Section titled “Step 3: Draft trigger at N=3”When a bucket accumulates 3 consecutive successes on the same signature, the bucketer emits a DraftTrigger containing the signature string and the three trajectories. The bucket is then cleared so the next success starts a fresh streak rather than immediately re-triggering.
The threshold is N=3, set at the call site in bootstrap.rs.
Step 4: SkillDrafter writes the skill
Section titled “Step 4: SkillDrafter writes the skill”SkillDrafter::draft() (drafter.rs) takes the DraftTrigger and writes to two locations:
Primary (loader-visible):
<config_dir>/wayland-core/skills/auto-<signature>/SKILL.md<config_dir>/wayland-core/skills/auto-<signature>/manifest.jsonThis path matches user_skills_dir() in wcore-skills::paths, so the skill loader picks it up on next boot without any additional configuration.
Secondary (legacy fallback, best-effort):
$WAYLAND_HOME/skills/auto/<signature>/SKILL.mdA failure on the secondary path is logged at WARN but does not abort the draft. A failure on the primary path does bubble up.
The manifest.json written alongside the skill contains:
{ "name": "auto-<signature>", "auto_drafted": true, "drafted_at": "<RFC3339 timestamp>", "signature": "<signature>", "evidence_count": 3, "needs_review": true, "score": 0.7, "scorer": "auto_drafter"}The SKILL.md body includes a notice about the draft status, the signature, the evidence count, and up to three example inputs from the triggering trajectories.
Step 5: In-session registration
Section titled “Step 5: In-session registration”Immediately after writing to disk, SkillDrafter calls register_bundled_skill (wcore_skills::bundled) to add the draft to the current session’s skill catalog. The strings are Box::leak-ed intentionally: plugin lifetime equals process lifetime, and the leak is bounded to one per drafted skill. The result is that the current session can invoke the skill by name without waiting for a restart.
Step 6: PromptStore persistence
Section titled “Step 6: PromptStore persistence”If the engine has a database connection, the drafter inserts an EvolvedPrompt row into the evolved_prompts SQLite table with scorer: "auto_drafter" and score: 0.7. A PromptStore failure is logged at WARN but does not prevent the on-disk draft from landing.
The score of 0.7 translates to 4 simulated successes via the seed_pairs_for formula (score × 5, rounded). This places the draft ahead of cold-start skill arms without overriding proven GEPA winners, which are seeded first at bootstrap.
Next-session hydration
Section titled “Next-session hydration”At bootstrap, the SkillRouter is seeded in layered order (bootstrap.rs:1253–1277):
- GEPA bench winners (
scorer = "bench", limit 1 per skill): highest priority. - Auto-drafted skills (
scorer = "auto_drafter", limit 1 per skill): seeded next, so real GEPA wins take precedence when both exist for the same skill name. - Prioritizer head-start: fills arms that neither GEPA nor auto-draft touched.
SkillDrafter is only installed when a real database handle is present (bootstrap.rs:1663). Without a database, drafts still land on disk but are not seeded into the router on the next boot.
Reviewing and editing a draft
Section titled “Reviewing and editing a draft”Drafted skills live under <config_dir>/wayland-core/skills/. You can inspect them with:
wayland-core --skills-auditPromote a draft to active or archive one you do not want:
wayland-core --skills-promote <PROCEDURE_ID>wayland-core --skills-archive <PROCEDURE_ID>See Skills Lifecycle for the full audit, promote, and archive workflow.
To edit a draft directly, open the SKILL.md at the path shown in the draft trigger trace and revise the body. Remove the notice block at the top when you are satisfied with the content.
Skill naming
Section titled “Skill naming”Drafted skills are named auto-<signature>. For example, three successful turns on variations of “refactor this code” might produce a skill named auto-code-refactor-review (the exact name depends on which three content words score longest after stopword stripping).
Because the name is derived from the signature rather than from a UUID, two runs that share the same top-3 content words produce the same skill name. A second draft on the same signature overwrites the prior one on disk but inserts a new row in the PromptStore (each row uses a fresh UUID v4 as its primary key).