- name
- ll
- description
- Typed tick loops with FlowMind validation and parallel tick dispatch. Use when running /ll, recurring pipelines, quality loops, or autonomous scheduler ticks.
- triggers
- ["ll","levloop"]
- argument-hint
- [create|schedule|run|status|ticks|list|stop|pause|proposal] <description or loop-file>
- allowed-tools
- ["Read","Write","Edit","Bash","Glob","Grep","Agent"]
# /ll — Loop Maker + Tick Scheduler
Create, schedule, and run typed tick loops with constraint engineering discipline.
## Invocation
```
/ll create "iterate on manifesto content" # Generate loop YAML
/ll schedule 10m # Schedule via CronCreate
/ll run # Run one tick now
/ll status # Show loop state + tick history
/ll ticks # Show tick type distribution
/ll list # List all loops
/ll stop # CronDelete active loop
/ll pause # Pause loop (user can resume)
/ll proposal # Loop proposes next actions instead of executing
/ll inspect <tick-id> # Show tick details + report
```
## Tick Execution Model
**A tick is a scheduler pass, not one action (JP 2026-10-31).** Each tick reads
the tracked state, evaluates every action type's guard, and starts ALL ready,
independent actions at once (1-n actions per tick). Sequencing is optional: an
action waits only when its guard names a prerequisite or it would edit the same
files as a running action. The loop defines:
```yaml
scheduler:
interval: 10m # how often the scheduler pass runs
max_live_delegates: 6 # cap on concurrent workers, not on actions per tick
silent_when: "no action ready and no state changed" # no message to the user
actions: # replaces one-type-per-tick selection
<action>: {guard: "<condition over state.json>", do: "<what starts>"}
```
Weighted or round-robin selection (below) still works for content loops that
want variety; for delivery loops, use guards over state.
**Every tick parallelizes all independent work:**
- Dispatch flowminds, tasks, exec items simultaneously via Agent tool
- Use haiku subagents for small/research items (parallel_safe)
- Use direct execution for serial/dependent items
- Concurrency is bounded by `max_live_delegates` (C1 bounded), not by a per-tick action count
- Each agent reports: DONE | NEEDS_CONTEXT | BLOCKED
**Self-learning:** Loop rescheduling when new data arrives mid-tick.
When /capture or user input adds new items, reschedule with updated queue.
**Preflight:** Before each tick, check:
1. Dependencies resolved (blockers cleared?)
2. Critical path via samurai scout (what unblocks the most?)
3. Budget remaining (max iterations, token budget)
4. Workstream + lifecycle hygiene (graph footer, handoff current?)
**After first schedule:** Run first tick immediately (don't wait for cron).
**CPU scheduling:** Each loop has workstream-scoped lifecycle hygiene ticks
interleaved with execution ticks. Hygiene = drift check, orphan scan, HUD check.
## HUD — Always-On Status Line
Every /ll response ends with a single HUD line. Not a footer. A status bar.
```
🧬 {ws} ⚡{exec} 📥{capture} ⏸️{paused} ✅{done} | 🚦{gate}={score} | ⏭️ {next} | 🔁ll:t{N} {delay}s
```
**Symbols:**
- `⚡` = executing right now
- `📥` = in capture/classify
- `⏸️` = paused (needs decision)
- `✅` = done this session
- `🚦` = current gate + score
- `⏭️` = what's next
- `🔁` = loop tick + delay
**/siterep** = expanded view (full dashboard). The HUD is the collapsed always-on version.
**This replaces the graph footer.** One line > six lines. Always present. Never forgotten.
## /ll IS /work (converging)
/ll and /work are the same thing at different timescales:
- `/work` = interactive, human-paced, one entity at a time
- `/ll` = autonomous, loop-paced, parallel entities per tick
- Both use `lifecycle-manifest.yaml` for verb→skill routing
- Both check gates via `DefaultGateEvaluator` (now with UNCERTAIN + variable triples)
- Both follow `idle-exec-policy.yaml` for auto-advance vs HITL decisions
The merge: /work calls /ll for execution. /ll calls /siterep for status. /siterep reads the same state.
---
## Loop Definition Generator
`/levloop create` produces a YAML file at `.lev/loops/<loop-id>/loop.yaml`:
```yaml
id: content-gtm-sprint
name: "Constraint Engineering GTM Content Loop"
description: "Iterate manifesto, articles, tweets, and publish pipeline"
tick_types:
- id: manifesto
description: "Create or iterate manifesto /now pages"
weight: 25
max_consecutive: 2
- id: article
description: "Write or improve articles"
weight: 30
max_consecutive: 3
- id: research
description: "Re-read source docs, identify gaps"
weight: 15
requires_after: [manifesto, article] # must follow creative work
min_interval: 3 # ticks between research ticks
- id: review
description: "De-slopify, quality check, voice alignment"
weight: 15
requires_after: [article]
- id: discover
description: "Identify new top-level themes, promote to manifesto"
weight: 10
min_interval: 5
- id: publish
description: "Publish to here.now, Substack, social"
weight: 5
requires_after: [review]
tick_constraints:
ordering: weighted_random # weighted_random | round_robin | priority | waterfall
self_validation: false # agent that does work NEVER validates its own
max_ticks_per_session: 20
validation:
between_ticks: true # generate adversarial flowmind between ticks
flowmind_template: adversarial-review # base template
auto_escalate_after: 3 # escalate to human after 3 consecutive failures
schedule:
interval: 10m # CronCreate interval
duration: 6h # auto-stop after duration
circuit_breaker:
threshold: 3 # consecutive no-advancement ticks
action: stop # stop | escalate | hygiene
execution:
adapter: claude-agent-sdk
model: sonnet
max_turns_per_tick: 15
verifier: null # shell command, exits 0 on success
knobs:
source_dir: "~/.agents/levnow"
content_dir: "content/"
prd_path: "content/ralph/prd.json"
```
---
## Tick Type System
### Built-in Types
| Type | Purpose | Default Weight |
|------|---------|---------------|
| `sweep` | Pre-check: move validated entities to done | 5% |
| `validate` | Verify previous tick's output (never self-validate) | 15% |
| `execute` | Do actionable work (highest priority ready item) | 30% |
| `research` | Re-read source material, identify gaps | 15% |
| `review` | Quality check, de-slopify, voice alignment | 20% |
| `discover` | Identify new topics, promote to top-level | 10% |
| `publish` | Push to here.now, Substack, social platforms | 5% |
### Ordering Strategies
| Strategy | How It Works |
|----------|-------------|
| `weighted_random` | Random selection weighted by type weight %. Good for balanced loops. |
| `round_robin` | Cycles through types in declared order. Predictable. |
| `priority` | Always picks highest-weight eligible type. Work-heavy. |
| `waterfall` | Autodev-loop style: sweep → validate → execute → hygiene. Falls through. |
### Selection Algorithm
Each tick:
1. Filter by `max_consecutive` — skip types that hit their consecutive limit
2. Filter by `min_interval` — skip types that ran too recently
3. Filter by `requires_after` — skip types whose prerequisite hasn't run
4. From remaining, select by ordering strategy
5. If nothing eligible, run hygiene/discover (always eligible)
### Self-Validation Rule
**The agent that does work NEVER validates its own work.**
Validation is always done by the NEXT tick. This is inherited from autodev-loop
and is non-negotiable. Set `self_validation: false` (the default).
### Evaluator Integrity Rule
Before a producing tick begins, freeze its acceptance: the tick's Done
Criteria, the loop's `validation` section, `execution.verifier`, and their
fixtures. Record their digests with the tick result and keep them out of every
tick's Scope; a tick that edits them is rejected. Only frozen acceptance can
pass a tick. Probes generated after seeing its output add diagnostics; they
never replace or weaken frozen acceptance. Any evaluator change, including a C4
ratchet promotion, is a new evaluator generation recorded between ticks; it
binds only ticks that begin afterward and never counts as advancement.
Validation passes only for the exact revision it checked; a later edit makes
that evidence stale until re-validated. Keep rejected tick records and their
evidence rather than deleting or overwriting them.
---
## Meta-Prompting: How to Write Tick Prompts
Every tick generates a prompt for `lev exec`. The prompt must answer 5 questions:
### The 5 Questions
1. **What does PASSING look like?** Show a reference file/module that already works.
2. **What does FAILING look like?** Show the exact current state or error.
3. **What specifically needs to change?** File, section, old value → new value.
4. **What must NOT change?** Scope boundary. "Touch ONLY these files."
5. **How do I verify?** Shell command that exits 0 on success.
### Tick Prompt Template
```
You are executing a [{tick_type}] tick for loop [{loop_id}].
## Context
{Read the loop YAML. Read the PRD. Read the last tick report.}
## Current State
{What exists now. Word counts, file paths, quality scores.}
## Task
{Specific work for this action. One item per worker; a tick may start many workers.}
## Reference
{A file that shows what "good" looks like for this type of work.}
## Scope
Touch ONLY: {list of files}
Do NOT modify: {exclusion list}
## Done Criteria
1. {Verifiable condition 1}
2. {Verifiable condition 2}
3. {Shell command that exits 0}
```
### Bad vs Good
**Bad** (vague, no verification):
```
Write another article about constraint engineering.
```
**Good** (specific, bounded, verifiable):
```
You are executing an [article] tick for loop [content-gtm-sprint].
## Task
Write article "Two Axioms and Everything That Follows" (WRITE-011 from PRD).
Deep dive into C1 Finitude and C2 Non-Commutation from dna/graph.yaml.
## Reference
Read content/articles/the-genesis-pattern-four-steps-to-ai-native-software.md
— it demonstrates the right voice, structure, and depth. 2,118 words.
## Scope
Create ONLY: content/articles/two-axioms-and-everything-that-follows.md
Do NOT modify existing articles.
## Done Criteria
1. File exists at content/articles/two-axioms-and-everything-that-follows.md
2. Word count >= 1200
3. Contains "C1 Finitude" and "C2 Non-Commutation"
4. Contains at least one quote from dna/graph.yaml
5. wc -w content/articles/two-axioms-and-everything-that-follows.md | awk '{exit ($1 < 1200)}'
```
---
## Single Tick Execution
Each tick follows this 10-step procedure:
```
1. LOAD loop YAML from .lev/loops/<loop-id>/loop.yaml
2. LOAD state from .lev/loops/<loop-id>/state.json
3. SELECT tick type using ordering strategy + constraints
4. GENERATE prompt using meta-prompting template + current state; freeze its
acceptance digests before step 5 (Evaluator Integrity Rule)
5. EXECUTE via lev exec or inline (Agent tool for complex, Read/Edit for simple)
6. RECORD result to .lev/loops/<loop-id>/ticks/<tick-number>.json
7. UPDATE state.json (tick count, type history, advancement tracking)
8. CHECKPOINT git: stage only the tick's task-owned paths from its Scope
(git add -- <path>...; never broad staging), then
git commit -m "levloop: {tick_type} — {summary}"
9. EMIT telemetry (tick type, duration, files changed, advancement)
10. SELECT next tick (or exit if circuit breaker / duration limit)
```
### State Schema
```json
{
"loop_id": "content-gtm-sprint",
"total_ticks": 14,
"ticks_by_type": { "article": 5, "review": 3, "manifesto": 3, "research": 2, "discover": 1 },
"consecutive_type": { "type": "article", "count": 2 },
"consecutive_no_advancement": 0,
"last_tick": { "number": 14, "type": "review", "advanced": true, "timestamp": "..." },
"created": "2026-04-10T18:00:00Z",
"scheduled_cron_id": "cron-abc123"
}
```
---
## Scheduling
### Slice Mode (one tick)
```
/levloop run # Scan → pick type → execute → checkpoint
```
### Time Mode (recurring)
```
/levloop schedule 10m # CronCreate with 10min interval
/levloop schedule 6h # Auto-stop after 6 hours
/levloop stop # CronDelete
```
Time mode is slice mode on a cron. Each tick runs independently with fresh context.
Memory persists through the filesystem (state.json, tick reports, git history).
### Exit Taxonomy
| Exit Reason | Trigger |
|-------------|---------|
| `no_work` | First scan found zero actionable items |
| `all_done` | PRD stories all have `passes: true` |
| `budget_exhausted` | Token usage crossed budget |
| `circuit_breaker` | K consecutive no-advancement ticks |
| `duration_limit` | Schedule duration exceeded |
| `interrupted` | SIGINT, SIGTERM, or manual `/levloop stop` |
---
## Dynamic Flowmind Generation
Between ticks, auto-generate an adversarial diagnostic flowmind. Its
post-output probes sit beside the tick's frozen acceptance (Evaluator Integrity
Rule): a failed probe records a diagnostic and may trigger the escalate fix
below, but any revision still passes only on frozen acceptance.
1. Read the previous tick's output (files changed, report)
2. Extract invariants that should hold (word count, voice consistency, no forbidden patterns)
3. Generate a 3-node flowmind YAML:
```yaml
name: tick-validation-{tick_number}
entry: check
nodes:
check:
op: lev.validate
inputs:
command: |
# Check invariants from previous tick
wc -w {file} | awk '{exit ($1 < 1200)}'
grep -q "constraints are the product" {file}
! grep -qi "game-changer\|rapidly evolving\|in conclusion" {file}
branches:
pass: report
fail: escalate
report:
terminal: true
escalate:
op: lev.exec
inputs:
task: "Previous tick output failed validation. Fix: {failure details}"
next: check
max_iterations: 2
on_timeout: report
```
4. Save to `.lev/loops/<loop-id>/flowminds/validate-tick-{n}.flow.yaml`
5. Run before the next creative tick
### C4 Ratchet for Validation
If the same invariant fails 3+ times across ticks, promote it from the generated
flowmind to the loop's `validation` section (permanent) as a new evaluator
generation recorded between ticks; it binds ticks that begin afterward. Gates
only move forward.
---
## Rounds vs Turns
| Unit | Definition |
|------|-----------|
| **Turn** | One agent interaction (one prompt → one response) |
| **Round** | A unit of work measured by context fill % OR turn count |
| **Tick** | One loop iteration. May contain multiple rounds. |
| **Loop** | The entire scheduled sequence of ticks. |
```
Loop
└── Tick (selected by type system)
└── Round (bounded by context % or turn count)
└── Turn (single agent interaction)
```
View on GitHub