Skip to content
Data
Skill

/slm-loop

Gate-verified bounded loops with SuperLocalMemory as the durable ledger. Use when a task has a checkable acceptance condition and you must iterate until an INDEPENDENT gate passes — never stopping because the agent believes it is done. `slm_loop_run` (MCP) waits, under hard

From plugin
superlocalmemory
27016 skills4 agents1 command1 MCP

Claude Code

$ npx -y skills add qualixar/superlocalmemory --skill slm-loop --agent claude-code

SKILL.md

slm-loop.SKILL.md
name: slm-loop
description: Gate-verified bounded loops with SuperLocalMemory as the durable ledger. Use when a task has a checkable acceptance condition and you must iterate until an INDEPENDENT gate passes — never stopping because the agent believes it is done. `slm_loop_run` (MCP) waits, under hard bounds, for an independently executed check registered by the operator to pass; `slm loop demo` shows the control flow keyless; `slm loop history` and `slm loop show <run_id>` (or `slm_loop_history` / `slm_loop_show`) inspect past runs, whose every lap is stored as queryable SLM memory (tag `loop:<name>`). Terminal statuses are DONE / HALT / PAUSE / KILLED / ERROR — report them exactly, never converting HALT/PAUSE/ERROR into success.
when_to_use: "run a bounded loop, gate-verified task, iterate until tests pass, verify against an independent gate, don't trust the agent's own done claim, slm loop, convergence loop, loop until green, loop ledger, wait for another agent's result"
allowed-tools: slm_loop_run, slm_loop_history, slm_loop_show, recall, report_outcome, get_soft_prompts, skill_health, skill_lineage, evolve_skill, observe_bounded_loop_evidence, Bash(slm:*)

slm-loop — Bounded, gate-verified agent loops

The one rule

A bounded loop is complete **only when an independent gate passes** — not when the agent claims it is finished. The agent's own "I'm done" signal is recorded for audit and is *never* used to terminate the loop. If you take one thing from this skill: **the gate is the authority.**

Use a bounded loop whenever the goal has a mechanical, checkable contract: a test suite, a JSON schema, a linter, a reconciliation rule, a citation checker, a security scan. When the goal is subjective, keep a human approval gate.

What SLM runs, and what you run

SLM's loop engine runs the laps, enforces the bounds, calls the gate and writes the ledger. It does **not** start your tests or linters: it carries no subprocess or sandbox machinery. What each surface gives you:

| Surface | What it does | |---|---| | `slm_loop_run` (MCP) | A *watcher* for a registered check. DONE needs `gate_contract={"job_id": ...}`: a job the operator registered with `superlocalmemory.loops.receipt_jobs.register_job` and executed with `run_registered_check`. Each lap's recall of `gate_query` only locates context; a matching memory alone never passes. Without a registered job the run ends HALT ("operator-registered job_id required"), which is the correct, honest outcome. | | `slm loop demo` (CLI) | A keyless convergence demo: a stub proposer, a deterministic gate that passes on lap 3, every lap recorded. Proves the engine and ledger work end to end. | | `slm loop history`, `slm loop show` / `slm_loop_history`, `slm_loop_show` | Read the ledger of past runs. | | `superlocalmemory.loops.run_bounded_loop` (Python) | The engine itself, for code that supplies its own runner and gate callables. |

For a task whose gate is a command (`pytest -q`, a schema validation), you run that command yourself each lap with Bash and read its exit code; the discipline below still applies, but SLM is not recording those laps. For graph runs with receipts, use the separate Bounded Loops product; SLM can take a read-only snapshot of its finished runs with `observe_bounded_loop_evidence(workspace)` (an absolute path), which records observations only and never changes recall or ranking.

What SLM adds

Every lap SLM runs is written as a durable, queryable memory (tagged `loop:<name>`, session `loop:<run_id>`). That makes a run:

  • **auditable** — inspect the decision, gate verdict and budget for each lap;
  • **historical** — a run's ledger survives across sessions;
  • **discoverable** — visible via `slm recall`, the dashboard, and any

SLM-integrated tool, alongside everything else the agent remembers.

MCP: `slm_loop_run`

slm_loop_run(
  name: str,                    # 1–128 chars; also the memory tag
  gate_query: str,              # the recall the gate checks each lap (up to 2000 chars)
  gate_min_score: float = 0.0,  # minimum top-result score to pass
  max_iterations: int = 20,     # hard lap cap, 1–200
  max_wallclock_s: float = 15.0,# hard time cap; 0 disables; never more than 120
  poll_interval_s: float = 1.0, # wait between laps; at least 0.25
  max_tokens: int = 0,          # optional token budget; 0 disables
  no_progress_window: int = 0,  # halt after N no-change laps; leave 0 for a watcher
  require_support: bool = False,# pass only if the answer check ran and judged it sufficient
  gate_contract: dict | None = None,  # {"job_id": <operator registration>}; required for DONE
)

The call **blocks** until the gate passes or a bound trips, then returns `{ok, status, reason, passed, laps, run_id, ledger: [{lap, decision, passed, detail}]}`. The gate recalls at most three memories per lap and ignores the loop's own ledger entries, so only a memory written by someone else can satisfy it. A recall the answer check judged insufficient never passes, even with a high score; with `require_support=True` an unchecked recall (check off, busy, loading, out of time) does not pass either. When the answer check is on, each lap asks it once about those memories; with the online check that is a request to the provider and may be billed. `slm_loop_run` is not available to remote callers.

slm_loop_history(name, limit=20)   # runs recorded under a loop name
slm_loop_show(run_id, limit=200)   # every lap of one run, in order

CLI

slm loop demo [--iterations N] [--json]   # keyless convergence demo
slm loop history [--name NAME] [--json]   # list recorded runs
slm loop show <run_id> [--json]           # every lap of one run

There is no `slm loop run`.

The bounds

A loop runs inside a safety envelope. Any bound tripping ends the run with `HALT` (never a success):

  • **max_iterations** — a hard lap cap.
  • **no_progress_window** — consecutive no-change laps before halting a spinning

agent.

  • **
Read more
@qualixar
Ships withsuperlocalmemory

Open-source governed, local-first memory control plane for AI agents and teams. arXiv:2608.08253

27016 skills4 agents1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
270
Star history of qualixar/superlocalmemory on GitHub, a chart by star-history.com

Other skills on superlocalmemory.

slm-cache

slm-cache

KV cache for repeated reads — call slm_cache_get(key) first; on a miss do the expensive operation then slm_cache_set(key, value,…

slm-compress

slm-compress

Compress large text, tool output, or transcripts to reduce context-window usage while keeping the full 1M window intact — call…

slm-graph

slm-graph

Index and query a codebase as a structural graph — build the code graph, trace blast radius of a change, find…

More skills from other plugins.

context-loader
Auto-invoked

context-loader

Search memories from earlier Pi sessions in this repository. Use it when earlier work may already explain the code, error,…

mem04d69k
@mem0ai@mem0aiInstall Skill
analyzing-ai-citations

analyzing-ai-citations

Answer AI citation and answer engine optimization (AEO) questions in PostHog: whether AI answer engines (ChatGPT, Claude, and an…

posthog11d41k
@posthog@posthogInstall Skill

Questions about slm-loop.

Which coding agents can use slm-loop?
slm-loop installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.