You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Discussion — mechanism-level finding from PR #685's investigation into #649, explicitly anticipated by #649's own closing comment. No real trade data anywhere below; no maintainer decision yet.
Owning outcome
A cash balance the user explicitly declares (--cash / an anchor) is either recorded into the account's cash total or refused by name. It must never be accepted by the CLI, parsed without error, and then silently excluded from every computed total — with nothing in the card, the honesty ledger, or any output surface saying so.
Mechanism
skills/fomo-kernel/engine/trade_recap.py (line numbers against origin/main@e662164):
cash_position (:265-324) buckets by cash-flow currency only: currencies = sorted({cf.get("currency", "USD") for cf in cash_flows}) or ["USD"] (:288). An anchor's own currency plays no part in defining that set.
_anchor_for(c) (:293-299), the closure cash_position uses to pair anchors to buckets, only matches an anchor whose currency equals one of those bucket currencies (or, for a legacy currency-less anchor, only when there is exactly one bucket). An anchor in a currency with no matching cash-flow row cannot match any c in the loop at :303, so it is never consulted — not added, not converted, not reported missing.
aggregate_currencies (:564-593), the shared currency-universe builder PR fix(fx): every currency entering account aggregation is fetched, and a missing rate fails closed (closes #649) #685 introduced, documents this exclusion as deliberate: "A cash anchor in a currency with no flow.cash_position buckets by cash-flow currency and _anchor_for pairs anchors into those buckets, so such an anchor is dropped rather than converted — it cannot widen what gets added together, and treating it as if it could would refuse a review over an amount nothing reads."
The drop itself is therefore a known, accepted side effect of #649's fix, pinned by test_cash_position_single_bucket_and_flowless_anchor_keep_the_identity (added in PR #685) — not a regression introduced by it. What is missing is disclosure: nothing in cash_position's return dict, currency_meta, or honesty_ledger records that a supplied anchor existed and was not used. A user who transcribes a JPY cash balance into --cash on a book with no JPY cash-flow row gets a card that looks exactly like one where they supplied no JPY anchor at all — the declared fact is indistinguishable from a fact never given.
What a fix here must also change
#649's own closing comment (owner, on the issue) names this directly: "the day the flowless-anchor drop itself gets fixed... that issue will say so" about taking anchors back into the universe builder. This is that issue, and it says so: whoever fixes this drop must also widen aggregate_currencies to include accepted cash anchors in its universe, not only fix cash_position/_anchor_for in isolation. PR #685's body ("Two decisions worth reviewing") and #649's final comment both flag a second consequence of that widening worth knowing in advance: the anchor's exclusion from the universe today is what keeps add-cash (#665's frozen-frame recompute, PR #684) exact-request compatible, because an anchor currently cannot change the market request. Widening the universe to include anchors would need to preserve that compatibility, not just fix the drop.
Evidence
Read against origin/main@e662164. No real trade data — this is a code-mechanism finding traced by direct reading of cash_position/_anchor_for/aggregate_currencies, matching the exclusion PR #685 already documented and pinned with a test.
Status
Discussion — mechanism-level finding from PR #685's investigation into #649, explicitly anticipated by #649's own closing comment. No real trade data anywhere below; no maintainer decision yet.
Owning outcome
A cash balance the user explicitly declares (
--cash/ an anchor) is either recorded into the account's cash total or refused by name. It must never be accepted by the CLI, parsed without error, and then silently excluded from every computed total — with nothing in the card, the honesty ledger, or any output surface saying so.Mechanism
skills/fomo-kernel/engine/trade_recap.py(line numbers againstorigin/main@e662164):cash_position(:265-324) buckets by cash-flow currency only:currencies = sorted({cf.get("currency", "USD") for cf in cash_flows}) or ["USD"](:288). An anchor's own currency plays no part in defining that set._anchor_for(c)(:293-299), the closurecash_positionuses to pair anchors to buckets, only matches an anchor whose currency equals one of those bucket currencies (or, for a legacy currency-less anchor, only when there is exactly one bucket). An anchor in a currency with no matching cash-flow row cannot match anycin the loop at:303, so it is never consulted — not added, not converted, not reported missing.aggregate_currencies(:564-593), the shared currency-universe builder PR fix(fx): every currency entering account aggregation is fetched, and a missing rate fails closed (closes #649) #685 introduced, documents this exclusion as deliberate: "A cash anchor in a currency with no flow.cash_positionbuckets by cash-flow currency and_anchor_forpairs anchors into those buckets, so such an anchor is dropped rather than converted — it cannot widen what gets added together, and treating it as if it could would refuse a review over an amount nothing reads."The drop itself is therefore a known, accepted side effect of #649's fix, pinned by
test_cash_position_single_bucket_and_flowless_anchor_keep_the_identity(added in PR #685) — not a regression introduced by it. What is missing is disclosure: nothing incash_position's return dict,currency_meta, orhonesty_ledgerrecords that a supplied anchor existed and was not used. A user who transcribes a JPY cash balance into--cashon a book with no JPY cash-flow row gets a card that looks exactly like one where they supplied no JPY anchor at all — the declared fact is indistinguishable from a fact never given.What a fix here must also change
#649's own closing comment (owner, on the issue) names this directly: "the day the flowless-anchor drop itself gets fixed... that issue will say so" about taking anchors back into the universe builder. This is that issue, and it says so: whoever fixes this drop must also widen
aggregate_currenciesto include accepted cash anchors in its universe, not only fixcash_position/_anchor_forin isolation. PR #685's body ("Two decisions worth reviewing") and #649's final comment both flag a second consequence of that widening worth knowing in advance: the anchor's exclusion from the universe today is what keepsadd-cash(#665's frozen-frame recompute, PR #684) exact-request compatible, because an anchor currently cannot change the market request. Widening the universe to include anchors would need to preserve that compatibility, not just fix the drop.Evidence
Read against
origin/main@e662164. No real trade data — this is a code-mechanism finding traced by direct reading ofcash_position/_anchor_for/aggregate_currencies, matching the exclusion PR #685 already documented and pinned with a test.Cross-references
add-cash's frozen-frame recompute) — named above as a downstream consumer of the current exclusion; relevant to anyone wideningaggregate_currenciesto include anchors.