Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

loops-init

English · 中文

A universal loop bootstrap scaffold — creation-phase bootstrap for one new feature in any project, upgrading "let the agent write, verify, and loop on its own" from prompt-based self-discipline to mechanism-enforced.

loops-init is a Claude Code skill. It only generates scaffolding: extract a spec, generate the builder/checker agents, generate anti-cheat hooks and idempotently merge them into the project's .claude/settings.json, lay down the DoD and the PROGRESS.md execution ledger, then STOP — hand off to human review and restart the session, after which the native Claude Code /goal runs the builder↔checker wave loop.

It does not dispatch agents in this session, does not run the loop, and does not build its own orchestrator.


Why it exists

When you hand a feature to an automated "agent implements → agent checks → loop again if it fails" cycle, the biggest risk isn't that the agent can't write code — it's that it will weaken the check just to make it pass: editing tests, deleting assertions, loosening the checker's criteria, and finally reporting a fake ALL GREEN.

Merely telling the agent "don't cheat" via prompt is not enough (METR's experiments show such prompt-only constraints are 70–95% ineffective). loops-init's answer is three orthogonal layers of defense, produced all at once:

Layer Role Implementation
① Verification layer builder writes, checker verifies — separation of duties the checker's tools: field has no Write/Edit = physically read-only
② Anti-cheat layer enforce at the mechanism layer (not via prompt) three hooks: PreToolUse / Stop / PostToolUse
③ Loop-control layer deterministic turn cap + continuous main agent with no amnesia + per-round evaluator feedback native Claude Code /goal

Core tenet: the checker physically cannot write code; the builder physically cannot touch the "loop-control source of truth" (spec / agents / hooks / settings / ledger). The path of weakening checks is sealed at the mechanism layer, rather than relying on the agent's self-discipline.


Design references

loops-init's loop design — "Think → Act → Observe → Verify → Evolve → Repeat", when to stop, how to verify, how to recover — draws directly on the Loop / Harness engineering material below. This project takes their thesis that "the gap between a hobby project and a production system lies in Harness engineering (including the Loop)" and turns it into a mechanism-enforceable bootstrap scaffold.

Recommended reading

  1. Loop Engineering — Addy Osmani (addyosmani.com)
  2. Loop Engineering — Firecrawl (firecrawl.dev)
  3. What Is the AI Agent Loop? — Oracle (blogs.oracle.com)
  4. Harness Engineering — OpenAI (openai.com)
  5. Harness Engineering for Coding Agent Users — Martin Fowler (martinfowler.com)
  6. Agentic Loops: From ReAct to Loop Engineering (datasciencedojo.com)
  7. Loop Engineering for AI Agents (Memory-First) — Mem0 (mem0.ai)

Recommended papers

  1. Agentic Harness Engineering — arXiv:2604.25850
  2. From Agent Loops to Structured Graphs — arXiv:2604.11378

Two-phase design

Phase 1 — this skill (one session)
  Step0 align → 1 extract spec → 2 fill agents → 3 probe infra
  → 4 gen hooks + merge settings → 5 golden compare → 6 write & [STOP]
        │
        ▼   (human reviews spec/agents, then restarts the session)
        │
Phase 2 — human + native /goal
  paste the /goal driver → builder↔checker loop, wave by wave, until ALL GREEN

Why you must stop and restart: Claude Code loads .claude/agents/*.md and hooks at session start. The agent/hook just Written in this session can't be invoked / isn't in effect in the current session — only a restart brings them online. So "write files → stop → human review → restart" is a hard requirement, not optional.

loops-init vs native /loop vs native /goal

Claude Code ships with two loop-related built-in skills: /loop and /goal. The three are not at the same layer and aren't competitors — once you see the division of labor, you see which gap loops-init fills.

native /loop native /goal loops-init
Essence a session-level scheduler that re-triggers on a time interval a loop engine that iterates toward a completion condition a bootstrap-scaffold generator for the loop (doesn't run the loop itself)
Drive signal the clock (/loop 5m …; omit the interval → dynamic 1 min–1 hr) completion condition + an evaluator (a small model, usually Haiku) that judges and gives feedback each round ——
When it stops manual stop / expires after 7 days the condition is judged satisfied by the evaluator; no built-in turn cap, you can explicitly add "stop after N rounds" stops as soon as files are written; hands off to human review + restart
Cross-round context each trigger is relatively independent the main agent never loses memory throughout ——
Who does the work the single prompt/command you gave a single main agent iterating across rounds (no native subagent dispatch) generates the two agents builder/checker + anti-cheat hooks + DoD
Verification / anti-cheat none none (only judges whether the condition is met) the core: physically read-only checker + mechanism-layer hooks that seal off "weakening checks"

loops-init complements /goal, it doesn't replace it: in Phase 2, the loop that actually drives builder↔checker is the native /goal. The "driver string" loops-init emits is essentially a carefully constructed /goal goal — it fills in, one by one, the blanks /goal leaves open:

  • turns /goal's abstract condition into a mechanically verifiable DoD (only "all DoDs judged ALL GREEN by the checker, with no check weakened" counts as done);
  • turns /goal's "single main agent does the work" into dispatching builder to implement and checker to verify each round (the subagent orchestration is written into the goal string by loops-init, not a native /goal capability);
  • supplies the turn cap /goal lacks, explicitly adding "stop after 8 rounds / stop on the same failure twice";
  • adds the hooks /goal doesn't care about at all — defending against cheating at the mechanism layer.

In one line: /goal provides the engine ("iterate until the condition is met + evaluator + no amnesia"), and loops-init provides the "fuel and guardrails fed to the engine" — the verification criteria, the per-round division of labor, the anti-cheat boundary. /loop (time-based repetition) has essentially no overlap with this goal iteration: you wouldn't use /loop to run builder↔checker.


Spine dependency order (inviolable)

Step0 align → Step1 extract spec → Step2 fill agents → Step3 probe infra → Step4 gen hooks + merge settings → Step5 golden compare → Step6 stop (emit /goal)
               ▲ no entry to Step2 until spec on disk      ▲ probing decides conditional gen      ▲ [MANDATORY] live-test agent_type before going online

Spec must precede agents: the multi-line blocks Step2 fills into the agent (naming / existing assets / coverage targets / semantic points) are excerpted directly from the spec. Without an actually-extracted spec, the agent is an empty shell — and an empty-shell checker will declare a false ALL GREEN.

Step What it does Output / key action
Step 0 Align with the source of truth Bash auto-probe + two AskUserQuestion batches (hard prerequisites / soft defaults); choose builder/checker models <SPEC_DIR>/00-alignment.md. Source of truth "none yet" → STOP
Step 1 Extract spec draft Mechanical layer dumps .xlsx/.xls → judgment layer maps by "source → spec md"; four kinds of doubt surfaced mechanically, not adjudicated for the user each spec md + _manifest.json coverage ledger
Step 2 Fill agent drafts Read the template masters, intelligently fill {{...}}, preserve non-placeholder sentences verbatim; archive conflicting old agents agents/builder.md checker.md + dod/wave*.yaml + PROGRESS.md
Step 3 Probe infra probe-infra.shHAS_GIT/HAS_TEST/CAN_COMPILE/OS/SHA_CMD; probe-hooks-enabled.sh → whether hooks can actually run decides subsequent conditional generation
Step 4 Generate hooks + merge settings Live-test agent_type before going online; render.sh renders → merge-settings.sh idempotently merges .claude/hooks/*.sh + registered into settings.json
Step 5 Golden comparison Re-render each hook with canonical.values, diff verbatim against fixtures/hooks.golden/ mismatch = template tampered → stop and alarm
Step 6 Write and stop Print the delivery report + emit two /goal driver strings → end the turn the only endpoint, never runs the loop

Generated artifacts

Artifact Location Role
builder agent .claude/agents/builder.md implements / fixes only; has Write/Edit but can't touch protected paths
checker agent .claude/agents/checker.md checks only, no Write/Edit (physically read-only); judges by rule-id across 5 categories (coverage / naming / style / reference / semantics)
anti-cheat hooks .claude/hooks/{loop-guard,loop-stall,post-audit}.sh see table below
DoD <SPEC_DIR>/dod/wave*.yaml each carries a rule id + a pre-assertion that currently must FAIL + a post-assertion with content-level grep
execution ledger <SPEC_DIR>/PROGRESS.md wave-level state machine pending→in-progress→GREEN|ESCALATED; only the main /goal session can write

The three hooks

hook event responsibility
loop-guard PreToolUse the unconditional anti-cheat core. Routes by agent_type: allow the main session; block any sub-agent writing to protected paths (spec / agent / CLAUDE.md / settings / hooks / .loop-state) — covering Write/Edit-family tools and Bash bypass-writes
loop-stall Stop idle detection. Content-hash snapshot of the watched file set; N consecutive rounds with no change → decision:block forces a stop, instead of burning to the turn cap
post-audit PostToolUse traces to audit.log (fires after the write, for post-hoc traceability only)

Conditional generation matrix (degrades with project capability, but the anti-cheat core is never absent)

Project capability loop-guard (anti-cheat) loop-stall (idle) post-audit (audit) DoD
Unconditional ✅ full
Has git Upgrade: commit + git diff HEAD to detect empty diff Upgrade: git diff count assertions / detect sneaky edits
Has test Upgrade: run $TEST_CMD to judge progress Upgrade: run test to judge regression Upgrade: runnable red→green test
No git, no test ✅ full Downgrade: content-hash snapshot, force a stop after N unchanged rounds Downgrade: only audit.log trace Downgrade: static assertions

loop-guard is decoupled from git/test: what degrades is only the precision of stall/audit, not the anti-cheat itself.


Directory structure

loops-init/
├── SKILL.md                      # main skill doc (English; full Step0–6 + §7 boundaries + §8 checkpoint)
├── lib/
│   ├── probe-infra.sh            # probe HAS_GIT/HAS_TEST/CAN_COMPILE/OS/SHA_CMD
│   ├── probe-hooks-enabled.sh    # probe whether hooks can actually run (fail-loud)
│   ├── render.sh                 # pure-bash literal substitution of __NAME__ placeholders
│   └── merge-settings.sh         # idempotently merge hooks into settings.json (purge-then-add + marker fingerprint)
├── templates/
│   ├── hooks/{loop-guard,loop-stall,post-audit}.tmpl.sh   # already debug-hardened; render only substitutes __X__
│   ├── agents/
│   │   ├── builder.tmpl.md        # {{...}} filled intelligently per spec
│   │   ├── checker.tmpl.md        # tools line has no Write/Edit
│   │   └── progress.tmpl.md       # scaffolds the PROGRESS.md ledger
│   └── dod/wave.dod.tmpl.yaml     # per-wave DoD template
└── fixtures/
    ├── canonical.values           # fixed neutral values for the Step5 golden comparison
    └── hooks.golden/              # golden snapshots (verbatim expected output of render(template, canonical))

Two placeholder systems, don't mix them: hook templates use __NAME__ (render.sh mechanical literal substitution); agent / dod / progress templates use {{NAME}} (loops-init fills intelligently by reading the spec + CLAUDE.md, not mechanical substitution).


Usage

1. Trigger (Phase 1)

/loops-init <feature ID or one-line requirement>

The skill runs through Step0–6, writes the files into the project's .claude/, then stops, and prints a delivery report (paths of each spec md + all doubts, the two agent paths + the pending-review list, the PROGRESS ledger, the hooks registration status, archived old agents).

2. Human review, 3 steps (Phase 2 begins)

  1. review the spec's contradiction resolutions / semantic-ambiguity items;
  2. calibrate the agents' domain sections, removing the <!-- ⚠️ 草稿·待人审 --> markers;
  3. restart the session (so the new agents + hooks load and take effect).

3. Paste the /goal driver string to run the loop

The skill emits two native /goal driver strings; after restart, pick one:

  • Mode A · Wave-by-wave human review (default, recommended): one string per wave; review the previous wave's PROGRESS before pasting the next. Wave boundary = human-review gate + fresh context per wave.
  • Mode B · One-shot run-to-completion (opt-in): a single composite string; the main /goal session advances all waves in order by itself. The cost: losing the inter-wave human-review gate, main-context bloat across waves, blurred stop semantics — for single-wave projects the two modes are equivalent; just use A.

The loop's brake: a wave that hits "the same failure twice (compared by rule-id, not file:line)" or "8 rounds not reached" stops at that wave, and writes the triggering rule-id + the checker's verbatim words into the "repeatedly-failing rule-id" zone of PROGRESS.md, for humans to harden the spec.


Key mechanisms

  • agent_type live-test (the linchpin): before bringing loop-guard online, first install a temporary probe that only echos and allows everything, and confirm with your own eyes the agent_type value the main session sends — if it's "main", tighten to fail-closed; if it's absent, keep it lenient (otherwise you'd lock out the main session / human reviewer). Before the live test, do not go online fail-closed.
  • Idempotent settings merge: merge-settings.sh uses purge-then-add + a marker fingerprint at the command tail (# loops-init:NAME:vN), keeping only the current version, never overwriting the user's existing permissions / env / other hooks; re-running won't leave v1/v2 coexisting and running deny twice.
  • Golden comparison guards against backsliding: the hook templates are debug-hardened one by one (no pipefail, ${var} to prevent unbound, [^[:alnum:]_] boundaries, etc.). Step5 uses the golden snapshots to catch "optimizing the template back into the pit". If you change a template you must regenerate fixtures/hooks.golden/ with render.sh, or Step5 will alarm.

Known boundaries (§7, told truthfully, no "fully sealed" illusion)

  • As long as the checker/builder keeps Bash, you cannot 100% prevent "writing files via Bash" (Turing-complete: python -c open() / base64 / redirection; regex can't catch them all). loop-guard's Bash interception blocks "casual/lazy weakening of checks", not "deliberate bypass".
  • builder/checker is a non-adversarial scenario (the agent only cuts corners to fake green, it's not an attacker), so "blocking the casual" suffices — this is an accepted residual, not a blocker. Rooting it out would require shrinking the checker's Bash to a command allowlist; not worth it in a non-adversarial scenario, left as go-forward.

Checkpoint and rollback (§8)

  • Wave-level checkpoint (HAS_GIT only): after each ALL GREEN wave and PROGRESS is written, the main session runs git tag loop-wave<N>-green, recording the tag name in PROGRESS's checkpoint column; failed waves are not tagged.
  • Rollback is manual: git reset --hard loop-wave<N>-green (destructive, discards all changes after that point). The rollback target only recognizes waves with status=GREEN (with checker evidence) in PROGRESS — even if the builder forges a tag via Bash it's harmless (it can't write PROGRESS).
  • Auto-rollback is not implemented: this version chooses "stop and hand off to a human + preserve the failure scene for diagnosis".

Design philosophy

This skill produces only the project-agnostic layer (scaffold structure, the three guardrails, the 5-category cross-check framework, the hook mechanism, the /goal shape, the boundaries). Supplied by the project (differs per project): the source-of-truth format and path, tech stack / iron laws (read the project CLAUDE.md; this skill only reads, never writes), naming, whether it compiles / is testable, the read-only reference directory.

So the upper bound on this skill's output quality = the quality of the target project's CLAUDE.md + source of truth. Garbage in, garbage out.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages