# Bean – a portable convergence gate for agent work

> Source: <https://github.com/grainulation/bean/>
> Published: 2026-06-21 23:49:21+00:00

**A portable convergence gate for agent work — for Claude Code and Codex.**

bean keeps an agent from declaring a task **"done"** until its claims are verified, its conflicts are resolved, or its open questions are named as honest residuals. It records what the agent learns as a typed claim ledger, runs a compiler that scores whether the work has actually converged, and — installed as a runtime — blocks the agent from stopping until it has.

bean replaces "do these N phases" with "keep going until there's nothing decisive left to learn." Each round the agent:

**Investigates the most decisive open question** the compiler flags — an unresolved conflict, a weakly-evidenced claim, a coverage gap.**Records what it learns** as typed claims at honest evidence tiers (`stated`

→`web`

→`documented`

→`tested`

→`production`

), in a ledger that persists across rounds.**Compiles**— a check that can*fail*for the whole task: conflicts, gaps, weak evidence, undischarged risks.**Revises beliefs**— when new evidence overturns a claim, it supersedes it instead of leaving the contradiction standing.

The loop ends only when there are no unresolved conflicts, every load-bearing claim meets its evidence bar, and a full round turns up nothing new — or an open question is named as a genuine residual. bean stops on **scored evidence**, not on the agent's say-so.

| Step | What happens |
|---|---|
Frame (once) |
State the goal; seed the ledger with known constraints. Does it earn the loop? |
1. Survey |
Re-assess what's available this round — tools, sub-agents, data sources. |
2. Investigate |
Attack the most decisive open question the compiler flagged. |
3. Record |
Write findings as typed claims at honest evidence tiers into the ledger. |
4. Compile |
Score convergence; optionally gate load-bearing claims on a real verifier. |
5. Revise beliefs |
Supersede claims new evidence overturns; resolve conflicts. |
6. Converged? |
No conflicts + evidence bar met + a dry round → deliver. Otherwise, loop again. |

**Plugin-only (advisory).** The`/bean`

skill gives the agent the convergence loop as guidance.**Installed runtime (enforced).**`./install.sh`

builds the binaries and registers a native Stop hook, so`bean-check`

becomes a hard gate: the agent cannot finish a bean-tracked task until the ledger converges or names its residuals.

bean ships as small static binaries (no runtime dependencies) plus the `/bean`

skill and the native hook.

**From source** (needs [Rust](https://rustup.rs)):

```
git clone https://github.com/grainulation/bean.git
cd bean && ./install.sh
```

This builds the runtime, installs the `/bean`

skill, and registers the Stop hook for Claude Code and Codex.

**Prebuilt binaries** (no Rust): download the tarball for your platform from the [latest release](https://github.com/grainulation/bean/releases) and put the binaries on your `PATH`

.

```
/bean <your task>
/bean quiet <your task>   # terse — failures still surfaced
```

bean engages when a task is worth the loop — "do this thoroughly," or work that spans multiple files, sources, or sessions — and stays out of the way for a trivial one-pass task. See [ EXAMPLE.md](/grainulation/bean/blob/main/EXAMPLE.md) for a worked before/after.

Five self-contained binaries, no install dependency:

— the compiler and gate. Reads`bean-check`

`.bean/claims.json`

(and optional`.bean/run.json`

) and exits nonzero until the loop converges: conflicts, undischarged risks, below-bar load-bearing claims, a dry round, the round budget, and the optional verifier gate. Emits a deterministic certificate.— runs a declared verifier (a command, with the claim on stdin) and records a scrubbed verdict for`bean-verify`

`bean-check`

to adjudicate.— the driver: injects the compiler's signal into the agent each round, records what it emits, enforces forward progress, and writes a per-run trace to`bean-run`

`.bean/runs/<run_id>.json`

. Works with any agent command.— the native Stop hook for Claude Code and Codex; blocks the agent from finishing until the loop converges, and is inert when a project has no`bean-hook`

`.bean/`

ledger.— a read-only trace analyzer: reads`bean-lessons`

`.bean/runs/*.json`

and writes a ranked report of recurring failure patterns to`.bean/lessons.json`

. Deterministic; it proposes, never applies.

A load-bearing claim can require an external verifier — your test suite, a type check, a state assertion — instead of trusting a self-asserted evidence tier. Set the mode in `.bean/run.json`

→ `verification.mode`

:

`compat`

(default) — no verifier required.`advisory`

— warn on an unverified load-bearing claim.`strict`

— require a passing verifier or a named residual.

See [ skills/bean/references/oracle-gate.md](/grainulation/bean/blob/main/skills/bean/references/oracle-gate.md).

The gate is a self-contained binary, so the same core runs in more than one place:

**Claude Code and Codex**— as a native Stop hook (the`/bean`

skill plus`bean-hook`

).**Any agent loop or CI pipeline**— call`bean-check`

/`bean-verify`

as a verification step that blocks "done" until the ledger converges.

bean works standalone with local files and binaries — no network, no service, no account.

**Not an agent framework.** It rides*inside*an agent loop as the verification layer; it complements an agent framework, it doesn't replace one.**Not an accuracy booster.** It doesn't make a model smarter. It reduces*silent false completion*— turning "confidently wrong and done" into verified, fixed, or honestly blocked.

**Lean.** Static binaries, zero runtime dependencies, no network by default, no telemetry.**A real gate.**`bean-check`

makes convergence falsifiable; the verifier gate makes it*external*— auditable verification, not a self-graded checkmark.**Coupled, not advisory.** With the runtime installed, the native hook means the discipline can't be silently skipped.**Discipline, not a transplant.** bean shapes the procedure an agent follows; it doesn't raise the model's ceiling. A weak model with bean converges on its answer more honestly, not more brilliantly.

See [ CONTRIBUTING.md](/grainulation/bean/blob/main/CONTRIBUTING.md). Run

`npm test`

and `node test/conformance.mjs`

before a PR.[MIT](/grainulation/bean/blob/main/LICENSE) © grainulation contributors.
