Nothing showed whether a rule was still earning its place. The new screen, on
5, lists every rule in file order with the number of transactions it claims,
marking those that claim none.
The count comes from Engine.Usage, which counts by first match, so a rule
shadowed by an earlier one reports zero even though its glob matches. That is
the case worth catching: such a rule looks correct in isolation and can never
fire.
d removes the selected rule and p removes every unused one, each behind a y/n
confirmation since this rewrites a hand-maintained file. config.DeleteRules
edits rules.toml textually rather than re-serialising the parsed rules, so
comments and layout survive; a comment directly above a rule goes with it,
while one separated by a blank line is left as a heading. The result is
re-parsed before it replaces the file.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Writing a glob by hand meant guessing what it would catch, then running retag
to find out. The new screen, on 4, puts the glob, account and tag fields on
the left and every still-untagged description on the right, sorted
alphabetically and grouped by description with an occurrence count.
Matches are marked as the glob is typed, along with a count, so the effect of
a rule is visible before it is written. Enter appends it to rules.toml via
config.AppendRule, reloads the engine from disk and retags, so the rows it
caught leave the list immediately.
Rules are appended rather than prepended, keeping the precedence of anything
already in the file. Since the preview only lists transactions no existing
rule has tagged, it reflects that precedence for free.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Records what the code assumes rather than what it does: why rule verdicts and
manual edits live in separate columns, how the dedupe fingerprint works, why
column positions must not be hardcoded from a sample PDF, and the pty
handshake needed to drive the TUI in a real terminal.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>