BLOCKER: YNAB split child IDs bypass Money import identity checks #948

Open
opened 2026-10-02 20:02:46 +00:00 by kayg · 0 comments
Owner

Blocking Money import finding from #462

Reviewed job/money-ident at ae35584698192489d53bea2a5ad72b23d98632c1.
This is a static code trace. No test or server ran. All values are synthetic.

DESIGN §48 requires equal source rows with one ID to merge and conflicting
fields under one ID to fail before conversion or totals. Split children do not
use the new top-level Transaction identity check.

Evidence: crates/plugins/money/src/import.rs:4219 groups separate children
without checking IDs. Lines 4294–4307 select and convert embedded children
without checking IDs. Regular children lose their ID in ImportSplit.
Transfer children keep their ID at line 4322 but bypass identity validation.

Small source: USD, Cash Account a, Expense Category food, no Assignments,
openings, source Account balance or month snapshots. One parent p dated
2026-01-31 has amount -1000 milliunits. Its two embedded children are exact
copies of {id: "s", category_id: "food", amount: -500}.

Expected: merge s once, then reject the -50 child/-100 parent mismatch. No
preview or Budget. Actual code trace: both children remain; their sum equals
the parent. crates/calternal-money/src/budget.rs:930 accepts the sum. Cash
balance becomes -100; Ready to Assign is 0; Food Activity/Available are -100.
Account checks pass because they use the accepted parent. No source Category
or Ready to Assign snapshots exist to catch this case.

Conflicting case: child s is -600 in Food and -400 in Other. This must fail.
Instead, Food Activity/Available become -60 and Other become -40. The same
cases work through separate children with transaction_id: "p".

Fix scope: validate child identity before conversion, including embedded and
separate lists, parent references, deletion state and transfer children. Keep
distinct IDs. Reject conflicts rather than generate new Markdown IDs.

Regression idea: test exact duplicates, conflicting amount/Category/parent/
Memo/deletion fields, and transfer-child collisions. Assert no retained
preview or publication. Existing top-level tests do not cover repeated IDs
within one child list.

Search before filing: "subtransactions" returned no issues; "split child"
returned only #462. This issue has one shared fix for child identity.

# Blocking Money import finding from #462 Reviewed `job/money-ident` at `ae35584698192489d53bea2a5ad72b23d98632c1`. This is a static code trace. No test or server ran. All values are synthetic. DESIGN §48 requires equal source rows with one ID to merge and conflicting fields under one ID to fail before conversion or totals. Split children do not use the new top-level Transaction identity check. Evidence: `crates/plugins/money/src/import.rs:4219` groups separate children without checking IDs. Lines 4294–4307 select and convert embedded children without checking IDs. Regular children lose their ID in `ImportSplit`. Transfer children keep their ID at line 4322 but bypass identity validation. Small source: USD, Cash Account `a`, Expense Category `food`, no Assignments, openings, source Account balance or month snapshots. One parent `p` dated 2026-01-31 has amount -1000 milliunits. Its two embedded children are exact copies of `{id: "s", category_id: "food", amount: -500}`. Expected: merge `s` once, then reject the -50 child/-100 parent mismatch. No preview or Budget. Actual code trace: both children remain; their sum equals the parent. `crates/calternal-money/src/budget.rs:930` accepts the sum. Cash balance becomes -100; Ready to Assign is 0; Food Activity/Available are -100. Account checks pass because they use the accepted parent. No source Category or Ready to Assign snapshots exist to catch this case. Conflicting case: child `s` is -600 in Food and -400 in Other. This must fail. Instead, Food Activity/Available become -60 and Other become -40. The same cases work through separate children with `transaction_id: "p"`. Fix scope: validate child identity before conversion, including embedded and separate lists, parent references, deletion state and transfer children. Keep distinct IDs. Reject conflicts rather than generate new Markdown IDs. Regression idea: test exact duplicates, conflicting amount/Category/parent/ Memo/deletion fields, and transfer-child collisions. Assert no retained preview or publication. Existing top-level tests do not cover repeated IDs within one child list. Search before filing: `"subtransactions"` returned no issues; `"split child"` returned only #462. This issue has one shared fix for child identity.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#948
No description provided.