Skip to main content
--epic <id> keeps the events whose epic is <id> or whose detour is <id> (0.50.0). A detour event is about two epics, the one paused (epic) and the one it was paused for (detour), so --epic <detour-id> shows the push that started that detour’s work. Before 0.50.0 every detour event recorded epic: null, so the per-epic DETOURS list was always empty and --epic left out every detour.

Why it ships with a reader, and would not ship without one

A log nobody reads is a data graveyard — and that argument has been used in this project to decline things, so it could not be waved away here. The reader landed in the same change as the writer. It answers questions that were previously archaeology: That last row is the one that earns its cost. A hand-edit of the state file shows up as a revision no recorded event accounts for — the failure mode this project has repeatedly found and repeatedly had to dig for.
The detail that makes that section signal rather than noise: events carry a revision range, not a single number. An ordinary update writes twice — once for the change, once for the re-render — so single-number events would flag every normal write as an out-of-band one, and the section would be pure noise on day one.
Named events (0.50.0). Reconcile verdicts, autonomy changes, priority changes and review-mode changes used to be logged as a bare state-write with no epic. Each is now a named event: The DETOURS line reads N push(es), N pop(s), N drop(s), and the per-epic figure counts interruptions: one per push-detour, where the pop used to be counted as a second. TIME TO PICKUP starts at an epic’s first work event; a detour, reconcile, priority, autonomy or review-mode event alone does not start it. activity --epic shows the epic-scoped settings events too.

Bounded by design

A log that grows without limit in every repository is a papercut every user inherits, so the limits are part of the feature rather than a later addition:
  • Segmented files named by timestamp, so “since when” and “how old” are answerable from the filename without opening anything.
  • A per-project cap, pruned oldest-first at a rotation boundary — and never down to zero segments.
  • purge-logs refuses twice: nothing without a selector, and nothing without an explicit confirmation flag. A --dry-run shows what would go.
  • An undeclared flag is refused by name (0.44.0). activity --bogus exits non-zero rather than printing the report. One pre-dispatch check refuses an undeclared flag and a surplus positional on every engine verb, before anything is written, naming the flags the verb does accept — so a typo answers no question at all rather than quietly answering a different one. set-activity-log’s on|off is its one positional, so set-activity-log on extra is refused too. --help anywhere after the verb prints help and toggles nothing. purge-logs accepts --force because it mutates, and it has no effect there.
  • The log directory is git-ignored automatically, so it never becomes a permanently untracked file in your working tree.
Off by default. set-activity-log on is a deliberate choice, and off stops it without removing what was already recorded.