Skip to content

majordomus history

Read the append-only ledger back, filtered by task, event or time.

Read the append-only ledger back, filtered by task, event or time.

  • read-only
  • memory
  • active task optional
  • --json

--validate reports malformed lines and exits 10. --rotate archives old lines and is the one subcommand that writes; it never deletes and refuses while under the cap.

Syntax

majordomus history [--task <id>] [--event <name>] [--since <n>m|h|d] [--limit <n>|--all] [--json]

Lifecycle

  1. Set up
  2. Begin
  3. Work
  4. Verify
  5. Conclude
  6. Inspect

Other commands at this stage:doctor, watch, search, doctrine, version, knowledge, rules, bench.

Reads

  • .ai/local/state/ledger.jsonl

Writes

Nothing. This command is read-only.

Exit codes

Only the codes this command can produce. The full contract is on the commands index.

  • 0 ok
  • 2 usage
  • 10 contract unmet
  • 13 internal error
  • 15 refused

Reading the ledger back

The ledger is append-only and is the canonical record of what happened. The event vocabulary is closed, so a filter can tell an unknown name from one that has not occurred.

What this task has done so far

event name is registered
yes

Given this repository

# An active task that has already produced a checkpoint, a decision and an open question.
. "$FIXTURE_SETUP/active-task.sh"
printf 'the parser now refuses tabs\n' | "$MJ" checkpoint >/dev/null
"$MJ" decision add "refuse tabs in the parser" --why "two encodings for one token" >/dev/null
"$MJ" question add "should tabs be an error or a warning?" >/dev/null

Run

$ majordomus history

Output contains

  • task.started
  • decision.recorded
  • question.opened

exit 0

Oldest first, each line carrying the timestamp, the event, the task and the git head it happened at.

Filtering on a name that is not registered

event name is registered
no

Given this repository

# An active task that has already produced a checkpoint, a decision and an open question.
. "$FIXTURE_SETUP/active-task.sh"
printf 'the parser now refuses tabs\n' | "$MJ" checkpoint >/dev/null
"$MJ" decision add "refuse tabs in the parser" --why "two encodings for one token" >/dev/null
"$MJ" question add "should tabs be an error or a warning?" >/dev/null

Run

$ majordomus history --event task.startd

Output contains

  • unknown event
  • one of:

exit 2

Answering "no matching events" would be the same answer a registered name that has not occurred gives. A filter that cannot distinguish those two is not a filter, so this is refused and the vocabulary is printed.

Reference

Read the append-only ledger back. Read-only.

Operational reconstruction, not a transcript. It answers what happened, when, for which task, at which git head, and what was accepted — and nothing about what anyone said.

Filters: --task <id>, --event <name>, --since <n>m|h|d or an ISO timestamp, --limit <n> (default 20, newest), --all. Output is oldest line first, so a filtered run reads as a narrative. --json emits the matching ledger lines verbatim.

--validate reports every line that is not a well-formed event and exits 10 if any is; doctor, check and watch run the same test, because a ledger the tool cannot parse is a ledger that cannot be used as evidence.

--rotate moves all but the newest ledger.retention_max_lines lines into ledger.<utc>.jsonl.archived and appends a ledger.rotated event recording how many moved. It never deletes, refuses to overwrite an existing archive, and does nothing when the ledger is under the cap.

$ majordomus history --task t-20260903193012-a4f1
2026-09-03T19:30:12Z  task.started         t-20260903193012-a4f1  3f2a9c1  profile=debugging scope=lib/auth
2026-09-03T19:45:00Z  task.checkpoint      t-20260903193012-a4f1  3f2a9c1  20260903T194500Z--main--3f2a9c1--8c1d0e4a2b6f9317.md
2026-09-03T19:52:31Z  decision.recorded    t-20260903193012-a4f1  3f2a9c1  Normalise the callback URI before comparing state
2026-09-03T20:14:08Z  task.finished        t-20260903193012-a4f1  b71e0c9  outcome=completed verify_exit=0

Evidence

Every case below runs in CI on Linux and macOS. The site refuses to build if a public command has no behavioural case, no negative case, or no demonstration.

Guarantees this command carries