hibi is a single self-contained executable. Output is TTY-aware: in a
terminal you get a rich, grouped-by-document human view (color paired with
symbols, honoring NO_COLOR); piped, redirected, or in CI you get compact JSON,
so the machine contract is preserved. The JSON is decision-first: every
payload leads { ok, action, schemaVersion, … }, the verdict and its
remediation menu come before any supporting detail, so a truncated read still
surfaces the decision and what to do about it.
Force a specific shape with the flag vocabulary: --json (compact JSON — the
machine contract agents and SDKs read), --json --pretty (indented JSON),
--pretty (rich human view even when piped), --compact (one line per claim),
--color auto|always|never (also honors NO_COLOR / FORCE_COLOR), and
--simple (ASCII symbols). hibi completions <zsh|bash|fish> prints a shell
completion script.
Two flags tune how much each JSON payload carries — the agent hot path:
--explain(alias--detailed): the JSON is concise by default (decision fields plus the remediation menu, bulky evidence dropped).--explainappends theevidencetail, anadvisorieslist, and the propositionfingerprintto every verdict.--no-hints(orHIBI_ADVICE=0): drop theremediationaction menu from every verdict andlistrow, for noise-sensitive harnesses.
All commands operate against a committed claim store (
.claims/, one file per
claim) beside your docs. The anchor is its own baseline, so every command runs
offline and is correct under a shallow clone (git clone --depth=1).Commands
version and help round out the set.
hibi record
record is span-first: the documented sentence’s span supplies the claim
text (the doc side), and you anchor zero or more code spans that back it
(the code side). The doc span is the only source of the claim text — there is
no side-channel override.
How a claim becomes behavioral.
--behavioral makes it behavioral,
wording irrelevant. With neither flag, the claim is behavioral iff the
deterministic keyword heuristic matches (keyword, comparison/ordering,
temporal/sequencing, or exception/error language) or it declares at least
one verifier. --no-behavioral skips the heuristic entirely and requires the
verifier list to be empty — a verifier is itself a behavioral declaration, so
the combination is a contradictory record, rejected by the schema at record
time and at store load. The error names the two legitimate noise levers:
narrow behaviorScope (exclude globs, or depth: 0) or
hibi ignore --claim <id> --reason <text>. Free-form kind labels (e.g.
“retry”) belong in the open attrs bag; the engine does not interpret them.suggested, its JSON carries a warning —
“recorded as suggested — won’t gate the build; pass --enforce to make it
gating” — so the advisory status never passes silently. And when the claim’s
proposition was reached by fingerprint dedup (the same sentence is already
claimed), the JSON adds existingClaims (the other claims asserting that
proposition) and a next hint — “this proposition is already claimed — did you
mean hibi reanchor?” — so you re-point the existing claim instead of recording
a duplicate.
Batch authoring — --from-file
To author many claims at once — onboarding a repo, or an agent grounding a set
of docs — pass a JSON array of claim specs instead of one claim’s worth of
flags. This avoids shell-quoting verbatim spans and records the whole set in one
pass. - reads the array from stdin.
doc plus one doc-span key are
required; everything else is optional:
doc, docQuote / docRange / docLine, codeFile,
codeQuote / codeRange / codeLine, glob, coarse, inlineId, trust
(default inferred), enforce / enforcement, behavioral, verifier,
pristine, owner, ref, ttl.
Every spec is validated before any write — a malformed item fails the
whole batch, never leaving half of it recorded. Propositions still dedup by
fingerprint, so the same sentence recorded from two files shares one meaning.
hibi reanchor
reanchor re-resolves a claim’s anchors against the current working tree and
resets its state to unchanged — the supported way to settle a moved claim or
re-point one after an edit. It preserves the claim’s identity (same id,
owner, and history); only its anchors and evidence baseline change. Whether
authored trust survives depends on --ref — reanchoring with --ref
asserts “I re-verified this” and retains trust; reanchoring without it
downgrades verified trust to inferred (see the flag table).
Recovering an orphan — --suggest
When a claim’s documented sentence has been deleted from its file, reanchor
alone can’t repair it — it has no span to resolve against. hibi reanchor <claim-id> --suggest is the read-only recovery aid: it takes the claim’s
stored doc-side text-quote and localizes it against the current content of
every document registered in the store, then prints the ranked candidate
targets so you can pick one and re-anchor with an explicit --doc-range.
It never writes the store or any document, and it always exits 0 (an
operational error still exits 1). It refuses to be combined with any mutation
flag, failing with exactly:
--suggest is read-only and cannot be combined with mutation flags.
snippet is the matched region text trimmed to 120 characters. Zero
candidates is a valid result (an empty array). The doc:orphaned remediation
action carries this command pre-filled, so you run it, inspect the candidates,
then hibi reanchor <id> --doc-range … to re-anchor.
Relocating a doc anchor (
--doc) moves the claim, it does not copy it: the
source document is left intact as audit, and the claim no longer anchors to it
— so the old file can be deleted without orphaning anything. This is the
generic primitive behind doc splits, merges, renames, and promotions; it is
not supersession, which records a document-to-document edge.hibi relocate
relocate is the batch consolidation primitive: it re-homes every live
(non-retired) claim stranded on --from onto --to in one pass, instead of
making you reanchor each one by hand. A claim is re-homed when its current
documented sentence appears verbatim in --to; each move rides the same
reanchor machinery, so it keeps the claim id, code side, and history, and only
the documentId changes. Claims whose sentence is absent from --to are
never silently dropped — they are reported as misses for you to reanchor or
retire by hand.
The JSON reports what moved and what did not:
doc and code on each relocated entry are the post-reanchor per-side
AnchorStates (e.g. unchanged). misses lists the claims that need a manual
reanchor or retire.
hibi list
list is the triage view: one lean row per claim, ordered most-severe-first,
so you can see the whole suspect set at a glance and pick the next claim to act
on. Narrow it with --state:
claimId,
propositionId, documentPath, codePath, status, severity, gates, and
the recommended remediation action (or null). It is the fast path to “which
claim, and what do I do,” with the full verdict a check away.
Pass --ids-only (on list or query) to drop the JSON envelope entirely
and emit a bare, de-duplicated, newline-delimited list of claim ids to stdout —
the shape a shell loop wants:
hibi coverage
coverage is the grounding-audit worklist: it segments a document into blocks
(blank-line separated; fenced code blocks kept whole) and reports each block as
covered — a live, code-grounded claim’s doc anchor resolves cleanly into it —
or uncovered. Read-only; it writes nothing and judges nothing.
unchanged/moved — a doc-only suggested placeholder or a
drifted anchor does not count (that is check’s concern). Walk the covered: false
regions and decide ground-or-prune: anchor the blocks a code span backs
(hibi record, or the batch --from-file), and cut the prose nothing backs. Hibi
never extracts claims from prose — the judgment on every uncovered block stays with
you. Note range offsets are banner-normalized (the HIBI banner is stripped before
segmenting), so identify a block by its preview text rather than byte-slicing the
raw file at range.
Each region also carries executable: true when its block is or contains a fenced
code block whose info string is one of the exact set sh, bash, zsh, shell,
console — the whole detection rule, no other heuristics (a ```json or ```ts
block is not executable). An uncovered executable block is the highest-value
grounding target: it can carry a command: verifier and reach a supported/refuted
behavioral verdict, so when any exist the next hint leads with them and
summary.uncoveredExecutableBlocks counts them; the general ground-or-prune steer
for any remaining prose blocks still follows. coverage only tags — it never
records a claim; creation stays explicit.
Gating a plan — --fail-uncovered
By default coverage is a pure report and always exits 0. Pass
--fail-uncovered to make it gate: when any uncovered block remains, the
command exits with the gating exit code 2 (the same code check uses for a
gating verdict). JSON and human output are unchanged — only the exit code
differs. This is the CI-enforceable form of “this plan must be fully grounded”:
an uncovered block is an unimplemented or unpruned plan item.
hibi retire
retire withdraws a single claim: it flips that claim’s enforcement to
retired, and a retired claim never gates or warns again. It is the supported way
to silence a claim that is genuinely obsolete — never hand-delete the claim’s
file from .claims/, which loses the audit trail.
alreadyRetired: true. Most drift verdicts that recommend retiring already hand
you the exact command in their remediation menu, claim id pre-filled. Pass
--dry-run to see what would be withdrawn without writing — the envelope gains
dryRun: true and next: "re-run without --dry-run to apply".
hibi ignore
ignore acknowledges a behavioral at-risk you have re-verified by hand:
it stores the acknowledged evidence — the current { path → hash } map — plus
your reason on the assertion (suppressed). While every acknowledged path
still carries its acknowledged hash, the at-risk is non-gating: the verdict
surfaces suppressed: true in JSON and does not affect exit codes.
The suppression lapses automatically: the moment any acknowledged evidence
path’s hash moves past the acknowledged one, or a new evidence path appears,
the claim flags again.
ignore silences one specific, inspected change-set —
never the claim itself. To withdraw a claim for good, use hibi retire.
hibi doctor
doctor is a store-health report: it surfaces the dead state that check
hides — claims and propositions that are not drifting but are nonetheless
broken or redundant. It is purely informational and always exits 0, so it
never gates a build; run it to triage the store, not to guard it.
Beyond the categories,
doctor reports two rate metrics, computed from a
read-only resolution pass (doctor never runs verifiers, and it still always
exits 0):
- Behavioral flag-rate — the share of behavioral claims currently
at-riskorrefuted. Guidance: above ~30% on a typical commit, tighten the change gate — narrowbehaviorScopewithexcludeglobs or a smallerdepth. - Doc-side orphaned / moved / changed rates. Guidance: above ~30% orphan rate on typical edits, use inline IDs for high-severity claims.
counts object (one tally per category), a
healthy: boolean (true iff every category is empty), and a next hint that
routes to the most pressing category (e.g. hibi list --state orphaned):
The verdict, in brief
Hibi never collapses a claim into one word. A verdict carries two independent axes plus a flag: anchor resolution per side (doc:unchanged · code:changed,
from the vocabulary unchanged · moved · changed · ambiguous · orphaned), an
optional behavioral belief on behavioral claims (unverified · at-risk · supported · refuted), and an orthogonal expired TTL flag. The JSON is
decision-first — the verdict and its remediation menu lead, the bulky evidence
trails (and only appears under --explain) — so a truncated read still surfaces
the decision and the next step. “Drift” and “stale” are only the human roll-up for
any claim needing attention, never machine states.
The full verdict model
States, confidence bands, grading, the remediation menu, and how a verdict
becomes an exit code, all live on the Verdicts page.
JSON output shapes
Every payload leads{ ok, action, schemaVersion, … }, where schemaVersion
(e.g. "v1") is emitted in the payload so a consumer can branch on the contract
version without reading a filename.
check / diff / status return a decision-first envelope: an ok/action/
schemaVersion header, a summary of counts, a verdicts array, and a
documents roll-up. Each verdict is concise by default —
{ assertionId, propositionId, documentId, doc, code, behavior?, expired, suppressed?, gates, changed?, remediation, notes } — with the evidence tail,
advisories, and fingerprint added only under --explain. The changed?
field is the one-line behavioral carve-out: it appears on behavior:at-risk /
refuted verdicts even on the concise path so you learn what moved.
suppressed? is true on an at-risk acknowledged via hibi ignore — the
verdict is surfaced but never affects exit codes. diff additionally reports
since and changedFiles.
Mutating verbs add a next field — the exact follow-up command to run — and
record, reanchor, and retire also return the resulting claimId:
list returns { ok, action, schemaVersion, state, count, claims[] }, where
each claim row is the lean handle described above. query returns
{ ok, action, schemaVersion, path, count, hits[] } — the way you find a claim’s
id before editing. coverage returns { ok, action, schemaVersion, doc, summary: { blocks, coveredBlocks, uncoveredBlocks, uncoveredExecutableBlocks, coverageRatio }, regions[], next }
— see hibi coverage above.
Exit codes
Hibi communicates results through its exit code, so it slots straight into CI and git hooks:moved and at-risk never gate. suggested claims never set a failing
exit code; only enforced claims can.
Strictness: --fail-on
--fail-on tunes which states fail the run:
Running verifiers: check --run-verifiers
Verifiers execute repo-committed commands — a supply-chain surface — so
they run only under check --run-verifiers. status, query, list,
doctor, and plain check never spawn a verifier process.
kind: "command": it runs the
verifier’s ref as a shell command via sh -c on POSIX or cmd /c on Windows
(cwd = repo root), so cross-platform repos should keep verifier refs
shell-neutral (e.g. bun test retry, not a shell builtin or && chain). Exit
0 → supported; non-zero → refuted; a timeout or spawn failure produces no
result, so the belief stays at the deterministic baseline. The per-verifier
timeout defaults to 120 seconds; tune it with --verifier-timeout <seconds>. External runner resolvers still require the default-deny manifest
(.claims/resolvers.json).
Verifier results beat change-gate routing: any failing verifier → refuted
(gating on an enforced claim); all passing → supported; otherwise the gate
result stands.
Global options
These apply to every command:Next
Verdicts, states & exit codes
The two-axis model in full: every state, the confidence bands, and gating.
CI, git hooks & agents
Wire these commands into a GitHub Action, a git hook, or an agent’s edit loop.

