From tl
Use when an agent's performance is uneven and you want systematic improvement. Runs diagnose -> challenge-gen -> challenge-run -> update learnings in a loop. Works with or without a team. Keywords: active-learn, training, adversarial, improve, agent, loop, capability, tuning, solo.
How this skill is triggered — by the user, by Claude, or both
Slash command
/tl:active-learn <agent-name> [rounds=3]<agent-name> [rounds=3]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are running **active-learn** -- the full adversarial training loop that diagnoses an agent's weaknesses, generates targeted challenges, executes them in rounds, and persists confirmed learnings. This is the capstone orchestrator of the active learning system.
You are running active-learn -- the full adversarial training loop that diagnoses an agent's weaknesses, generates targeted challenges, executes them in rounds, and persists confirmed learnings. This is the capstone orchestrator of the active learning system.
Target agent: $ARGUMENTS
Parse arguments (agent name, round count)
-> Phase 1: Diagnose (inline profiling from learnings + git signals)
-> Phase 2: Generate challenges (inline, 3-5 per round)
-> Phase 3: Execute round (Task dispatch, serial, evaluate inline)
-> Phase 4: Learn (update learnings.md, write capability.yaml)
-> Re-diagnose: compare to previous struggle profile
-> If new weaknesses found: loop to Phase 2
-> If no new weaknesses or max rounds reached: emit training summary
Extract from $ARGUMENTS:
rounds=N, default 3)Example inputs: skill-author, rust-dev rounds=5, infra rounds=2
If $ARGUMENTS is empty:
.claude/team.yaml and list available agent namesDetermine operating mode by attempting to read .claude/team.yaml:
If .claude/team.yaml exists AND the agent name is found in members:
role, model, and owns patterns from the fileIf .claude/team.yaml does not exist OR the agent name is not found in it:
main-session for this run.claude/tackline/memory/agents/<name>/ now use .claude/tackline/memory/agents/solo/ insteadrole is "main session", model is the current model, and owns is treated as the full project (no pattern filtering in git analysis)$ARGUMENTS was empty and team.yaml also does not exist, skip listing available agents -- instead prompt: "Which topic or skill area should I train on? (No team.yaml found -- running in solo mode.)"Read .claude/tackline/memory/agents/<name>/learnings.md (team mode) or .claude/tackline/memory/agents/solo/learnings.md (solo mode) if it exists -- note current line count as the baseline.
Check for existing capability tracking:
.claude/tackline/memory/agents/<name>/capability.yaml if it exists.claude/tackline/memory/agents/solo/capability.yaml if it existsDo not proceed until:
solo (solo mode)Build a struggle profile from historical evidence. This embeds the approach from /diagnose-agent.
Read the agent's learnings history from git:
# Edit timeline
git log --oneline --follow -- .claude/tackline/memory/agents/<name>/learnings.md
# Actual diffs to see what changed
git log -p --follow -- .claude/tackline/memory/agents/<name>/learnings.md
Parse the diffs to extract:
In team mode, read .claude/team.yaml to extract the agent's owns patterns. In solo mode, no owns filtering applies -- analyze all project files.
git log --oneline --since="30 days ago" -- <owns-patterns>
Scan for fix: commits following feat: commits on the same files within 7 days.
Look for:
Skip if learnings entries lack dispatch: fields.
If entries contain (dispatch: task-xyz) annotations:
Combine signals into a ranked list:
Difficulty Calibration:
Store the profile internally as the round-0 baseline. Order: WEAKNESS (HIGH first) -> GAP -> STRENGTH.
Generate 3-5 targeted challenges per round. This embeds the approach from /challenge-gen.
From the current struggle profile, select weaknesses to target this round:
For each selected weakness, search for real-world edge cases:
Codebase edge cases:
git log --oneline --all --since="60 days ago" -- <owns-patterns>
Look for complex patterns, error handling paths, configuration edge cases, cross-cutting concerns the learnings don't mention.
External edge cases (WebSearch):
Verify each external finding applies to the codebase (check imports, packages, git history).
git log --format="%H %s" --since="60 days ago" -- <owns-patterns>
Scan for fix: commits following feat: commits on the same files. Prioritize fix_after_feat commits and frequently-changed files.
For each candidate commit:
git show --format="%B" --no-patch <commit-hash>
git show --format="" <commit-hash>
git show <commit-hash>^:<file-path>
Combine candidates into 3-5 challenges. Every challenge MUST pass:
Drop any challenge that fails. If fewer than 3 survive, return to 2b/2c for more candidates.
Calibrate difficulty to the Difficulty Calibration level from Phase 1d.
mkdir -p .claude/tackline/memory/agents/<name>/challenges # team mode
mkdir -p .claude/tackline/memory/agents/solo/challenges # solo mode
Write challenges to .claude/tackline/memory/agents/<name>/challenges/<timestamp>-round-<N>-challenges.md (team mode) or .claude/tackline/memory/agents/solo/challenges/<timestamp>-round-<N>-challenges.md (solo mode):
# Round <N> Challenges for <agent-name>
Generated: <date>
Training cycle: /active-learn round <N>
Difficulty level: <novice | intermediate | expert | adversarial>
Targeted weaknesses: <list>
## Challenge 1: <title>
**Strategy**: edge-case | commit-replay
**Targeted weakness**: <WEAKNESS or GAP name>
**Difficulty**: <level>
### Scenario
<What the agent sees>
### Acceptance Criteria
<Pass/fail conditions>
### Hidden Trap
<What makes this hard -- NOT shown to agent>
### Ground Truth
<Correct approach -- for evaluation only>
For each challenge, compose a self-contained prompt and dispatch via Task.
Compose the prompt:
In team mode use the agent name and role from team.yaml. In solo mode, substitute:
main-sessionmain session practitioner.claude/tackline/memory/agents/solo/learnings.mdYou are <agent-name or "main-session">, a on the team.
Your Learnings
Task
Acceptance Criteria
Reflection
After completing the task, provide:
- Approach: What approach did you take and why?
- Confidence: How confident are you in your solution? (LOW / MEDIUM / HIGH)
- Uncertainty: What aspects are you least sure about?
- Alternative approaches: What other approaches did you consider and why did you reject them?
- Risk areas: Where might this solution break or be wrong?
CRITICAL: Never include Hidden Trap or Ground Truth in the agent prompt. This is the single most important constraint of the entire training loop. Including evaluation criteria defeats the challenge.
Dispatch:
Standard mode (default) — Team mode:
Task({
subagent_type: "general-purpose",
model: "<agent's model from team.yaml>",
prompt: "<composed prompt>"
})
Standard mode (default) — Solo mode (no team.yaml): use the current session model:
Task({
subagent_type: "general-purpose",
model: "claude-sonnet-4-6",
prompt: "<composed prompt>"
})
Worktree isolation mode — append isolation: "worktree" to either call signature:
Task({
subagent_type: "general-purpose",
isolation: "worktree",
model: "<agent's model or current session model>",
prompt: "<composed prompt>"
})
Benefits of worktree isolation mode:
Agent ID capture: After each dispatch, record the agent ID returned by Task in a per-weakness map:
weakness_agents: {
"<weakness-name>": "<agent-id-from-task-output>"
}
This map carries forward into subsequent rounds to enable resume dispatch (see Phase 5b).
Serial dispatch only -- no run_in_background. Each challenge is a controlled experiment.
After each dispatch returns, evaluate on three dimensions.
Worktree isolation mode — diff before evaluating:
If dispatching in worktree isolation mode, retrieve the worktree's branch name from the Task output and diff it against the base commit before running the standard evaluation:
git diff <base-commit>..<worktree-branch> -- <relevant paths>
Use this diff as additional evidence during Result Assessment and Trap Detection. Changes the agent made (or failed to make) are observable at the file level, not just from the agent's self-reported reflection. A solution that claims PASS but left no relevant diff is a red flag.
Result Assessment (PASS / PARTIAL / FAIL):
For commit-replay: compare against ground truth diff (semantic equivalence counts). For edge-case: check if solution handles the specific trap scenario.
Trap Detection (CAUGHT / PARTIAL / MISSED):
Confidence Calibration (OVER / UNDER / WELL_CALIBRATED):
| Self-reported | Actual result | Calibration |
|---|---|---|
| HIGH | PASS | WELL_CALIBRATED |
| HIGH | PARTIAL | OVER |
| HIGH | FAIL | OVER |
| MEDIUM | PASS | UNDER (slightly) |
| MEDIUM | PARTIAL | WELL_CALIBRATED |
| MEDIUM | FAIL | OVER |
| LOW | PASS | UNDER |
| LOW | PARTIAL | WELL_CALIBRATED |
| LOW | FAIL | WELL_CALIBRATED |
Nuance: If agent reported HIGH confidence but correctly identified the trap in risk areas, lean toward WELL_CALIBRATED.
Growth Signal:
Every rating MUST cite specific evidence from the agent's output. "MISSED" without explanation is not acceptable.
Write to .claude/tackline/memory/agents/<name>/challenges/<timestamp>-round-<N>-evaluation.md (team mode) or .claude/tackline/memory/agents/solo/challenges/<timestamp>-round-<N>-evaluation.md (solo mode):
# Round <N> Evaluation: <agent-name>
Evaluated: <date>
Training cycle: /active-learn round <N>
## Challenge 1: <title>
**Result**: PASS | PARTIAL | FAIL
**Trap Detection**: CAUGHT | PARTIAL | MISSED
**Confidence Calibration**: OVER | UNDER | WELL_CALIBRATED
**Targeted Weakness**: <weakness name>
**Growth Signal**: <signal>
**Resume Signal**: LEARNED | PARTIAL | NO_CHANGE | N/A <!-- present only when this was a resumed dispatch; N/A for first-round fresh dispatch -->
### Agent's Approach
<Brief summary>
### Evaluation Notes
<Why these ratings. Cite evidence.>
---
## Round Summary
- Results: X/N passed, Y partial, Z failed
- Trap detection: X caught, Y partial, Z missed
- Calibration: X well-calibrated, Y over-confident, Z under-confident
From the round evaluation, extract learnings the agent should retain:
Read .claude/tackline/memory/agents/<name>/learnings.md (team mode) or .claude/tackline/memory/agents/solo/learnings.md (solo mode). Append new entries tagged with challenge provenance:
- <learning description> (source: /active-learn round N, challenge: <title>, <date>)
Rules:
Write or update .claude/tackline/memory/agents/<name>/capability.yaml (team mode) or .claude/tackline/memory/agents/solo/capability.yaml (solo mode):
# Capability tracking for <agent-name or "solo">
# Updated by /active-learn on <date>
agent: <name or "solo"> # "solo" when running without a team
last_updated: <ISO date>
total_rounds: <cumulative across all /active-learn runs>
total_challenges: <cumulative>
domains:
<domain-area-1>:
pass_rate: <X/N>
trap_detection_rate: <X/N>
calibration: <dominant pattern: over | under | well_calibrated>
trajectory: improving | stable | declining
last_tested: <ISO date>
<domain-area-2>:
pass_rate: <X/N>
trap_detection_rate: <X/N>
calibration: <pattern>
trajectory: <direction>
last_tested: <ISO date>
persistent_weaknesses:
- <weakness that survived multiple rounds>
- ...
confirmed_strengths:
- <strength validated by PASS + CAUGHT>
- ...
history:
- date: <ISO date>
rounds: <N>
pass_rate: <overall X/N>
new_learnings: <count added>
early_stopped: <true/false>
reason: <if early stopped, why>
Domain areas map to the agent's owns patterns and the weakness categories from the struggle profile. If capability.yaml already exists, merge new data -- increment cumulative counts, update pass rates per domain, append to history.
After completing a round, re-run Phase 1 logic (lightweight -- focus on the round's results rather than full git analysis):
Stop the loop if ANY of these are true:
Continue the loop if:
If continuing: return to Phase 2 with the updated struggle profile. The new round targets weaknesses that emerged or persisted.
In subsequent rounds — resume vs fresh dispatch for re-tested weaknesses:
When Phase 2 selects a weakness that was already challenged in a prior round (i.e., an entry exists in weakness_agents for that weakness), use resume dispatch in Phase 3a instead of a fresh Task call. The resumed agent retains its prior attempt and the feedback from Phase 3b/4a within this session, testing whether it can learn across rounds. Max 3 rounds per weakness before treating as persistent and switching to a fresh agent.
In resume mode, compose a feedback prompt that includes:
Task({
resume: "<agent-id from weakness_agents[weakness-name]>",
prompt: "<feedback summary>\n\n<new challenge prompt>"
})
In fresh mode (new weakness, or weakness exceeding the 3-round cap): use standard Task dispatch as defined in Phase 3a and record the new agent ID in weakness_agents.
This resume behavior is the active learning signal: an agent that improves on a resumed attempt has demonstrated within-session learning from feedback. Record this in Phase 3c under a Resume Signal field:
After the loop completes (early stop or max rounds), emit the final summary.
In solo mode, prepend the SOLO MODE label to the summary block so the user knows which mode was active.
<!-- Solo mode only: -->
> **SOLO MODE** -- No team.yaml found. Ran as 'main-session'. Results written to .claude/tackline/memory/agents/solo/.
## Training Summary: <agent-name or "solo (main-session)">
**Source**: /active-learn
**Input**: <agent-name or "solo"> rounds=<N>
**Pipeline**: /active-learn (<rounds-completed> rounds, <total-challenges> challenges)
### Items (N)
1. **<domain/weakness>: <trajectory>** -- <description of how this area changed>
- initial_severity: HIGH | MEDIUM | LOW
- final_severity: HIGH | MEDIUM | LOW | RESOLVED
- rounds_tested: <N>
- pass_rate: <X/Y>
- trap_detection: <X/Y>
- growth_signal: <signal>
2. ...
### Improvement Trajectory
| Round | Challenges | Passed | Traps Caught | Calibration | New Learnings | Resume Signals |
|-------|-----------|--------|--------------|-------------|---------------|----------------|
| 1 | N | X | Y | pattern | Z | N/A |
| 2 | N | X | Y | pattern | Z | X learned, Y no_change |
| ... | | | | | | |
<!-- Resume Signals column: only populated for rounds 2+, where some challenges used resume dispatch. Lists count of LEARNED / PARTIAL / NO_CHANGE outcomes. -->
Overall trend: <improving | stable | declining>
Early stopped: <yes/no, reason>
### Persistent Weaknesses
<Weaknesses that survived all rounds without improvement. These need different intervention -- perhaps restructured ownership, pair-dispatch, or manual coaching.>
### Recommended Next Steps
<Concrete recommendations based on results:>
- If improving: "Schedule next /active-learn in 2 weeks to continue trajectory"
- If stable: "Agent may be at capability ceiling for current learnings format. Consider restructuring ownership or adding pair-dispatch for weak areas."
- If persistent weaknesses: "Weakness X survived N rounds. Consider: manual coaching on X, reducing X from ownership, or pairing with <other-agent> on X tasks."
### Summary
<One paragraph synthesizing the training cycle: how many rounds ran, what improved, what persists, and what the overall trajectory means for the agent's role on the team.>
Ensure capability.yaml is up to date with the final state (written in Phase 4c of the last round).
Report the file path so the user can review:
.claude/tackline/memory/agents/<name>/capability.yaml.claude/tackline/memory/agents/solo/capability.yamlrules/memory-layout.md, checkpoint at phase boundaries to .claude/tackline/memory/scratch/active-learn-checkpoint.md.See also: /diagnose-agent (standalone profiling), /challenge-gen (standalone generation), /challenge-run (standalone execution), /sprint (task dispatch with learning loop).
npx claudepluginhub tyevans/tackline --plugin tacklineUse after /diagnose-agent when you have a struggle profile and need training challenges. Generates edge-case and commit-replay challenges calibrated to weak areas. Keywords: challenge, training, improvement, active-learning, edge-case, replay, agent, weakness.
Extracts session patterns into reusable learnings with analyze, review, and list modes. Manages a learnings.jsonl file for persistent memory across sessions.
Captures amend/learn/remember/forget keywords from the user and updates agent or skill configurations by parsing the change, previewing a diff, applying it, and logging to an audit trail.