chant ledger
Synopsis
Section titled “Synopsis”chant ledger <table> [dir] [--member <name>] [--where <field><op><value>]... [--since <time>] [--at <rev>] [--json]Description
Section titled “Description”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 7dmember 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.
Filters
Section titled “Filters”--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.
| Operator | Holds when the field | Types |
|---|---|---|
= and != | equals, or doesn’t equal, the value | all |
<, <=, > and >= | is before or after the value | number, time, text |
~ | contains the value | text |
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.
Output
Section titled “Output”| Field | Holds |
|---|---|
table | the table read |
columns | its columns, in order |
at | --at as given, or null |
filter | where, each clause as given, and since, the ISO instant it was read as, or null |
total | the rows in the table before the filter |
rows | the rows every filter matched |
malformed | lines 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.
The other reads
Section titled “The other reads”chant workspace records and chant workspace runs take --where too, over the fields of what they list. See workspace records and workspace runs.
Options
Section titled “Options”| Option | Description |
|---|---|
<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 |
--json | print the read contract document |