Skip to main content

loopuccino

Brew a better handoff.

CI Release PyPI License: MIT Python 3.9 through 3.13

What is loopuccino

loopuccino is a pair: an Agent Skill that designs the loop, and a CLI that checks the paperwork the loop leaves behind. The skill turns iterative, long-running, or multi-agent AI work into an explicit contract — what the outcome is, which evidence decides it, and when to stop without success. The CLI is the deterministic gate on the way out: it reads one handoff.md and reports whether the next session can resume from it without guessing.

Quick start

git clone https://github.com/Noah-TaeHwan/loopuccino.git && cd loopuccino
pipx install loopuccino                          # or: uv tool install loopuccino
loopuccino install --platform claude --apply      # -> ~/.claude/skills/loopuccino

Start a new session in your agent and /loopuccino is available. The CLI is published to PyPI (pipx install loopuccino / uv tool install loopuccino); the Agent Skill wires in from the checkout via loopuccino install, which symlinks the skill directory from the repository source.

The CLI

loopuccino init writes a starter handoff. It refuses to replace an existing file unless you pass --force, and exits 2 when it refuses.

$ loopuccino init
loopuccino init: wrote handoff.md

loopuccino check reads one Markdown file, writes nothing, and exits 0 when no errors were found.

$ loopuccino check handoff.md
loopuccino check: handoff.md

PASS  CHECK-OK     Required handoff contract checks passed

Result: PASS (0 errors, 0 warnings)

A document that is missing a required part fails with a diagnostic and exit 1:

$ loopuccino check bad.md
loopuccino check: bad.md

ERROR STRUCT-001            Missing required section: goal

Result: FAIL (1 errors, 0 warnings)

loopuccino check --contract adds the opt-in loop contract layer described below.

loopuccino status reads a loop contract card and the loop-log.jsonl beside it, and prints where the loop stands — so progress can be checked without interrupting whatever is running. --all prints the three most recent events instead of only the latest.

$ loopuccino status loop-contract.md
state  in_progress (mode: durable)
last   [round 3] verifier: pass — 18/18 re-verified
next   Re-run the acceptance oracle, then record the result here.

loopuccino install wires the Agent Skill into an agent's skill directory. It reports the target state and changes nothing until you pass --apply:

$ loopuccino install --platform claude
loopuccino install: platform=claude
source  ~/src/loopuccino/skills/loopuccino
target  ~/.claude/skills/loopuccino
status  MISSING  not installed
run again with --apply to perform the change

$ loopuccino install --platform claude --apply
loopuccino install: platform=claude
source  ~/src/loopuccino/skills/loopuccino
target  ~/.claude/skills/loopuccino
status  OK       symlink -> ~/src/loopuccino/skills/loopuccino

Both paths print in full; they are shortened to ~ here.

loopuccino update reports whether the installed CLI, the checkout, and the skill wiring are in sync, and checks GitHub for a newer release (offline is fine — the check degrades to local-only). Nothing changes without --apply, which pulls the checkout and reinstalls the CLI:

$ loopuccino update
loopuccino update: checkout ~/src/loopuccino
cli      0.8.0 (installed)
checkout 0.9.0 (pyproject)
latest   0.9.0 (github)
skill    claude  OK       symlink -> ~/src/loopuccino/skills/loopuccino
verdict  cli 0.8.0 < checkout 0.9.0
action   reinstall the CLI from ~/src/loopuccino
run again with --apply to perform the update

The handoff contract

The file must contain these H2 sections:

Section Purpose
State state and previous_state values
Goal The intended outcome
Current state What is true now
Done Completed work or acceptance items
Blocked reason, owner, and decision_needed, or none for all three
Changed files Files changed in the work session
Verification command and result entries
Next action The first useful action for the next session
Resume command A concrete command, path, or document reference

Allowed states are planned, in_progress, blocked, ready_for_review, verified, handed_off, and closed. A verified or closed handoff needs a recorded passing result such as passed, success, or green; loopuccino does not rerun the command.

