SOW-0122: fast --list-invocations and stock IDX alignment; track remaining CLI gaps
Stacked on #20. Completes SOW-0122 (.agents/sow/done/SOW-0122-20260621-journalctl-performance-followups.md) and opens SOW-0166, SOW-0167 and SOW-0168 for the remaining measured gaps.
Decisions for review (agent-chosen, pending your review)
--list-invocationsprefilter limited to 32 IDs.- SOW-0121 added a prefilter, an OR of every invocation-ID value, to keep sparse-ID journals cheap.
- Every step evaluates every term, so with ~10,000 IDs the command was 240-590x slower than stock.
- It now applies only up to 32 IDs (
ELIGIBILITY_MAX_TERMS/invocationEligibilityMaxTerms). Above that, the walk matches stock's unit/boot walk. - Rows without an ID are skipped either way, so output is unchanged.
- IDX column sized like stock: the column is as wide as the widest index, at least 3 when the header shows. Previously, at 100+ rows stock printed
IDX/-99and we printedIDX/-99.
Measurements
Fixtures: 1.5M entries, as one 931 MB file and as 300 files. Full table: .local/sow0122/report.md (local, not committed), summarized in the SOW.
--list-invocations -u | before | after | stock v262 |
|---|---|---|---|
| Rust, file / dir | 27.7 s / 13.0 s | 0.23 s / 0.67 s | 0.06 s / 1.03 s |
| Go, file / dir | 14.5 s / 15.4 s | 0.66 s / 1.81 s |
Output is byte-identical to stock for --list-invocations (with and without -q) and --list-boots, in both languages.
Rust is otherwise at or faster than stock: full output is 2-4x faster. The new pending SOWs:
| SOW | Gap | Measured |
|---|---|---|
| SOW-0166 | Directory --since seek | 17x slower than stock |
| SOW-0167 | Every Go open loads the whole entry array | 0.27 s / 160 MB floor per file |
| SOW-0168 | --follow polls and reopens instead of waiting | idle CPU and latency far above stock; needs your decision (inotify vs cheaper polling) |
Validation
- Query matrix vs v262 oracle: 3587/3587 PASS.
- Parser parity: 134/134 in each language.
go test ./cmd/journalctlandcargo test -p journalctl: pass.- New paired tests for the IDX width rule.
Summary by cubic
Completes SOW-0122 by fixing --list-invocations performance and IDX column alignment in both CLIs, and opens SOW-0166, SOW-0167, and SOW-0168 for the remaining measured gaps. Output is now byte-identical to stock for --list-invocations and --list-boots; Rust is otherwise at or faster than stock. Carries the sow-0160/xz-dictionary base via merges, with its SOWs recorded in the ledger.
Two agent-chosen decisions, both approved by the user on 2026-11-03:
- The valid-ID prefilter (an OR of every invocation ID) is now bounded to 32 IDs. Above that, the walk matches stock's unit/boot walk; rows without a valid ID are skipped either way, so output is unchanged. This takes
--list-invocations -ufrom 240-590x slower than stock to near parity (Rust 0.23 s file / 0.67 s dir vs stock 0.06 s / 1.03 s). - The IDX column is sized to the widest index, at least 3 when the header is shown, matching stock's table formatting.
Residual gaps tracked as new SOWs
- SOW-0166: directory
--sinceseek at 17x slower than stock; the SOW records the reproduction procedure. - SOW-0167: every Go open loads the full entry array (0.27 s and 160 MB floor per file).
- SOW-0168:
--followpolls and reopens instead of waiting; decided 2026-11-03 to make portable polling cheap (reuse readers, check header counters per poll, back off while idle) — inotify needs a separate policy decision.
Validation: 3587/3587 query matrix PASS against the v262 oracle, 134/134 parser parity in each language, paired IDX-width tests added, and both go test ./cmd/journalctl and cargo test -p journalctl pass.