Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add commands/littlebearapps/untether/step-classifygit clone --depth 1 https://github.com/littlebearapps/untetherWhat it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00000 | $0.01939 |
| Opus 5 | $0.00000 | $0.00970 |
| Sonnet 5 | $0.00000 | $0.00388 |
| Haiku 4.5 | $0.00000 | $0.00194 |
Grade A, and why
step-classify scanned grade A with 1 finding against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Runs shell commandslowCapability
Expected in a hook, worth knowing in a rule or an instructions file.
| **runner-subprocess** | `subprocess.create.failed`, `subprocess.died_without_completion`, `runner_failed`, signal exits (rc=143/137), JSONL parse errors, EventFactory misuse | grep `engine=<X>` `event=session.summary`; How it starts
The opening of the file, as written. The whole thing — 63 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Step 1 — Classify
This is the canonical Untether issue-class table. Pick exactly one primary class per issue (the area where the root cause lives). If behaviour crosses boundaries, note a secondary class.
For each row: the column "diagnostic hints" lists grep targets and the canonical rule file that owns the area. Match aggressively — over-classifying is far less costly than under-classifying.
The 15 classes
| Class | Indicators in logs / chat | Diagnostic hints | Canonical rule |
|---|---|---|---|
| runner-subprocess | subprocess.create.failed, subprocess.died_without_completion, runner_failed, signal exits (rc=143/137), JSONL parse errors, EventFactory misuse |
grep engine=<X> event=session.summary; check 3-event contract; verify proc_returncode and last_event_type |
runner-development.md |
| telegram-transport | Outbox stuck, rate-limit 429, callback_data overflow, message-too-long, voice transcription failures, file upload denied, media-group dedup | grep outbox, file_transfer, voice_transcription, rate_limit, 429; check TelegramOutbox invariants; verify callback_data ≤ 64 bytes |
telegram-transport.md |
| control-channel | Approval buttons missing / stuck, PTY FD leak, ask-question crash, plan-mode cooldown abuse, ExitPlanMode loop, AskUserQuestion stuck-sequential | grep control_request, control_response, _DISCUSS_COOLDOWN, _PENDING_ASK_REQUESTS; check PTY finally cleanup; check session-registry cleanup |
control-channel.md |
| trigger-cron-webhook | Cron fired wrong time / wrong tz, webhook 401/403/429/503, SSRF block, fetch-cron parse failure, hot-reload didn't apply, run_once re-fired |
grep trigger.fired, cron, webhook, ssrf, triggers paused, config.reload; check timezone string in cron config; verify HMAC signature |
(none — see src/untether/triggers/) |
| session-resume-lock | Wrong session resumed, stale resume token, session lock leak, registry not cleaned, /continue failures |
grep SessionLockMixin, lock_for, session_id, resume; check WeakValueDictionary cleanup; verify lock acquired before subprocess spawn |
runner-development.md |
| stall-liveness-watchdog | subprocess.liveness_stall, subprocess.liveness_kill, stall_warning, peak_idle excessive, repeat stall_warnings on cron sessions |
grep liveness, stall, proc_diag, cpu_active; check tool_timeout vs mcp_tool_timeout; see systemic-patterns.md for by-design cases (cron + plan-mode) |
(none — see src/untether/utils/proc_diag.py) |
| auto-continue | Auto-continue loops (death spiral), missing auto-continue (Claude exit with last_event_type=user), retry exhaustion, signal-death suppression bypass |
grep auto_continue, last_event_type, proc_returncode; check signal-death suppression (rc=143/137); verify [auto_continue].max_retries |
runner-development.md |
| config-hot-reload | Restart-required key edited mid-run, hot-reload race, update_from() field copy missed, TelegramBridgeConfig corruption |
grep config.reload, restart_required, RESTART_REQUIRED_FIELDS; check update_from() field coverage; verify slot preservation; see feedback_agent_self_restart_pattern in MEMORY.md |
telegram-transport.md §TelegramBridgeConfig hot-reload |
| fleet-rollout | fleet-rollout.sh failure, attestation marker missing, version mismatch across hosts, partial-rollback state |
check ~/.untether-dev/integration-test-pass-${VERSION}.json exists; check pipx list on each host; verify integration-test gate not bypassed |
release-discipline.md §Fleet rollout |
| outbox-delivery | Files not delivered, deny-glob false-positive, size-limit hit, file-count cap, auto-cleanup didn't fire | grep outbox, deny_glob, file_transfer; check .untether-outbox/ dir in project; verify [transports.telegram.files] config |
telegram-transport.md §Outbox file delivery |
| cost-budget | Per-run budget exceeded silently, daily budget reset wrong, alert level skipped, auto-cancel didn't trigger | grep cost_budget, budget.alert, auto_cancel; check cost_tracker.py; verify daily reset timezone |
(none — see src/untether/cost_tracker.py) |
| at-scheduler-cancel-restart | /at delay lost on restart, /cancel didn't drop pending delay, /new orphan tasks, /restart drain timeout |
grep at_scheduler, cancel.requested, shutdown.drain, _cancel_chat_tasks; verify drain integration via at_scheduler.active_count() |
(none — see src/untether/telegram/at_scheduler.py, commands/topics.py) |
| help-faq-release-guard | FAQ deleted/moved (hook block), guard-script edit blocked, force-push to master blocked, PR merge to master blocked, MCP write to master blocked | check .claude/hooks.json enforcement; verify help-faq-protect.sh, release-guard.sh, release-guard-protect.sh, release-guard-mcp.sh; check docs/faq/faq.md exists and has ≥7 question-shaped H2s |
help-faq.md, release-discipline.md §Release guard |
| auto-error-watcher | Watcher daemon stopped, false-positive filings, duplicate issues, wrong host tag, signature dedup miss | check systemctl --user status untether-issue-watcher on each host; inspect ~/.local/state/untether-issue-watcher/seen.json; verify HOST env var |
(none — see MEMORY.md untether-issue-watcher section) |
| ci-pipeline-release-guard | CI job failure (format/ruff/ty/pytest/build/lockfile/install-test/pip-audit/bandit/codeql/docs), validate_release.py reject, auto-tag-on-master skip on stable bump, OIDC publish failure |
check .github/workflows/; verify pyproject.toml version matches CHANGELOG.md heading; verify all changelog entries have [#N] links; check uv lock --check clean |
release-discipline.md, context-quality.md |
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2d ago First seen · 63 lines · 0 tokens per session scan A 757b2656ba40
step-classify is a command published in the GitHub repository littlebearapps/untether (66 stars, last pushed 3d ago), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 1,939 tokens. A static security scan graded it A with 1 finding (runs shell commands). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other commands, from other repositories
add-plugin
Integrate a spec-driven/skill framework as a bundled agtx plugin. Pass a GitHub repo URL to auto-generate the plugin.toml, or run without arguments to write one from scratch.
evolve
Run an optional AHE iteration to evaluate or improve this OpenCode harness with evidence and attribution.
loop-status
Consulta el estado durable de una misión sin adquirir locks ni escribir archivos.
skill-creator
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
fd-resume
Restore from checkpoint.json (falling back to STATE.md) — brief the user, PAUSE for confirmation, then continue from the recorded command and stage.
no-vibe-btw
One-shot escape hatch — let AI write code to project files for a single task, then restore no-vibe mode.