Skip to content

chant ledger

llms.txt lists every page for an agent
chant ledger <table> [dir] [--member <name>] [--where <field><op><value>]... [--since <time>] [--at <rev>] [--json]

chant ledger prints the rows of one ledger on the local chant/lifecycle branch (#4363). It has the same tables, columns and rows as chant query, and it filters them with typed filters, so no SQL engine loads and it runs on any Node.js chant runs on. With --json it prints a document that follows ledger.schema.json, a read contract at version 1.

$ chant ledger gates --where op=tf-apply --where kind=resolution --since 7d
member op gate kind timestamp resolved_by ...
------ -------- ------ ---------- ------------------------ ------------
tf-apply wave-1 resolution 2026-10-21T05:10:00.000Z approver-one
(1 of 2 rows)

It reads the local branch and never fetches. Inside a workspace it reads every member’s ledger and each row names its member; --member keeps the members it names. Outside a workspace member is null.

In the JSON document a column that chant query keeps as JSON text (attributes, labels, outcomes, promoted_from, restores, redeploys, unchanged_since, artifacts) is an object or array, and signed and empty are booleans.

--where <field><op><value> keeps the rows the clause holds for. It can be given more than once, and every clause has to hold. Each column has a type, and a clause is checked against it before anything is read. A field the table doesn’t have, an operator the type doesn’t take, or a value not of the type is the error filter-invalid.

OperatorHolds when the fieldTypes
= and !=equals, or doesn’t equal, the valueall
<, <=, > and >=is before or after the valuenumber, time, text
~contains the valuetext

The value null matches a null field, with = and != only. A time field (observed_at, last_updated, started, ended, timestamp, expires_at) takes an ISO 8601 date or time, or a span back from now: 30m, 24h, 7d or 2w. A JSON column takes a key under it with dots, such as labels.team=core or attributes.instanceType~large, and compares the value as the type it holds there.

--since <time> keeps the rows whose time column is at or after the time: observed_at for resources and snapshots, started for runs, and timestamp for gates, deploys, cuts, applies, pr_envs, control_entries and release_status. releases has no time column, so filter it with --where.

--at <rev> reads the ledger as a commit of chant/lifecycle held it, such as chant/lifecycle~3 or a commit id. A revision git can’t resolve is the error revision-unknown.

FieldHolds
tablethe table read
columnsits columns, in order
at--at as given, or null
filterwhere, each clause as given, and since, the ISO instant it was read as, or null
totalthe rows in the table before the filter
rowsthe rows every filter matched
malformedlines and files of the table that could not be read as their kind, left out

A failure prints error with a code: filter-invalid, table-unknown, revision-unknown or ledger-unreadable, and exits 1.

chant workspace records and chant workspace runs take --where too, over the fields of what they list. See workspace records and workspace runs.

OptionDescription
<table>resources, snapshots, runs, gates, deploys, releases, cuts, applies, pr_envs, control_entries or release_status
[dir]where to read from; the current directory by default
--member <name>read only these members’ ledgers; repeatable, or a comma list
--where <field><op><value>keep the rows the clause holds for; repeatable
--since <time>keep the rows at or after an ISO time or a span such as 7d
--at <rev>read the ledger at a commit of chant/lifecycle
--jsonprint the read contract document

chant