agentleFS
enckequityenckequity/samebrain/skills/smartloop/SKILL.md

smartloop

Skill0 starsChanged 5 months agoMITView on GitHub

Run an explicitly invoked /smartloop task with durable state, checkpoints, verification tiers, and wait or resume handling.

  • Commits and pushes

The file

We split this skill into the rules it gives an agent

7 rules. About 0 are common, 4 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    When SMARTLOOP_SYNC_REMOTE is set (a private git remote URL), the state dir is a git clone of it — park on one machine, resume on another:

    line 84
  2. Very specific:

    Rehydrate: Read state.md — one file. Do not scroll conversation history to "remember".

    line 105
  3. Distinctive:

    When in doubt, tier up.

    line 170
  4. Distinctive:

    Prefer symbol-level code reads (LSP/serena) when available.

    line 176
  5. Very specific:

    Verify every criterion goal-backward against the Contract — against what was promised, not what was done.

    line 189
  6. Distinctive:

    When a run parks or blocks, move to the next queue entry instead of sleeping.

    line 214
  7. Distinctive:

    Stop at queue-empty (notify: portfolio drained) or session limit (park).

    line 219

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

smartloop

Drive a task to verified completion at minimum token cost. Progress lives in a state file OUTSIDE the conversation, so wakes, compaction, crashes, and rate limits never lose work. The conversation is scratch; the state file is memory.

State dir: $SMARTLOOP_DIR or ~/.smartloop. One run = <dir>/<slug>/state.md + <dir>/<slug>/evidence/. Never inside a repo.

