Citadel Loop Contract

June 9, 2026 ยท View on GitHub

Citadel treats a loop as a bounded operating contract, not as "keep prompting until something happens." A loop can be manual, scheduled, Codex-native, daemon-backed, PR-driven, or foreground-only, but it should always expose the same reviewable parts.

Contract Fields

Every loop record should declare:

FieldPurpose
idStable loop identifier.
typeWorkflow family, such as foreground-loop, daemon, pr-watch, or schedule.
triggerWhat starts the loop: manual command, schedule, daemon tick, Codex automation, file watch, or PR check.
inputGoal or queue the loop consumes.
scopeFiles, repo area, PR, issue queue, or project boundary the loop may touch.
permissionsFilesystem, network, and approval assumptions.
budgetAttempt count, spend ceiling, or per-run cost model.
verifierCommand, verification profile, or external status that decides whether work is done.
retryMaximum attempts and optional backoff.
stopConditionsShared terminal states that end or pause the loop.
statePathDurable state record under .planning/loops/ or a legacy state file.
reviewArtifactReport, PR, package, or evidence file a human can inspect.
recoveryHow to continue or roll back if the loop stops midstream.

Shared Stop States

All loop-like workflows should use the same stop vocabulary:

StatusMeaning
doneWork completed by the loop's declared standard.
verifier-passedThe verifier passed and the loop stopped successfully.
verifier-failedThe verifier failed and no autonomous repair should continue.
blockedThe loop cannot make safe progress without new information.
budget-exhaustedThe spend, time, session, or attempt budget was reached.
attempt-limitThe retry ceiling was reached.
needs-human-reviewA human decision is required before more work.
unsafe-to-continueThe loop stopped before taking a risky action.
no-active-workThere is no campaign, PR, queue item, or task left to process.
stoppedThe user or operator explicitly stopped the loop.

Registry

First-class loop records live in:

.planning/loops/{loop-id}.json

node scripts/loops.js list also reads legacy loop state such as:

  • .planning/daemon.json
  • .planning/codex-automations/*.json

This keeps older workflows visible while new workflows adopt the common contract.

Built-In Templates

Citadel ships these loop templates through core/loops/templates.js:

TemplateUse
pr-review-repairMonitor a PR, read review/CI feedback, and apply bounded targeted fixes.
issue-triagePeriodically classify new issues and write a reviewable summary.
dependency-refreshCheck dependency drift and verify safe updates.
docs-drift-checkDetect public docs or command drift.
nightly-healthRun routine project health checks and summarize blockers.
visual-qaExercise UI routes and capture inspectable evidence.
security-scanRun bounded security checks and stop for human review.
demo-proof-refreshRefresh operating-loop proof artifacts.

Preview templates with:

node scripts/loops.js templates

Create a plan from a template with:

node scripts/loops.js plan --template docs-drift-check --write

Foreground Loops

Use /loop or node scripts/loop-runner.js for bounded repetition inside the current session:

node scripts/loop-runner.js --action "npm run lint -- --fix" --verify "npm run lint" --max-attempts 3 --write

The verifier controls success. If the verifier passes, the loop stops with verifier-passed. If attempts run out, it stops with attempt-limit.

Design Rule

Do not add a new autonomous or repeated workflow without either:

  1. Writing a loop contract record, or
  2. Explaining why it is not a loop.

The goal is simple: every repeated agent workflow should be inspectable, bounded, reversible, and easy to stop.