Juvenal
Quis agit ipsos agentes? — Who acts upon the agents?
Juvenal is a framework for orchestrating AI coding agents through verified implementation phases. It prevents agents from cheating on success criteria, helps agents implement complex projects in phases, etc.
The Problem
Agents such at giant problems.
This is probably only a temporary problem, but for now, an AI agent given a massive problem will fumble it.
It'll take shortcuts, lie, cheat, steal, the works.
The Solution
There's no honor among agents!
Agent B feels no obligation to cover for some shortcut that Agent A made.
This makes an implementation-verification loop with separate agents pretty effective for catching cut corners.
When Agent B catches Agent A's shoddy work, Agent C can be spun up to implement fixes, and so on.
How It Works
A deterministic Python runtime orchestrates AI coding agents (Claude or Codex) through alternating steps:
- Implementation — an agent executes a prompt to build/modify code
- Verification — separate checker agents verify the work, and can run commands when instructed to do so
- Bounce — if verification fails, the pipeline bounces back (to a configurable target phase or the most recent implement phase) with failure context injected. A global bounce limit (
max_bounces) prevents infinite loops.
The implementing agent and the checking agent are separate processes, so the implementer can't cheat by weakening tests, etc.
Other Such Frameworks
Juvenal is conceptually similar to ralph, but it works slightly better for my exact purposes and reinventing the wheel is cheap now!
Install
pip install -e ".[dev]"
Claude Code Skill
Juvenal ships as a Claude Code plugin, so you can use it directly from Claude Code with /juvenal.
Install the plugin
From the marketplace (pending approval):
/plugin install juvenal
From source (works now):
claude --plugin-dir /path/to/juvenal/plugin
Usage
Once installed, invoke the skill in Claude Code:
/juvenal add authentication to the Flask app
Claude will create a Juvenal workflow for your goal and run it. You can also ask for help with workflow formats or run existing workflows.
Quick Start
# Scaffold a workflow
juvenal init my-project
# Run a workflow
juvenal run workflow.yaml
# Decompose a complex goal into implement phases, then run planner + your fixed checker stack
juvenal run --standard-checkers --phased-implementer 'software-engineer:add authentication to the Flask app'
# Generate a workflow from a goal
juvenal plan "implement a REST API with tests" -o workflow.yaml
# Plan and immediately run
juvenal do "add authentication to the Flask app"
Embedded API
Juvenal exposes an embedded Python API. The repository includes a toy example at tests/mockup.py:
import subprocess, tempfile
from juvenal.api import do, goal, plan_and_do
tmpdir = tempfile.mkdtemp()
subprocess.run(["git", "init"], cwd=tmpdir, check=True)
subprocess.run(["git", "commit", "--allow-empty", "-m", "init"], cwd=tmpdir, check=True)
with goal("build a toy todo CLI", working_dir=tmpdir):
do("write example-brief.md describing the toy todo CLI", checker="pm")
do(
["create sample-interactions.md with happy-path transcripts",
"add edge-case transcripts to sample-interactions.md"],
checkers=["security-engineer"],
)
do(
["derive acceptance-checklist.md from the prep artifacts",
"expand the checklist with missing coverage",
"add persisted-state scenarios to the checklist",
"write smoke-test.sh for shell validation"],
checkers=["tester", "senior-tester"],
)
plan_and_do("build the toy todo CLI in toy_app/")
Run it from a repo checkout: python -m tests.mockup
Workflow Formats
YAML
name: "my-workflow"
backend: claude
max_bounces: 999
backoff: 2.0 # exponential backoff between bounces (seconds)
max_backoff: 60.0 # cap on backoff delay
notify:
- https://example.com/webhook
phases:
- id: implement
prompt: "Implement the feature."
timeout: 300
env:
NODE_ENV: production
checks:
- prompt: |
Run `pytest tests/ -x` from the working directory and use the result to verify the implementation.
Do not modify code while checking.
Emit `VERDICT: FAIL: <reason>` if the command fails; otherwise emit `VERDICT: PASS`.
- tester # built-in role shorthand
- role: senior-engineer # role as dict
- prompt: "Check for security." # inline prompt
Directory Convention