Claude
Skills
Sign in
Back

start

Included with Lifetime
$97 forever

Scaffold LOOP_CONTRACT.md in the current project and kick off a self-revising autonomous loop.

General

What this skill does


# autoloop: Start

Scaffold `LOOP_CONTRACT.md` and start a self-revising `/loop` that reads the contract each firing.

> **Self-Evolving Skill**: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.

## Arguments

- Positional (optional): contract file path. Defaults to `./LOOP_CONTRACT.md`.

## Step 1: Ensure hooks are installed

Install BOTH autoloop hooks into `~/.claude/settings.json` if not already present. Idempotent.

- **PostToolUse → `heartbeat-tick.sh`** — ticks heartbeat on every tool invocation, detects cwd drift.
- **SessionStart → `session-bind.sh`** — authoritatively binds `owner_session_id` from stdin payload (replaces broken `$CLAUDE_SESSION_ID` env-var capture; ref [anthropics/claude-code#47018](https://github.com/anthropics/claude-code/issues/47018)).
- **PreToolUse(ScheduleWakeup) → `pacing-veto.sh`** — denies pacing-disguised wakers (delays in the 300–1199s cache-miss zone, or any >270s with token-budget/cache-warm/self-pacing/cooldown/rest in the reason text). Forces Tier 0 (in-turn) when no real external blocker exists.

```bash
# Source the hook install library
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$HOME/.claude/plugins/marketplaces/cc-skills/plugins/autoloop}"
source "$PLUGIN_ROOT/scripts/hook-install-lib.sh"

# Wave 5 A4: strip macOS quarantine xattrs in case this is the first run
# after `claude plugin marketplace add`. No-op on Linux / clean trees.
strip_plugin_quarantine_xattrs "$PLUGIN_ROOT" >/dev/null 2>&1 || true

# Wave 5 A8: explicit "auto-setup-on-start". If neither hook is installed,
# announce that we're running first-time setup before the install_all_hooks
# call so the user understands the side effect. If both are already
# installed, stay quiet — there's nothing to surface.
SETTINGS_PATH="$HOME/.claude/settings.json"
if [ "$(is_hook_installed "$SETTINGS_PATH" 2>/dev/null)" != "yes" ] || \
   [ "$(is_session_bind_installed "$SETTINGS_PATH" 2>/dev/null)" != "yes" ]; then
  echo "Installing autoloop hooks into ~/.claude/settings.json (one-time setup)..."
fi

# Install all four autoloop hooks (idempotent). DO NOT swallow stderr —
# install_all_hooks emits actionable diagnostics on failure (malformed JSON,
# write errors, missing hook scripts) that the user needs to see. If install
# fails, abort the bootstrap rather than continuing into a half-bootstrapped
# state where the loop appears registered but session-bind / heartbeat /
# pacing-veto / empty-firing-detector never run.
if ! install_all_hooks; then
  echo "ERROR: Failed to install autoloop hooks." >&2
  echo "  The bootstrap cannot continue safely — a registered loop without" >&2
  echo "  its hooks installed is what /autoloop:tinker calls F2_missing_hooks." >&2
  echo "  Inspect: jq . $SETTINGS_PATH ; ls $PLUGIN_ROOT/hooks/" >&2
  exit 1
fi

# Wave 6 anti-fragility (v12.52.0+): runtime self-test the just-installed
# hooks. Without this, a hook can be registered in settings.json yet crash
# on real invocation due to: missing shebang, broken shellcheck disable,
# stale path to a sibling lib, syntax error from a botched edit, missing
# dependency. The self-test catches those by feeding each hook a synthetic
# Claude Code event payload in a sandbox HOME and asserting exit 0.
if ! run_hook_runtime_selftest "$PLUGIN_ROOT" 2>&1; then
  echo "ERROR: Autoloop hook runtime self-test failed." >&2
  echo "  Hooks were registered in settings.json but at least one crashes" >&2
  echo "  on invocation. Inspect the FAIL line(s) above." >&2
  echo "  Recover: /autoloop:tinker will redo the install with diagnostics." >&2
  exit 1
fi
```

Result: every Claude session opening in a registered loop's contract dir will (1) bind to the loop on SessionStart, then (2) tick heartbeat with cwd-drift detection on every tool invocation.

## Step 2: Preflight (v2 layout — `.autoloop/<slug>--<hash>/CONTRACT.md`)

Wave 3 introduced a new on-disk layout: contracts live under
`<project_cwd>/.autoloop/<campaign-slug>--<short-hash>/CONTRACT.md` with a
sibling `state/` directory. This makes multi-campaign coexistence in one cwd
first-class and lets any AI agent ID the right contract by directory name.

**Migration is automatic on first `/autoloop:start` in any directory that
contains a legacy `<cwd>/LOOP_CONTRACT.md`:**

```bash
PROJECT_CWD="${1:-$(pwd -P)}"
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$HOME/.claude/plugins/marketplaces/cc-skills/plugins/autoloop}"
source "$PLUGIN_ROOT/scripts/registry-lib.sh"
source "$PLUGIN_ROOT/scripts/state-lib.sh"

# Returns "noop" if nothing to migrate, or two lines starting with
# "migrated_to_loop_id:" / "migrated_to_path:" on success.
MIGRATION_OUTPUT=$(migrate_legacy_contract "$PROJECT_CWD" "${CLAUDE_SESSION_ID:-$$-$(date +%s)}")
if [ "$MIGRATION_OUTPUT" != "noop" ]; then
  echo "$MIGRATION_OUTPUT"
  echo "Legacy LOOP_CONTRACT.md migrated to .autoloop/ subdir; resuming with new layout."
fi
```

**Then check whether ANY v2 contract already exists for this project:**

```bash
existing=$(compgen -G "$PROJECT_CWD/.autoloop/*--[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]/CONTRACT.md" 2>/dev/null || true)
if [ -n "$existing" ]; then
  echo "v2 contract(s) present:"
  echo "$existing"
  # Ask the user: resume an existing campaign, start a new one alongside, or stop?
fi
```

Use `AskUserQuestion` to choose: **resume existing**, **start new campaign alongside** (creates a second `.autoloop/<slug>--<hash>/`), or **stop**.

## Step 3: Collect contract inputs

Use `AskUserQuestion` to collect:

```
1. name        — short slug for this loop (e.g. "odb-research", "flaky-ci-watcher")
2. scope       — one-line Core Directive describing the long-horizon goal
3. cadence     — typical wake-up cadence hint (continuous | event-driven | hourly | daily)
```

The contract path is **derived deterministically** from `name` + a stable
short_hash, so the user does not pick a path:

```bash
SLUG=$(slugify "$NAME_INPUT")
SHORT_HASH=$(compute_short_hash "${CLAUDE_SESSION_ID:-$$-$(date +%s)}" "$(date -u +%s)")
CONTRACT_DIR="$PROJECT_CWD/.autoloop/${SLUG}--${SHORT_HASH}"
CONTRACT_PATH="$CONTRACT_DIR/CONTRACT.md"
mkdir -p "$CONTRACT_DIR/state/revision-log"
```

If `$CONTRACT_DIR` already exists, append a numeric suffix to short_hash or
ask the user to pick a different `name`.

## Step 4: Scaffold the contract

Copy the plugin-shipped template and substitute placeholders. Use
`$CLAUDE_PLUGIN_ROOT` (set by Claude Code for every plugin skill) to
resolve the template — **do not use `$0`**, which is not set when a
SKILL.md is loaded as instructions rather than executed as a script.

```bash
# CLAUDE_PLUGIN_ROOT points at /…/plugins/<plugin-name> when invoked from
# a skill. Fall back to the marketplace cache path if unset (e.g., when a
# user invokes the skill's Bash manually outside the harness).
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$HOME/.claude/plugins/marketplaces/cc-skills/plugins/autoloop}"
TEMPLATE="$PLUGIN_ROOT/templates/LOOP_CONTRACT.template.md"
if [ ! -f "$TEMPLATE" ]; then
  echo "ERROR: template missing at $TEMPLATE — reinstall the plugin" >&2
  exit 1
fi
cp "$TEMPLATE" "$CONTRACT_PATH"

# Also copy the PROVENANCE.md template (Wave 3) — sits alongside CONTRACT.md
PROV_TEMPLATE="$PLUGIN_ROOT/templates/PROVENANCE.template.md"
if [ -f "$PROV_TEMPLATE" ]; then
  cp "$PROV_TEMPLATE" "$CONTRACT_DIR/PROVENANCE.md"
fi
```

Then inject user inputs via `sed` (or Edit the file via Claude's tools):

- `<SHORT_DESCRIPTIVE_NAME>` → user-provided `name`
- `<ISO_8601_UTC>` → `date -u +"%Y-%m-%dT%H:%M:%SZ"` (always `-u`; bare `date` returns local time and silently mismatches the contract's UTC fields)
- `<RELATIVE_PATH_TO_LOOP_CONTRACT_MD>` → `$CONTRACT_PATH` (now under `.autoloop/<slug>--<hash>/CONTRACT.md`)
- `<CORE DIRECTIVE>` / `<PROJECT OR CAMPAIGN TITLE>` → user-provided `scope`

After the template is in place, call `init_contract_frontmatter_v2` to stamp
all 
Files: 1
Size: 16.8 KB
Complexity: 24/100
Category: General

Related in General