
Toil Mining
- 22 installs
- 416 repo stars
- Updated August 5, 2026
- boshu2/agentops
toil-mining is a Claude Code skill that mines usage history for repeated manual toil and emits a ranked list of automation candidates scored by frequency times pain.
About
toil-mining scans usage history - past agent sessions, command analytics, and shell history - for repeated manual toil, scores each cluster by frequency times pain, and emits a ranked list of automation candidates. It filters out machine echoes and hands the ranked list to a separate routing skill that decides the automation shape. A developer uses it to decide what to automate next based on measured evidence rather than intuition.
- Mines cass sessions, rtk analytics, and shell history for repeated toil
- Scores each cluster by frequency times pain, filtering machine echoes
- Emits a ranked candidate list, but never builds or shapes the automation
Toil Mining by the numbers
- 22 all-time installs (skills.sh)
- Ranked #1,273 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
toil-mining capabilities & compatibility
- Capabilities
- toil mining · automation discovery
- Use cases
- research · orchestration
- Pricing
- Free
What toil-mining says it does
Measure before believing.
This skill emits candidates; it never builds the automation or picks its shape.
npx skills add https://github.com/boshu2/agentops --skill toil-miningAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 22 |
|---|---|
| repo stars | ★ 416 |
| Last updated | August 5, 2026 |
| Repository | boshu2/agentops ↗ |
What it does
Mine usage history for repeated toil, score each cluster by frequency times pain, and emit ranked automation candidates.
Who is it for?
Deciding what to automate next from measured usage history rather than intuition.
Skip if: Building the automation or choosing its shape; those belong to a separate routing skill.
When should I use this skill?
When the same prompt keeps getting hand-pasted across sessions or you ask what to automate next.
What you get
A ranked candidate list written to .agents/toil-mining/, each with a suggested next step, handed off for shape routing.
- Ranked candidate list at .agents/toil-mining/YYYY-MM-DD-candidates.md
- Optional bead candidates
By the numbers
- Four execution steps: collect, cluster, score, emit
- Scores by frequency times pain across 4 history sources
Files
/toil-mining — Mine usage history for automation candidates
Purpose: the operator's own history is the highest-signal backlog nobody
reads. This skill mines it — past agent sessions, command analytics, shell
history — clusters the repeated prompts and command sequences, scores each
cluster by frequency x pain, and hands a ranked candidate list to
/automation-shape-routing, which decides the shape (workflow vs swarm vsskill). Toil-mining is that router's missing feeder: routing is useless
without a measured queue of things worth routing.
Use when: the same prompt keeps getting hand-pasted across sessions; the operator asks what to automate next; or the scheduled compounding sweep fires. Non-goals: building the automation, choosing its shape, or editing history.
(user-invocable: false is interim — promotion to invocable needs catalog + dispositions rows, a separate one-line change outside this skill's directory.)
⚠️ Critical Constraints
- ⛔ NEVER dispatch via `claude -p` / `claude --print` — scheduled ticks and headless workers use `codex exec` (or the local llama lane). Why: because of LAW 0 —
claude -pbills the API / burns the Max quota, is hook-blocked on this host, and a sweep that fires on a timer would burn it on a schedule. - Measure before believing. Candidates come from counted history, never from "I feel like I do this a lot." Why: because intuition about repetition is unreliable — the measured record shows the inversion that intuition misses (see worked example: rituals at 94x while skills sat at ≤9x).
- This skill emits candidates; it never builds the automation or picks its shape. Why: because shape (workflow vs swarm vs skill) is
/automation-shape-routing's single job — a miner that also builds grades its own homework and duplicates the router. - Filter machine echoes before clustering. Tool results, file-update confirmations, and error strings repeat far more than any human ritual and are not toil. Why: because the top raw counts are almost always harness noise; ranking them wastes the whole run (in the fixture, the top 4 raw entries are all machine echoes).
- Hand-pasted prompts are the loudest toil signal. A long, structured prompt pasted N times is a skill or tick that does not exist yet. Why: because each paste costs operator attention and drifts a little — variant copies of the same ritual diverge until no canonical version exists.
- Read sources read-only. Session archives, analytics DBs, and shell history are evidence; never rewrite or prune them. Why: because the mine must stay replayable — next month's sweep diffs against the same record.
Sources
| Source | How to read it | What it yields |
|---|---|---|
| cass (session archaeology) | /cass queries over past agent sessions | Repeated hand-typed prompts, recurring rescue patterns, abandoned-then-retried tasks |
| rtk analytics | rtk gain --history, rtk discover | Command-level frequency, token-savings misses, commands worth proxying |
| Shell history | history / ~/.zsh_history timestamps | Repeated command sequences and multi-step chains outside agent sessions |
| Usage-data scans | ritual-scan JSON (e.g. ~/.claude/usage-data/rituals-*.json) | Pre-counted repeated prompts across all projects, with first/last-seen windows |
Execution Steps
Step 1: Collect
Pull from every available source above; skip missing ones gracefully and note which were consulted. Capture per item: text, count, first/last seen, source.
Checkpoint: at least one source produced counted data. If none did, stop and report "no measurable history" — do not fall back to guessing.
Step 2: Cluster
Group near-duplicates (the same ritual pasted with small edits, the same command chain with different arguments) into clusters. Then split each cluster: human-initiated toil vs machine echo (tool results, success confirmations, error strings). Discard the echoes from ranking; keep their counts as context.
Checkpoint: every surviving cluster traces to something a human typed, pasted, or deliberately re-ran.
Step 3: Score — frequency x pain
score = frequency x pain, where pain weighs: length/structure of the pasted text, whether it runs unattended (overnight > interactive), consequence of getting it wrong (safety gates, money, external sends), and drift risk (how many variants the cluster contains). Rank descending. A high-frequency one-word nudge ("ok") can still rank low: frequency alone is not the verdict.
Checkpoint: the ranking would survive the operator reading it — each score has a one-line justification naming both factors.
Step 4: Emit and hand off
Write the ranked candidate list (see Output Specification), each with a suggested next step. Hand the list to /automation-shape-routing for the shape decision; durable candidates worth tracking become bead candidates via /beads-workflow. The miner stops there.
Modes
| Mode | Trigger | Behavior |
|---|---|---|
| (default) | invoked on demand | One mining pass over all sources, full report |
--compounding | scheduled tick (launchd on Mac, systemd user timer on bushido) | Proactive sweep: diff against the previous findings file, report only new/grown clusters, append to the findings ledger, queue bead candidates. Dispatched headlessly via codex exec — never claude -p. Design: references/tick-design.md |
Compounding is the point: a one-off mine pays once; a scheduled sweep keeps catching new rituals as they form, before they fossilize into 90-paste habits.
Worked Example
Input: fixtures/rituals-excerpt.json — a 20-entry excerpt derived from a real ritual scan (71,191 prompts scanned). Step 2 discards the top raw counts (1545x "Bash completed with no output", 498x, 337x, 319x — all machine echoes). Step 3 ranks the surviving human toil:
# Toil-mining candidates — 2026-06-12
| Rank | Cluster | Freq | Pain | Why it ranks here | Suggested next step |
|---|---|---|---|---|---|
| 1 | overnight factory supervisor ritual ("[/loop overnight factory supervisor — Bo is asleep...]") | 94 | very high | ~150-word safety-critical prompt, hand-pasted, runs unattended overnight, gates external actions | route to automation-shape-routing; likely a scheduled tick + skill |
| 2 | META-ORCHESTRATOR TICK v2 | 81 | very high | multi-section orchestration pass, pasted 81x in ~20h, drift-prone across variants | same — strongest tick candidate |
| 3 | one-work-tick factory prompt | 39 | high | structured single-unit work dispatch with hard gates | fold into the same tick family as #1/#2 |
| 4 | "keep going towards goal" | 44 | medium | pure nudge; cheap to type but signals a missing supervisor loop | symptom of #1-#3; closes when they ship |
| — | "ok" (112x) | 112 | low | one-word approval; frequency high, pain near zero | not a candidate — note only |
Frequency inversion: these hand-pasted rituals ran 94/81/44/39 times while no
skill invocation exceeded 9 in the same window. The automation that exists is
not the automation that is needed.Candidate #1 is the 94x overnight-supervisor ritual: highest combined score because it is long, safety-gated, unattended, and pasted nearly a hundred times — exactly the profile of a tick that should already exist.
Output Specification
Format: markdown report — ranked candidate table (cluster, frequency, pain, justification, suggested next step) plus a sources-consulted line and the discarded-echo note; the same data may be mirrored as JSON when a caller asks for machine output. Filename: written to .agents/toil-mining/YYYY-MM-DD-candidates.md (compounding mode appends a dated section to the same directory's ledger). Next action: hand the top candidates to /automation-shape-routing; track keepers as bead candidates.
Quality Rubric
- [ ] Every candidate carries a measured count from a named source, not an estimate
- [ ] Machine echoes were filtered and noted, never ranked
- [ ] Each score names both factors (frequency AND pain) in one line
- [ ] The report ends with a handoff to automation-shape-routing, not a built automation
- [ ] No history source was modified
- [ ] Compounding runs diffed against the prior findings file instead of re-reporting old clusters
See Also
- automation-shape-routing — downstream consumer; decides the shape of each candidate
- cass — the session-archaeology source
- beads-workflow — lands accepted candidates on the tracker
Reference Documents
- references/tick-design.md — the compounding-mode scheduled-tick design (launchd / systemd user timer dispatching codex exec; findings ledger + bead candidates)
{
"source": "derived from ~/.claude/usage-data/rituals-2026-06-12.json (prompts truncated to 280 chars, example_paths dropped)",
"total_prompts_scanned": 71191,
"note": "frequency inversion: hand-typed rituals repeat 94/81/44/39 times while skill invocations peak at <=9 in the same window",
"repeated_prompts": [
{
"prompt": "(Bash completed with no output)",
"count": 1545,
"agents": [
"claude_code"
],
"first_seen": "2026-04-28T19:49:03.292000+00:00",
"last_seen": "2026-06-12T00:59:02.606000+00:00",
"is_ritual": true
},
{
"prompt": "Structured output provided successfully",
"count": 498,
"agents": [
"claude_code"
],
"first_seen": "2026-05-29T12:33:46.412000+00:00",
"last_seen": "2026-06-11T12:24:48.477000+00:00",
"is_ritual": true
},
{
"prompt": "<tool_use_error>File has not been read yet. Read it first before writing to it.</tool_use_error>",
"count": 337,
"agents": [
"claude_code"
],
"first_seen": "2026-05-21T01:05:26.352000+00:00",
"last_seen": "2026-06-12T00:33:23.730000+00:00",
"is_ritual": true
},
{
"prompt": "[Request interrupted by user]",
"count": 319,
"agents": [
"claude_code"
],
"first_seen": "2026-05-25T17:18:07.314000+00:00",
"last_seen": "2026-06-12T01:02:19.193000+00:00",
"is_ritual": true
},
{
"prompt": "ok",
"count": 112,
"agents": [
"claude_code"
],
"first_seen": "2026-05-29T15:04:36.118000+00:00",
"last_seen": "2026-06-11T16:36:26.065000+00:00",
"is_ritual": true
},
{
"prompt": "[/loop overnight factory supervisor — Bo is asleep, Athena in charge until he stops the loop] Keep the autonomous factory alive AND safe: (1) run `factory status`; if it's OFF, run `factory go` to restart it. (2) Runaway/health check: confirm `continuity-budget cap-check --run fa",
"count": 94,
"agents": [
"claude_code"
],
"first_seen": "2026-06-06T04:52:39.294000+00:00",
"last_seen": "2026-06-06T12:19:40.801000+00:00",
"is_ritual": true
},
{
"prompt": "No matching deferred tools found",
"count": 86,
"agents": [
"claude_code"
],
"first_seen": "2026-05-26T17:39:58.194000+00:00",
"last_seen": "2026-06-11T11:21:26.800000+00:00",
"is_ritual": true
},
{
"prompt": "Wasted call — file unchanged since your last Read. Refer to that earlier tool_result instead.",
"count": 82,
"agents": [
"claude_code"
],
"first_seen": "2026-06-08T00:03:19.350000+00:00",
"last_seen": "2026-06-10T20:55:39.575000+00:00",
"is_ritual": true
},
{
"prompt": "META-ORCHESTRATOR TICK v2 (Athena — outside the work; never implement inline; delegate; silent unless escalation warranted).\n\nPass over ~/dev/control-plane:\n1. LOOP HEALTH: `br ready | head -12`, `br list --status=in_progress`. Append ONE dated line to evidence/meta-orchestrator-",
"count": 81,
"agents": [
"claude_code"
],
"first_seen": "2026-06-10T00:54:15.185000+00:00",
"last_seen": "2026-06-10T20:54:15.920000+00:00",
"is_ritual": true
},
{
"prompt": "The server returned HTTP 403 Forbidden.\n\nThe response body was not retrieved. If this URL requires authentication, use an authenticated tool (e.g. `gh` for GitHub, or an MCP-provided fetch tool) instead of WebFetch.",
"count": 70,
"agents": [
"claude_code"
],
"first_seen": "2026-05-25T22:29:54.157000+00:00",
"last_seen": "2026-06-10T23:33:21.520000+00:00",
"is_ritual": true
},
{
"prompt": "Exit code 1\nrtk: rtk find does not support compound predicates or actions (e.g. -not, -exec). Use `find` directly.",
"count": 70,
"agents": [
"claude_code"
],
"first_seen": "2026-05-30T14:59:17.673000+00:00",
"last_seen": "2026-06-11T10:16:29.057000+00:00",
"is_ritual": true
},
{
"prompt": "The file /Users/bo/dev/personal-site/src/app/training/page.tsx has been updated successfully. (file state is current in your context — no need to Read it back)",
"count": 60,
"agents": [
"claude_code"
],
"first_seen": "2026-05-30T13:53:26.279000+00:00",
"last_seen": "2026-06-11T00:28:07.329000+00:00",
"is_ritual": true
},
{
"prompt": "Sent to 1 pane(s)",
"count": 49,
"agents": [
"claude_code"
],
"first_seen": "2026-06-08T17:36:46.398000+00:00",
"last_seen": "2026-06-10T17:14:53.103000+00:00",
"is_ritual": true
},
{
"prompt": "keep going towards goal",
"count": 44,
"agents": [
"claude_code"
],
"first_seen": "2026-06-08T19:09:02.114000+00:00",
"last_seen": "2026-06-08T22:53:10.776000+00:00",
"is_ritual": true
},
{
"prompt": "(empty)",
"count": 43,
"agents": [
"claude_code"
],
"first_seen": "2026-05-26T15:10:58.443000+00:00",
"last_seen": "2026-06-10T14:57:14.522000+00:00",
"is_ritual": true
},
{
"prompt": "You are ONE work tick in Bo's autonomous factory (repo: /Users/bo/dev/agentops). Bo is OUT. Do ONE unit of real work, then STOP. Gates are absolute.\n\n1. Pick ONE ready item you can advance AUTONOMOUSLY: cd /Users/bo/dev/agentops && bd ready. Prefer pure code/docs factory work, or",
"count": 39,
"agents": [
"claude_code"
],
"first_seen": "2026-06-06T05:23:15.730000+00:00",
"last_seen": "2026-06-06T12:05:50.367000+00:00",
"is_ritual": true
},
{
"prompt": "[Request interrupted by user for tool use]",
"count": 34,
"agents": [
"claude_code"
],
"first_seen": "2026-05-25T17:46:30.487000+00:00",
"last_seen": "2026-06-11T15:39:43+00:00",
"is_ritual": true
},
{
"prompt": "<local-command-stdout>Set model to \u001b[1mFable 5\u001b[22m and saved as your default for new sessions</local-command-stdout>",
"count": 34,
"agents": [
"claude_code"
],
"first_seen": "2026-06-09T17:39:30.640000+00:00",
"last_seen": "2026-06-12T00:52:02.362000+00:00",
"is_ritual": true
},
{
"prompt": "0",
"count": 29,
"agents": [
"claude_code"
],
"first_seen": "2026-05-31T16:50:51.361000+00:00",
"last_seen": "2026-06-11T03:46:13.337000+00:00",
"is_ritual": true
},
{
"prompt": "Send a message to one or more agents\n\nUsage: am mail send [OPTIONS] --project <PROJECT_KEY> --from <SENDER> --to <TO> --subject <SUBJECT> --body <BODY>\n\nOptions:\n -p, --project <PROJECT_KEY> Project key (slug or human_key)\n --from <SENDER> Sender agent name\n ",
"count": 29,
"agents": [
"claude_code"
],
"first_seen": "2026-06-05T23:29:11.423000+00:00",
"last_seen": "2026-06-12T00:40:33.949000+00:00",
"is_ritual": true
}
]
}
Compounding-mode scheduled tick — design
How --compounding runs unattended: a host scheduler fires a headless worker on a cadence, the worker runs one mining sweep, and the results land in durable artifacts (a findings ledger + bead candidates) instead of a chat transcript.
⛔ Dispatch constraint (LAW 0)
The tick dispatches `codex exec` — NEVER claude -p / claude --print. That path bills the Anthropic API and/or burns the Claude Max weekly quota, is mechanically blocked on this host (~/.claude/hooks/no-claude-p-guard.sh), and a scheduler would re-commit the violation on every fire. Acceptable headless lanes: codex exec (default), the local llama endpoint for cheap pre-filtering. There is no third option; do not reason past this.
Shape
scheduler (launchd | systemd user timer)
└─> tick script (thin shell wrapper)
└─> codex exec "<compounding-mode prompt>"
├─> reads sources (cass, rtk history, shell history, ritual scans)
├─> diffs clusters against the previous findings entry
├─> appends a dated section to .agents/toil-mining/findings.md
└─> emits bead-candidate stanzas for new/grown clustersThe tick is idempotent per day: re-firing overwrites nothing, it appends one dated section keyed by date. The worker gets a fresh context every fire — all continuity lives in the findings ledger it diffs against, not in the session.
Cadence
Weekly is the default. Daily is wasteful (rituals take days to form); monthly lets a new ritual hit dozens of pastes before it is caught. Tune per host activity, not per enthusiasm.
Mac — launchd
~/Library/LaunchAgents/com.bo.toil-mining-tick.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>Label</key><string>com.bo.toil-mining-tick</string>
<key>ProgramArguments</key><array>
<string>/bin/zsh</string><string>-lc</string>
<string>codex exec "Run the toil-mining skill in --compounding mode over this host's usage history; append findings to .agents/toil-mining/findings.md and emit bead candidates for new clusters." >> "$HOME/.local/state/toil-mining/tick.log" 2>&1</string>
</array>
<key>StartCalendarInterval</key><dict>
<key>Weekday</key><integer>1</integer>
<key>Hour</key><integer>7</integer>
<key>Minute</key><integer>30</integer>
</dict>
</dict></plist>Load with launchctl bootstrap gui/$(id -u) <plist>; verify with launchctl print gui/$(id -u)/com.bo.toil-mining-tick.
bushido (WSL) — systemd user timer
~/.config/systemd/user/toil-mining-tick.service:
[Unit]
Description=toil-mining compounding sweep (codex exec; never claude -p)
[Service]
Type=oneshot
ExecStart=/usr/bin/env zsh -lc 'codex exec "Run the toil-mining skill in --compounding mode over this host's usage history; append findings to .agents/toil-mining/findings.md and emit bead candidates for new clusters."'~/.config/systemd/user/toil-mining-tick.timer:
[Unit]
Description=weekly toil-mining sweep
[Timer]
OnCalendar=Mon 07:30
Persistent=true
[Install]
WantedBy=timers.targetEnable with systemctl --user enable --now toil-mining-tick.timer; inspect with systemctl --user list-timers and journalctl --user -u toil-mining-tick.service.
Output routing
| Artifact | Path | Contract |
|---|---|---|
| Findings ledger | .agents/toil-mining/findings.md | Append-only dated sections; each section = sources consulted, new clusters, grown clusters (with previous→current counts), echo-filter note |
| Candidate report | .agents/toil-mining/YYYY-MM-DD-candidates.md | Same ranked-table format as on-demand mode |
| Bead candidates | tracker (br create, P3 by default) | One bead per new candidate above the ranking threshold, body citing the findings section; dedupe against open toil beads before creating |
The tick never auto-builds an automation and never escalates a candidate past "bead created" — shape decisions stay with /automation-shape-routing, and anything external stays gated on the operator.
Failure behavior
- Worker failure: log to the tick log and exit non-zero; the next fire retries. No partial ledger writes — build the section in a temp file, append atomically.
- Missing source (no rtk, no ritual scan that week): note it in the section and continue with the rest; an empty sweep is a valid, cheap result.
- Quota/rate pressure on the codex lane: skip the fire (log "skipped: lane unavailable") rather than falling back to any Claude headless path — the fallback that "just this once" uses
claude -pis the exact failure LAW 0 exists to stop.
Related skills
FAQ
Does it build the automation?
No. It emits ranked candidates and hands them to a separate routing skill; it never builds the automation or picks its shape.
How does it avoid ranking noise?
It filters machine echoes - tool results, success confirmations, and error strings - before clustering, because the top raw counts are almost always harness noise.