Agentic code review on push
After your coding agent pushes a change, Balladeer starts an independent agentic code review. The review uses your team's agreed promises to look for regressions in the behavior the change affects, and reports back to that session. A reproduced break gives your agent something concrete to repair and keep as a regression test.
The push lands first, so your normal CI can start while the review runs. This review checks selected promises; it does not establish that every part of the change is correct.
What do I need to set up?#
Run setup on your laptop. When the durable balladeer command is installed,
setup adds the push hooks at user scope for Claude Code and Codex. They work in connected
repositories and their worktrees without a hook-install command for each checkout.
In Codex, trust Balladeer's hooks under /hooks before they can run. Setup reports an unavailable
push check if the command could not be installed; MCP tools alone do not prove the hooks work.
Existing repository-specific push hooks take precedence over the laptop-wide entry.
The check uses your existing Claude Code or Codex login and its usage allowance. It needs no separate customer model API key. An unavailable login or exhausted budget is a gap to report, never a passing result.
Which promises does it check?#
On the first push after a promise is agreed, the check identifies where its behavior lives. It shares paths and symbol names, called anchors, with the team's other agents. You do not need to create a behavior map first.
By default, it selects promises when the change touches their anchored code, including moved or deleted files. A current local behavior map supplies deeper context where one exists, including linked tests. The judge runs linked tests first. An untouched promise is not a checked promise, and selection is not proof of complete behavioral coverage.
The check is separate from sealed CI verification. An agreed promise can be checked even while its hosted status is Unprotected.
What do the results mean?#
| Result | What was established | What happens next |
|---|---|---|
| Kept | The judge exercised passing cases and found they held on the checked commit. | Continue, while retaining the limits of the exercised cases. |
| Broken | A reproduction failed on the changed commit and passed on its base; the runner verified both executions. | Inspect the reproduction and repair the behavior, or ask the owner about an intentional change. |
| Could not tell | The judge could not establish a usable answer. | Read the reason; restore the missing login, execution, time, or evidence and check again. |
If no promise is selected, the response says so. Promises left without usable anchors or unfinished checks are gaps, never implicit passes. A kept result does not qualify a sealed verifier, grant Protected status, or establish what is deployed.
From a reproduced break to a regression test#
Balladeer keeps the verified reproduction locally and tells the pushing agent where to find it. Within the authorized work, the agent can:
- Repair the behavior without weakening the promise or test expectation.
- Move the reproduction into your repository's ordinary test suite with the promise ID at its top.
- Establish that it fails on the break and passes with the fix.
- Link it with
balladeer map --link-test, and commit the test with the repair for normal review. - Explain in one line what it added and push the repair.
From then on, that regression test runs in your own suite and CI, without a model or Balladeer service. Keeping a reproduction in the local judge log alone does not add it to your suite. The hook does not commit or rewrite your tests itself.
If the person deliberately changed the behavior, the agent asks before undoing it. Only the meaning owner can agree a change to the promise. If an existing sealed check missed the same break, the agent also proposes a verifier repair for owner review.
Can the check hold a push?#
Report mode is the default: the check runs after a successful push and never holds it. A
repository can opt into checking before the push with .continuity/judge.json:
{
"mode": "block"
}In block mode a reproduced break, or a judge still running at the time limit, can hold the push. A command that commits and pushes in the same line is held because the commit does not yet exist when the check starts; commit first, then push separately. An unanchored promise is named as unchecked and does not itself hold the push.
This is a local agent-hook setting, not a server-side GitHub merge rule. Ordinary CI and branch protection remain your team's choices.
Turn it off or back on#
For this laptop, including open sessions:
balladeer judge --push-check off
balladeer judge --push-check onA checkout with its own hook owns that check separately. For explicit repository installation or a
Git pre-push hook, consult balladeer judge --help in the CLI reference. A Git
pre-push hook runs before the push; it does not supply the default after-push journey.
Are new promises captured on every push?#
No. Checking existing agreed promises is on by default after supported setup. Offers of new promises at the push are a separate option and are off by default. When enabled, the default reads repairs and offers one commitment. It still needs your answer before recording anything. See capture.