Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Improves a voice profile by learning from manual edits. Use after editing generated text to refine registers and close voice drift over time.
.claude/skills/athola-voice-learn/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 79% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 12% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 79% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 42% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 48% | 0% |
Learn from user edits to improve the voice profile over time.
scribe:voice-extract)scribe:voice-review)
Every piece flows through three stages:
The learning agent compares stages 2 and 3 (post-review vs post-edit) to identify patterns in what the user changed. These patterns inform register and rule updates.
patterns. Rule bloat degrades output.
registers. Universal patterns go to craft rules or agents.
require user resolution.
matching existing accumulator entries) before becoming rules.
detectability. Craft-level changes are neutral. Prefer craft-level updates.
has 8+ rules.
voice-learn:snapshots-loaded - All three stages readvoice-learn:diff-analyzed - Changes categorizedvoice-learn:accumulator-checked - Prior patterns reviewedvoice-learn:proposals-generated - Updates proposedvoice-learn:user-approved - Changes accepted by userLoad: @modules/snapshot-management
bashPROFILE_DIR="$HOME/.claude/voice-profiles/{name}" SNAP_DIR="$PROFILE_DIR/learning/snapshots" # Find the most recent snapshot set # Format: {piece-name}-{timestamp}-{stage}.md
Read all three stages for the target piece.
Load: @modules/pattern-analysis
Compare post-review vs post-edit. Categorize every change:
| Category | Example | |----------|---------| | Tone adjustment | Softened a claim, added hedge | | Voice insertion | Added parenthetical, aside, humor | | Structure change | Broke paragraph, reordered | | Precision edit | Replaced vague with specific | | Deletion | Removed fluff or decoration | | Addition | Added context, example, anchor |
Read learning/accumulator.json:
json{ "patterns": [ { "id": "pat-001", "category": "tone_adjustment", "description": "Softens confident claims about tool capabilities", "instances": [ {"piece": "blog-post-1", "date": "2026-04-08", "diff": "..."} ], "target": "register", "status": "accumulating", "first_seen": "2026-04-08", "last_seen": "2026-04-08" } ], "staleness_threshold_days": 30 }
Match new changes against existing patterns:
For patterns that reach threshold (3+ instances or 1-2 matching prior accumulator entries with 2+ instances):
markdown## Proposed Update **Pattern**: {description} **Target**: {register file or craft-rules.md} **Evidence**: {N instances across M pieces} | Piece | Date | Change Made | |-------|------|-------------| | ... | ... | ... | **Proposed edit**: - File: {path} - Section: {section name} - Current: "{current text or 'new addition'}" - Proposed: "{new text}"
Add to accumulator with current instances. Report:
Holding: "{pattern description}" (N instances, need 3+)If a new pattern contradicts an existing accumulator entry:
Contradiction detected:
- Existing: "{accumulator pattern}"
- New: "{contradicting pattern}"
- Resolution required: user must choosePresent proposals to user:
Learning found N patterns ready to apply:
[1] {pattern}: {proposed change}
Evidence: {N instances}
[a]pply / [s]kip / [v]iew evidence?
[2] ...Apply approved changes to the target files.
Patterns in the accumulator expire after staleness_threshold_days (default 30). If a pattern hasn't recurred within that window, it was likely a one-off preference rather than a voice trait.
On each learning pass, prune stale entries:
bash# Remove patterns older than threshold with < 3 instances
The learning system captures snapshots automatically when voice-review completes. Snapshot naming:
{piece-filename}-{YYYYMMDD-HHMMSS}-pre-review.md
{piece-filename}-{YYYYMMDD-HHMMSS}-post-review.md
{piece-filename}-{YYYYMMDD-HHMMSS}-post-edit.mdThe post-edit snapshot is captured when the user runs /voice-learn after finishing their manual edits.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 3,608 | 16,553 | +359% | 1 | 1 | 0% | 565 | 2,497 | +342% | 0 | 0 | — |
case-02 | fail→fail | 5,287 | 8,279 | +57% | 1 | 1 | 0% | 816 | 1,730 | +112% | 0 | 0 | — |
case-03 | fail→fail | 4,694 | 5,878 | +25% | 1 | 1 | 0% | 812 | 1,677 | +107% | 0 | 0 | — |
case-04 | fail→pass | 6,755 | 3,919 | -42% | 1 | 1 | 0% | 1,122 | 2,003 | +79% | 0 | 0 | — |
case-05 | fail→fail | 2,425 | 3,559 | +47% | 1 | 1 | 0% | 294 | 1,857 | +532% | 0 | 0 | — |
case-06 | fail→pass | 17,068 | 9,652 | -43% | 1 | 1 | 0% | 2,595 | 2,909 | +12% | 0 | 0 | — |
case-07 | pass→pass | 6,287 | 5,019 | -20% | 1 | 1 | 0% | 850 | 2,246 | +164% | 0 | 0 | — |
case-08 | fail→pass | 6,851 | 3,007 | -56% | 1 | 1 | 0% | 979 | 1,752 | +79% | 0 | 0 | — |
case-09 | fail→pass | 10,204 | 4,659 | -54% | 1 | 1 | 0% | 1,516 | 2,152 | +42% | 0 | 0 | — |
case-10 | pass→pass | 10,859 | 4,100 | -62% | 1 | 1 | 0% | 1,657 | 1,965 | +19% | 0 | 0 | — |
case-11 | fail→pass | 12,249 | 9,168 | -25% | 1 | 1 | 0% | 1,891 | 2,790 | +48% | 0 | 0 | — |
case-12 | fail→pass | 12,172 | 3,394 | -72% | 1 | 1 | 0% | 1,732 | 1,913 | +10% | 0 | 0 | — |
case-13 | pass→pass | 5,107 | 2,724 | -47% | 1 | 1 | 0% | 696 | 1,787 | +157% | 0 | 0 | — |
case-14 | pass→pass | 9,059 | 3,758 | -59% | 1 | 1 | 0% | 1,268 | 1,971 | +55% | 0 | 0 | — |
case-15 | fail→pass | 11,855 | 2,727 | -77% | 1 | 1 | 0% | 1,801 | 1,745 | -3% | 0 | 0 | — |
case-16 | fail→fail | 10,739 | 3,420 | -68% | 1 | 1 | 0% | 1,690 | 1,921 | +14% | 0 | 0 | — |
case-17 | pass→pass | 7,963 | 4,355 | -45% | 1 | 1 | 0% | 1,255 | 2,064 | +64% | 0 | 0 | — |
case-18 | fail→pass | 7,248 | 4,076 | -44% | 1 | 1 | 0% | 1,060 | 1,980 | +87% | 0 | 0 | — |
case-19 | fail→pass | 7,165 | 5,173 | -28% | 1 | 1 | 0% | 1,076 | 2,265 | +111% | 0 | 0 | — |
case-20 | pass→pass | 14,028 | 5,471 | -61% | 1 | 1 | 0% | 2,111 | 2,326 | +10% | 0 | 0 | — |
case-21 | fail→pass | 21,852 | 2,453 | -89% | 1 | 1 | 0% | 2,006 | 1,775 | -12% | 0 | 0 | — |
case-22 | fail→pass | 11,132 | 3,046 | -73% | 1 | 1 | 0% | 1,922 | 1,929 | +0% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 20 counted toward the lift figure. The other 2 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +50 percentage points is the difference between those two pass rates over the 20 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.