Follow-up nit from the #668 review (merged as fc6992cf). Display only — no money path is affected, nothing spends on this value.
What changed
#668 moved the total computation in cmd_balance from inside the row loop (after the --mint filter's continue) to before it, over all rows:
// main before #668 — accumulated after the filter, so `total` was the FILTERED total
for row in &rows {
if let Some(filter) = filter.as_deref() {
if row.mint_url != filter { continue; }
}
total = total.saturating_add(row.balance_sats); // <- only matched rows
...
}
// after #668 — computed over ALL rows, before the loop
let total = rows.iter().map(|row| row.balance_sats).fold(0u64, u64::saturating_add);
So maxplayer wallet balance --mint <X> now reports a total_sats that includes mints the filter excluded and which appear nowhere in the output.
Measured
Fixture: configured testnut default seeded with 100 sats, plus an unconfigured https://stray-mint.example/ seeded with 41. Command: wallet balance --mint https://testnut.cashudevkit.org.
mint=https://testnut.cashudevkit.org role=default balance_sats=100 play_money=true
configured_total_sats=100
total_sats=141
The 41 sats come from a mint that was filtered out. On main before #668 this printed total_sats=100. configured_total_sats ignores the filter for the same reason.
Why it survived review
balance_mint_filter_distinguishes_discovered_from_never_seen asserts only the row line, never the total. In its fixture the default holds 0, so the filtered total and the whole-wallet total are both 41 — the two semantics are byte-identical in that output, and no test discriminates them.
Suggested fix
Either scope both totals to the matched rows when --mint is present, or leave them whole-wallet and label them so the number is not read as being about the filtered mint. Whichever is chosen, add a test whose fixture makes the filtered and whole-wallet totals differ, so the assertion can tell them apart.
Note the agent-facing contract in web/app/.well-known/skills/buyer-operate/skill.md says "total_sats is whole-wallet spendable sats", which is now unconditionally true — but under --mint it reads as a total for the mint that was asked about.
Follow-up nit from the #668 review (merged as
fc6992cf). Display only — no money path is affected, nothing spends on this value.What changed
#668 moved the
totalcomputation incmd_balancefrom inside the row loop (after the--mintfilter'scontinue) to before it, over all rows:So
maxplayer wallet balance --mint <X>now reports atotal_satsthat includes mints the filter excluded and which appear nowhere in the output.Measured
Fixture: configured testnut default seeded with 100 sats, plus an unconfigured
https://stray-mint.example/seeded with 41. Command:wallet balance --mint https://testnut.cashudevkit.org.The 41 sats come from a mint that was filtered out. On main before #668 this printed
total_sats=100.configured_total_satsignores the filter for the same reason.Why it survived review
balance_mint_filter_distinguishes_discovered_from_never_seenasserts only the row line, never the total. In its fixture the default holds 0, so the filtered total and the whole-wallet total are both 41 — the two semantics are byte-identical in that output, and no test discriminates them.Suggested fix
Either scope both totals to the matched rows when
--mintis present, or leave them whole-wallet and label them so the number is not read as being about the filtered mint. Whichever is chosen, add a test whose fixture makes the filtered and whole-wallet totals differ, so the assertion can tell them apart.Note the agent-facing contract in
web/app/.well-known/skills/buyer-operate/skill.mdsays "total_satsis whole-wallet spendable sats", which is now unconditionally true — but under--mintit reads as a total for the mint that was asked about.