Start from the synthetic template in template/handoff.md. loopuccino init writes that same file for you.

The loop contract

loopuccino check --contract handoff.md adds one optional layer on top of the handoff contract. It checks whether the document declares the five parts of an execution contract before anyone claims the work is done:

Slot Heading the checker looks for What it adds over the handoff contract
Outcome and non-goals Outcome and non-goals Goal states the intent; this states the observable result and what must not change
Authority and action boundary Authority and action boundary Which inputs win, which acts are allowed, and which need approval
Current state and next action Current state plus Next action, or a combined Current state and next action Already covered by the handoff contract; accepted in either form
Acceptance evidence Acceptance evidence Verification records what was run and what came back; this declares up front which check decides which claim, and what it cannot prove
Bounds, stopping, and handoff Bounds, stopping, and handoff Attempt, cost, and time bounds, what counts as no progress, and when to stop without success

The flag is opt-in. Without it no CONTRACT-* diagnostic is ever emitted, so a handoff that never adopted this contract is never failed for omitting it.

Why these checks read structure only

These checks decide one question: is each slot declared, non-empty, and formatted as a declaration? They do not decide whether a declared outcome is the right outcome, whether an action boundary is safe, whether the named evidence actually proves the claim, or whether the work is genuinely finished. Those are judgement calls, and a regular expression that imitated them would produce confident output with nothing behind it. That would break the safety boundary below: loopuccino reports structure and does not vouch for truth.

The Agent Skill

The repository ships loopuccino as an Agent Skill. It is plain Markdown, so any harness that reads skill-style instructions can use it. It is meant to trigger when AI work is iterative, long-running, resumable, unattended, cross-session, high-risk, or multi-agent — the cases that need evidence-closed completion, explicit stopping, recovery, challenge, or handoff. Triggers are written in English and Korean.

The method is one contract and three modes. The contract names five things before work starts: the outcome and non-goals, the authority and action boundary, the current state and next action, the acceptance evidence that decides which claim, and the bounds, stopping, and handoff rules. The mode is the smallest mechanism that fits — micro when iteration fits in one response, durable when the work must survive a context boundary, and orchestrated only when independent evidence or disjoint parallel work actually justifies coordination. The loop itself is ACT -> CHECK -> DECIDE, with a rare fresh-eyes challenge inside DECIDE when machinery is growing but evidence is not.

For unattended or judged runs in Claude Code, read Claude Code goal/loop and instantiate the thin goal and loop templates per project. Other harnesses reuse the same templates; only the command surface differs.

Cross-agent install matrix

Platform Target Method Notes
claude ~/.claude/skills/loopuccino symlink Tracks the checkout; pulling the repo updates the skill
codex ~/.codex/skills/loopuccino symlink Same as above
agents ~/.agents/skills/loopuccino symlink Same as above, for harnesses that read ~/.agents/skills
hermes <--dest>/loopuccino copy --dest is required; commit the copy in that repository and redeploy so its runtime picks it up

Without --apply the command only reports each target's state:

Status Meaning
OK Installed and pointing at this checkout
MISSING Nothing at the target path yet
STALE A symlink pointing somewhere else; --force replaces it
CONFLICT A real directory is in the way; loopuccino refuses to touch it

Real directories at a target path are never removed. For hermes, --force refreshes the copy.

Design principles

  • Smallest mode. The skill starts at the least machinery that can work, and does not promote to durable or orchestrated modes just because tools and agents happen to be available.
  • Evidence-closed completion. COMPLETED requires the declared success condition to be evaluated true with the evidence it named up front. A budget limit, a tool that returned, or a partial check is never completion by itself.
  • Truthful stopping. When a bound is reached, the honest answers are PARTIAL, BLOCKED, or STOPPED, with the best-known artifact preserved — not a claim of success and not a promise to report later.
  • Privacy lint. This repository holds itself to the same standard: a test in the suite scans every tracked text file for private tokens and fails CI if one appears, so nothing from a working session leaks into a public artifact.

