CLI
The open-source CLI, the local regime-tape catalog, and how the local judge relates to the hosted certified path.
The kestrel.markets npm package ships the language, the deterministic
runtime, and a CLI. Everything on this page runs offline on your machine, and
every command shown here was run before it was written down.
npx kestrel.markets helpLight verbs run under plain node
Parsing, printing, and rendering need no special runtime:
| Verb | What it does |
|---|---|
parse / validate | parse + validate a Kestrel document, fail-closed |
print | canonical re-print; print(parse(x)) is byte-stable |
frame / percept | render a Frame from a fixture JSON |
version, help | metadata |
Save the canonical practice plan as atm-rider.kestrel:
PLAN atm-rider budget 0.5R ttl +60m
WHEN phase open
DO buy 1 atm C @ lean(bid, fair, 0.5)npx kestrel.markets parse atm-rider.kestrelvalid documents=1 statements=1Heavy verbs need the Bun runtime
run, day, agent, runs, lineage, and leaderboard drive the session
runtime and the local run registry, which are Bun-hosted. Under plain node
they refuse loudly instead of degrading:
error code=RUNTIME_UNAVAILABLE message=this command requires the Bun runtime hint=run with `bun` (e.g. `bun x kestrel.markets …`) or install on a supported platformThat is exit code 4, a typed refusal, never a raw stack. Run heavy verbs with
Bun. Note that the CLI's shebang names node, and bun x honors shebangs, so
on a machine that also has node installed, force the Bun runtime explicitly:
bun x --bun kestrel.markets run --bus choppy-1101.jsonl \
--plans atm-rider.kestrel --fill strict-cross-v1 --r-usd 10000The local catalog: three regime tapes
The open-source catalog ships three synthetic, content-addressed regime tapes
(generic index instrument, public corpus tier). They install with the package
under node_modules/kestrel.markets/src/catalog/fixtures/; copy them next to
your plan:
npm i kestrel.markets
cp node_modules/kestrel.markets/src/catalog/fixtures/*.jsonl .Each entry pins its graded fill model, and each run below is real output, byte-identical on every machine, every time:
| Catalog entry | Tape | Fill model | Graded output |
|---|---|---|---|
choppy-1101-strict | choppy-1101.jsonl | strict-cross-v1 | settle=1772461770000 pnl=-65 events=302 |
spike-1102-maker-fair | spike-1102.jsonl | maker-fair-v1 | settle=1772461770000 pnl=-71 events=302 |
trending-1103-maker-fair | trending-1103.jsonl | maker-fair-v1 | settle=1772461770000 pnl=-71 events=302 |
bun x --bun kestrel.markets run --bus spike-1102.jsonl \
--plans atm-rider.kestrel --fill maker-fair-v1 --r-usd 10000settle=1772461770000 pnl=-71 events=302The canonical practice plan loses on all three tapes. That is the point: the judge is honest, the tape is the same for every agent, and a run costs $0 to reproduce. Beat it and share the proof.
Fill models
Two fill models ship, and each catalog entry permits exactly one for its graded run, so two people quoting the same entry are always quoting the same counterfactual:
strict-cross-v1fills only when the market crosses your price, the conservative floor.maker-fair-v1models resting-order fills against a hazard model, for maker-style plans.
Recording, querying, machine output
Every run and day auto-records into a local SQLite registry
(data/kestrel.db by default, --db to move it, --no-record to skip):
bun x --bun kestrel.markets runs list
bun x --bun kestrel.markets runs show <run_id>
bun x --bun kestrel.markets leaderboardEvery verb takes --json for machine-stable output (a bare pipe gets the
terse text line; only --json is jq-stable), plus --format, --agent, and
--no-color. There is also an agent verb: a JSONL request/response mode
that projects the SDK surface for a driving process.
Local judge, hosted certification
The local run is not a toy twin of the platform: it is the same open
certification computation the hosted judge runs. A catalog entry pins its
tape root, its expected graded-bus conformance root, and the engine and judge
epochs it was recorded under; a drifted engine, a corrupted tape, or an
unknown fill model is refused fail-closed rather than silently regraded. Your
local grade and the platform's grade of the same inputs are the same bytes.
What the hosted path adds is not a different judge but attestation: a signed Grade, verifiable by anyone, at a public proof URL, with the metered receipt chain around it. Local runs and the free hosted sim are practice-tier artifacts, and practice grades are never ranking evidence. See Evidence for the certification boundary and the Quickstart for the hosted funnel.
One honest note: the published CLI (kestrel.markets@0.2.0) is local-only
today. The platform-connected CLI mode, driving hosted sessions with the same
verbs against api.kestrel.markets, ships in the next release; until then the
hosted faces are HTTP, the SDK, and MCP.