Use when asked to create an automation loop or automate a recurring task with an FSM.
Pro scans all 5 files and shows the line behind each finding
Scanned 10/6/2026
npx -y skills add BrennonTWilliams/little-loops --skill create-loop --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Create Loop?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/brennontwilliams-create-loop-little-loops)More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.
---
name: create-loop
description: Use when asked to create an automation loop or automate a recurring task with an FSM.
allowed-tools:
- Bash(mkdir:*, test:*, ll-loop:*)
metadata:
short-description: Use when asked to create an automation loop or automate a recurring task with an
trigger_fixtures:
should_fire:
- "create an automation loop to automate this recurring task"
- "automate this recurring task with an FSM loop"
should_not_fire:
- "generate an FSM eval harness yaml from issue ids"
- "generate a verification loop from acceptance criteria"
---
# Create Loop
Interactive command for creating new automation loop configurations. This command guides you through:
1. Choosing a structural loop pattern (fix until clean, maintain constraints, drive a metric, run a sequence, or harness a skill/prompt)
2. Gathering type-specific parameters
3. Naming the loop
4. Generating and previewing FSM YAML
5. Saving and validating
6. Optional test iteration to verify the loop works
## Allowed Tools
Use these tools during the workflow:
- `AskUserQuestion` - For interactive prompts
- `Write` - To save the loop configuration
- `Bash` - To run validation and create directories
- `Read` - To check for existing loops
## Workflow
### Step -1: Natural Language Pre-fill (when args provided)
**If `args` is non-empty**, parse the natural language description before doing anything else. Skip this step entirely when `args` is empty or absent.
#### Inference Rules
Read the description and infer the following fields:
**Loop type** — map keywords to types:
- "fix", "clean", "until passing", "lint", "type check", "test" → `fix-until-clean`
- "maintain", "keep", "enforce", "constraint", "guard" → `maintain-constraints`
- "reduce", "increase", "drive", "metric", "count", "score", "coverage" → `drive-metric`
- "sequence", "steps", "pipeline", "stage", "ordered" → `run-sequence`
- "harness", "wrap", "skill", "prompt", "iterate", "refine" → `harness`
- "bandit", "explore", "exploit", "A/B", "strategy" → `rl-bandit`
- "generate", "score", "RLHF", "quality", "candidate" → `rl-rlhf`
- "policy", "act", "observe", "reward", "agent" → `rl-policy`
- "decision table", "policy rules", "policy router", "multi-score routing", "rubric route" → `policy-router`
- "optimize", "meta", "improve loop", "improve skill", "improve command" → `meta-optimize`
- "route", "dispatch", "compose", "orchestrate", "supervisor", "router" → `orch-router`
**Key parameters** — extract as many as possible from the description:
- Check/fix command (e.g., "run pytest", "run mypy", "run ruff")
- Target skill or prompt name
- Metric name and direction (reduce/increase) and target value
- Step names for sequences
- Max iterations (e.g., "up to 10 times", "max 5 iterations")
- Loop name hint (e.g., "call it X", "name it X")
**Suggested loop name** — derive from inferred type and targets (same rules as Step 3).
#### Confirmation Display
Present a structured summary of inferred values in text (not a tool call), then use AskUserQuestion:
```
I understood your description as:
Loop type: <inferred type label>
<param key>: <inferred value>
<param key>: <inferred value>
...
Suggested name: <suggested-name>
Anything I couldn't confidently infer will be asked next.
```
```yaml
questions:
- question: "Does this match what you want?"
header: "Confirm intent"
multiSelect: false
options:
- label: "Yes, generate the loop (Recommended)"
description: "Use inferred values — skip the wizard and go straight to YAML preview"
- label: "Let me adjust first"
description: "Walk through the guided questions with inferred values as defaults"
```
#### Routing
- **"Yes, generate the loop"** — skip Steps 0–3, proceed directly to **Step 4** with all inferred values already populated. For any parameter that could not be confidently inferred, use the type-appropriate defaults from [loop-types.md](loop-types.md).
- **"Let me adjust first"** — proceed to **Step 0**, but pre-select inferred values as the default answer in each subsequent `AskUserQuestion` call (highlight the inferred option or pre-fill the text). The user can override any of them.
---
### Step 0: Creation Mode
Use AskUserQuestion to determine whether to use a template or build from scratch:
```yaml
questions:
- question: "How would you like to create your loop?"
header: "Creation mode"
multiSelect: false
options:
- label: "Start from template (Recommended)"
description: "Choose a pre-built loop for common tasks"
- label: "Build from scratch"
description: "Configure a new loop from scratch using the guided wizard"
```
**If "Start from template"**: Read [templates.md](templates.md) for template selection and customization flow (Steps 0.1-0.2), then skip to Step 4.
**If "Build from scratch"**: Skip to Step 1 (Loop Type Selection)
---
### Step 1: Loop Type Selection (Custom Mode Only)
If user selected "Build from scratch" in Step 0, use this flow.
Use AskUserQuestion with a single-select to determine the loop type:
```yaml
questions:
- question: "What kind of automation loop do you want to create?"
header: "Loop type"
multiSelect: false
options:
- label: "Fix until clean (Recommended)"
description: "Run a check and fix issues until it passes. Pattern: evaluate → fix → done"
- label: "Maintain constraints"
description: "Keep multiple conditions true in a chain. Pattern: check-fix pairs chained to terminal"
- label: "Drive a metric toward a target"
description: "Measure a value and apply fixes until it reaches goal. Best for: reducing error counts, coverage"
- label: "Run a sequence of steps"
description: "Execute steps in order, repeat until condition met. Best for: multi-stage builds"
- label: "Harness a skill or prompt"
description: "Wrap a skill/prompt with plan-evaluate-iterate. Auto-generates evaluation from project context."
- label: "Specialist role pipeline"
description: "Decompose a task into Plan -> Research -> Implement -> Report specialist roles. Best for deep refactors, multi-file features, and cross-cutting changes."
- label: "RL: Bandit (explore vs exploit)"
description: "Epsilon-greedy bandit loop — alternate explore/exploit rounds, routing on reward convergence. Best for: A/B strategy selection, prompt optimization, hyperparameter search."
- label: "RL: RLHF-style (generate → score → refine)"
description: "Generate candidate output, score quality, refine until quality target is met. Best for: iterative content improvement, prompt refinement, answer quality loops."
- label: "RL: Policy iteration (act → observe → improve)"
description: "Agent acts, observes reward, improves policy toward a target. Best for: environment interaction, agent training simulations, adaptive automation."
- label: "Policy router (decision table)"
description: "Score an artifact on multiple dimensions and route via a declarative rule table. Pattern: score → parse_scores → policy_dispatch → action states"
- label: "Optimize a harness (meta-loop)"
description: "Iteratively improve a loop YAML, skill, agent, or command using an external scorer. Generates diagnosis-first scaffolding required for meta-loops (SHOR-compliant)."
- label: "Orch: Router (dynamic dispatch)"
description: "Classify a goal and dispatch to the best-fit existing loop. Pattern: classify → score → dispatch → review → done"
- label: "Orch: Composer (goal → DAG)"
description: "Decompose a goal into a sequence of sub-loops run via depends_on. Maps to loop-composer built-in loop."
- label: "Orch: Supervisor (adaptive re-plan)"
description: "Run a loop, reassess on failure, re-plan the sub-loop sequence. Maps to loop-composer-adaptive built-in loop."
- label: "Orch: Cluster (multi-goal fan-out)"
description: "Orchestrate a list of goals (sprint, EPIC, backlog slice) as batches with cross-batch context propagation. Maps to goal-cluster built-in loop."
```
**Type Mapping:**
- "Fix until clean" -> `fix-until-clean` type (states: evaluate, fix, done)
- "Maintain constraints" -> `maintain-constraints` type (check/fix pairs + terminal)
- "Drive a metric toward a target" -> `drive-metric` type (states: measure, apply, done)
- "Run a sequence of steps" -> `run-sequence` type (step_0...step_N, check_done, done)
- "Harness a skill or prompt" -> `harness` type (states: discover, execute, check_concrete, check_semantic, check_invariants, advance, done)
- "Specialist role pipeline" -> `specialist-pipeline` type (states: plan, research, implement, report, done)
- **Sub-loop composition** — not a wizard type; use `loop:` field in YAML to invoke other loops as child FSMs (see [reference.md](reference.md))
- "RL: Bandit (explore vs exploit)" -> `rl-bandit` type (states: explore, exploit, reward, done)
- "RL: RLHF-style (generate → score → refine)" -> `rl-rlhf` type (states: generate, score, refine, done)
- "RL: Policy iteration (act → observe → improve)" -> `rl-policy` type (states: act, observe, score, improve, done)
- "Policy router (decision table)" -> `policy-router` type (states: score, parse_scores, policy_dispatch, action states, done)
- "Optimize a harness (meta-loop)" -> `meta-optimize` type (states: diagnose, baseline, propose, apply, score, gate, commit_or_revert, done)
- "Orch: Router (dynamic dispatch)" -> `orch-router` type (states: classify, score, dispatch, review, done)
- "Orch: Composer (goal → DAG)" -> `loop-composer` built-in loop (run via `ll-loop run loop-composer "..."`)
- "Orch: Supervisor (adaptive re-plan)" -> `loop-composer-adaptive` built-in loop (run via `ll-loop run loop-composer-adaptive "..."`)
- "Orch: Cluster (multi-goal fan-out)" -> `goal-cluster` built-in loop (run via `ll-loop run goal-cluster "goal1\ngoal2\n..."` or `ll-loop run goal-cluster "EPIC-NNN"`)
### Step 2: Type-Specific Questions
Based on the selected loop type, read [loop-types.md](loop-types.md) for the detailed question flow and FSM YAML generation for each type.
---
### Step 3: Loop Name
After gathering type-specific parameters, ask for the loop name:
```yaml
questions:
- question: "What should this loop be called?"
header: "Loop name"
multiSelect: false
options:
- label: "<auto-suggested-name>"
description: "Based on your selections"
- label: "Custom name"
description: "Enter your own name"
```
**Auto-suggest names based on loop type:**
- Fix until clean: `fix-<targets>` (e.g., `fix-types-and-lint`)
- Maintain constraints: `<constraint-names>-guardian` (e.g., `tests-types-lint-guardian`)
- Drive a metric: `reduce-<metric>` or `increase-<metric>` (e.g., `reduce-lint-errors`)
- Run a sequence: `<step-summary>-loop` (e.g., `fix-test-check-loop`)
- Harness a skill/prompt: `harness-<skill-name>` or `<skill-name>-loop` (e.g., `harness-refine-issue`)
### Step 4: Preview and Confirm
Generate and display the FSM YAML.
**Generate FSM YAML:**
Read [loop-types.md](loop-types.md) for the FSM YAML template for the selected loop type. Generate the complete FSM YAML based on the parameters gathered in Step 2.
Also generate a summary preview showing:
1. States in execution order (use -> between states)
2. Transitions for each non-terminal state
3. Terminal states marked with `[terminal]`
4. Initial state and max_steps from the configuration
**Routing graph check (before presenting to user):**
Scan the generated routing graph for infinite cycles. If any non-terminal state A routes to state B (via `on_no`, `on_error`, or `next:`), and state B routes unconditionally back to A, warn the user inline:
> ⚠️ Routing cycle detected: `<A>` → `<B>` → `<A>`. If the condition that triggers `on_no`/`on_error` is persistent (e.g. a required tool is unavailable), this cycle runs until `max_steps` is exhausted. Consider routing failures forward to a recovery or terminal state instead.
The most common case: a `generate` state with `next: evaluate` and an `evaluate` state with `on_no: generate` is a cycle when Playwright or another external capture tool is absent. The fix is `on_no: score` (degrade to LLM evaluation) rather than `on_no: generate`.
Also warn if the generated YAML includes a `terminal: true` failure state that has an `action:` field — the action is silently skipped by the executor (`_finish("terminal")` fires before any action runs). The correct pattern is a two-state `diagnose → failed` split: a non-terminal `diagnose` state with the diagnostic action and `next: failed`, followed by a bare `failed: terminal: true` state with no action.
**Display format:**
```
Here's your loop configuration:
## FSM YAML
```yaml
<generated-yaml>
```
## Summary
States: <state1> -> <state2> -> ... -> <terminal>
Transitions:
<state1>: <verdict>-><target>, <verdict>-><target>
<state2>: next-><target>
...
<terminal>: [terminal]
Initial: <initial-state>
Max steps: <max_steps>
Evaluator: <type> [<details>] # Only shown if non-default evaluator configured
This will create: {{config.loops.loops_dir}}/<name>.yaml
```
Use AskUserQuestion:
```yaml
questions:
- question: "Save this loop configuration?"
header: "Confirm"
multiSelect: false
options:
- label: "Yes, save and validate"
description: "Save to {{config.loops.loops_dir}}/<name>.yaml and run validation"
- label: "No, start over"
description: "Discard and restart the wizard"
```
### Step 5: Save and Validate
If confirmed:
1. **Create directory if needed:**
```bash
mkdir -p {{config.loops.loops_dir}}
```
2. **Check for existing file:**
```bash
test -f {{config.loops.loops_dir}}/<name>.yaml && echo "EXISTS" || echo "OK"
```
If exists, ask:
```yaml
questions:
- question: "A loop with this name already exists. Overwrite?"
header: "Overwrite"
multiSelect: false
options:
- label: "Yes, overwrite"
description: "Replace the existing loop configuration"
- label: "No, choose different name"
description: "Go back and pick a new name"
```
3. **Write the file** using the Write tool:
- Path: `{{config.loops.loops_dir}}/<name>.yaml`
- Content: The generated YAML
4. **Validate** using ll-loop CLI:
```bash
ll-loop validate <name>
```
5. **Offer test iteration** (after validation succeeds):
Use AskUserQuestion:
```yaml
questions:
- question: "Would you like to run a test iteration to verify the loop works?"
header: "Test run"
multiSelect: false
options:
- label: "Yes, run one iteration (Recommended)"
description: "Execute check command and verify evaluation works"
- label: "No, I'll test manually"
description: "Skip test iteration"
```
If "Yes, run one iteration":
```bash
ll-loop test <name>
```
Display the test output directly. Example output:
```
## Test Iteration: my-loop
State: check
Action: {{config.project.type_cmd}}
Exit code: 1
Output:
Found 3 errors in 1 file (checked 5 source files)
Evaluator: exit_code (default)
Verdict: FAILURE
Would transition: check -> fix
Loop appears to be configured correctly
```
The test command validates your loop configuration by running one iteration:
- Shows the state and action being tested
- Displays exit code and output (truncated if long)
- Reports evaluator type and verdict
- Indicates what transition would occur
Continue to the success report regardless of test result.
6. **Report results:**
On success (no test issues):
```
Loop created successfully!
File: {{config.loops.loops_dir}}/<name>.yaml
States: <list-of-states>
Initial: <initial-state>
Max iterations: <max>
Run now with: ll-loop <name>
Tip: Run /ll:review-loop <name> to audit quality and best practices.
```
On success with test issues (test ran but found problems):
```
Loop created successfully!
File: {{config.loops.loops_dir}}/<name>.yaml
States: <list-of-states>
Initial: <initial-state>
Max iterations: <max>
Note: Test iteration found issues - see output above.
You may want to review the configuration before running.
Run now with: ll-loop <name>
Tip: Run /ll:review-loop <name> to audit quality and best practices.
```
On validation failure:
```
Loop saved but validation failed:
<error-message>
Please fix the configuration at {{config.loops.loops_dir}}/<name>.yaml
```
## Additional Resources
- For pre-built loop templates, see [templates.md](templates.md)
- For loop type question flows and FSM YAML generation, see [loop-types.md](loop-types.md)
- For quick reference tables and advanced configuration, see [reference.md](reference.md)
**Note on `from:` inheritance**: A new loop that closely matches an existing one can declare `from: <parent-loop-name>` at the top level instead of duplicating the full state graph. Inheritance is resolved before validation and diagram generation, so the validator and `/ll:review-loop` always see the materialized loop. See `docs/guides/LOOPS_GUIDE.md#loop-template-inheritance-via-from` for merge rules.
## Examples
```bash
# Start the interactive wizard
/ll:create-loop
# Pass a natural language description to skip most wizard questions
/ll:create-loop run mypy and ruff until they both pass
/ll:create-loop reduce lint errors to zero using ruff check, max 8 iterations
/ll:create-loop harness the refine-issue skill and iterate until the issue is implementation-ready
/ll:create-loop maintain tests passing and types clean, call it quality-guardian
/ll:create-loop poll GitHub CI every 5 minutes and retry on failure, max 20 iterations
```
When args are provided, the skill infers loop type and parameters from the description, shows a
confirmation summary, and — if confirmed — jumps straight to the YAML preview (Step 4), skipping
the guided wizard entirely.
---
## Integration
This command creates FSM loop configurations that can be executed with the `ll-loop` CLI.
Works well with:
- `ll-loop <name>` - Execute the created loop
- `ll-loop validate <name>` - Validate loop configuration
- `/ll:check-code` - Often used as a fix action in loops
- `/ll:manage-issue` - Used for complex bug fixes in loops
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!