Skip to main content

giro

Guarded loops for AI coding agents. giro turns a Spec into integrated, verified work through bounded loops that exit exactly two ways — proof, or a hand raised to a human. Nothing silent in between.

Giro — a lap, a loop, a tour in stages. The engine runs the laps; you write the route and take the finish.

Status: pre-alpha (M0). The loop engine, state store, gate runner, and CLI exist and are fully tested against a fake driver. Live agent drivers are the next milestone. Successor to pierg/orchestrion, rebuilt from scratch around a narrower thesis.

The thesis

Most agent frameworks describe what an agent should do and hope it complies. giro inverts that:

Control never crosses an LLM. Content always does.

The giro CLI is a deterministic loop engine. It owns every arrow — state transitions, budgets, gate execution, wave scheduling, escalation. LLM contexts are spawned inside the loop to do the creative work (implement, plan, judge), and each one ends by emitting a JSON envelope. A budget enforced by a while loop cannot be talked out of; an LLM "following instructions" can.

One primitive, two levels

An actor makes an attempt. An independent verifier — a set of gates — judges it. All green: the loop exits with proof. Otherwise the findings feed the next attempt, until the budget runs out and the loop escalates to needs-human. It cannot just stop.

Loop Actor Verifier On fail
Issue loop a fresh worker context [verify] gates retry, findings carried forward
Spec loop a wave of Issue loops [validate] gates findings become gap Issues → next wave

There is no third loop. Validate is the Spec loop's verifier; gap Issues are its feedback. The "lifecycle" is one feedback edge, not a controller.

One verb

giro implement <target>

The router reads the target and picks the level. An Issue runs the Issue loop. A Spec runs the Spec loop — planned into Issues first if it has none. No second entrypoint, no mode flags. When a run ends needs-human, you answer (edit the Issue, decide the question) and run the same command again: re-invoking is the answer, and the budget resets.

Merging giro/<spec> into your main line stays your hand, always.

Gates

A gate is anything that ends in { "verdict": "pass" | "fail", "findings": [...] }.

  • command — a shell command; exit 0 is pass. Deterministic and cheap.
  • prompt — a rubric applied by a fresh, blind judge context.
  • skill — a full SKILL.md procedure, same envelope at the end.

Judges start blind on every attempt; findings feed the next actor, never the next judge. A judge that can't produce the envelope gets one retry, then fails closed. All gates run to completion — the next attempt sees every finding, not just the first.

State

Specs and Issues are markdown with tiny frontmatter, committed beside the code:

docs/specs/<slug>/SPEC.md            state: draft | active | done | needs-human
docs/specs/<slug>/issues/NN-slug.md  state: ready | in-progress | done | needs-human | wontfix

The store is the durable checkpoint: kill the engine at any point and giro implement resumes from exactly where the markdown says. Every attempt appends its story to the Issue file — the history is readable, not buried in a log.

Quickstart

uv tool install giro   # not yet published — for now: uv sync && uv run giro
cd your-project
giro init              # writes giro.toml — set your [verify] gates
giro implement <spec>  # go

Exit codes are the contract: 0 proof, 2 needs-human, 1 error. CI and chat agents read them the same way.

Layout

  • docs/design.md — the founding design: vocabulary, state machines, envelopes, loop contracts, decisions.
  • skills/ — the LLM touchpoints: what workers, judges, and chat doorways are told.
  • src/giro/ — the engine. loops.py is the heart.

Roadmap

  • M0 — engine core (this): guarded loops, gates, store, CLI; proven end-to-end with a fake driver.
  • M1 — live driver: claude -p worker/judge/planner contexts; first real Spec shipped by the machine.
  • M2 — parallel waves: concurrency > 1, isolated worktrees, integration branch + re-verify.
  • M3 — the doorway: /giro chat skill, escalation console, one-shot install (CLI + skills).

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

giro-0.0.1.tar.gz (33.2 kB view details)

Uploaded Source

Built Distribution

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

giro-0.0.1-py3-none-any.whl (23.9 kB view details)

Uploaded Python 3

File details

Details for the file giro-0.0.1.tar.gz.

File metadata

  • Download URL: giro-0.0.1.tar.gz
  • Upload date:
  • Size: 33.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for giro-0.0.1.tar.gz
Algorithm Hash digest
SHA256 164d52aa2f4b077eb4aa9bc9fbc040af5d29a5e9c674f136967a4ee7885e0363
MD5 49e8d22b67192dce9a4f5d596bb2a7f7
BLAKE2b-256 25250f1c8d2ed6b9faa453afd71d178513a905f2924106584687bf45b8d3a7e4

See more details on using hashes here.

File details

Details for the file giro-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: giro-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 23.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for giro-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 483250d4c615313a4b29974a0f3d8c192634477ccbc9caf20948f0a2758f6fc6
MD5 bf30ae0fe40b57c019e99233048266a8
BLAKE2b-256 6bc9d6cb2df4f587dc5c63c12ba0dae19f98968dad72891ecdaecbd0748c522a

See more details on using hashes here.

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