Skip to main content
A resolver is a program that grades an anchor, runs a verifier, or attaches advisory notes to a verdict. The built-in drift resolver runs in-process and does not speak the wire protocol. External resolvers run out-of-process and talk to the engine over JSONL-RPC on stdin and stdout.

Roles

There is no built-in supersession resolver and no semantic advisor; supersession is an engine operation (hibi supersede).

The protocol

Newline-delimited JSON-RPC, one object per line. Three methods:
method
Returns { name, version, kinds, tier, advisory, verifierKinds? }. The engine calls it first and routes work only to a resolver that claimed it.
method
Params: { assertion, files: { doc, code: { path: content } }, proposition? }. Returns { verdict?, advisories? }. The engine reads the files; the resolver never touches the filesystem.
method
Params: { assertion, verifier, changedEvidence }. No file contents are sent. Returns { behavior: "supported" | "refuted", advisories?, notes? }; advisories and notes default to empty. An error response, a timeout, or a spawn failure counts as no result.
Print any message schema with hibi schema --name <Name> (for example ResolveParams, VerifyParams, Verdict). hibi schema with no name lists the names. The schemas in schemas/*.v3.json are generated from the Zod model.

Enabling a resolver

The manifest is default-deny. A resolver not listed in .claims/resolvers.json is never launched.

override

The built-in kinds are text-quote, text-position, ast-node, value, and coarse. A non-advisory external resolver that claims one of them replaces the deterministic core verdict for every anchor carrying that kind. That is refused by default: without "override": true on the manifest entry, the built-in kinds are dropped from the resolver’s list with a warning on stderr. An advisory resolver may declare any kinds; it never produces a verdict.

Provenance for model-backed advisors

An advisory from a modelBacked resolver must carry provenance: { model, promptHash, contextHash, params? }. The registry drops advisories without it and prints one warning per run per resolver.

Verifier kinds and the built-in command runner

A verifier’s kind is an open string matched against the verifierKinds a runner declares. The built-in runner handles command: it executes ref as a shell command from the repository root. Exit 0 is supported, non-zero is refuted, a timeout or spawn failure is no result. The default timeout is 120 seconds, set with --verifier-timeout <seconds>.
Verifiers execute repo-committed commands. They run only under check --run-verifiers. check without that flag, list, and coverage never spawn a verifier. External runners also require the manifest.

Writing your own

Import the server from the main package:
serveResolver owns the framing and dispatch. The same module exports the protocol types (ResolveParams, ResolveResult, VerifyParams, VerifyResult, DescribeResult) and the model types (Assertion, Verdict, Selector, and the rest). A resolver in another language reads requests on stdin, writes responses on stdout, and validates against hibi schema.

Where to go next

SDK

The @npupko/hibi/resolver export.

Behavioral claims

Where verify fits.