Commands

  • /smartloop <task> — start (slug = short kebab-case from the task)
  • /smartloop resume [slug] — re-enter a run; with no slug and exactly one non-done run, resume that one; otherwise list and ask
  • /smartloop status — print one line per run from the state files; when {{REPO}}/telemetry/*/smartloop-runs.jsonl has a record for a slug, append its cost line (iters, wall time, outcome); nothing else
  • /smartloop portfolio — drain every non-done run under one quota (below)
  • /smartloop backlog <source> — queue-draining mode (below)

Agent adapters

The protocol and state files are agent-neutral; only the harness primitives differ. Look up your row and substitute accordingly:

AdapterClaude CodeCodexCursorOpenCode
Session id (for owner_session)CLAUDE_CODE_SESSION_ID envsession/thread id from the harnessconversation id from the harnessSMARTLOOP_SESSION_ID env (driver-set) → else <agent>-<machine>-<date>
Scheduled wakesnative (ScheduleWakeup)none → park-onlybackground agents only → park-onlynone → park-only, swept by the launchd driver
Liveness hooksSessionStart sweep + Stop auditsame (hooks.json)same (hooks.json)driver --portfolio sweep; Stop audit not wired

Park-only fallback: without scheduled wakes, ladder tiers 1–2 are unavailable — use tier 0 (harness-tracked work) or park (tier 3). A parked run is resumable from any agent: state files carry no agent-specific content. OpenCode has no native wake, so an OpenCode run always parks: {{REPO}}/bin/smartloop-driver.sh (opt-in launchd job via --install, every 30 min) resumes each non-done run listed in ~/.smartloop/driver-allowlist with opencode run --auto --agent autonomous "/smartloop resume <slug>". Add a slug to that allowlist to let the driver carry it; absent the file, the driver drives every non-done run. If you cannot determine a session id, use <agent>-<machine>-<date>; the Stop audit only protects exact owner_session matches, so a stable id matters.

State file format

---
slug: <task-slug>
status: working | waiting:<what> | limit-paused | done | blocked:<needs-user>
owner_session: <CLAUDE_CODE_SESSION_ID of the owning session>
next_wake: <ISO8601 when sleeping | parked | omit otherwise>
---
## Contract
Goal: <one line>
Criteria:
- [ ] <executable check — command/URL/condition>   [tier 0|1|2]
Out of scope: <explicit list>
Assumptions: <stated where the task was ambiguous>

## Journal
- <iter N> did X; learned Y; evidence: evidence/<file>

## Next action
<single concrete step any fresh session can execute>

Hard rules: the Contract is never edited after iteration 0 — criteria only get checked off, each with an evidence pointer. Journal entries ≤3 lines, pointers never payloads. A Stop hook audits next_wake: ending a turn with a non-terminal run and no live wake (and not parked) is blocked. The audit only protects the session named in owner_session.

The front matter is a machine-parseable contract: exactly the keys slug, status, owner_session, owner_machine (when state sync is on), next_wake (when applicable), one key: value per line, no nesting, no extra keys. Tooling parses it; prose belongs in the body.

Cross-machine resume (optional)

When SMARTLOOP_SYNC_REMOTE is set (a private git remote URL), the state dir is a git clone of it — park on one machine, resume on another:

  • Once per machine: git clone "$SMARTLOOP_SYNC_REMOTE" <state-dir> (or git init + git remote add origin in an existing dir).
  • At park (and at every terminal checkpoint): git add -A && git commit -m "smartloop: <slug> <status>" && git push from the state dir. Fail-silent — offline parks reconcile on the next pull.
  • At resume entry, before Rehydrate: git pull --rebase --autostash from the state dir, then proceed.
  • Takeover rule: claim both owner_session and owner_machine (short hostname). Never take over a run whose next_wake is a live future timestamp on another machine — a sleeping owner is not abandoned.

Every entry — start, wake, or resume — runs the same 6 steps

  1. Compile (first entry only). Transform the raw task into the Contract: one-line goal; success criteria as executable checks, each tier-classified; out-of-scope list; stated assumptions. A code-producing task auto-adds the criterion "adversarial review loop complete; blocking findings resolved" [tier 2]. Write the state file before any work.
  2. Rehydrate. Read state.md — one file. Do not scroll conversation history to "remember"; if the answer is not in the state file, the journal was written wrong — fix the journal discipline instead. Then take ownership: write this session's id (shell env CLAUDE_CODE_SESSION_ID) into owner_session — on every entry, not just the first. The Stop audit is owner-scoped; stale ownership means no liveness protection.
  3. Triage against the Contract: which criteria are unmet? Is the next action executable now, blocked on something external, or is everything verified (→ Finish)?
  4. Execute the smallest unit that produces verifiable progress, through context firewalls: exploration, test-fix cycles, and audits run inside subagents whose contexts are disposable — only structured conclusions return. Use cheap/fast models for mechanical subagent work. Long commands run in the background; never await them by sleeping.
  5. Verify per the criterion's tier (below). Evidence goes to evidence/; the journal records the pointer.
  6. Checkpoint. Append a journal entry (≤3 lines); update Next action and status; roll journal entries older than the current phase into a 5-line summary once the journal exceeds ~80 lines; if about to sleep, write next_wake. Wake prompts are always /smartloop resume <slug> — never a bare task description (re-entering through the skill reloads the full protocol every wake).
  7. Pace with the wait ladder.

Wait ladder (a wake replays the whole conversation as input — pay attention)

TierWhenDo
0Waiting on harness-tracked work (background commands/agents/workflows)No polling wakes — the harness re-invokes on completion. Schedule the single 3600s hang-guard and record it in next_wake; it doubles as the Stop-audit satisfier.
1Fast-changing external state (CI finishing in minutes)Wakes ≤270s (prompt cache stays warm)
2In-context state still genuinely valuable (hot debugging)1200–3600s; justify in the journal. Never 300–1100s.
3Long/indefinite wait (limit pause, overnight, waiting on user)Park (default): checkpoint, notify, next_wake: parked, end with no wake. Resume costs one state-file read.

At every sleep decision: state what the wait is for, pick the lowest tier that serves it, park when in doubt — the state file guarantees nothing is lost. Learned pacing priors, when present, live in {{REPO}}/global/addenda/smartloop-pacing.md (regenerated from the trace corpus by bin/optimize.mjs --pacing) — consult them before choosing a tier.

Verification tiers

  • Tier 0 — mechanical (file moves, config, docs): self-check — re-read or dry-run the result.
  • Tier 1 — code changes: executed evidence required (test/build/probe run; excerpt saved to evidence/). Write the failing test first where the project's rules call for TDD.
  • Adversarial review loop — once per changeset at the integration boundary (changeset complete, before commit/PR/merge/deploy). Run three lenses: contract fit, correctness, and safety/security/operations. Round 1 reviews the whole diff/result; if any blocking finding appears, fix it and run the next round only on the fix delta. The loop ends only when no critical/high finding remains and no medium finding still breaks the Contract.
  • Tier 2 — ship-gates (merge, deploy, external comms, money): the full adversarial panel is mandatory, with schema-forced verdicts. For code, review and refutation merge into this single panel rather than separate ceremonies.
  • Panel verdicts are labeled data. Record each tier-2 verdict as a structured object — {"lens": "correctness|security|contract", "verdict": "pass|fail", "reason": "<one line>"} — in evidence/adversarial-review.jsonl, grouped by round, and carry the final array into the run-summary verdicts field at finish. Never free-prose a verdict; the corpus feeds later analysis.
  • Learned tier floors: {{REPO}}/global/addenda/smartloop-tiers.md, when present, lists task patterns whose past runs were done-then-redone (generated by bin/optimize.mjs --apply-tiers within human-set bounds). Matching tasks verify at the listed tier or higher.
  • When in doubt, tier up.

Token rules (mandatory)

  • Orchestrate, don't labor: heavy reads and noisy iteration belong in subagents. The loop session dispatches, verifies, checkpoints.
  • Prefer symbol-level code reads (LSP/serena) when available; otherwise search first, then read only the needed range. Cap all output.
  • Subagent prompts demand structured, capped returns.
  • Evidence is pointed to, never pasted — not into the journal, not into chat.

Limits and parking

On a rate-limit error: the state file is already current (step 5 ran last iteration); set status limit-paused, notify, park. Resume from any session via /smartloop resume — the SessionStart sweep surfaces it automatically.

Finishing

Verify every criterion goal-backward against the Contract — against what was promised, not what was done. Set status done, final journal entry, send a one-line notification (done / blocked-on-user / limit-paused), no wake.

Then append one run-summary line to {{REPO}}/telemetry/<machine>/smartloop-runs.jsonl (machine = short hostname; create directories as needed) — single-line JSON, exactly these fields:

{"ts":"<iso8601>","slug":"<slug>","outcome":"done|blocked|abandoned","iters":<n>,"wall_s":<seconds from first journal entry to now>,"verdicts":[]}

verdicts carries any tier-2 panel results from the run (empty array if none). This trace corpus feeds later analysis (pacing stats, eval export) — the format is a contract; do not add or rename fields.

Portfolio mode

/smartloop portfolio — drain every non-done run under one shared quota:

  1. Get the ordered queue: node {{REPO}}/hooks/smartloop-sweep.mjs --portfolio — active runs cheapest-rehydrate-first (smallest journal), limit-paused runs deferred to the end.
  2. Work the queue head through the normal 6-step entry (take ownership, triage, execute, verify, checkpoint). One run at a time — never interleave.
  3. When a run parks or blocks, move to the next queue entry instead of sleeping. A limit pause on the session parks the whole portfolio (status per run is already checkpointed); a limit-pause on one run's external dependency only defers that run.
  4. Re-run the queue command between items — priorities shift as journals grow.
  5. Stop at queue-empty (notify: portfolio drained) or session limit (park).

Backlog mode

/smartloop backlog <source> — the Contract is "drain the queue": each item becomes a sub-contract run through the full protocol. Honor the repo's multi-agent claim protocol before starting an item; isolate per-item work in its own worktree. Park at queue-empty or limit.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.