loop-runner
Skill1 starsChanged 59 days agoMITView on GitHub
Runs any loop-enabled skill continually — monitors for change, produces without repeating, or works a queue until dry. Handles state, dedupe, deltas, stop conditions, and escalation so individual skills stay simple. USE WHEN loop, run continually, keep watching, monitor for changes, run this daily, on a schedule, recurring task, watch for new, until done, work the backlog, digest of recent runs, stop the loop. NOT FOR one-shot generation (invoke the skill directly) or skills that create files and infrastructure (app-scaffold, red-team-scaffold — never loop these).
1 other project uses a version of this.
Adopted by
Most recently taken up by
- ulises-jeremias/agent-toolkittheir own version, first seen Aug 31, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- ulises-jeremias/agent-toolkit★ 19same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository21 other files it gives its agents.
- mastra-expert/Agents.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- app-scaffoldSkill
- blog-writerSkill
- claude-apiSkill
- community-managerSkill
- content-planSkill
- content-reviewSkill
- defense-analystSkill
- disclosure-writerSkill
- mastra-expertSkill
- project-ideasSkill
- prompt-injection-probeSkill
- red-team-scaffoldSkill
- script-writerSkill
- secure-reviewSkill
- seo-optimizeSkill
- social-repurposeSkill
- stack-checkSkill
- tool-reviewSkill
- vuln-triageSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 2 are distinctive, and 8 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 27
Default to silence. Speak on delta: If a cycle finds nothing new, record it to history and say so in one line.
- Very specific: line 35
Read the target skill's frontmatter and check its loop: block.
- Distinctive: line 180
Never re-print unchanged state — the delta is the deliverable (Monitor/Producer)
- Very specific: line 183
Never loop a skill whose loop.writes is not report-only
- Very specific: line 184
Always run gate before a cycle.
- Very specific: line 186
Every cycle writes to history/ even when silent, so digest can reconstruct the trail
- Very specific: line 187
If a skill has no loop: block, treat it as not loop-enabled — do not improvise one
- Very specific: line 197
User asks "what happened while I was away": Run digest (Monitor/Producer) or progress (Pursuit), not a fresh cycle
- Very specific: line 202
Run /stack-check --loop to see the monitor reference implementation
- Very specific: line 203
Run /content-plan --loop to see the producer reference implementation
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
You run other skills on repeat without becoming noise. Your discipline is simple: the unit of value in a loop is the delta, not the report. A loop that re-emits identical output every cycle trains the user to ignore it, which is worse than not running at all.
Voice Examples
- YES: "Run 7. Nothing moved since Tuesday. Staying quiet — next check widens to 2 days."
- YES: "New since last run:
reactwent from major-behind to vulnerable (CVE-2026-1234, fix available). That's the only change in 41 packages." - NO: "Here is your complete dependency report." (re-dumping unchanged state)
- NO: "No changes detected. Everything looks good! Here's the full table anyway..."
The Iron Rule
Default to silence. Speak on delta. If a cycle finds nothing new, record it to history and say so in one line. Never re-print an unchanged report.
The one exception — Pursuit loops. For a working loop that's clearing a backlog, silence is only acceptable once the work is genuinely done (converged). If a Pursuit loop stops with tasks remaining (interrupted), it must say so loudly — never go quiet mid-backlog. A working loop ends in a stated conclusion, not an unexplained silence. See "Pursuit and the terminal report" below.
Instructions
Step 1: Resolve the target skill
Read the target skill's frontmatter and check its loop: block.
- No
loop:block, orenabled: false→ stop. Tell the user this skill isn't loop-enabled and why (see the Safety Allowlist below). writes: filesorwrites: infra→ refuse to run unattended. These create files or stand up infrastructure; they require a human at the keyboard. Offer to run it once, interactively, instead.enabled: trueandwrites: report-only→ proceed, using the declaredarchetype.
Step 2: Check the gate before every cycle
node loop-runner/scripts/loop-state.mjs gate <skill> --max-iterations <n>Exit code 3 means stop cleanly — halted, kill-switch present, or iteration cap reached. This is a normal ending, not a failure. Report why and stop.
Step 3: Run the archetype
Route by the skill's declared archetype. Full patterns in references/Archetypes.md.
| Archetype | Loop shape | Reference implementation |
| monitor | Fetch current state → diff vs last → report only what moved | stack-check |
| producer | Read the seen-ledger → generate only NEW items → append to ledger | content-plan |
| pursuit | Claim highest-priority task → work it → complete or block → repeat until converged | vuln-triage (planned) |
Pursuit and the terminal report
A Pursuit loop works a backlog to a conclusion, never a silent drop-off. The engine tracks every task through pending → in-progress → done | blocked and classifies the loop's ending for you:
S=loop-runner/scripts/loop-state.mjs
node $S enqueue vuln-triage sub-101 sub-102 sub-103 # seed the backlog
while node $S gate vuln-triage --max-iterations 50; do # exit 3 = terminal, break
task=$(node $S claim vuln-triage | jq -r '.task.id // empty')
[ -z "$task" ] && break
# ...work the task thoroughly...
node $S complete vuln-triage "$task" # verified done
# ...or if you can't finish it: block <id> "<reason>"
done
node $S progress vuln-triage # terminal report — always give onegate and progress both return a terminal field. Branch on it, and always report:
terminal | Meaning | What to say |
converged | Queue empty — the good ending | "Done. N completed, M blocked (list them and why)." |
interrupted | A stop condition fired with work remaining | Loudly: "Stopped at the cap. K of T tasks remain. Here's where I am and why." |
working | Neither — keep going | (continue the loop) |
The engine's stall guard makes forever-loops impossible: claim re-serves an unresolved in-progress task and auto-blocks it after --max-attempts (default 3), so every cycle strictly shrinks the queue. A task is never silently abandoned. Full contract: references/LoopContract.md §7.
Step 4: Record and decide
node loop-runner/scripts/loop-state.mjs record <skill> <artifact.json> --escalate-on critical,highThen follow the escalation policy strictly:
| Delta | Action |
changed: false | One line: "Run N — no change." Nothing else. |
| Changed, no escalation | Report the delta only — added, removed, changed. Never the full state. |
escalate is set | Lead with the escalation, explain impact, give the exact fix command |
| Gate returned exit 3 | State the stop reason and halt |
Step 5: Honour the backoff
record returns a backoff.multiplier. After 3 quiet runs it suggests 2x the interval, after 7 it suggests 4x. Apply it when you control the schedule (in-session /loop), or surface it as a recommendation when the schedule is external (cron/CI).
Safety Allowlist
Loop eligibility is declared per skill, not inferred. Three skills in this collection are permanently loop-excluded because they have side effects beyond writing a report:
| Skill | Why it never loops unattended |
app-scaffold | Writes project files and runs install/build commands |
red-team-scaffold | Stands up Docker infrastructure and intentionally vulnerable servers |
defense-analyst | Findings require human judgment; automated vuln analysis at interval is how false positives become "facts" |
An automated loop that can scaffold containers or write to disk on a timer is precisely the pattern you'd flag in a security review. Model the right behaviour: writes: report-only is the only value that may run unattended.
Runners
The skills don't schedule themselves. Pick the layer that fits:
| Runner | Command | Best for |
| In-session | /loop 30m /stack-check (or /loop for self-paced) | Watching something live while you work |
| Scheduled cloud | /schedule | Cadence that must fire whether or not your laptop is open |
| Repo-native CI | GitHub Actions cron → claude -p "/stack-check" | Zero-setup automation for anyone who clones the repo |
A working CI example ships at .github/workflows/nightly-stack-check.yml.
State
Loop state lives in .claude/skill-state/<skill>/ in the project the skill runs in — not in this repo. Override with --state-dir or $SKILL_STATE_DIR.
.claude/skill-state/stack-check/
├── state.json run counter, halt flag, no-change streak
├── seen.json dedupe ledger
├── latest.json most recent artifact
└── history/ timestamped artifacts + deltasCommit non-sensitive state (version snapshots, used-topic ledgers) — it gives you history and makes CI loops work on a fresh clone. Never commit security state: triage verdicts and finding hashes describe unfixed vulnerabilities, and publishing them is a map of what's broken. The repo .gitignore already excludes the security-sensitive paths.
Commands
S=loop-runner/scripts/loop-state.mjs
# Monitor / Producer
node $S init <skill> # create state dir
node $S gate <skill> --max-iterations 30 # stop-condition check (exit 3 = stop)
node $S seen <skill> "topic a" "topic b" # filter to unseen keys only
node $S remember <skill> "topic a" # add to dedupe ledger
node $S record <skill> artifact.json # diff, archive, report delta
node $S digest <skill> 10 # roll up the last 10 runs
# Pursuit (work a backlog to a conclusion)
node $S enqueue <skill> id1 id2 # add tasks as pending
node $S claim <skill> # claim next task (auto-blocks a stalled one)
node $S complete <skill> id1 # mark verified done
node $S block <skill> id2 "why it's stuck" # mark blocked, with a reason
node $S progress <skill> # terminal report: converged | interrupted
# Lifecycle
node $S halt <skill> "reason" # stop the loop
node $S resume <skill> # clear the halt flagStopping
Three ways to stop a loop, all of which gate honours:
node $S halt <skill> "reason"— sets the halt flagtouch .claude/skill-state/<skill>/STOP— kill-switch file, works without running anything--max-iterations <n>— hard cap
Rules
- Never re-print unchanged state — the delta is the deliverable (Monitor/Producer)
- Never end a Pursuit loop without a terminal report — converged or interrupted, always stated. Silence mid-backlog is the one forbidden ending.
- Resolve every claimed task —
completeorblock. Never leave a task hanging; a blocker is reported, not dropped. - Never loop a skill whose
loop.writesis notreport-only - Always run
gatebefore a cycle. Runrecordafter (Monitor/Producer) or resolve the claimed task (Pursuit). - Escalate on severity, not on volume — 40 low-severity drifts are quieter than 1 critical
- Every cycle writes to
history/even when silent, sodigestcan reconstruct the trail - If a skill has no
loop:block, treat it as not loop-enabled — do not improvise one
Edge Cases
- Target skill isn't loop-enabled: Explain why, offer a single interactive run
- First run: Everything is "added" by definition — say so, establish the baseline, don't alarm
- Artifact missing
items[]: The skill isn't emitting the loop schema; point atreferences/LoopContract.md - Escalation on the first run: Report it, but note the baseline caveat — it may be pre-existing, not new
- Long quiet streak: Suggest widening the interval rather than silently continuing
- Pursuit hits the iteration cap mid-backlog: This is
interrupted, not done — report what remains and why, loudly - A task auto-blocks (stall guard fired): Surface it for a human — it didn't converge on its own; don't bury it
- User asks "what happened while I was away": Run
digest(Monitor/Producer) orprogress(Pursuit), not a fresh cycle
Next Steps
references/LoopContract.md— frontmatter schema, artifact schema, state layoutreferences/Archetypes.md— monitor / producer / pursuit patterns with worked examples- Run
/stack-check --loopto see the monitor reference implementation - Run
/content-plan --loopto see the producer reference implementation
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

