No proof, no "done."
HonestBao is a deterministic, local-first evidence gate for AI coding agents. It does not try to decide whether every sentence an AI produces is true. It checks a narrower boundary that software can verify: whether explicit completion claims are supported by fresh evidence from the current working tree.
Chinese product name: 誠實豆沙包. CLI and package name: honestbao.
The deterministic core, public-alpha surface, hardening, signed review closure, and read-only release preflight are implemented:
- JSON Schema validation for policies, completion envelopes, and receipts
- repository fingerprinting over
HEAD, scoped Git state, file content, file mode, and policy hash file_exists,git_diff, shell-freecommand, andhuman_reviewcollectors- deterministic
VERIFIED / BLOCKED / CONTRADICTED / NEEDS_HUMAN / ERRORevaluation - stale-evidence detection after repository, policy, or collector changes
- zero-write verification by default: policy and envelope may live in an
external sidecar, and no
.honestbaodirectory is created - opt-in append-only
.honestbao/ledger.jsonlwith receipt hash chaining - self-contained receipt semantics: each evidence item records its failure mode and reason, and receipt validation recomputes the verdict
- CLI text and JSON projections of the same receipt
- bounded command time/output, executable and environment allowlists, secret redaction, path-containment checks, and source-change race detection
- read-only loopback viewer with English and Traditional Chinese projections
- macOS and Linux CI definitions for Node.js 20 and 22
- a reusable agent completion contract and consumer GitHub Actions example
- automatic fail-closed command isolation: every command uses macOS
sandbox-execor Linuxbubblewrapwith denied network, a read-only filesystem, and isolated temporary storage - two-party repository-write consent: both policy
writablePathsand the runtime--allow-repository-writesflag are required - detached Ed25519 receipt attestations; private keys stay outside the repository and never enter receipts or the ledger
- signed Ed25519 human-review decisions bound to one unresolved receipt, task, check, claim, source fingerprint, policy, and collector specification
- deterministic instruction packets for Codex and Claude Code; adapters map registered claim IDs and argv but never decide the verdict
honestbao doctorchecks Node, repository scope, policy paths, command availability, Git requirements, sandbox enforcement, review keys, and ledger integrity without executing policy commands or creating runtime state
- Node.js 20 or newer
- Git when repository identity or
git_diffevidence is required - macOS with
/usr/bin/sandbox-exec, or Linux withbubblewrap, for every policy containing a command check
npm ci
npm test
npm packInstall the resulting tarball in a target project without waiting for a public registry release:
npm install --save-dev /absolute/path/to/honestbao/honestbao-0.7.0.tgz
npx honestbao --versionThe test suite uses temporary Git repositories and covers current proof, missing files, failed commands, timeouts, output limits, path traversal, disallowed executables, source mutation during collection, policy drift, secret redaction, immutable freshness assessment, CLI exit codes, and ledger mutation. It also executes filesystem and loopback-network isolation tests, detached signature tampering tests, and both supported agent instruction adapters. Signed-review tests also cover approval, rejection, source and policy drift, wrong or malformed trust keys, forged ledger references, and receipt v2 compatibility. Doctor tests cover invalid policies, path escape, missing allowlisting, sandbox enforcement, review trust, ledger corruption, and read-only CLI behavior.
honestbao doctor and honestbao verify do not create, modify, rename, or
delete anything in the target repository by default. Internal Git inspection
uses no-optional-lock mode and disables fsmonitor and untracked-cache updates,
so it does not refresh .git/index. Every policy command is placed in an OS
sandbox with network denied and the host filesystem read-only, including when
the policy omits a sandbox object.
For a zero-footprint integration, keep policy and envelope files outside the target repository and pass their absolute paths:
npx honestbao doctor \
--root /path/to/project \
--policy "$HOME/.config/honestbao/my-project/policy.json"
npx honestbao verify \
--root /path/to/project \
--policy "$HOME/.config/honestbao/my-project/policy.json" \
--envelope "$HOME/.config/honestbao/my-project/completion.json" \
--jsonOnly these explicit operations write target-repository state:
| Operation | Explicit consent | Target write |
|---|---|---|
| Initialize an in-repository policy | honestbao init |
honestbao.config.json |
| Persist a receipt | verify --ledger |
.honestbao/ledger.jsonl |
| Persist a signed review | review sign --write |
Policy-configured review JSON |
| Persist an attestation | attest sign --output <path> |
Requested attestation JSON |
| Let a collector write | Policy writablePaths and --allow-repository-writes |
Only pre-existing declared subpaths |
Package installation is performed by the user's package manager and is outside HonestBao's runtime write boundary.
init is an explicit convenience command for users who want the policy checked
into the target repository:
npx honestbao init --root /path/to/projectEdit /path/to/project/honestbao.config.json so its task, claims, paths, and
structured command specifications describe that project. Before running any
evidence command, preflight the local setup:
npx honestbao doctor --root /path/to/project
npx honestbao doctor --root /path/to/project --jsonThe policy may instead stay in an external sidecar as shown above. doctor
exits 0 when no blocking setup fault exists and 5 when a required
runtime, path, command, sandbox, key, or ledger check fails. An empty ledger and
a supported non-Git setup are warnings, not false failures. The command does
not execute policy commands, append a receipt, create .honestbao, or make a
network request.
Then create a completion envelope such as:
{
"contractVersion": "1",
"taskId": "checkout-timeout",
"claims": [
"implementation-exists",
"regression-test-passes",
"user-facing-behavior-reviewed"
],
"summary": "Checkout timeout recovery is ready for verification."
}Run the gate from any directory:
npx honestbao verify \
--root /path/to/project \
--envelope completion.jsonThis prints the receipt and does not persist it. Every command check is isolated
automatically. A policy only needs a sandbox object when it requests a narrow
writable subpath:
{
"sandbox": {
"network": "deny",
"filesystem": "read_only",
"writablePaths": ["scratch"]
}
}Every writablePaths entry must already exist and resolve inside the repository.
The repository root, .git, and .honestbao cannot be made writable. The
command still fails with REPOSITORY_WRITE_NOT_AUTHORIZED unless the same run
also includes the explicit runtime capability:
npx honestbao verify \
--root /path/to/project \
--envelope completion.json \
--allow-repository-writesMachine-readable output:
npx honestbao verify \
--root /path/to/project \
--envelope completion.json \
--jsonPersist a receipt only when local history is wanted:
npx honestbao verify \
--root /path/to/project \
--envelope completion.json \
--ledgerInspect the latest receipt against the current repository without rewriting the historical receipt:
npx honestbao inspect --root /path/to/projectValidate every ledger line and hash-chain link:
npx honestbao ledger verify --root /path/to/projectOpen the read-only local viewer:
npx honestbao view --root /path/to/projectGenerate a deterministic completion packet for an agent:
npx honestbao instructions --root /path/to/project --task checkout-timeout --agent codex
npx honestbao instructions --root /path/to/project --task checkout-timeout --agent claude-code --jsonSign the latest ledger receipt with a private key stored outside the repository, then verify it with the corresponding public key:
npx honestbao attest sign \
--root /path/to/project \
--private-key "$HOME/.config/honestbao/signing-key.pem" \
--output .honestbao/latest.attestation.json
npx honestbao attest verify \
--root /path/to/project \
--public-key /path/to/signing-key.pub.pem \
--attestation .honestbao/latest.attestation.jsonThe signature authenticates exact receipt bytes. It does not say that an older
receipt is still fresh; use honestbao inspect for current freshness.
To let an authorized reviewer close a human_review check, bind the check to a
repository-owned public key and a runtime decision path:
{
"id": "user-review",
"claimId": "user-facing-behavior-reviewed",
"type": "human_review",
"required": true,
"paths": ["src"],
"invalidation": "repository_fingerprint",
"review": {
"decisionPath": ".honestbao/reviews/user-review.json",
"trustedPublicKeyPath": "honestbao-reviewer.pub.pem"
}
}The first verification explicitly records unresolved review evidence. An authorized human
then signs that exact ledger receipt with an external private key; HonestBao
writes only the policy-configured decision file after --write is supplied:
npx honestbao verify --root /path/to/project --envelope completion.json --ledger
npx honestbao review sign \
--root /path/to/project \
--check user-review \
--decision approved \
--private-key "$HOME/.config/honestbao/reviewer.pem" \
--write \
--note "Reviewed the current user flow."
npx honestbao verify --root /path/to/project --envelope completion.jsonA current approval can close the gate. A rejection contradicts the claim. Any
source, policy, or collector drift makes the decision stale. Invalid keys,
signatures, or ledger references fail closed. Legacy human_review checks with
no review contract continue to return NEEDS_HUMAN.
Agent instructions are available in
examples/agent-completion-instructions.md.
Projects that install HonestBao as a locked development dependency can start
from examples/github-actions/honestbao.yml.
HonestBao's own cross-platform workflow also runs npm run self:verify. That
command completes the full test suite first, then uses HonestBao to verify the
compiled CLI and package dry-run without writing a ledger.
| Code | Result | Meaning |
|---|---|---|
| 0 | VERIFIED |
Every claimed check has current supporting evidence |
| 2 | BLOCKED |
Evidence is missing, stale, failed, timed out, or too large |
| 3 | CONTRADICTED |
Current evidence conflicts with a claim whose policy says so |
| 4 | NEEDS_HUMAN |
Automatic evidence passed, but review is still required |
| 5 | ERROR |
Policy, envelope, ledger, path, or collector could not be evaluated safely |
An agent may say "verified complete" only after exit code 0. It should report
the returned reason and next action for every other code.
For honestbao doctor, exit code 0 means the local setup is ready to run the
gate; it is not a verification receipt. Exit code 5 means preflight found a
blocking setup fault.
- Commands are an executable plus an argument array. HonestBao never invokes a shell and rejects shell executables even if a policy attempts to allow one.
- Command execution inherits only environment names explicitly allowlisted by the policy.
- Configured secret values are replaced before stdout or stderr reaches a receipt.
- Secrets must be supplied through allowlisted environment variables, never as command arguments or literal policy values.
- Paths must resolve inside the repository, including through symlinks.
.honestbao,.git,node_modules, and coverage output are excluded from source fingerprints. Source-bound checks cannot target those excluded paths.- A repository mutation during collection produces
ERROR; it cannot become a green result. - If a Git working tree is present, failures while reading
HEADor scoped status fail closed asCOLLECTOR_ERROR; they are never treated as a clean repository. Git inspection disables optional locks, fsmonitor, and untracked-cache updates. Non-Git directories remain valid for non-Git checks. - Every command is sandboxed and never falls back to ordinary execution. Missing or
unusable OS isolation produces
SANDBOX_UNAVAILABLEorSANDBOX_SETUP_FAILED. - Repository writes require both an existing policy-declared writable subpath and explicit runtime authorization. Neither consent alone is enough.
- Detached attestations use Ed25519 and identify the public key by its SPKI SHA-256 hash. HonestBao does not generate, upload, or assign trust to keys.
- Signed review closure trusts the repository-bound public key and whoever controls its matching private key. The private key must remain outside the repository and inaccessible to the agent being reviewed.
HonestBao itself makes no network request. Every command receives enforceable network denial and read-only filesystem isolation.
honestbao doctor may perform a bounded local Git inspection and an OS sandbox
isolation probe. It never executes a command from the policy and never writes
repository or ledger state.
| Protected | Not protected |
|---|---|
Zero-write doctor and default verify |
Explicit init, --ledger, --write, --output, or double-authorized writable paths |
| Shell-free argv execution | A malicious sandbox backend or compromised operating system |
| Automatic network and filesystem write isolation | Read confidentiality: allowed executables can read host files visible to the OS sandbox |
| Executable and environment allowlists | Malicious behavior inside an explicitly allowed executable beyond this boundary |
| Repository path and symlink containment | A malicious repository or machine owner |
| Runtime and output bounds | Compromised operating systems |
| Secret redaction before receipt persistence | Secrets placed directly in argv or policy text |
| Source, policy, and collector freshness | Requirements absent from the policy |
| Receipt hash-chain integrity and detached Ed25519 signatures | Signer identity, key custody, or remote attestation |
| Signed human decisions bound to unresolved ledger evidence | A dishonest reviewer or compromised review private key |
src/: deterministic runtime and CLItests/: fixture and black-box testscontracts/: machine-readable contracts.github/workflows/ci.yml: macOS/Linux CIexamples/: agent contract, self-verification inputs, and CI exampledocs/ARCHITECTURE.md: architecture source of truthdesign/index.html: selected product interfacedesign/architecture.html: visual architecture
The package also exposes its typed library API from honestbao; consumers do
not need to import internal dist/ paths.
Receipt contract v2 remains readable and keeps verdict semantics self-contained. Receipt v3 adds signed human-review metadata; it deliberately does not accept the earlier experimental v1 shape.
HonestBao does not eliminate hallucinations. It does not prove product quality, business correctness, security, or user satisfaction unless the policy captures suitable evidence. The local hash chain detects accidental drift and ledger mutation. A detached signature authenticates receipt bytes to a supplied public key, but neither mechanism defends against a malicious machine owner, compromised operating system, stolen signing key, or intentionally dishonest policy author. A signed review proves that the matching key approved or rejected one bound receipt; it does not prove reviewer identity, competence, or honesty.

