viewer: no false "database differs" while the books are being written

New concurrency test: one thread writes entries, drafts and receipts as
fast as it can while a Snapshot (the viewer) refreshes in a loop. At
every refresh the snapshot's books must balance, never go backward, and
never see the writer's database as differing from the journal; at the
end it must equal the writer in full. It failed 30 runs in 50:
check_disk read the applied position and the tables in separate
statements, so a write landing between them made a consistent database
look like it "differs", which the viewer shows as a problem in Needs
attention.

- check_disk reads in one read transaction (one consistent view).
- A database that has applied lines the viewer hasn't read yet is now
  DiskCheck::Ahead ("viewer catching up"), not Behind.
- Without the transaction the test fails 14 runs in 20; with it, 50/50.

Also: members' equity spec 3b states the exact bound (a member's period
income is within two cents of their share, one cent of rounding at each
end; the running balance chains exactly), and the spec-blind property
checks that bound. docs/testing.md gains the concurrency layer and item
12: each close into members' capital still rounds on its own (pending).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GWVo7x3UHw5kwCUaWxiejX
This commit is contained in:
swaitsandClaude Opus 5.5 committed 2026-10-13 18:51:15 -06:00
1 parent 45982f702d
commit ad80171ba2
6 files changed
+165 -10

No files matched your search

+7 -5
View File
@@ -2394,10 +2394,12 @@ proptest! {
prop_assert_eq!(st.total.beginning, balance_sheet_as_of(&b.l, prev(day(a))).unwrap().total_equity);
}
/// Oracle: ME INVARIANT 3 — the period's income (closing entries
/// excluded: the model) is split by share to the cent by largest
/// remainder: parts sum to it and each is within one cent of its exact
/// share, and the larger exact remainder never gets less rounding.
/// Oracle: ME INVARIANTS 3-3b — the members' incomes sum to the period's
/// income (closing entries excluded: the model), and each is within
/// less than two cents of its exact share: under one cent of rounding
/// at each end of the cumulative split (docs/testing.md #7: a member's
/// running balance, what Form 1065 K-1 Item L reports, chains exactly;
/// see `each_members_capital_chains_across_statements`).
#[test]
fn prop_me_period_income_split_by_share(gens in arb_books(), (a, _m, e) in three_days(), pct in 1i64..100, month in opt_month()) {
let mut b = build(&gens);
@@ -2409,7 +2411,7 @@ proptest! {
prop_assert_eq!(st.total.net_income, ni);
let cent = c(1);
for (col, share) in st.members.iter().zip([share_a, Decimal::ONE - share_a]) {
prop_assert!((col.net_income - ni * share).abs() < cent, "{:?} share {}", col, share);
prop_assert!((col.net_income - ni * share).abs() < cent + cent, "{:?} share {}", col, share);
}
}
}