Diagnostics and exit codes

  • STRUCT-001: required section is missing.
  • STRUCT-002: required section is empty.
  • STATE-001: state is missing or not allowed.
  • STATE-002: previous-to-current state transition is not allowed.
  • STATE-003: verified or closed has no passing verification result.
  • RESUME-001: blocked handoff is missing a reason, owner, or decision.
  • RESUME-002: next action has no explicit target or command.
  • EVIDENCE-001: non-final state has no passing verification result; this is a warning.

With --contract:

  • CONTRACT-001: a loop contract slot is not declared.
  • CONTRACT-002: a declared slot has no content.
  • CONTRACT-003: a declared slot still holds only unfilled <placeholder> text. A line counts as a placeholder when it is exactly one <...> token, optionally preceded by a list marker and a label: and optionally wrapped in backticks; the slot is only reported when every one of its non-blank lines is such a line, so this check under-reports rather than guesses.
  • CONTRACT-004: Acceptance evidence labels no Structural, Semantic, Operational, or Success line; this is a warning, because a label is only weak evidence that the planes were actually separated.
Exit code Meaning
0 No errors; warnings may be present.
1 Handoff contract errors were found.
2 Usage or input-file error.
3 Unexpected checker error.

Safety boundary

loopuccino is deliberately local and deterministic:

  • It uses only the Python standard library at runtime.
  • check reads one Markdown file and writes nothing.
  • init writes one file at the path you name, and will not replace an existing file unless you pass --force.
  • install only touches the filesystem: no network, Git, or shell calls.
  • update is the one command that reaches further: it may query the GitHub releases API (a single read-only request; nothing is uploaded), and with --apply it runs git pull --ff-only and reinstalls the CLI. check, init, status, and install never touch the network, Git, or a shell.
  • It does not execute commands found in the handoff.
  • Outside of update, it does not inspect Git or the filesystem beyond reading the input path.
  • It does not scan secrets, call a model, or upload content. Outside of update's single read-only release check, it makes no network requests.
  • It emits human-readable output only.
  • It judges the structure of what a document declares. It never judges whether those declarations are true, adequate, or well chosen.

Development

uv sync --extra test
uv run pytest -q
uv build

The project targets Python 3.9 through 3.13. Pull requests run the same test suite across that matrix. Released changes are recorded in CHANGELOG.md.

Name

loopuccino is pronounced loop-oo-CHEE-no — loop plus cappuccino, which is also what the mark draws: steam off the crema tracing a loop. The canonical spelling is lowercase loopuccino for the brand, package, repository, and command. Brand files live in assets/brand/.

License

MIT. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

loopuccino-0.10.0.tar.gz (41.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

loopuccino-0.10.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file loopuccino-0.10.0.tar.gz.

File metadata

  • Download URL: loopuccino-0.10.0.tar.gz
  • Upload date:
  • Size: 41.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for loopuccino-0.10.0.tar.gz
Algorithm Hash digest
SHA256 ab6925e5829fc8cf772040347fac72bbf74c7e66412260d38985c39366e1122c
MD5 30e66e7df704e49056e0d133252ce3ba
BLAKE2b-256 e654b518deddf19f4c7a17323c04db96f65edb0c331b192aacffa702c24e5470

See more details on using hashes here.

Provenance

The following attestation bundles were made for loopuccino-0.10.0.tar.gz:

Publisher: publish.yml on Noah-TaeHwan/loopuccino

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file loopuccino-0.10.0-py3-none-any.whl.

File metadata

  • Download URL: loopuccino-0.10.0-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for loopuccino-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d4c1a6a05a5faa5128cb6f5c6ef52de64166e4ea4fe35b0f2fe8a01281a7c648
MD5 3579534c72d9ad61a817ec56d6048427
BLAKE2b-256 80becf221d00d580c2a654b7f5062a4c36e0c87f0ef57334d1a65d7b5bfb6d68

See more details on using hashes here.

Provenance

The following attestation bundles were made for loopuccino-0.10.0-py3-none-any.whl:

Publisher: publish.yml on Noah-TaeHwan/loopuccino

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page