Money: month view ordering after category create and concurrent assigns; overspend event gaps (#826 review) #984

Open
opened 2026-10-03 06:53:55 +00:00 by kayg · 46 comments
Owner

Follow-ups from the break-the-numbers review of job/datafix2 (#826, 2026-10-03). Review verdict: PASS (no server number wrong). These are display and event defects.

  1. A2: new category hidden after create during a reload. refreshMonth uses one cache key ('refresh'), so the forced reload after creating a category joins an older in-flight read. Both category-create handlers then paint the old month. Fix: call moneyStore.refresh(budget) before the forced load in both handlers (apps/web/src/lib/money/store.svelte.ts and the month route). Test: create a category while a month read is in flight → the new category is visible.
  2. A3: out-of-order assign responses. Two assigns in different cells whose responses arrive reversed → the older report wins in view, memory and browser storage (reports carry a random UUID with no order). Fix: the server returns a monotonic month revision; the client keeps the highest. Property test over response orders.
  3. Overspend event (#491): checks the transaction's month instead of the current month for back-dated entries; only create emits it (edit and delete don't); each create recalculates the budget twice more; no tests for money.transaction_logged / money.category_overspent. Fix all four with tests; reuse one budget calculation per write.
    Money rule: this needs its own break-the-numbers review before merge.
## Follow-ups from the break-the-numbers review of job/datafix2 (#826, 2026-10-03). Review verdict: PASS (no server number wrong). These are display and event defects. 1. **A2: new category hidden after create during a reload.** `refreshMonth` uses one cache key (`'refresh'`), so the forced reload after creating a category joins an older in-flight read. Both category-create handlers then paint the old month. Fix: call `moneyStore.refresh(budget)` before the forced load in both handlers (`apps/web/src/lib/money/store.svelte.ts` and the month route). Test: create a category while a month read is in flight → the new category is visible. 2. **A3: out-of-order assign responses.** Two assigns in different cells whose responses arrive reversed → the older report wins in view, memory and browser storage (reports carry a random UUID with no order). Fix: the server returns a monotonic month revision; the client keeps the highest. Property test over response orders. 3. **Overspend event (#491):** checks the transaction's month instead of the current month for back-dated entries; only create emits it (edit and delete don't); each create recalculates the budget twice more; no tests for `money.transaction_logged` / `money.category_overspent`. Fix all four with tests; reuse one budget calculation per write. Money rule: this needs its own break-the-numbers review before merge.
Author
Owner

Starting #984 on branch job/moneyfu-984, based on origin/dev at 4a871b383864dad0d6c87bcd22b7f0d589e3506e. The supplied checkout had a zero-byte .git file and zero-byte tracked files, so I preserved it as moneyfu-984.empty-checkout-20261003 and restored this worktree from the shared repository. Next I am merging origin/job/datafix2 as requested.

Starting #984 on branch `job/moneyfu-984`, based on `origin/dev` at `4a871b383864dad0d6c87bcd22b7f0d589e3506e`. The supplied checkout had a zero-byte `.git` file and zero-byte tracked files, so I preserved it as `moneyfu-984.empty-checkout-20261003` and restored this worktree from the shared repository. Next I am merging `origin/job/datafix2` as requested.
Author
Owner

Integration finding: origin/dev had DESIGN §§60–61, while origin/job/datafix2 added Agent discovery and Instant interactions but labeled both §58. I resolved the only merge conflict by keeping those additions as §§58–59 and preserving the newer Canvas/history decisions as §§60–61. git diff --check -- docs/DESIGN.md passed; no conflict markers remain.

Integration finding: `origin/dev` had DESIGN §§60–61, while `origin/job/datafix2` added Agent discovery and Instant interactions but labeled both §58. I resolved the only merge conflict by keeping those additions as §§58–59 and preserving the newer Canvas/history decisions as §§60–61. `git diff --check -- docs/DESIGN.md` passed; no conflict markers remain.
Author
Owner

Finding: the focused Money Vitest command could not start because this restored worktree has no installed web dependencies (vitest and @sveltejs/kit/vite are unresolved). I will install from the committed Bun lockfile and rerun the focused test before the web gates.

Finding: the focused Money Vitest command could not start because this restored worktree has no installed web dependencies (`vitest` and `@sveltejs/kit/vite` are unresolved). I will install from the committed Bun lockfile and rerun the focused test before the web gates.
Author
Owner

Finding: cargo run -p calternal-server -- openapi compiled the server graph but stopped at #[derive(RustEmbed)] because apps/web/build/ does not exist in this restored worktree. Focused Money Vitest (9 tests) and bun run check passed. I am creating the production web build, then will rerun OpenAPI generation.

Finding: `cargo run -p calternal-server -- openapi` compiled the server graph but stopped at `#[derive(RustEmbed)]` because `apps/web/build/` does not exist in this restored worktree. Focused Money Vitest (9 tests) and `bun run check` passed. I am creating the production web build, then will rerun OpenAPI generation.
Author
Owner

Finding: create_transaction calls budget::continuous_months(&check, &month), where month comes from the transaction date, and compares that month's totals. A historical cash overspend can therefore emit money.category_overspent even when the current month is not overspent; update and delete do not check crossings. I am adding one paired before/after replay call per transaction write, comparing affected categories in the user's current month, and adding event assertions for create/update/delete.

Finding: `create_transaction` calls `budget::continuous_months(&check, &month)`, where `month` comes from the transaction date, and compares that month's totals. A historical cash overspend can therefore emit `money.category_overspent` even when the current month is not overspent; update and delete do not check crossings. I am adding one paired before/after replay call per transaction write, comparing affected categories in the user's current month, and adding event assertions for create/update/delete.
Author
Owner

Finding: the core now exposes one paired replay call for comparing pre-write and post-write month totals, and the Money property suite checks both results against independent calculate calls over generated ledgers. Core slice committed as 81e088916.

Gate evidence: cargo clippy -p calternal-money --all-targets -- -D warnings passed (Finished dev profile ... in 2m 31s). cargo test -p calternal-money passed: 15 unit tests, 12 property/integration tests, 2 vector tests, 0 failures.

Finding: the core now exposes one paired replay call for comparing pre-write and post-write month totals, and the Money property suite checks both results against independent `calculate` calls over generated ledgers. Core slice committed as `81e088916`. Gate evidence: `cargo clippy -p calternal-money --all-targets -- -D warnings` passed (`Finished dev profile ... in 2m 31s`). `cargo test -p calternal-money` passed: 15 unit tests, 12 property/integration tests, 2 vector tests, 0 failures.
Author
Owner

The core commit was amended only to list the new paired-replay invariant in the property test module documentation. Its current SHA is 78d8370fd (replacing 81e088916). The previously reported core gates remain green.

The core commit was amended only to list the new paired-replay invariant in the property test module documentation. Its current SHA is `78d8370fd` (replacing `81e088916`). The previously reported core gates remain green.
Author
Owner

The event fix is committed as b8a0ba28b. Transaction event checks now use the request User's time zone and current month; create, edit and delete compare affected categories with one paired replay call and publish only 0-or-positive to negative crossings after durable writes. Overspend event IDs include the per-User write revision, so a category can cross again after it is healed.

Gate evidence: cargo clippy -p calternal-plugin-money --all-targets -- -D warnings passed (Finished dev profile ... in 13.33s). cargo test -p calternal-plugin-money passed: 30 tests, 0 failures; doc tests passed (0 tests). The focused cases cover create payload fields, a backdated change that overspends the current month, a historical-only overspend that emits no current event, and update/delete crossings.

The event fix is committed as `b8a0ba28b`. Transaction event checks now use the request User's time zone and current month; create, edit and delete compare affected categories with one paired replay call and publish only 0-or-positive to negative crossings after durable writes. Overspend event IDs include the per-User write revision, so a category can cross again after it is healed. Gate evidence: `cargo clippy -p calternal-plugin-money --all-targets -- -D warnings` passed (`Finished dev profile ... in 13.33s`). `cargo test -p calternal-plugin-money` passed: 30 tests, 0 failures; doc tests passed (0 tests). The focused cases cover create payload fields, a backdated change that overspends the current month, a historical-only overspend that emits no current event, and update/delete crossings.
Author
Owner

The production-build OpenAPI export and generated API client now agree on the server's unsigned month revision; OpenAPI marks it as an int64 with minimum 0. The generated schema correction is committed as 1db394e8f.

The production-build OpenAPI export and generated API client now agree on the server's unsigned month `revision`; OpenAPI marks it as an `int64` with minimum 0. The generated schema correction is committed as `1db394e8f`.
Author
Owner

Screenshot finding: the existing apps/web/e2e/money.mjs stops before screenshots because its applyScheme sends auto_scheme.location: null; the current AutoSchemeSettings request accepts mode only (crates/calternal-server/src/appearance.rs), and the server returned 422. I left that existing fixture and its expectations unchanged per the owner rule. I am capturing the requested Money month screenshots with a focused production harness using the current request shape and macOS platform emulation.

Screenshot finding: the existing `apps/web/e2e/money.mjs` stops before screenshots because its `applyScheme` sends `auto_scheme.location: null`; the current `AutoSchemeSettings` request accepts `mode` only (`crates/calternal-server/src/appearance.rs`), and the server returned 422. I left that existing fixture and its expectations unchanged per the owner rule. I am capturing the requested Money month screenshots with a focused production harness using the current request shape and macOS platform emulation.
Author
Owner

Finished #984 on job/moneyfu-984 at HEAD 51536608075333dbaff7a92ad0d894fdd72c827c.

Built: A2 refresh invalidation after category creation; A3 per-User month revisions with highest-revision retention in view, memory and browser storage; current-month, User-time-zone overspend crossings for create/edit/delete; money.transaction_logged and overspend event tests; a paired before/after calculation API and generated Money property test. OpenAPI now marks the revision nonnegative. The requested origin/job/datafix2 and latest origin/dev are merged.

Files: apps/web/src/lib/money/store.svelte.ts, apps/web/src/lib/money/acknowledged-month.svelte.test.ts, apps/web/src/routes/money/[budget]/[month]/+page.svelte, crates/plugins/money/src/{store.rs,views.rs,routes.rs,tests.rs}, crates/calternal-money/src/budget.rs, crates/calternal-money/tests/properties.rs, contracts/openapi.json, packages/api-client/src/generated.ts, docs/DESIGN.md.

Gate output (verbatim):

  • cargo fmt --check: exit 0, no output.
  • cargo clippy -p calternal-money --all-targets -- -D warnings:
    Checking calternal-money v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-money)
    Finished dev profile [unoptimized + debuginfo] target(s) in 2m 31s
  • cargo test -p calternal-money: 15 passed; 0 failed unit tests, 12 passed; 0 failed property/integration tests, 2 passed; 0 failed vector tests; doc tests passed.
  • cargo clippy -p calternal-plugin-money --all-targets -- -D warnings:
    Blocking waiting for file lock on package cache (3 occurrences)
    Checking calternal-plugin-money v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/plugins/money)
    Finished dev profile [unoptimized + debuginfo] target(s) in 13.33s
  • cargo test -p calternal-plugin-money: 30 passed; 0 failed; doc tests passed (0 tests).
  • bun run check: svelte-check found 0 errors and 0 warnings.
  • bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts --maxWorkers=2: Test Files 1 passed (1); Tests 9 passed (9).
  • Production screenshot harness: PASS Money month screenshots: 390, 820, and 1440px in Light and Dark, macOS platform.
  • cargo clean: Removed 15068 files, 7.1GiB total.
  • cargo clippy -p calternal-server --all-targets -- -D warnings: incomplete; stopped at the four-hour job limit while compiling dependencies (exit 130 after Ctrl-C). cargo test -p calternal-server was not run.

Screenshots are in the worktree at artifacts/money-984/ (six PNGs). They were not attached: the installed fj issue comment interface accepts a text body but provides no attachment option. The existing bun e2e/money.mjs stopped before capture because its Appearance fixture sends auto_scheme.location: null and the server returned 422; that existing fixture/assertion was left unchanged. The focused production capture used the current mode-only Appearance contract.

UX gaps closed: the category-create race no longer hides the new category; lower-revision assign responses no longer replace newer results; overspend events now follow current-month transitions across backdated edits and deletes.

UX gaps left: the existing budget breadcrumb title is clipped at 390px and 820px in the screenshots. Full bun run test, the full E2E suite, adversarial matrices and the separate Money break-the-numbers review remain for the merge round. Merge-round gates to run: cargo clippy -p calternal-server --all-targets -- -D warnings; cargo test -p calternal-server -- --test-threads=4; bun run test; full E2E and the required Money break-the-numbers review. The full Money E2E needs its stale Appearance request fixture aligned with the current mode-only contract before it can pass.

Decisions not specified in DESIGN: month revisions start from Unix microseconds and advance atomically after durable writes, relying on a nondecreasing wall clock across ordinary restarts; transaction event month uses the User's request/settings time zone with the existing UTC fallback; overspend event IDs include the write revision so later crossings after healing remain distinct. calculate_pair performs one paired call and one shared month walk, with separate exact before/after replay states. The Money core helper is public so the plugin can reuse it.

Finished #984 on `job/moneyfu-984` at HEAD `51536608075333dbaff7a92ad0d894fdd72c827c`. Built: A2 refresh invalidation after category creation; A3 per-User month revisions with highest-revision retention in view, memory and browser storage; current-month, User-time-zone overspend crossings for create/edit/delete; `money.transaction_logged` and overspend event tests; a paired before/after calculation API and generated Money property test. OpenAPI now marks the revision nonnegative. The requested `origin/job/datafix2` and latest `origin/dev` are merged. Files: `apps/web/src/lib/money/store.svelte.ts`, `apps/web/src/lib/money/acknowledged-month.svelte.test.ts`, `apps/web/src/routes/money/[budget]/[month]/+page.svelte`, `crates/plugins/money/src/{store.rs,views.rs,routes.rs,tests.rs}`, `crates/calternal-money/src/budget.rs`, `crates/calternal-money/tests/properties.rs`, `contracts/openapi.json`, `packages/api-client/src/generated.ts`, `docs/DESIGN.md`. Gate output (verbatim): - `cargo fmt --check`: exit 0, no output. - `cargo clippy -p calternal-money --all-targets -- -D warnings`: `Checking calternal-money v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-money)` `Finished dev profile [unoptimized + debuginfo] target(s) in 2m 31s` - `cargo test -p calternal-money`: `15 passed; 0 failed` unit tests, `12 passed; 0 failed` property/integration tests, `2 passed; 0 failed` vector tests; doc tests passed. - `cargo clippy -p calternal-plugin-money --all-targets -- -D warnings`: `Blocking waiting for file lock on package cache` (3 occurrences) `Checking calternal-plugin-money v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/plugins/money)` `Finished dev profile [unoptimized + debuginfo] target(s) in 13.33s` - `cargo test -p calternal-plugin-money`: `30 passed; 0 failed`; doc tests passed (0 tests). - `bun run check`: `svelte-check found 0 errors and 0 warnings`. - `bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts --maxWorkers=2`: `Test Files 1 passed (1); Tests 9 passed (9)`. - Production screenshot harness: `PASS Money month screenshots: 390, 820, and 1440px in Light and Dark, macOS platform`. - `cargo clean`: `Removed 15068 files, 7.1GiB total`. - `cargo clippy -p calternal-server --all-targets -- -D warnings`: incomplete; stopped at the four-hour job limit while compiling dependencies (exit 130 after Ctrl-C). `cargo test -p calternal-server` was not run. Screenshots are in the worktree at `artifacts/money-984/` (six PNGs). They were not attached: the installed `fj issue comment` interface accepts a text body but provides no attachment option. The existing `bun e2e/money.mjs` stopped before capture because its Appearance fixture sends `auto_scheme.location: null` and the server returned 422; that existing fixture/assertion was left unchanged. The focused production capture used the current mode-only Appearance contract. UX gaps closed: the category-create race no longer hides the new category; lower-revision assign responses no longer replace newer results; overspend events now follow current-month transitions across backdated edits and deletes. UX gaps left: the existing budget breadcrumb title is clipped at 390px and 820px in the screenshots. Full `bun run test`, the full E2E suite, adversarial matrices and the separate Money break-the-numbers review remain for the merge round. Merge-round gates to run: `cargo clippy -p calternal-server --all-targets -- -D warnings`; `cargo test -p calternal-server -- --test-threads=4`; `bun run test`; full E2E and the required Money break-the-numbers review. The full Money E2E needs its stale Appearance request fixture aligned with the current mode-only contract before it can pass. Decisions not specified in DESIGN: month revisions start from Unix microseconds and advance atomically after durable writes, relying on a nondecreasing wall clock across ordinary restarts; transaction event month uses the User's request/settings time zone with the existing UTC fallback; overspend event IDs include the write revision so later crossings after healing remain distinct. `calculate_pair` performs one paired call and one shared month walk, with separate exact before/after replay states. The Money core helper is public so the plugin can reuse it.
Author
Owner

Independent correctness review started in detached worktree /home/kayg/Developer/calternal-wt/rev-moneyfu at 5153660807, comparison base job/datafix2. Source branch will remain unchanged. Tests will cover the actual route invalidation sequence as well as revision ordering, event transitions and paired exact arithmetic. No private files will be accessed.

Independent correctness review started in detached worktree /home/kayg/Developer/calternal-wt/rev-moneyfu at 51536608075333dbaff7a92ad0d894fdd72c827c, comparison base job/datafix2. Source branch will remain unchanged. Tests will cover the actual route invalidation sequence as well as revision ordering, event transitions and paired exact arithmetic. No private files will be accessed.
Author
Owner

Review finding R1: actual +page.svelte saveAssigned calls refresh(budget) before rememberMonth for every response. refresh removes the current highest report from memory and browser storage, so the comparison has no current revision. Independent route-sequence probe with response revisions 2 then 1: expected mounted/memory/browser = 2/2/2; actual = 1/1/1. Property test seed 984 shrinks to [2,1,1]. Existing branch ordering property passes because it omits the route refresh step. No server write loss shown; A3 remains unfixed. Review continues with event and arithmetic tests.

Review finding R1: actual +page.svelte saveAssigned calls refresh(budget) before rememberMonth for every response. refresh removes the current highest report from memory and browser storage, so the comparison has no current revision. Independent route-sequence probe with response revisions 2 then 1: expected mounted/memory/browser = 2/2/2; actual = 1/1/1. Property test seed 984 shrinks to [2,1,1]. Existing branch ordering property passes because it omits the route refresh step. No server write loss shown; A3 remains unfixed. Review continues with event and arithmetic tests.
Author
Owner

Review boundary finding: a focused probe using the real assign API and HTTP transport accepts a delayed successful User A PUT after session-ended/auth-changed and publishes its report through the route continuation into User B memory and browser storage. Expected both surfaces empty; actual both contain the synthetic User A Budget report. This predates #984 and is NOT a demonstrated normal sign-in leak: +layout.svelte forces a fresh document after session end/User changes, which mitigates this unit-level missing fence. GETs are fenced correctly. I will report it separately from the confirmed A3 acceptance failure.

Review boundary finding: a focused probe using the real assign API and HTTP transport accepts a delayed successful User A PUT after session-ended/auth-changed and publishes its report through the route continuation into User B memory and browser storage. Expected both surfaces empty; actual both contain the synthetic User A Budget report. This predates #984 and is NOT a demonstrated normal sign-in leak: +layout.svelte forces a fresh document after session end/User changes, which mitigates this unit-level missing fence. GETs are fenced correctly. I will report it separately from the confirmed A3 acceptance failure.
Author
Owner

Review performance finding (static, not a measured regression): routes.rs project_with still replays the proposed ledger at lines 421-428. budget.rs calculate_pair creates two Replay states at lines 922-923 and calls month for both at 928-929. Create therefore still performs the validation replay plus two event replays; edit/delete now also do the pair. The requested reuse of the validated after calculation is not implemented. I added a deferred 1,000/100,000-transaction pair-vs-independent profile with five raw samples and CPU/RSS collection; it will not run in this non-performance job under the verification policy. No matching Money profile exists in docs/perf/baseline.json.

Review performance finding (static, not a measured regression): routes.rs project_with still replays the proposed ledger at lines 421-428. budget.rs calculate_pair creates two Replay states at lines 922-923 and calls month for both at 928-929. Create therefore still performs the validation replay plus two event replays; edit/delete now also do the pair. The requested reuse of the validated after calculation is not implemented. I added a deferred 1,000/100,000-transaction pair-vs-independent profile with five raw samples and CPU/RSS collection; it will not run in this non-performance job under the verification policy. No matching Money profile exists in docs/perf/baseline.json.
Author
Owner

Confirmed review finding R2: the real Money router read a temporary Budget.md replacement made through calternal-fs. The new report correctly contained assigned=123 minor units, but its revision stayed 1791028553413667, identical to the pre-write report. Expected a greater revision for changed source files; assertion failed. Full Money plugin run: test result: FAILED. 36 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 34.40s. All existing 30 tests and the six other added route/zone probes passed. This is a revision contract gap for normal server file writes, not incorrect server arithmetic.

Confirmed review finding R2: the real Money router read a temporary Budget.md replacement made through calternal-fs. The new report correctly contained assigned=123 minor units, but its revision stayed 1791028553413667, identical to the pre-write report. Expected a greater revision for changed source files; assertion failed. Full Money plugin run: test result: FAILED. 36 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 34.40s. All existing 30 tests and the six other added route/zone probes passed. This is a revision contract gap for normal server file writes, not incorrect server arithmetic.
Author
Owner

Independent Money review — #984

Verdict: BLOCK for #984 acceptance. A3 still fails in the assign route.
No wrong server arithmetic or lost server write was found in the completed probes.

Reviewed source: job/moneyfu-984 at 51536608075333dbaff7a92ad0d894fdd72c827c.
Comparison: git diff job/datafix2...job/moneyfu-984.
Work: detached worktree /home/kayg/Developer/calternal-wt/rev-moneyfu.
The source branch was not changed. No private data was read.

Findings

R1 — A3 is not fixed. In the month route, saveAssigned calls
refresh(budget) before rememberMonth for each response. refresh deletes
the current report from memory and browser storage. The highest-revision
comparison therefore has no retained report to compare with.

Expected for responses 2 then 1: route continuation, memory and browser
snapshot retain revision 2. Actual: all three contain revision 1. The
generated property (seed 984) shrinks to [2, 1, 1]. The branch's property
passes because it calls rememberMonth without the route's refresh step.
This is a confirmed stale display and snapshot defect; no server write was lost.
Preserve a per-User/Budget/month acknowledged revision through invalidation,
or compare the acknowledgement before deleting the retained report.

R2 — file writes do not advance the report revision. Expected: the changed report has a greater revision. Actual: Assignment changed to 123 minor units but both reports kept revision 1791028553413667. FAIL.
The revision only advances in UserMoney::replace and create_file.
The file cache separately detects changes by fingerprint. A source-file
replacement can therefore change the report without advancing its revision.
This needs revision handling for normal server file writes as well as Money
route writes. The probe uses calternal-fs on a temporary Home, not a live
Files endpoint.

R3 — the write calculation is not reused (performance follow-up).
project_with still calculates the proposed ledger for validation
(routes.rs:421–428). calculate_pair constructs two Replay states and
calls month on each (budget.rs:922–929). Create still has its validation
replay plus two event replays. Edit and delete now also perform the pair.
This is a static call-count finding, not a measured regression. One function
call and one outer month loop do not remove the second after-state replay.

R4 — late successful writes have no session fence at the API/store boundary.
A real assign/HTTP-transport probe delays only fetch. It sends
session-ended, changes the synthetic User and sends auth-changed, then
returns the old User's successful response. Expected: no new-User snapshot.
Actual: the route continuation stores the old User's report in new-User
memory and browser storage. This behavior predates #984. The app shell
reloads the document on User changes and sign-out, so this probe does not
prove a leak through normal sign-in. Treat it as a boundary-hardening gap.
The delayed GET User-switch probe passes.

Expected versus actual

Probe Expected Actual
Assign responses 2 then 1, with actual route invalidation Keep 2 in return value, memory and browser snapshot All retain 1: FAIL
Generated assign ordering with duplicates Keep maximum revision [2,1,1] retains 1: FAIL
Direct acknowledgement ordering without route invalidation Keep maximum revision PASS (branch property)
Budget/month/User keys Independent revisions; clear returning User snapshot PASS
Stored higher revision followed by lower GET Keep stored report PASS
Legacy, negative, fractional and unsafe browser revisions Drop invalid report PASS
User switch during GET Fence old read PASS
Category create with another month read pending Fresh category; fence old read; invalidate other stored months PASS
Backdated create, edit and delete Emit only current-month crossings PASS
Exactly zero, healing, recrossing, subsequent negative edits and delete Only nonnegative-to-negative transitions; unique IDs PASS
Moving refund to another category Event for category it leaves PASS
Moving refund to next month One current-month event at exact -100 minor units PASS
Concurrent assignments Distinct ordered revisions; latest response equals final report PASS
Source-file replacement Changed report has greater revision FAIL: unchanged 1791028553413667
Imported splits and on/off-budget transfers Reject unsupported edit/delete with 422, no file or event change PASS
Local month and year edges Sep in Los Angeles, Oct in Kolkata, Jan in Kiritimati PASS; deterministic local-day primitive, not a frozen-clock HTTP test
Mixed before/after replays, additions/deletions/cross-month edits, all four currency scales Match independent exact calculations PASS
Odd negative split and tracking transfer Explicit -50/-51 remainder; transfer changes no category total PASS
Excess currency precision; malformed, reversed or duplicate months Reject; no rounding PASS
10,000-transaction paired replay Exact match on both sides PASS
Old-User successful PUT after lifecycle reset Boundary refuses publication FAIL in unit continuation; shell reload mitigation applies

Built and files

Review-only tests and a deferred performance profile:

  • apps/web/src/lib/money/review-984.svelte.test.ts
  • apps/web/src/lib/money/review-session-984.svelte.test.ts
  • crates/calternal-money/tests/review_984.rs
  • crates/plugins/money/src/review_984.rs
  • crates/plugins/money/src/tests.rs (test module registration only)
  • bench/money-pair-review-984.sh

Review commits: f85cda21790f5ad673daa87b892d54958b3b9792 (browser probes),
e12ea32ab0eea16038efa458195bf76d59fdb6c5 (route probes), and HEAD
b2127e0fd440fc59ab4a342992b7f45c81bad2e1 (arithmetic/profile).
The review history is retained locally as refs/reviews/rev-moneyfu-984.
Existing assertions and production code were not changed. Failing review
assertions keep the required behavior as evidence. These commits are review
evidence, not a candidate to merge unchanged.

Gate output (verbatim)

cargo fmt --check: exit 0, no output.

cargo clippy -p calternal-money --all-targets -- -D warnings:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 10m 14s

cargo test -p calternal-money:

test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.84s
test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.52s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.47s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-plugin-money --all-targets -- -D warnings:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 17s

cargo test -p calternal-plugin-money (exit 101; intended review failure R2):

test result: FAILED. 36 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 34.40s

bun run check:

svelte-check found 0 errors and 0 warnings

bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts src/lib/money/review-984.svelte.test.ts --maxWorkers=2 (exit 1; two R1 probes):

 Test Files  1 failed | 1 passed (2)
      Tests  2 failed | 17 passed (19)

bunx vitest run src/lib/money/review-session-984.svelte.test.ts --maxWorkers=2 (exit 1; boundary probe R4):

 Test Files  1 failed (1)
      Tests  1 failed (1)

bash -n bench/money-pair-review-984.sh and git diff --check: exit 0, no output.
Raw logs and the review patch are retained in the local review artifacts.

Known gaps and decisions

  • Performance measurement is deferred by the verification policy for this
    non-performance job. No matching Money baseline exists in
    docs/perf/baseline.json. No latency, CPU or RSS claim is made.
  • The ignored profile compares paired and independent replays on 1,000 and
    100,000 transactions with five raw latency samples; /usr/bin/time -v
    reports whole-process CPU and peak RSS, including fixture setup. It does
    not measure full HTTP route latency.
  • Time-zone month edges use the same deterministic local_day primitive as
    production today. The HTTP event tests use the actual current month;
    they do not freeze the production clock at a month boundary.
  • Server revision seeds rely on a nondecreasing wall clock across restarts.
    Clock rollback and suspend/restart recovery were not exercised.
  • No production UI feature changed, so no screenshot set was generated.
  • Decision: preserve the exact requested review snapshot. git fetch origin
    was run once, but origin/dev was not merged into the detached review:
    that would change the subject being reviewed. The source job had already
    merged origin/dev in the supplied head.
  • No product decisions were added. The review retains synthetic fixtures
    and reuses the branch's route helpers and the public arithmetic oracle.

For the merge round

  • Fix R1, then run
    cd apps/web && bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts src/lib/money/review-984.svelte.test.ts --maxWorkers=2
    to prove that the real route invalidation sequence retains the maximum.
  • Resolve R2, then run
    cargo test -p calternal-plugin-money review_file_replacement_advances_month_revision -- --test-threads=4.
  • Run cd apps/web && bun run test,
    cargo clippy -p calternal-server --all-targets -- -D warnings,
    cargo test -p calternal-server -- --test-threads=4,
    bash tests/adversarial/run.sh and bun tests/adversarial/money_api.mjs
    on the combined branch. These must prove full-suite compatibility, server
    integration and live-server input/isolation behavior. This review ran no
    live server protocol matrix.
  • Build the deferred profile on the build host:
    cargo test -p calternal-money --test review_984 --release --no-run.
    Copy its test binary to the perf VM, then run
    MONEY_REVIEW_BIN=<copied-release-test-binary> flock /root/perf.lock bash bench/money-pair-review-984.sh.
    The script records load average inside the lock. Compare the two modes;
    use a separate route profile to measure the full write cost.

Cleanup: cargo clean reported:

Removed 4141 files, 1.6GiB total

Web build output was deleted. The detached review worktree was removed.
Logs, the report and the review patch are retained at
/home/kayg/Developer/calternal/artifacts/rev-moneyfu-984/.

# Independent Money review — #984 Verdict: **BLOCK for #984 acceptance. A3 still fails in the assign route.** No wrong server arithmetic or lost server write was found in the completed probes. Reviewed source: `job/moneyfu-984` at `51536608075333dbaff7a92ad0d894fdd72c827c`. Comparison: `git diff job/datafix2...job/moneyfu-984`. Work: detached worktree `/home/kayg/Developer/calternal-wt/rev-moneyfu`. The source branch was not changed. No private data was read. ## Findings **R1 — A3 is not fixed.** In the month route, `saveAssigned` calls `refresh(budget)` before `rememberMonth` for each response. `refresh` deletes the current report from memory and browser storage. The highest-revision comparison therefore has no retained report to compare with. Expected for responses 2 then 1: route continuation, memory and browser snapshot retain revision 2. Actual: all three contain revision 1. The generated property (seed 984) shrinks to `[2, 1, 1]`. The branch's property passes because it calls `rememberMonth` without the route's `refresh` step. This is a confirmed stale display and snapshot defect; no server write was lost. Preserve a per-User/Budget/month acknowledged revision through invalidation, or compare the acknowledgement before deleting the retained report. **R2 — file writes do not advance the report revision.** Expected: the changed report has a greater revision. Actual: Assignment changed to 123 minor units but both reports kept revision `1791028553413667`. FAIL. The revision only advances in `UserMoney::replace` and `create_file`. The file cache separately detects changes by fingerprint. A source-file replacement can therefore change the report without advancing its revision. This needs revision handling for normal server file writes as well as Money route writes. The probe uses `calternal-fs` on a temporary Home, not a live Files endpoint. **R3 — the write calculation is not reused (performance follow-up).** `project_with` still calculates the proposed ledger for validation (`routes.rs:421–428`). `calculate_pair` constructs two `Replay` states and calls `month` on each (`budget.rs:922–929`). Create still has its validation replay plus two event replays. Edit and delete now also perform the pair. This is a static call-count finding, not a measured regression. One function call and one outer month loop do not remove the second after-state replay. **R4 — late successful writes have no session fence at the API/store boundary.** A real `assign`/HTTP-transport probe delays only `fetch`. It sends `session-ended`, changes the synthetic User and sends `auth-changed`, then returns the old User's successful response. Expected: no new-User snapshot. Actual: the route continuation stores the old User's report in new-User memory and browser storage. This behavior predates #984. The app shell reloads the document on User changes and sign-out, so this probe does **not** prove a leak through normal sign-in. Treat it as a boundary-hardening gap. The delayed GET User-switch probe passes. ## Expected versus actual | Probe | Expected | Actual | | --- | --- | --- | | Assign responses 2 then 1, with actual route invalidation | Keep 2 in return value, memory and browser snapshot | All retain 1: FAIL | | Generated assign ordering with duplicates | Keep maximum revision | `[2,1,1]` retains 1: FAIL | | Direct acknowledgement ordering without route invalidation | Keep maximum revision | PASS (branch property) | | Budget/month/User keys | Independent revisions; clear returning User snapshot | PASS | | Stored higher revision followed by lower GET | Keep stored report | PASS | | Legacy, negative, fractional and unsafe browser revisions | Drop invalid report | PASS | | User switch during GET | Fence old read | PASS | | Category create with another month read pending | Fresh category; fence old read; invalidate other stored months | PASS | | Backdated create, edit and delete | Emit only current-month crossings | PASS | | Exactly zero, healing, recrossing, subsequent negative edits and delete | Only nonnegative-to-negative transitions; unique IDs | PASS | | Moving refund to another category | Event for category it leaves | PASS | | Moving refund to next month | One current-month event at exact -100 minor units | PASS | | Concurrent assignments | Distinct ordered revisions; latest response equals final report | PASS | | Source-file replacement | Changed report has greater revision | FAIL: unchanged `1791028553413667` | | Imported splits and on/off-budget transfers | Reject unsupported edit/delete with 422, no file or event change | PASS | | Local month and year edges | Sep in Los Angeles, Oct in Kolkata, Jan in Kiritimati | PASS; deterministic local-day primitive, not a frozen-clock HTTP test | | Mixed before/after replays, additions/deletions/cross-month edits, all four currency scales | Match independent exact calculations | PASS | | Odd negative split and tracking transfer | Explicit -50/-51 remainder; transfer changes no category total | PASS | | Excess currency precision; malformed, reversed or duplicate months | Reject; no rounding | PASS | | 10,000-transaction paired replay | Exact match on both sides | PASS | | Old-User successful PUT after lifecycle reset | Boundary refuses publication | FAIL in unit continuation; shell reload mitigation applies | ## Built and files Review-only tests and a deferred performance profile: - `apps/web/src/lib/money/review-984.svelte.test.ts` - `apps/web/src/lib/money/review-session-984.svelte.test.ts` - `crates/calternal-money/tests/review_984.rs` - `crates/plugins/money/src/review_984.rs` - `crates/plugins/money/src/tests.rs` (test module registration only) - `bench/money-pair-review-984.sh` Review commits: `f85cda21790f5ad673daa87b892d54958b3b9792` (browser probes), `e12ea32ab0eea16038efa458195bf76d59fdb6c5` (route probes), and HEAD `b2127e0fd440fc59ab4a342992b7f45c81bad2e1` (arithmetic/profile). The review history is retained locally as `refs/reviews/rev-moneyfu-984`. Existing assertions and production code were not changed. Failing review assertions keep the required behavior as evidence. These commits are review evidence, not a candidate to merge unchanged. ## Gate output (verbatim) `cargo fmt --check`: exit 0, no output. `cargo clippy -p calternal-money --all-targets -- -D warnings`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 10m 14s ``` `cargo test -p calternal-money`: ```text test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.84s test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.52s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.47s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-plugin-money --all-targets -- -D warnings`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 17s ``` `cargo test -p calternal-plugin-money` (exit 101; intended review failure R2): ```text test result: FAILED. 36 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 34.40s ``` `bun run check`: ```text svelte-check found 0 errors and 0 warnings ``` `bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts src/lib/money/review-984.svelte.test.ts --maxWorkers=2` (exit 1; two R1 probes): ```text Test Files 1 failed | 1 passed (2) Tests 2 failed | 17 passed (19) ``` `bunx vitest run src/lib/money/review-session-984.svelte.test.ts --maxWorkers=2` (exit 1; boundary probe R4): ```text Test Files 1 failed (1) Tests 1 failed (1) ``` `bash -n bench/money-pair-review-984.sh` and `git diff --check`: exit 0, no output. Raw logs and the review patch are retained in the local review artifacts. ## Known gaps and decisions - Performance measurement is deferred by the verification policy for this non-performance job. No matching Money baseline exists in `docs/perf/baseline.json`. No latency, CPU or RSS claim is made. - The ignored profile compares paired and independent replays on 1,000 and 100,000 transactions with five raw latency samples; `/usr/bin/time -v` reports whole-process CPU and peak RSS, including fixture setup. It does not measure full HTTP route latency. - Time-zone month edges use the same deterministic `local_day` primitive as production `today`. The HTTP event tests use the actual current month; they do not freeze the production clock at a month boundary. - Server revision seeds rely on a nondecreasing wall clock across restarts. Clock rollback and suspend/restart recovery were not exercised. - No production UI feature changed, so no screenshot set was generated. - Decision: preserve the exact requested review snapshot. `git fetch origin` was run once, but `origin/dev` was not merged into the detached review: that would change the subject being reviewed. The source job had already merged `origin/dev` in the supplied head. - No product decisions were added. The review retains synthetic fixtures and reuses the branch's route helpers and the public arithmetic oracle. ## For the merge round - Fix R1, then run `cd apps/web && bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts src/lib/money/review-984.svelte.test.ts --maxWorkers=2` to prove that the real route invalidation sequence retains the maximum. - Resolve R2, then run `cargo test -p calternal-plugin-money review_file_replacement_advances_month_revision -- --test-threads=4`. - Run `cd apps/web && bun run test`, `cargo clippy -p calternal-server --all-targets -- -D warnings`, `cargo test -p calternal-server -- --test-threads=4`, `bash tests/adversarial/run.sh` and `bun tests/adversarial/money_api.mjs` on the combined branch. These must prove full-suite compatibility, server integration and live-server input/isolation behavior. This review ran no live server protocol matrix. - Build the deferred profile on the build host: `cargo test -p calternal-money --test review_984 --release --no-run`. Copy its test binary to the perf VM, then run `MONEY_REVIEW_BIN=<copied-release-test-binary> flock /root/perf.lock bash bench/money-pair-review-984.sh`. The script records load average inside the lock. Compare the two modes; use a separate route profile to measure the full write cost. Cleanup: `cargo clean` reported: ```text Removed 4141 files, 1.6GiB total ``` Web build output was deleted. The detached review worktree was removed. Logs, the report and the review patch are retained at `/home/kayg/Developer/calternal/artifacts/rev-moneyfu-984/`.
Author
Owner

Follow-up started on job/moneyfu-984, base 5153660807. Bringing in the independent review regression commits from refs/reviews/rev-moneyfu-984 before changes; will reproduce R1/R2/R4 and fix revision publication and source tracking.

Follow-up started on job/moneyfu-984, base 51536608075333dbaff7a92ad0d894fdd72c827c. Bringing in the independent review regression commits from refs/reviews/rev-moneyfu-984 before changes; will reproduce R1/R2/R4 and fix revision publication and source tracking.
Author
Owner

Reproduction: focused Vitest initially reported 3 failed / 17 passed: reversed assign publication and delayed old-User PUT. Two extra storage probes also failed: invalidation before acknowledgement discarded a restored report, and warm memory ignored newer browser storage. The fix retains bounded highest revisions through refresh, compares stored reports with memory, and fences all Money API responses on User/lifecycle changes. No existing expectations were changed.

Reproduction: focused Vitest initially reported 3 failed / 17 passed: reversed assign publication and delayed old-User PUT. Two extra storage probes also failed: invalidation before acknowledgement discarded a restored report, and warm memory ignored newer browser storage. The fix retains bounded highest revisions through refresh, compares stored reports with memory, and fences all Money API responses on User/lifecycle changes. No existing expectations were changed.
Author
Owner

Client slices committed as 36cfb9237 and the following storage repair commit. Focused Vitest passes all 23 tests. A third storage probe found that cachedMonth returned the newest memory report but left older restored bytes in browser storage; it now repairs those bytes while preserving fetchedAt. Invalid stored JSON also cannot erase a valid revision fence. Rust baseline is compiling the dependency graph before the file-replacement reproduction.

Client slices committed as 36cfb9237 and the following storage repair commit. Focused Vitest passes all 23 tests. A third storage probe found that cachedMonth returned the newest memory report but left older restored bytes in browser storage; it now repairs those bytes while preserving fetchedAt. Invalid stored JSON also cannot erase a valid revision fence. Rust baseline is compiling the dependency graph before the file-replacement reproduction.
Author
Owner

Server reproduction confirmed: review_file_replacement_advances_month_revision failed on the real Money router: changed report kept revision 1791032330610943 (0 passed; 1 failed). The added source-set probe also failed on an Accounts.md replacement. Applying a bounded per-Budget source hash/generation record covering Budget.md, Accounts.md and ordered month names/hashes; reports will carry the generation of their own source snapshot. API write identities remain distinct for events.

Server reproduction confirmed: review_file_replacement_advances_month_revision failed on the real Money router: changed report kept revision 1791032330610943 (0 passed; 1 failed). The added source-set probe also failed on an Accounts.md replacement. Applying a bounded per-Budget source hash/generation record covering Budget.md, Accounts.md and ordered month names/hashes; reports will carry the generation of their own source snapshot. API write identities remain distinct for events.
Author
Owner

Merged origin/dev once before final gates: merge HEAD ab58aee9d7, origin/dev d4e718881. Integration added DESIGN §62 only, without conflicts or source changes. All 8 focused server review probes passed after the source-generation fix (including unchanged bytes, content restoration, added/deleted month files). Final per-crate clippy/test and web checks are now running.

Merged origin/dev once before final gates: merge HEAD ab58aee9d750f74cdbdc735b9dd758d508623ab3, origin/dev d4e718881. Integration added DESIGN §62 only, without conflicts or source changes. All 8 focused server review probes passed after the source-generation fix (including unchanged bytes, content restoration, added/deleted month files). Final per-crate clippy/test and web checks are now running.
Author
Owner

Source-generation fix committed as 726cf58bd; API description/generated client follow-up e6dc43e8d. Final plugin gates passed: cargo fmt --check (exit 0, no output); clippy: Finished dev profile [unoptimized + debuginfo] target(s) in 16m 23s; test result: ok. 38 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 74.55s. Web: svelte-check found 0 errors and 0 warnings; Test Files 3 passed (3), Tests 26 passed (26). Continuing core/server integration gates and a focused mounted-route regression with screenshots.

Source-generation fix committed as 726cf58bd; API description/generated client follow-up e6dc43e8d. Final plugin gates passed: cargo fmt --check (exit 0, no output); clippy: Finished `dev` profile [unoptimized + debuginfo] target(s) in 16m 23s; test result: ok. 38 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 74.55s. Web: svelte-check found 0 errors and 0 warnings; Test Files 3 passed (3), Tests 26 passed (26). Continuing core/server integration gates and a focused mounted-route regression with screenshots.
Author
Owner

Integration progress: calternal-money clippy passed (Finished dev profile [unoptimized + debuginfo] target(s) in 54.33s); core tests passed 15 unit, 12 property/integration, 4 review (1 performance profile ignored), 2 vector tests, and doc tests. calternal-server clippy passed: Finished dev profile [unoptimized + debuginfo] target(s) in 30m 53s. Server test build is running next. DESIGN §48 revision contract is committed as 79b61c6cf; no Rust or web implementation changed after the successful gates.

Integration progress: calternal-money clippy passed (Finished `dev` profile [unoptimized + debuginfo] target(s) in 54.33s); core tests passed 15 unit, 12 property/integration, 4 review (1 performance profile ignored), 2 vector tests, and doc tests. calternal-server clippy passed: Finished `dev` profile [unoptimized + debuginfo] target(s) in 30m 53s. Server test build is running next. DESIGN §48 revision contract is committed as 79b61c6cf; no Rust or web implementation changed after the successful gates.
Author
Owner

Server gate finding (existing in supplied base, not modified): cargo test -p calternal-server -- --test-threads=4 failed with test result: FAILED. 159 passed; 2 failed; 5 ignored; 0 measured; 0 filtered out; finished in 21.75s. Failing names: integrations::tests::independent_review::mail_626_and_connected_accounts_apply_in_both_orders and integrations::tests::independent_review::populated_0012_and_mail_0009_preserve_links_in_both_orders. Both stop at integrations_review.rs:88: assert_eq!(mail.migrations.last().unwrap().version, 9), actual 10. git show 515366080:crates/calternal-server/src/integrations_review.rs contains the same assertion; git ls-tree 515366080 lists plugins/mail/migrations/0010_preference_revision.sql. There is no follow-up diff in these files. Per the owner rule, I preserved both expectations; the orchestrator must decide their correction. Debug server build and focused Money browser evidence continue.

Server gate finding (existing in supplied base, not modified): cargo test -p calternal-server -- --test-threads=4 failed with test result: FAILED. 159 passed; 2 failed; 5 ignored; 0 measured; 0 filtered out; finished in 21.75s. Failing names: integrations::tests::independent_review::mail_626_and_connected_accounts_apply_in_both_orders and integrations::tests::independent_review::populated_0012_and_mail_0009_preserve_links_in_both_orders. Both stop at integrations_review.rs:88: assert_eq!(mail.migrations.last().unwrap().version, 9), actual 10. git show 515366080:crates/calternal-server/src/integrations_review.rs contains the same assertion; git ls-tree 515366080 lists plugins/mail/migrations/0010_preference_revision.sql. There is no follow-up diff in these files. Per the owner rule, I preserved both expectations; the orchestrator must decide their correction. Debug server build and focused Money browser evidence continue.
Author
Owner

Additional refresh-path finding from the production app: category creation starts a forced month read; an Assignment acknowledgement supersedes it and displays the new amount; releasing the obsolete GET caused the cold/forced load catch to paint This budget has a problem. The focused DOM-state probe failed (actual true, expected false for seeing an error state). The shared read cache correctly throws RevisionCacheSupersededError, but the route treated that cancellation as a real error. Adding a cancellation guard and saving the real-response browser regression as apps/web/e2e/money-revisions-984.mjs. The reversed-assign production probe already passes; six macOS screenshots were captured before this additional fix.

Additional refresh-path finding from the production app: category creation starts a forced month read; an Assignment acknowledgement supersedes it and displays the new amount; releasing the obsolete GET caused the cold/forced load catch to paint This budget has a problem. The focused DOM-state probe failed (actual true, expected false for seeing an error state). The shared read cache correctly throws RevisionCacheSupersededError, but the route treated that cancellation as a real error. Adding a cancellation guard and saving the real-response browser regression as apps/web/e2e/money-revisions-984.mjs. The reversed-assign production probe already passes; six macOS screenshots were captured before this additional fix.
Author
Owner

Money #984 follow-up implemented on job/moneyfu-984. Head: 56d02542d3.
Base: 5153660807. Merged origin/dev once at ab58aee9d7 (origin/dev d4e718881). No push, deploy or issue close.

What was built

  • Cherry-picked the independent review tests first (review commits f85cda217, e12ea32ab, b2127e0fd). Confirmed the browser tests failed on reversed Assignment acknowledgements and the delayed old-User write; confirmed the real router file-replacement test failed on an unchanged revision.
  • Compare every month response and browser restore against the greatest retained revision. Refresh invalidates visible cached reads without discarding that ordering fence. Warm memory also compares restored browser bytes and repairs older stored reports.
  • Fence every Money API completion, including successful writes and failures, to the initiating User and shared lifecycle generation. Added same-User session-ended, session-expired and access-changed regressions. The User-switch probe now passes directly; it does not depend on a forced reload.
  • Derive ordered report generations from the complete source content hashes and filenames: Budget.md, Accounts.md and month files. Changed, added, removed and restored source files advance the generation; identical bytes retain it. Responses use the generation captured with their loaded Budget.
  • Added a real production browser regression for reversed HTTP acknowledgements and a forced read superseded by an Assignment. This found an additional defect: canceled refresh painted a false budget error after the acknowledged write. The route now treats that shared cancellation as superseded and keeps the latest report.
  • Updated the revision contract, regenerated the API client and documented the behavior in DESIGN §48. The compiled server OpenAPI command regenerated contracts/openapi.json with no additional diff. No dependencies or migrations changed.

Files

apps/web/e2e/money-revisions-984.mjs
apps/web/src/lib/money/api.ts
apps/web/src/lib/money/review-984.svelte.test.ts
apps/web/src/lib/money/review-session-984.svelte.test.ts
apps/web/src/lib/money/store.svelte.ts
apps/web/src/routes/money/[budget]/[month]/+page.svelte
bench/money-pair-review-984.sh
contracts/openapi.json
crates/calternal-money/tests/review_984.rs
crates/plugins/money/src/review_984.rs
crates/plugins/money/src/routes.rs
crates/plugins/money/src/store.rs
crates/plugins/money/src/tests.rs
crates/plugins/money/src/views.rs
docs/DESIGN.md
packages/api-client/src/generated.ts

Verification (verbatim terminal excerpts)
All Cargo commands used CARGO_PROFILE_DEV_DEBUG=line-tables-only, CARGO_INCREMENTAL=0, CARGO_BUILD_JOBS=4, and worktree target/tmp. No workspace gates.

cargo fmt --check: exit 0, no output.

cargo clippy -p calternal-plugin-money --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 16m 23s

cargo test -p calternal-plugin-money

test result: ok. 38 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 74.55s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-money --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 54.33s

cargo test -p calternal-money

test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.26s
test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 3.52s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.56s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-server --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 30m 53s

cargo test -p calternal-server (NOT green)

test result: FAILED. 159 passed; 2 failed; 5 ignored; 0 measured; 0 filtered out; finished in 21.75s
error: test failed, to rerun pass `-p calternal-server --bin calternal-server`

Both failures are existing Mail migration review tests at integrations_review.rs:88:

assertion `left == right` failed
  left: 10
 right: 9

Failing tests: integrations::tests::independent_review::mail_626_and_connected_accounts_apply_in_both_orders and integrations::tests::independent_review::populated_0012_and_mail_0009_preserve_links_in_both_orders. The original base already contains both the latest-version-9 assertion and Mail migration 0010_preference_revision.sql. Neither file changed here. Filed #1010; kept existing expectations unchanged as instructed. Their migration-order assertions are not reached, and subsequent server test targets may not run after this binary fails.

cd apps/web && bun run check

$ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
User browser caches use userStorage; only documented device/public-link exceptions remain.
Text sizes and UI shape values use shared role tokens.
UI transitions and animation options use shared motion tokens or documented exceptions.
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/moneyfu-984/apps/web
Getting Svelte diagnostics...

svelte-check found 0 errors and 0 warnings

cd apps/web && bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts src/lib/money/review-984.svelte.test.ts src/lib/money/review-session-984.svelte.test.ts --maxWorkers=2

 Test Files  3 passed (3)
      Tests  26 passed (26)
   Start at  16:56:08
   Duration  8.35s (transform 47%, environment 36%, setup 13%, tests 3%, import 1%)

Production web build passed. With this branch's server and fresh production SPA, CALTERNAL_E2E_ASSET_OVERRIDE=1 bun e2e/money-revisions-984.mjs:

PASS production route: reversed assign responses keep the newest displayed values and browser report
PASS production route: a superseded forced refresh keeps the acknowledged report without an error state
PASS production screenshots: macOS, 390/820/1440px, Light/Dark

Screenshots are local at artifacts/money-984-followup/screenshots/money-{light,dark}-{390,820,1440}.png. All six were inspected, including icon/text pairs; visual approval remains with Claude. The available fj CLI has no attachment command; the images are retained for the orchestrator to attach, not committed. Raw output and reproduction logs are in artifacts/money-984-followup/.

UX gaps closed

  • Reversed acknowledgements no longer roll back the mounted report, memory or browser storage.
  • Browser restore cannot overwrite a newer retained report, including while memory is warm.
  • External source writes no longer leave a changed report at an equal revision.
  • An old User/lifecycle completion cannot populate the next User's Money state.
  • Superseded forced refresh cannot replace the latest acknowledged report with a false error.
  • Delayed Assignment publication is fenced to its original route.

UX gaps left / known gaps

  • Existing narrow-width breadcrumb truncation remains visible in the review screenshots. This job changes response ordering, not layout.
  • Server gates remain red for #1010. No existing expectations were changed.
  • The inherited Unix-microsecond seed assumes a nondecreasing wall clock across normal restarts; clock rollback across process restarts is not covered.
  • No performance numbers were measured, per the non-performance-job verification policy. The cherry-picked replay profile remains available for the perf VM; no performance claim is made.
  • Full suites, adversarial matrices, release, staging and real Mac interop belong to the merge round. The existing full Money browser test also has a stale Appearance request with location:null (422); it was not changed here.

Decisions

  • Reuse existing parsed BLAKE3 hashes, length-frame the ordered filename/hash set, and retain at most 200 source records per User. Serialize source observations and attach the resulting generation to the loaded Budget snapshot.
  • Keep at most eight greatest report references separately from visible read caches; clear both at an authoritative denial or shared User/access/Plugin lifecycle boundary.
  • Use the shared lifecycle invalidation event list to fence all API completions; a forced reload is no longer required to make the probe safe.
  • Treat shared superseded-read cancellation as cancellation in the mounted month route. Keep acknowledged content immediately; do not wait on motion.

For the merge round

  • Resolve #1010 with the owner, then cargo test -p calternal-server -- --test-threads=4; prove both migration-order/data-preservation tests reach their real assertions.
  • cd apps/web && bun run test --maxWorkers=2 and bun run test:e2e:money (first align the stale Appearance request with its current contract); prove full Money actions and other consumers remain correct.
  • Run the combined branch's full e2e and bash tests/adversarial/run.sh, including its Money API coverage; prove authorization, filesystem and concurrent-write behavior against the real combined server.
  • Run the second independent Money review at the head above.
  • If replay performance is measured, build the release review_984 binary on the build host and copy it to the perf VM; run bench/money-pair-review-984.sh inside flock /root/perf.lock with MONEY_REVIEW_BIN set. Compare with the baseline; no compilation on the VM.

Cleanup

Removed 16044 files, 8.4GiB total

Deleted apps/web/build and apps/web/.svelte-kit/output. Working tree is clean.

Money #984 follow-up implemented on job/moneyfu-984. Head: 56d02542d3dc37a007215538c7cd39046d9d5ed8. Base: 51536608075333dbaff7a92ad0d894fdd72c827c. Merged origin/dev once at ab58aee9d750f74cdbdc735b9dd758d508623ab3 (origin/dev d4e718881). No push, deploy or issue close. What was built - Cherry-picked the independent review tests first (review commits f85cda217, e12ea32ab, b2127e0fd). Confirmed the browser tests failed on reversed Assignment acknowledgements and the delayed old-User write; confirmed the real router file-replacement test failed on an unchanged revision. - Compare every month response and browser restore against the greatest retained revision. Refresh invalidates visible cached reads without discarding that ordering fence. Warm memory also compares restored browser bytes and repairs older stored reports. - Fence every Money API completion, including successful writes and failures, to the initiating User and shared lifecycle generation. Added same-User session-ended, session-expired and access-changed regressions. The User-switch probe now passes directly; it does not depend on a forced reload. - Derive ordered report generations from the complete source content hashes and filenames: Budget.md, Accounts.md and month files. Changed, added, removed and restored source files advance the generation; identical bytes retain it. Responses use the generation captured with their loaded Budget. - Added a real production browser regression for reversed HTTP acknowledgements and a forced read superseded by an Assignment. This found an additional defect: canceled refresh painted a false budget error after the acknowledged write. The route now treats that shared cancellation as superseded and keeps the latest report. - Updated the revision contract, regenerated the API client and documented the behavior in DESIGN §48. The compiled server OpenAPI command regenerated contracts/openapi.json with no additional diff. No dependencies or migrations changed. Files ``` apps/web/e2e/money-revisions-984.mjs apps/web/src/lib/money/api.ts apps/web/src/lib/money/review-984.svelte.test.ts apps/web/src/lib/money/review-session-984.svelte.test.ts apps/web/src/lib/money/store.svelte.ts apps/web/src/routes/money/[budget]/[month]/+page.svelte bench/money-pair-review-984.sh contracts/openapi.json crates/calternal-money/tests/review_984.rs crates/plugins/money/src/review_984.rs crates/plugins/money/src/routes.rs crates/plugins/money/src/store.rs crates/plugins/money/src/tests.rs crates/plugins/money/src/views.rs docs/DESIGN.md packages/api-client/src/generated.ts ``` Verification (verbatim terminal excerpts) All Cargo commands used CARGO_PROFILE_DEV_DEBUG=line-tables-only, CARGO_INCREMENTAL=0, CARGO_BUILD_JOBS=4, and worktree target/tmp. No workspace gates. `cargo fmt --check`: exit 0, no output. `cargo clippy -p calternal-plugin-money --all-targets -- -D warnings` ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 16m 23s ``` `cargo test -p calternal-plugin-money` ``` test result: ok. 38 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 74.55s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-money --all-targets -- -D warnings` ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 54.33s ``` `cargo test -p calternal-money` ``` test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.26s test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 3.52s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.56s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-server --all-targets -- -D warnings` ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 30m 53s ``` `cargo test -p calternal-server` (NOT green) ``` test result: FAILED. 159 passed; 2 failed; 5 ignored; 0 measured; 0 filtered out; finished in 21.75s error: test failed, to rerun pass `-p calternal-server --bin calternal-server` ``` Both failures are existing Mail migration review tests at integrations_review.rs:88: ``` assertion `left == right` failed left: 10 right: 9 ``` Failing tests: integrations::tests::independent_review::mail_626_and_connected_accounts_apply_in_both_orders and integrations::tests::independent_review::populated_0012_and_mail_0009_preserve_links_in_both_orders. The original base already contains both the latest-version-9 assertion and Mail migration 0010_preference_revision.sql. Neither file changed here. Filed #1010; kept existing expectations unchanged as instructed. Their migration-order assertions are not reached, and subsequent server test targets may not run after this binary fails. `cd apps/web && bun run check` ``` $ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json User browser caches use userStorage; only documented device/public-link exceptions remain. Text sizes and UI shape values use shared role tokens. UI transitions and animation options use shared motion tokens or documented exceptions. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/moneyfu-984/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `cd apps/web && bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts src/lib/money/review-984.svelte.test.ts src/lib/money/review-session-984.svelte.test.ts --maxWorkers=2` ``` Test Files 3 passed (3) Tests 26 passed (26) Start at 16:56:08 Duration 8.35s (transform 47%, environment 36%, setup 13%, tests 3%, import 1%) ``` Production web build passed. With this branch's server and fresh production SPA, `CALTERNAL_E2E_ASSET_OVERRIDE=1 bun e2e/money-revisions-984.mjs`: ``` PASS production route: reversed assign responses keep the newest displayed values and browser report PASS production route: a superseded forced refresh keeps the acknowledged report without an error state PASS production screenshots: macOS, 390/820/1440px, Light/Dark ``` Screenshots are local at artifacts/money-984-followup/screenshots/money-{light,dark}-{390,820,1440}.png. All six were inspected, including icon/text pairs; visual approval remains with Claude. The available fj CLI has no attachment command; the images are retained for the orchestrator to attach, not committed. Raw output and reproduction logs are in artifacts/money-984-followup/. UX gaps closed - Reversed acknowledgements no longer roll back the mounted report, memory or browser storage. - Browser restore cannot overwrite a newer retained report, including while memory is warm. - External source writes no longer leave a changed report at an equal revision. - An old User/lifecycle completion cannot populate the next User's Money state. - Superseded forced refresh cannot replace the latest acknowledged report with a false error. - Delayed Assignment publication is fenced to its original route. UX gaps left / known gaps - Existing narrow-width breadcrumb truncation remains visible in the review screenshots. This job changes response ordering, not layout. - Server gates remain red for #1010. No existing expectations were changed. - The inherited Unix-microsecond seed assumes a nondecreasing wall clock across normal restarts; clock rollback across process restarts is not covered. - No performance numbers were measured, per the non-performance-job verification policy. The cherry-picked replay profile remains available for the perf VM; no performance claim is made. - Full suites, adversarial matrices, release, staging and real Mac interop belong to the merge round. The existing full Money browser test also has a stale Appearance request with location:null (422); it was not changed here. Decisions - Reuse existing parsed BLAKE3 hashes, length-frame the ordered filename/hash set, and retain at most 200 source records per User. Serialize source observations and attach the resulting generation to the loaded Budget snapshot. - Keep at most eight greatest report references separately from visible read caches; clear both at an authoritative denial or shared User/access/Plugin lifecycle boundary. - Use the shared lifecycle invalidation event list to fence all API completions; a forced reload is no longer required to make the probe safe. - Treat shared superseded-read cancellation as cancellation in the mounted month route. Keep acknowledged content immediately; do not wait on motion. For the merge round - Resolve #1010 with the owner, then `cargo test -p calternal-server -- --test-threads=4`; prove both migration-order/data-preservation tests reach their real assertions. - `cd apps/web && bun run test --maxWorkers=2` and `bun run test:e2e:money` (first align the stale Appearance request with its current contract); prove full Money actions and other consumers remain correct. - Run the combined branch's full e2e and `bash tests/adversarial/run.sh`, including its Money API coverage; prove authorization, filesystem and concurrent-write behavior against the real combined server. - Run the second independent Money review at the head above. - If replay performance is measured, build the release review_984 binary on the build host and copy it to the perf VM; run bench/money-pair-review-984.sh inside `flock /root/perf.lock` with MONEY_REVIEW_BIN set. Compare with the baseline; no compilation on the VM. Cleanup ``` Removed 16044 files, 8.4GiB total ``` Deleted apps/web/build and apps/web/.svelte-kit/output. Working tree is clean.
Author
Owner

Second independent #984 review started in detached worktree /home/kayg/Developer/calternal-wt/rev2-moneyfu, source job/moneyfu-984 HEAD 56d02542d3dc37a007215538c7cd39046d9d5ed8, comparison base job/datafix2. Re-running first-review evidence from refs/reviews/rev-moneyfu-984 (already included by the implementation branch), then adding generation/storage/lifecycle attacks. Source branch remains unchanged. No private data will be accessed. Per latest verification policy, performance profile and full server/adversarial/UI suites are deferred to merge round; focused router and regression tests run here.

Second independent #984 review started in detached worktree `/home/kayg/Developer/calternal-wt/rev2-moneyfu`, source `job/moneyfu-984` HEAD `56d02542d3dc37a007215538c7cd39046d9d5ed8`, comparison base `job/datafix2`. Re-running first-review evidence from `refs/reviews/rev-moneyfu-984` (already included by the implementation branch), then adding generation/storage/lifecycle attacks. Source branch remains unchanged. No private data will be accessed. Per latest verification policy, performance profile and full server/adversarial/UI suites are deferred to merge round; focused router and regression tests run here.
Author
Owner

Second-review progress: the inherited 38 Money router tests pass, including both original BLOCK reproductions (reversed Assign responses and external Budget.md replacement now advance/retain the expected revision). Browser tests pass: Test Files 3 passed (3); Tests 29 passed (29), including a new 200-case property mixing multi-tab storage restores, duplicate acknowledgements and actual route invalidation. Added equal-size rapid A/B/A file replacements with concurrent duplicate reads and same Budget ID across Users; final plugin gates are running.

Fetched and merged origin/dev once into the detached review history (6bb979f78, origin/dev cfee85c6b11537968aaa0685d1ed1c3ac68a8c3e). The DESIGN conflict was separator/section-history overlap; retained §§58–59 and all current rules. No Money production code changed in this integration.

Non-blocking limitation from the first review remains: project_with validates the proposed ledger with a replay, then calculate_pair replays both before/after states. This is not after-state reuse. No performance numbers are claimed; measuring the existing profile is deferred by the latest non-performance-job verification policy.

Second-review progress: the inherited 38 Money router tests pass, including both original BLOCK reproductions (reversed Assign responses and external Budget.md replacement now advance/retain the expected revision). Browser tests pass: `Test Files 3 passed (3); Tests 29 passed (29)`, including a new 200-case property mixing multi-tab storage restores, duplicate acknowledgements and actual route invalidation. Added equal-size rapid A/B/A file replacements with concurrent duplicate reads and same Budget ID across Users; final plugin gates are running. Fetched and merged origin/dev once into the detached review history (`6bb979f78`, origin/dev `cfee85c6b11537968aaa0685d1ed1c3ac68a8c3e`). The DESIGN conflict was separator/section-history overlap; retained §§58–59 and all current rules. No Money production code changed in this integration. Non-blocking limitation from the first review remains: `project_with` validates the proposed ledger with a replay, then `calculate_pair` replays both before/after states. This is not after-state reuse. No performance numbers are claimed; measuring the existing profile is deferred by the latest non-performance-job verification policy.
Author
Owner

Second review finding R5: non-atomic multi-tab browser publication can lower the stored revision. Deterministic storage-level probe uses the production MoneyStore, mocked User storage and synthetic reports. Tab B starts warm at 100 and accepts acknowledgement 150; after B's comparison read but immediately before its setItem, inject Tab A's publication of 200. B then writes 150 unconditionally in #storeMonth. Expected final browser revision 200; actual 150. Assertion: AssertionError: expected 150 to be 200 // Object.is equality. Focused file: Tests 1 failed | 16 passed (17).

The sequential restore tests pass; they do not cover another tab publishing between the comparison and setItem. No Money storage listener or cross-tab serialization is present. This is a persisted snapshot ordering defect, not wrong server arithmetic, data loss, or a cross-User leak. The test models a possible interleaving at the storage boundary; a normal two-browser reproduction has not been run. Preserve this independent failing expectation as review evidence. Both prior BLOCK cases now pass; all 40 plugin/router tests pass, including rapid equal-size A/B/A replacements and separate Users' identical Budget IDs.

Second review finding R5: non-atomic multi-tab browser publication can lower the stored revision. Deterministic storage-level probe uses the production MoneyStore, mocked User storage and synthetic reports. Tab B starts warm at 100 and accepts acknowledgement 150; after B's comparison read but immediately before its setItem, inject Tab A's publication of 200. B then writes 150 unconditionally in #storeMonth. Expected final browser revision 200; actual 150. Assertion: `AssertionError: expected 150 to be 200 // Object.is equality`. Focused file: `Tests 1 failed | 16 passed (17)`. The sequential restore tests pass; they do not cover another tab publishing between the comparison and setItem. No Money storage listener or cross-tab serialization is present. This is a persisted snapshot ordering defect, not wrong server arithmetic, data loss, or a cross-User leak. The test models a possible interleaving at the storage boundary; a normal two-browser reproduction has not been run. Preserve this independent failing expectation as review evidence. Both prior BLOCK cases now pass; all 40 plugin/router tests pass, including rapid equal-size A/B/A replacements and separate Users' identical Budget IDs.
Author
Owner

Second independent Money review — #984

Verdict: BLOCK for persisted multi-tab revision ordering (R5). Both original BLOCK cases are fixed. No wrong server arithmetic, lost server write, crash or cross-User leak was found in these probes.

Reviewed source: job/moneyfu-984 at 56d02542d3dc37a007215538c7cd39046d9d5ed8; comparison git diff job/datafix2...job/moneyfu-984. Detached review worktree: /home/kayg/Developer/calternal-wt/rev2-moneyfu. Review evidence HEAD: 0bd4608fd0552ab9bca075ecd9e6964cd83192e3, retained locally at refs/reviews/rev2-moneyfu-984. Source branch unchanged. No push, deploy or private-data access.

Read CLAUDE.md, CONTEXT.md, DESIGN §48 and relevant event/session rules; read #984 and #826's review comment. Re-ran the first-review tests retained in refs/reviews/rev-moneyfu-984 and already cherry-picked into the source. Existing assertions were kept. Fetched and merged origin/dev once in the detached history, merge 6bb979f78, origin/dev cfee85c6b11537968aaa0685d1ed1c3ac68a8c3e. Kept both sides' DESIGN sections when resolving separator/history conflicts. That integration changed no Money production code.

Failing case R5

MoneyStore.#acceptMonth reads browser storage before #storeMonth writes it. These operations do not form one cross-tab transaction.

  1. Tab B has revision 100 in memory/browser storage.
  2. B receives revision 150 and compares it with 100.
  3. Tab A publishes revision 200 after B's comparison read, before B's setItem.
  4. B writes 150 unconditionally, replacing 200.

Expected browser snapshot: revision 200. Actual: 150. This loses the greatest persisted report and can restore stale values after reload. It does not change source files or server totals.

The independent regression uses the production MoneyStore with mocked User storage. It inserts the other tab's publication immediately before the older setItem. This is a deterministic storage-boundary interleaving, not a completed two-browser reproduction. The ordinary sequential multi-tab restore probes pass; they do not cover this interval. No Money snapshot storage-event listener or publication serialization is present. Preserve this failing expectation as evidence, not as a candidate test suite to merge unchanged. Make publication safe across tabs (for example, serialize all publishers or retain reports under immutable revision keys), then prove the regression passes.

AssertionError: expected 150 to be 200 // Object.is equality

Location: apps/web/src/lib/money/review-984.svelte.test.ts:158; assertion at line 170.

Expected versus actual

Attack Expected Actual
First review R1: Assign responses 2 then 1, actual route refresh sequence Mounted result, memory and browser stay at 2 PASS
Reversed/duplicated response property Keep maximum revision PASS, first-review seed 984
First review R2: source Budget.md replacement Changed report gets greater generation PASS
Accounts/month/Budget source edits, restore old bytes, add/delete month Every observed changed set advances; repeated equal bytes stay stable PASS
Rapid equal-size A/B/A edits, concurrent duplicate GETs Exact Assignment; strictly increasing changed generations; duplicate reads equal PASS, 16 replacement rounds, each followed by equal-byte replacement
Same Budget ID in separate Users' Homes Other User writes leave owner's report and generation unchanged PASS
Multi-tab restores mixed with duplicated acks and refresh Greatest retained report on every surface PASS, 200 generated sequences, seed 2984, up to 60 operations each
Another Budget refresh while a read is pending Cancel old GET and retain independent higher acknowledgement PASS
Equal-generation duplicate acknowledgement Idempotent exact totals PASS, 20 repetitions
Higher tab publication between comparison read and older write Persist 200 FAIL, persists 150 (R5)
Browser restore, invalid legacy/unsafe revision, Budget/month separation Keep highest valid retained report, isolate keys PASS
User switch during GET or successful PUT; same-User lifecycle reset Reject old completion before publication PASS
Category create with pending read Fence pre-create read; fresh category; clear other month snapshots PASS
Backdated create/edit/delete; zero, healing and recrossing Only current-month nonnegative-to-negative crossings; unique IDs PASS
Category change and cross-month refund move Emit for affected old category/current month with exact amount PASS
User-zone month/year edges Correct local calendar month PASS, deterministic local-day primitive; not frozen-clock HTTP
Imported split and on/off-budget transfer write attempts 422; unchanged file; no write events PASS
Paired exact replay across negative amounts, splits, transfers, all four currency scales Match both independent replays; reject excess precision without rounding PASS, 128 generated cases plus explicit remainder tests
10,000-row paired replay Exact results on both sides PASS

Equal content retaining one generation is intentional. A/B/A content restoration after an observed B gets a fresh generation; it is not a hash collision. No cryptographic BLAKE3 collision was constructed or claimed.

Built and files

Review-only tests, no production fixes:

  • apps/web/src/lib/money/review-984.svelte.test.ts: mixed storage/ack property, independent Budget cancellation, duplicate idempotence, failing concurrent storage publication.
  • crates/plugins/money/src/review_984.rs: rapid equal-size content restoration, duplicate reads and separate Users' identical Budget IDs.
  • docs/DESIGN.md: integration conflict resolution only; no new product decision.

Atomic evidence commits: ebd784800 (passing browser probes), e4d5ef349 (module reasoning), ae1d8df94 (passing router probes), 0bd4608fd (isolated intentionally failing R5 evidence). Merge commit: 6bb979f78.

Gate output (verbatim excerpts)

All Cargo commands used the preset target directory, CARGO_PROFILE_DEV_DEBUG=line-tables-only, CARGO_INCREMENTAL=0, CARGO_BUILD_JOBS=4 and this worktree's target/tmp. No workspace gate or server build.

cargo fmt --check: exit 0, no output.

cargo clippy -p calternal-plugin-money --all-targets -- -D warnings:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 42s

cargo test -p calternal-plugin-money -- --test-threads=4:

test result: ok. 40 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 16.43s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo test -p calternal-money -- --test-threads=4 (re-run arithmetic review; core unchanged):

test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.17s
test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.73s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.41s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cd apps/web && bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts src/lib/money/review-984.svelte.test.ts src/lib/money/review-session-984.svelte.test.ts --maxWorkers=2 (exit 1; intended R5 review failure):

 Test Files  1 failed | 2 passed (3)
      Tests  1 failed | 29 passed (30)

cd apps/web && bun run check:

svelte-check found 0 errors and 0 warnings

Known gaps and decisions

  • R5 remains unfixed in this review-only scope. It is a storage-boundary reproduction; a two-browser production confirmation remains to be done.
  • The first review's performance concern remains: project_with replays for validation, then calculate_pair builds two replay states. The validated after result is not reused. No performance measurement or regression claim was made. The existing profile covers 1,000 and 100,000 transactions with pair versus independent latency samples, CPU and peak RSS. The latest verification policy defers measurement in this non-performance job. There is no Money profile baseline in docs/perf/baseline.json.
  • The wall-clock revision seed assumes no clock rollback across restarts. Ordering records are bounded (eight client reports, 200 server source records). Tests claim ordering for retained records, not indefinite history.
  • Month-edge tests use the production local-day primitive; they do not freeze the HTTP route clock. Full-server matrices, production browser suites and Mac interop were not run under this review job's verification policy. This review changed tests only, so it requires no new screenshot set.
  • No dependency, arithmetic, event semantics or product design decisions were introduced. The deterministic cross-tab publication interleaving is a review test choice. It preserves the highest-persisted-revision expectation as a failing assertion.

UX gaps closed / left

Closed by the source branch and confirmed here: the original reversed Assignment acknowledgement, source-file generation gap, sequential restore ordering, category-create invalidation and old-User completion fence.

Left: concurrent tab publication can replace the greatest browser snapshot (R5). This review did not modify product code or judge visual quality.

For the merge round

  • Fix R5, then run cd apps/web && bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts src/lib/money/review-984.svelte.test.ts src/lib/money/review-session-984.svelte.test.ts --maxWorkers=2; prove persisted revision 200 survives the interleaving.
  • Add a two-tab production check for the same interval to the existing browser regression, then run cd apps/web && CALTERNAL_E2E_ASSET_OVERRIDE=1 bun e2e/money-revisions-984.mjs; prove actual mounted values and restart snapshots stay ordered.
  • Run cd apps/web && bun run test --maxWorkers=2, bun run test:e2e:money (resolve the known stale Appearance fixture first) and bash tests/adversarial/run.sh; prove combined server/UI behavior and authorization.
  • Resolve the source branch's known #1010 server gate failures, then run cargo test -p calternal-server -- --test-threads=4; prove migration-order assertions execute.
  • If measuring the extra replay work, copy a build-host release review_984 test binary to the perf VM, set MONEY_REVIEW_BIN, then run flock /root/perf.lock bash bench/money-pair-review-984.sh. Record load average and compare both modes. Do not compile on the VM.

Cleanup

Removed 4033 files, 1.6GiB total

Review history retained locally; report and raw logs archived in the main worktree under artifacts/rev2-moneyfu-984/. The detached worktree is removed after posting this report.

## Second independent Money review — #984 Verdict: **BLOCK for persisted multi-tab revision ordering (R5).** Both original BLOCK cases are fixed. No wrong server arithmetic, lost server write, crash or cross-User leak was found in these probes. Reviewed source: `job/moneyfu-984` at `56d02542d3dc37a007215538c7cd39046d9d5ed8`; comparison `git diff job/datafix2...job/moneyfu-984`. Detached review worktree: `/home/kayg/Developer/calternal-wt/rev2-moneyfu`. Review evidence HEAD: `0bd4608fd0552ab9bca075ecd9e6964cd83192e3`, retained locally at `refs/reviews/rev2-moneyfu-984`. Source branch unchanged. No push, deploy or private-data access. Read CLAUDE.md, CONTEXT.md, DESIGN §48 and relevant event/session rules; read #984 and #826's review comment. Re-ran the first-review tests retained in `refs/reviews/rev-moneyfu-984` and already cherry-picked into the source. Existing assertions were kept. Fetched and merged `origin/dev` once in the detached history, merge `6bb979f78`, origin/dev `cfee85c6b11537968aaa0685d1ed1c3ac68a8c3e`. Kept both sides' DESIGN sections when resolving separator/history conflicts. That integration changed no Money production code. ### Failing case R5 `MoneyStore.#acceptMonth` reads browser storage before `#storeMonth` writes it. These operations do not form one cross-tab transaction. 1. Tab B has revision 100 in memory/browser storage. 2. B receives revision 150 and compares it with 100. 3. Tab A publishes revision 200 after B's comparison read, before B's setItem. 4. B writes 150 unconditionally, replacing 200. Expected browser snapshot: revision **200**. Actual: **150**. This loses the greatest persisted report and can restore stale values after reload. It does not change source files or server totals. The independent regression uses the production MoneyStore with mocked User storage. It inserts the other tab's publication immediately before the older setItem. This is a deterministic storage-boundary interleaving, not a completed two-browser reproduction. The ordinary sequential multi-tab restore probes pass; they do not cover this interval. No Money snapshot storage-event listener or publication serialization is present. Preserve this failing expectation as evidence, not as a candidate test suite to merge unchanged. Make publication safe across tabs (for example, serialize all publishers or retain reports under immutable revision keys), then prove the regression passes. ```text AssertionError: expected 150 to be 200 // Object.is equality ``` Location: `apps/web/src/lib/money/review-984.svelte.test.ts:158`; assertion at line 170. ### Expected versus actual | Attack | Expected | Actual | | --- | --- | --- | | First review R1: Assign responses 2 then 1, actual route refresh sequence | Mounted result, memory and browser stay at 2 | PASS | | Reversed/duplicated response property | Keep maximum revision | PASS, first-review seed 984 | | First review R2: source Budget.md replacement | Changed report gets greater generation | PASS | | Accounts/month/Budget source edits, restore old bytes, add/delete month | Every observed changed set advances; repeated equal bytes stay stable | PASS | | Rapid equal-size A/B/A edits, concurrent duplicate GETs | Exact Assignment; strictly increasing changed generations; duplicate reads equal | PASS, 16 replacement rounds, each followed by equal-byte replacement | | Same Budget ID in separate Users' Homes | Other User writes leave owner's report and generation unchanged | PASS | | Multi-tab restores mixed with duplicated acks and refresh | Greatest retained report on every surface | PASS, 200 generated sequences, seed 2984, up to 60 operations each | | Another Budget refresh while a read is pending | Cancel old GET and retain independent higher acknowledgement | PASS | | Equal-generation duplicate acknowledgement | Idempotent exact totals | PASS, 20 repetitions | | Higher tab publication between comparison read and older write | Persist 200 | FAIL, persists 150 (R5) | | Browser restore, invalid legacy/unsafe revision, Budget/month separation | Keep highest valid retained report, isolate keys | PASS | | User switch during GET or successful PUT; same-User lifecycle reset | Reject old completion before publication | PASS | | Category create with pending read | Fence pre-create read; fresh category; clear other month snapshots | PASS | | Backdated create/edit/delete; zero, healing and recrossing | Only current-month nonnegative-to-negative crossings; unique IDs | PASS | | Category change and cross-month refund move | Emit for affected old category/current month with exact amount | PASS | | User-zone month/year edges | Correct local calendar month | PASS, deterministic local-day primitive; not frozen-clock HTTP | | Imported split and on/off-budget transfer write attempts | 422; unchanged file; no write events | PASS | | Paired exact replay across negative amounts, splits, transfers, all four currency scales | Match both independent replays; reject excess precision without rounding | PASS, 128 generated cases plus explicit remainder tests | | 10,000-row paired replay | Exact results on both sides | PASS | Equal content retaining one generation is intentional. A/B/A content restoration after an observed B gets a fresh generation; it is not a hash collision. No cryptographic BLAKE3 collision was constructed or claimed. ### Built and files Review-only tests, no production fixes: - `apps/web/src/lib/money/review-984.svelte.test.ts`: mixed storage/ack property, independent Budget cancellation, duplicate idempotence, failing concurrent storage publication. - `crates/plugins/money/src/review_984.rs`: rapid equal-size content restoration, duplicate reads and separate Users' identical Budget IDs. - `docs/DESIGN.md`: integration conflict resolution only; no new product decision. Atomic evidence commits: `ebd784800` (passing browser probes), `e4d5ef349` (module reasoning), `ae1d8df94` (passing router probes), `0bd4608fd` (isolated intentionally failing R5 evidence). Merge commit: `6bb979f78`. ### Gate output (verbatim excerpts) All Cargo commands used the preset target directory, CARGO_PROFILE_DEV_DEBUG=line-tables-only, CARGO_INCREMENTAL=0, CARGO_BUILD_JOBS=4 and this worktree's target/tmp. No workspace gate or server build. `cargo fmt --check`: exit 0, no output. `cargo clippy -p calternal-plugin-money --all-targets -- -D warnings`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 42s ``` `cargo test -p calternal-plugin-money -- --test-threads=4`: ```text test result: ok. 40 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 16.43s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo test -p calternal-money -- --test-threads=4` (re-run arithmetic review; core unchanged): ```text test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.17s test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.73s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.41s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cd apps/web && bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts src/lib/money/review-984.svelte.test.ts src/lib/money/review-session-984.svelte.test.ts --maxWorkers=2` (exit 1; intended R5 review failure): ```text Test Files 1 failed | 2 passed (3) Tests 1 failed | 29 passed (30) ``` `cd apps/web && bun run check`: ```text svelte-check found 0 errors and 0 warnings ``` ### Known gaps and decisions - R5 remains unfixed in this review-only scope. It is a storage-boundary reproduction; a two-browser production confirmation remains to be done. - The first review's performance concern remains: `project_with` replays for validation, then `calculate_pair` builds two replay states. The validated after result is not reused. No performance measurement or regression claim was made. The existing profile covers 1,000 and 100,000 transactions with pair versus independent latency samples, CPU and peak RSS. The latest verification policy defers measurement in this non-performance job. There is no Money profile baseline in `docs/perf/baseline.json`. - The wall-clock revision seed assumes no clock rollback across restarts. Ordering records are bounded (eight client reports, 200 server source records). Tests claim ordering for retained records, not indefinite history. - Month-edge tests use the production local-day primitive; they do not freeze the HTTP route clock. Full-server matrices, production browser suites and Mac interop were not run under this review job's verification policy. This review changed tests only, so it requires no new screenshot set. - No dependency, arithmetic, event semantics or product design decisions were introduced. The deterministic cross-tab publication interleaving is a review test choice. It preserves the highest-persisted-revision expectation as a failing assertion. ### UX gaps closed / left Closed by the source branch and confirmed here: the original reversed Assignment acknowledgement, source-file generation gap, sequential restore ordering, category-create invalidation and old-User completion fence. Left: concurrent tab publication can replace the greatest browser snapshot (R5). This review did not modify product code or judge visual quality. ### For the merge round - Fix R5, then run `cd apps/web && bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts src/lib/money/review-984.svelte.test.ts src/lib/money/review-session-984.svelte.test.ts --maxWorkers=2`; prove persisted revision 200 survives the interleaving. - Add a two-tab production check for the same interval to the existing browser regression, then run `cd apps/web && CALTERNAL_E2E_ASSET_OVERRIDE=1 bun e2e/money-revisions-984.mjs`; prove actual mounted values and restart snapshots stay ordered. - Run `cd apps/web && bun run test --maxWorkers=2`, `bun run test:e2e:money` (resolve the known stale Appearance fixture first) and `bash tests/adversarial/run.sh`; prove combined server/UI behavior and authorization. - Resolve the source branch's known #1010 server gate failures, then run `cargo test -p calternal-server -- --test-threads=4`; prove migration-order assertions execute. - If measuring the extra replay work, copy a build-host release review_984 test binary to the perf VM, set MONEY_REVIEW_BIN, then run `flock /root/perf.lock bash bench/money-pair-review-984.sh`. Record load average and compare both modes. Do not compile on the VM. ### Cleanup ```text Removed 4033 files, 1.6GiB total ``` Review history retained locally; report and raw logs archived in the main worktree under `artifacts/rev2-moneyfu-984/`. The detached worktree is removed after posting this report.
Author
Owner

Continuing the second review fix on job/moneyfu-984, base HEAD 56d02542d. Cherry-picked review probe 0bd4608fd as a1ea2c3bb, retaining the second-review ordering properties as well. I will serialize month browser publication across tabs and reuse validation totals for overspend comparisons. No pushes or deployment.

Continuing the second review fix on `job/moneyfu-984`, base HEAD `56d02542d`. Cherry-picked review probe `0bd4608fd` as `a1ea2c3bb`, retaining the second-review ordering properties as well. I will serialize month browser publication across tabs and reuse validation totals for overspend comparisons. No pushes or deployment.
Author
Owner

Confirmed rev2 R5 before the fix: the cherry-picked probe reported AssertionError: expected 150 to be 200; Tests 1 failed | 16 passed (17). The original assertion and interleaving are unchanged.

The final month Storage seam now acquires a per-User exclusive Web Lock, reads the stored revision inside the lock, and keeps the highest report before publication/pruning. All month write/repair callers use that seam. Storage events reconcile memory and mounted month views. Refresh keeps persisted ordering fences instead of deleting them. Queue completions are fenced on session/access reset. Without Web Locks, month persistence stays disabled and memory remains usable. The lock semantics are defined in https://www.w3.org/TR/web-locks/; this is a browser coordination choice, not a dependency addition.

Focused Vitest now passes 35 tests, including the original rev2 probe, delayed acquisition, queued lifecycle cancellation, storage-event view updates and the no-lock case. Existing assertions and fixture data were not changed; a shared test-only LockManager seam supplies the new platform dependency.

R3: project_with retains checked totals through the later of the event month and last source month. Overspend comparison takes those totals (not an after Ledger) and replays only the before state. A focused regression proves a future validation month does not shift the current-month event comparison. The Money plugin clippy passes; its 39-test gate is running.

Confirmed rev2 R5 before the fix: the cherry-picked probe reported `AssertionError: expected 150 to be 200`; `Tests 1 failed | 16 passed (17)`. The original assertion and interleaving are unchanged. The final month Storage seam now acquires a per-User exclusive Web Lock, reads the stored revision inside the lock, and keeps the highest report before publication/pruning. All month write/repair callers use that seam. Storage events reconcile memory and mounted month views. Refresh keeps persisted ordering fences instead of deleting them. Queue completions are fenced on session/access reset. Without Web Locks, month persistence stays disabled and memory remains usable. The lock semantics are defined in https://www.w3.org/TR/web-locks/; this is a browser coordination choice, not a dependency addition. Focused Vitest now passes 35 tests, including the original rev2 probe, delayed acquisition, queued lifecycle cancellation, storage-event view updates and the no-lock case. Existing assertions and fixture data were not changed; a shared test-only LockManager seam supplies the new platform dependency. R3: `project_with` retains checked totals through the later of the event month and last source month. Overspend comparison takes those totals (not an after Ledger) and replays only the before state. A focused regression proves a future validation month does not shift the current-month event comparison. The Money plugin clippy passes; its 39-test gate is running.
Author
Owner

Atomic commits: replay reuse bafebf6d3; cross-tab guarded publication and two-tab browser regression 1231185dc; equal-revision freshness correction d33d45f2a. The required single origin/dev merge is 8885db692 (base bd11bacb5). HEAD is d33d45f2a3537de27ad1eb1113ff2e2ba1f8530a.

Freshness finding: retaining the stored entry on an equal revision also retained its old timestamp. A successful equal-revision revalidation would therefore trigger another refresh on the next warm open. The guard now advances the timestamp on a fresh equal revision and preserves it when rejecting a lower reply. Two focused regressions cover both cases. Storage key decoding now has one shared path; unrelated preference storage events do not scan Money reports.

Final Money plugin gates after integration:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 10.10s
test result: ok. 39 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 53.68s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Web gates:

svelte-check found 0 errors and 0 warnings
 Test Files  3 passed (3)
      Tests  37 passed (37)

Server clippy:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 07s

The server test binary finished compilation; its tests and the production two-tab/screenshots check are still to complete. No pushes or deployment.

Atomic commits: replay reuse `bafebf6d3`; cross-tab guarded publication and two-tab browser regression `1231185dc`; equal-revision freshness correction `d33d45f2a`. The required single `origin/dev` merge is `8885db692` (base `bd11bacb5`). HEAD is `d33d45f2a3537de27ad1eb1113ff2e2ba1f8530a`. Freshness finding: retaining the stored entry on an equal revision also retained its old timestamp. A successful equal-revision revalidation would therefore trigger another refresh on the next warm open. The guard now advances the timestamp on a fresh equal revision and preserves it when rejecting a lower reply. Two focused regressions cover both cases. Storage key decoding now has one shared path; unrelated preference storage events do not scan Money reports. Final Money plugin gates after integration: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 10.10s test result: ok. 39 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 53.68s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Web gates: ```text svelte-check found 0 errors and 0 warnings Test Files 3 passed (3) Tests 37 passed (37) ``` Server clippy: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 07s ``` The server test binary finished compilation; its tests and the production two-tab/screenshots check are still to complete. No pushes or deployment.
Author
Owner

Finished the rev2 Money fix for #984 on job/moneyfu-984 at HEAD d33d45f2a3537de27ad1eb1113ff2e2ba1f8530a. Third independent review remains to be run. No pushes or deployment.

Built: all month browser writes and restore repairs use a guarded per-User Web Lock. The guard reads the stored revision inside the lock and keeps the greatest report. Refresh retains browser ordering fences. Storage events update memory and mounted month views. Session/access changes cancel queued publications. Equal-revision reads refresh freshness; lower acknowledgements do not. Transaction validation keeps the after totals and the event comparison reuses them, with only the before state replayed. The event comparator takes totals rather than an after Ledger, so a second after replay is not available through that path.

Probe evidence: review commit 0bd4608fd was cherry-picked as a1ea2c3bb first. Before the fix, the unchanged rev2 race probe reported AssertionError: expected 150 to be 200, with Tests 1 failed | 16 passed (17). Its assertion and interleaving remain unchanged and now pass. The shared test-only Web Lock seam adds the platform API dependency; existing fixture values and expectations remain unchanged. The original route-ordering and source-file-generation blocker tests also pass.

Files:

  • apps/web/src/lib/money/store.svelte.ts
  • apps/web/src/lib/money/locks.fixture.ts
  • apps/web/src/lib/money/acknowledged-month.svelte.test.ts
  • apps/web/src/lib/money/review-984.svelte.test.ts
  • apps/web/src/lib/money/review-session-984.svelte.test.ts
  • apps/web/src/routes/money/[budget]/[month]/+page.svelte
  • apps/web/e2e/money-revisions-984.mjs
  • crates/plugins/money/src/routes.rs

Atomic commits: a1ea2c3bb (review probes), bafebf6d3 (replay reuse), 1231185dc (cross-tab publication), d33d45f2a (freshness and shared key decoding). The required single origin/dev merge is 8885db692, from bd11bacb5; conflict resolution keeps dev's unique Notes test identities and the branch's Instant interactions section. No migration was added or renumbered.

Gate output (verbatim excerpts; complete logs are in artifacts/moneyfu-rev2/):

cargo fmt --check: exit 0, no output.

cargo clippy -p calternal-plugin-money --all-targets -- -D warnings:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 10.10s

cargo test -p calternal-plugin-money -- --test-threads=4:

test result: ok. 39 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 53.68s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-server --all-targets -- -D warnings:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 07s

cargo test -p calternal-server -- --test-threads=4:

test result: FAILED. 160 passed; 2 failed; 5 ignored; 0 measured; 0 filtered out; finished in 40.11s

cd apps/web && bun run check:

svelte-check found 0 errors and 0 warnings

cd apps/web && bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts src/lib/money/review-984.svelte.test.ts src/lib/money/review-session-984.svelte.test.ts --maxWorkers=2:

 Test Files  3 passed (3)
      Tests  37 passed (37)

Production focused regression: CALTERNAL_SERVER_BIN=<this job binary> CALTERNAL_E2E_ASSET_OVERRIDE=1 bun e2e/money-revisions-984.mjs:

PASS production route: reversed assign responses keep the newest displayed values and browser report
PASS production route: a superseded forced refresh keeps the acknowledged report without an error state
PASS production two-tab publication: both mounted views and reload retain the newest revision under lock contention
PASS production screenshots: macOS, 390/820/1440px, Light/Dark

cargo build -p calternal-server:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 39s

The server test gate exits 101 on the two existing #1010 Mail review assertions. Both stop at integrations_review.rs:88:

assertion `left == right` failed
  left: 10
 right: 9

Failing tests: mail_626_and_connected_accounts_apply_in_both_orders and populated_0012_and_mail_0009_preserve_links_in_both_orders. The current migration is 10; the tests assert 9. No expectations were changed. See #1010.

Production evidence: the real server was built from this checkout and the regression used the current production web build. Binary SHA-256: d2efd842b9ceca4f1d9b52e677b879bf25b9021c8be2af2b5e66124a6f8e7e72. The two-tab test holds a real per-User Web Lock while releasing a late durable acknowledgement, verifies both mounted views, then reloads and checks the stored report. All four focused browser checks pass.

Screenshots: six current production captures, with macOS platform emulation, are attached to #984. They remain untracked at artifacts/money-984-followup/screenshots/. Icon/label positions were inspected from the actual captures; visual quality review belongs to Claude.

Width Light Dark
390 px Light Dark
820 px Light Dark
1440 px Light Dark

UX gaps closed: other tabs now update a mounted month report; late replies cannot regress stored or mounted revisions; queued persistence cannot repopulate after a lifecycle/access reset; a successful equal-revision revalidation stays warm without repeated reads. Earlier category-create, reversed-acknowledgement and source-generation regressions remain passing.

UX gaps left: the existing Budget breadcrumb title is still truncated at 390 px and 820 px in both schemes. Its styling was not changed in this fix.

Decisions: use one exclusive per-User Web Lock for month publication and pruning, with storage-event reconciliation. Keep acceptance in memory synchronous and perform persistence in the background. If Web Locks are absent or refused, keep memory usable and skip unsafe month persistence, silently. Keep persisted revision fences through refresh; freshness remains local invalidation state. A fresh equal revision advances its timestamp without replacing content identity. This uses the Web Locks coordination model. No dependency or source-format change.

Known limits: snapshot ordering applies within the existing eight-month retained bound. The existing server revision restart/clock assumption is unchanged. No performance measurements were run under the verification policy for this non-performance job; no matching Money baseline is present. Third independent review and the combined merge-round checks remain.

For the merge round:

  • Resolve #1010, then cargo test -p calternal-server -- --test-threads=4: run both migration-order probes past the version assertion.
  • cd apps/web && bun run test --maxWorkers=2: validate the combined web branch.
  • cd apps/web && bun run test:e2e:money: full Money flow; its known auto_scheme.location: null fixture remains for the orchestrator to resolve.
  • bash tests/adversarial/run.sh: combined authorization and robustness matrices, once under the merge-round policy.
  • Full E2E, staging and real Mac interop belong to the merge round. The focused two-tab regression and six screenshots already ran here.
  • If profiling the replay work, use the existing bench/money-pair-review-984.sh on the perf VM under flock /root/perf.lock, with a build-host release review binary. No build or measurement was run on the VM in this job.

Cleanup: cargo target and web production output are removed. Screenshot artifacts and raw gate logs remain in the worktree; none is committed.

Finished the rev2 Money fix for #984 on `job/moneyfu-984` at HEAD `d33d45f2a3537de27ad1eb1113ff2e2ba1f8530a`. Third independent review remains to be run. No pushes or deployment. Built: all month browser writes and restore repairs use a guarded per-User Web Lock. The guard reads the stored revision inside the lock and keeps the greatest report. Refresh retains browser ordering fences. Storage events update memory and mounted month views. Session/access changes cancel queued publications. Equal-revision reads refresh freshness; lower acknowledgements do not. Transaction validation keeps the after totals and the event comparison reuses them, with only the before state replayed. The event comparator takes totals rather than an after Ledger, so a second after replay is not available through that path. Probe evidence: review commit `0bd4608fd` was cherry-picked as `a1ea2c3bb` first. Before the fix, the unchanged rev2 race probe reported `AssertionError: expected 150 to be 200`, with `Tests 1 failed | 16 passed (17)`. Its assertion and interleaving remain unchanged and now pass. The shared test-only Web Lock seam adds the platform API dependency; existing fixture values and expectations remain unchanged. The original route-ordering and source-file-generation blocker tests also pass. Files: - `apps/web/src/lib/money/store.svelte.ts` - `apps/web/src/lib/money/locks.fixture.ts` - `apps/web/src/lib/money/acknowledged-month.svelte.test.ts` - `apps/web/src/lib/money/review-984.svelte.test.ts` - `apps/web/src/lib/money/review-session-984.svelte.test.ts` - `apps/web/src/routes/money/[budget]/[month]/+page.svelte` - `apps/web/e2e/money-revisions-984.mjs` - `crates/plugins/money/src/routes.rs` Atomic commits: `a1ea2c3bb` (review probes), `bafebf6d3` (replay reuse), `1231185dc` (cross-tab publication), `d33d45f2a` (freshness and shared key decoding). The required single `origin/dev` merge is `8885db692`, from `bd11bacb5`; conflict resolution keeps dev's unique Notes test identities and the branch's Instant interactions section. No migration was added or renumbered. Gate output (verbatim excerpts; complete logs are in `artifacts/moneyfu-rev2/`): `cargo fmt --check`: exit 0, no output. `cargo clippy -p calternal-plugin-money --all-targets -- -D warnings`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 10.10s ``` `cargo test -p calternal-plugin-money -- --test-threads=4`: ```text test result: ok. 39 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 53.68s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-server --all-targets -- -D warnings`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 07s ``` `cargo test -p calternal-server -- --test-threads=4`: ```text test result: FAILED. 160 passed; 2 failed; 5 ignored; 0 measured; 0 filtered out; finished in 40.11s ``` `cd apps/web && bun run check`: ```text svelte-check found 0 errors and 0 warnings ``` `cd apps/web && bunx vitest run src/lib/money/acknowledged-month.svelte.test.ts src/lib/money/review-984.svelte.test.ts src/lib/money/review-session-984.svelte.test.ts --maxWorkers=2`: ```text Test Files 3 passed (3) Tests 37 passed (37) ``` `Production focused regression: CALTERNAL_SERVER_BIN=<this job binary> CALTERNAL_E2E_ASSET_OVERRIDE=1 bun e2e/money-revisions-984.mjs`: ```text PASS production route: reversed assign responses keep the newest displayed values and browser report PASS production route: a superseded forced refresh keeps the acknowledged report without an error state PASS production two-tab publication: both mounted views and reload retain the newest revision under lock contention PASS production screenshots: macOS, 390/820/1440px, Light/Dark ``` `cargo build -p calternal-server`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 39s ``` The server test gate exits 101 on the two existing #1010 Mail review assertions. Both stop at `integrations_review.rs:88`: ```text assertion `left == right` failed left: 10 right: 9 ``` Failing tests: `mail_626_and_connected_accounts_apply_in_both_orders` and `populated_0012_and_mail_0009_preserve_links_in_both_orders`. The current migration is 10; the tests assert 9. No expectations were changed. See https://git.kayg.org/kayg/calternal/issues/1010. Production evidence: the real server was built from this checkout and the regression used the current production web build. Binary SHA-256: `d2efd842b9ceca4f1d9b52e677b879bf25b9021c8be2af2b5e66124a6f8e7e72`. The two-tab test holds a real per-User Web Lock while releasing a late durable acknowledgement, verifies both mounted views, then reloads and checks the stored report. All four focused browser checks pass. Screenshots: six current production captures, with macOS platform emulation, are attached to #984. They remain untracked at `artifacts/money-984-followup/screenshots/`. Icon/label positions were inspected from the actual captures; visual quality review belongs to Claude. | Width | Light | Dark | | --- | --- | --- | | 390 px | [Light](https://git.kayg.org/attachments/6b2f7910-0062-4dfd-adf2-461eddac6d38) | [Dark](https://git.kayg.org/attachments/1c3d04da-d652-4b86-a06c-1dabac2ad5e6) | | 820 px | [Light](https://git.kayg.org/attachments/788785fa-eea8-47e2-a3cc-f28e4e7470b5) | [Dark](https://git.kayg.org/attachments/9ecfe4d7-e6f8-4b42-afca-405a46e30d54) | | 1440 px | [Light](https://git.kayg.org/attachments/e7be576a-1255-4453-a737-ff97487b45f0) | [Dark](https://git.kayg.org/attachments/cb837f42-1363-4a63-840e-476719cd271d) | UX gaps closed: other tabs now update a mounted month report; late replies cannot regress stored or mounted revisions; queued persistence cannot repopulate after a lifecycle/access reset; a successful equal-revision revalidation stays warm without repeated reads. Earlier category-create, reversed-acknowledgement and source-generation regressions remain passing. UX gaps left: the existing Budget breadcrumb title is still truncated at 390 px and 820 px in both schemes. Its styling was not changed in this fix. Decisions: use one exclusive per-User Web Lock for month publication and pruning, with storage-event reconciliation. Keep acceptance in memory synchronous and perform persistence in the background. If Web Locks are absent or refused, keep memory usable and skip unsafe month persistence, silently. Keep persisted revision fences through refresh; freshness remains local invalidation state. A fresh equal revision advances its timestamp without replacing content identity. This uses the [Web Locks coordination model](https://www.w3.org/TR/web-locks/). No dependency or source-format change. Known limits: snapshot ordering applies within the existing eight-month retained bound. The existing server revision restart/clock assumption is unchanged. No performance measurements were run under the verification policy for this non-performance job; no matching Money baseline is present. Third independent review and the combined merge-round checks remain. For the merge round: - Resolve #1010, then `cargo test -p calternal-server -- --test-threads=4`: run both migration-order probes past the version assertion. - `cd apps/web && bun run test --maxWorkers=2`: validate the combined web branch. - `cd apps/web && bun run test:e2e:money`: full Money flow; its known `auto_scheme.location: null` fixture remains for the orchestrator to resolve. - `bash tests/adversarial/run.sh`: combined authorization and robustness matrices, once under the merge-round policy. - Full E2E, staging and real Mac interop belong to the merge round. The focused two-tab regression and six screenshots already ran here. - If profiling the replay work, use the existing `bench/money-pair-review-984.sh` on the perf VM under `flock /root/perf.lock`, with a build-host release review binary. No build or measurement was run on the VM in this job. Cleanup: cargo target and web production output are removed. Screenshot artifacts and raw gate logs remain in the worktree; none is committed.
Author
Owner

Third independent #984 review started in detached worktree /home/kayg/Developer/calternal-wt/rev3-moneyfu at d33d45f2a3537de27ad1eb1113ff2e2ba1f8530a, base job/datafix2. I will rerun the preserved first and second review tests and add cross-tab storage failure/closure probes. The source branch will not be changed. No private files will be accessed.

Third independent #984 review started in detached worktree `/home/kayg/Developer/calternal-wt/rev3-moneyfu` at `d33d45f2a3537de27ad1eb1113ff2e2ba1f8530a`, base `job/datafix2`. I will rerun the preserved first and second review tests and add cross-tab storage failure/closure probes. The source branch will not be changed. No private files will be accessed.
Author
Owner

Starting third independent Money correctness review. Worktree: detached /home/kayg/Developer/calternal-wt/rev3-moneyfu; target job/moneyfu-984 head d33d45f2a3; base job/datafix2 ff8e857c27. Existing uncommitted review artifacts were present at start and are being inspected in place.

Starting third independent Money correctness review. Worktree: detached /home/kayg/Developer/calternal-wt/rev3-moneyfu; target job/moneyfu-984 head d33d45f2a3537de27ad1eb1113ff2e2ba1f8530a; base job/datafix2 ff8e857c27207d724c92d978ce22d53801e0b510. Existing uncommitted review artifacts were present at start and are being inspected in place.
Author
Owner

Finding (detached current-head test): a valid transaction in the first future-only month cannot be created before a current-month Money file exists. expected HTTP 201 but got 400 (). With a seeded future-only month, expected edit 200/delete 204 but both got 400 with the same error. The test additions are only in the detached review worktree; remains unchanged.

Finding (detached current-head test): a valid transaction in the first future-only month cannot be created before a current-month Money file exists. expected HTTP 201 but got 400 (). With a seeded future-only month, expected edit 200/delete 204 but both got 400 with the same error. The test additions are only in the detached review worktree; remains unchanged.
Author
Owner

Finding (detached current-head test): a valid transaction in the first future-only month cannot be created before a current-month Money file exists. review3_first_future_transaction_keeps_current_event_month expected HTTP 201 but got 400 (the current month could not be calculated). With a seeded future-only month, review3_future_only_edit_and_delete_keep_current_event_month expected edit 200 and delete 204, but both got 400 with the same error. The test additions are only in the detached review worktree; job/moneyfu-984 remains unchanged.

Finding (detached current-head test): a valid transaction in the first future-only month cannot be created before a current-month Money file exists. `review3_first_future_transaction_keeps_current_event_month` expected HTTP 201 but got 400 (`the current month could not be calculated`). With a seeded future-only month, `review3_future_only_edit_and_delete_keep_current_event_month` expected edit 200 and delete 204, but both got 400 with the same error. The test additions are only in the detached review worktree; `job/moneyfu-984` remains unchanged.
Author
Owner

Independent Money correctness review — third round

Verdict: BLOCK. A valid future-only Budget cannot create, edit or delete its first transaction because event comparison cannot calculate the User's current month. No revision-ordering, arithmetic or cross-tab regression was found in the other completed probes.

Reviewed job/moneyfu-984 at d33d45f2a3537de27ad1eb1113ff2e2ba1f8530a, based on job/datafix2 at ff8e857c27207d724c92d978ce22d53801e0b510. The target branch was not changed. All test Homes and browser data were synthetic. No private data was read.

Confirmed failure

  • Expected: first future-month transaction create returns 201; edit returns 200; delete returns 204.
  • Actual: all three return 400 with the current month could not be calculated when the Budget's earliest source month is later than the current month. The review-only route tests are review3_first_future_transaction_keeps_current_event_month and review3_future_only_edit_and_delete_keep_current_event_month.
  • Cause: the replay starts at the earliest source month, so it omits the current event month when all source data is future-dated. No source write occurs after the failed check.

Expected and actual for the other attacks

Attack Expected Actual
Reversed, duplicate and concurrent Assignment replies; User/Budget/month separation; lower server response after browser restore Retain the greatest valid server revision in route, memory and browser storage PASS: both review ref suites; web suite has 24 passing tests. Concurrent server assignments return distinct revisions and the greatest response equals disk.
Category creation while an older month read is pending Reload the created Category; do not repaint the older report PASS: focused store property and route-sequence tests.
External source-file replacement, addition, deletion and byte restoration Changed sources advance revision; unchanged bytes keep it stable PASS: Money route source-generation tests cover Budget.md, Accounts.md and month files.
Backdated create; edit/delete across zero in both directions; category/month moves Emit only a current-month nonnegative-to-negative crossing, after the write PASS: route tests cover create, historical-only overspend, edits, deletes, healing, recrossing, category changes and cross-month moves. User-zone month/year conversion cases pass for Los Angeles, Kolkata and Kiritimati. Route event tests use UTC; the route clock is not injectable.
Split and on/off-budget transfers Preserve exact split remainder; transfers change account balances and no Category totals; unsupported split/transfer edits emit no write events PASS: exact paired replay tests cover negative split remainder and cash/card transfers to a Tracking account; router tests reject imported split/transfer writes and see no event.
Exact paired arithmetic, scale rejection, negative amounts, malformed month ranges Paired result equals independent calculations without rounding PASS: 128 generated cases over JPY, USD, KWD and CLF; explicit negative remainder and invalid-scale/month cases pass.
Large ledger Keep exact results on a large source set PASS: 10,000-row paired replay test. The 100,000-row latency/CPU/RSS profile is intentionally ignored in this job and must run on the locked perf VM in the merge round.
Cross-tab storage publication and recovery Never let a delayed lower publisher replace a higher report; server data remains usable if optional browser storage fails PASS: unit storage-event and lock-interleaving tests, plus the production browser run below. No BroadcastChannel path exists; the app uses Web Locks and Storage events.

Production browser run

The production SPA and server were built from the reviewed checkout. A real two-tab and two-browser run passed. The second browser started with cookies only, no copied localStorage. All six assertions passed:

PASS closing lock holder releases queued publication without losing exact Assignment
PASS closing queued publisher restores its durable Assignment from the server
PASS a storage event carries the newer exact Assignment into another mounted tab
PASS two browser processes restore exact latest values from the server
PASS quota storage failure: exact writes remain usable and reload from server without page errors
PASS private storage failure: exact writes remain usable and reload from server without page errors

Gates

cargo fmt --check: exit 0, no output.

cargo clippy -p calternal-plugin-money --all-targets -- -D warnings:

    Checking calternal-plugin-money v0.0.1 (/home/kayg/Developer/calternal-wt/rev3-moneyfu/crates/plugins/money)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 12.64s

cargo test -p calternal-plugin-money:

---- tests::review_984::review3_first_future_transaction_keeps_current_event_month stdout ----
assertion `left == right` failed: valid future transaction: {"error":{"code":"bad_request","message":"the current month could not be calculated"}}
left: 400
right: 201

---- tests::review_984::review3_future_only_edit_and_delete_keep_current_event_month stdout ----
assertion `left == right` failed: edit: {"error":{"code":"bad_request","message":"the current month could not be calculated"}}; delete: {"error":{"code":"bad_request","message":"the current month could not be calculated"}}
left: (400, 400)
right: (200, 204)

test result: FAILED. 39 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 17.05s

cargo clippy -p calternal-money --all-targets -- -D warnings:

    Checking calternal-money v0.0.1 (/home/kayg/Developer/calternal-wt/rev3-moneyfu/crates/calternal-money)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 17.35s

cargo test -p calternal-money --test review_984:

test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 7.51s

bunx vitest run src/lib/money/review-984.svelte.test.ts --maxWorkers=2:

 Test Files 1 passed (1)
      Tests 24 passed (24)

bun run check:

svelte-check found 0 errors and 0 warnings

Production build completed (✓ built in 2m 25s; adapter wrote the site to build). It emitted non-fatal module-level use client directive warnings from existing bundled dependencies.

For the merge round

Run the deferred paired-versus-independent 1,000/100,000-row profile on the perf VM with the prebuilt release test binary. Measure pair and independent separately under flock /root/perf.lock, record /proc/loadavg inside each lock, and report p50/p95, CPU and RSS. This review did not run a release build or perf measurement.

Decisions and gaps

  • Test decision: future-dated transactions are valid because the route accepts any valid YYYY-MM-DD date and DESIGN §48 defines Money dates as calendar dates without an upper bound. The API currently rejects those writes only when no current-month source file exists.
  • The design does not define cross-tab signaling. The reviewed implementation uses Web Locks and Storage events; the live Storage-event path passed. There is no separate BroadcastChannel path.
  • The only confirmed correctness gap is the future-only first-month failure. The review-only tests and E2E probe were kept in the detached worktree and will be removed with it.
# Independent Money correctness review — third round **Verdict: BLOCK.** A valid future-only Budget cannot create, edit or delete its first transaction because event comparison cannot calculate the User's current month. No revision-ordering, arithmetic or cross-tab regression was found in the other completed probes. Reviewed `job/moneyfu-984` at `d33d45f2a3537de27ad1eb1113ff2e2ba1f8530a`, based on `job/datafix2` at `ff8e857c27207d724c92d978ce22d53801e0b510`. The target branch was not changed. All test Homes and browser data were synthetic. No private data was read. ## Confirmed failure - Expected: first future-month transaction create returns 201; edit returns 200; delete returns 204. - Actual: all three return 400 with `the current month could not be calculated` when the Budget's earliest source month is later than the current month. The review-only route tests are `review3_first_future_transaction_keeps_current_event_month` and `review3_future_only_edit_and_delete_keep_current_event_month`. - Cause: the replay starts at the earliest source month, so it omits the current event month when all source data is future-dated. No source write occurs after the failed check. ## Expected and actual for the other attacks | Attack | Expected | Actual | |---|---|---| | Reversed, duplicate and concurrent Assignment replies; User/Budget/month separation; lower server response after browser restore | Retain the greatest valid server revision in route, memory and browser storage | PASS: both review ref suites; web suite has 24 passing tests. Concurrent server assignments return distinct revisions and the greatest response equals disk. | | Category creation while an older month read is pending | Reload the created Category; do not repaint the older report | PASS: focused store property and route-sequence tests. | | External source-file replacement, addition, deletion and byte restoration | Changed sources advance revision; unchanged bytes keep it stable | PASS: Money route source-generation tests cover Budget.md, Accounts.md and month files. | | Backdated create; edit/delete across zero in both directions; category/month moves | Emit only a current-month nonnegative-to-negative crossing, after the write | PASS: route tests cover create, historical-only overspend, edits, deletes, healing, recrossing, category changes and cross-month moves. User-zone month/year conversion cases pass for Los Angeles, Kolkata and Kiritimati. Route event tests use UTC; the route clock is not injectable. | | Split and on/off-budget transfers | Preserve exact split remainder; transfers change account balances and no Category totals; unsupported split/transfer edits emit no write events | PASS: exact paired replay tests cover negative split remainder and cash/card transfers to a Tracking account; router tests reject imported split/transfer writes and see no event. | | Exact paired arithmetic, scale rejection, negative amounts, malformed month ranges | Paired result equals independent calculations without rounding | PASS: 128 generated cases over JPY, USD, KWD and CLF; explicit negative remainder and invalid-scale/month cases pass. | | Large ledger | Keep exact results on a large source set | PASS: 10,000-row paired replay test. The 100,000-row latency/CPU/RSS profile is intentionally ignored in this job and must run on the locked perf VM in the merge round. | | Cross-tab storage publication and recovery | Never let a delayed lower publisher replace a higher report; server data remains usable if optional browser storage fails | PASS: unit storage-event and lock-interleaving tests, plus the production browser run below. No BroadcastChannel path exists; the app uses Web Locks and Storage events. | ## Production browser run The production SPA and server were built from the reviewed checkout. A real two-tab and two-browser run passed. The second browser started with cookies only, no copied localStorage. All six assertions passed: ```text PASS closing lock holder releases queued publication without losing exact Assignment PASS closing queued publisher restores its durable Assignment from the server PASS a storage event carries the newer exact Assignment into another mounted tab PASS two browser processes restore exact latest values from the server PASS quota storage failure: exact writes remain usable and reload from server without page errors PASS private storage failure: exact writes remain usable and reload from server without page errors ``` ## Gates `cargo fmt --check`: exit 0, no output. `cargo clippy -p calternal-plugin-money --all-targets -- -D warnings`: ```text Checking calternal-plugin-money v0.0.1 (/home/kayg/Developer/calternal-wt/rev3-moneyfu/crates/plugins/money) Finished `dev` profile [unoptimized + debuginfo] target(s) in 12.64s ``` `cargo test -p calternal-plugin-money`: ```text ---- tests::review_984::review3_first_future_transaction_keeps_current_event_month stdout ---- assertion `left == right` failed: valid future transaction: {"error":{"code":"bad_request","message":"the current month could not be calculated"}} left: 400 right: 201 ---- tests::review_984::review3_future_only_edit_and_delete_keep_current_event_month stdout ---- assertion `left == right` failed: edit: {"error":{"code":"bad_request","message":"the current month could not be calculated"}}; delete: {"error":{"code":"bad_request","message":"the current month could not be calculated"}} left: (400, 400) right: (200, 204) test result: FAILED. 39 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 17.05s ``` `cargo clippy -p calternal-money --all-targets -- -D warnings`: ```text Checking calternal-money v0.0.1 (/home/kayg/Developer/calternal-wt/rev3-moneyfu/crates/calternal-money) Finished `dev` profile [unoptimized + debuginfo] target(s) in 17.35s ``` `cargo test -p calternal-money --test review_984`: ```text test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 7.51s ``` `bunx vitest run src/lib/money/review-984.svelte.test.ts --maxWorkers=2`: ```text Test Files 1 passed (1) Tests 24 passed (24) ``` `bun run check`: ```text svelte-check found 0 errors and 0 warnings ``` Production build completed (`✓ built in 2m 25s`; adapter wrote the site to `build`). It emitted non-fatal module-level `use client` directive warnings from existing bundled dependencies. ## For the merge round Run the deferred paired-versus-independent 1,000/100,000-row profile on the perf VM with the prebuilt release test binary. Measure `pair` and `independent` separately under `flock /root/perf.lock`, record `/proc/loadavg` inside each lock, and report p50/p95, CPU and RSS. This review did not run a release build or perf measurement. ## Decisions and gaps - Test decision: future-dated transactions are valid because the route accepts any valid `YYYY-MM-DD` date and DESIGN §48 defines Money dates as calendar dates without an upper bound. The API currently rejects those writes only when no current-month source file exists. - The design does not define cross-tab signaling. The reviewed implementation uses Web Locks and Storage events; the live Storage-event path passed. There is no separate BroadcastChannel path. - The only confirmed correctness gap is the future-only first-month failure. The review-only tests and E2E probe were kept in the detached worktree and will be removed with it.
Author
Owner

Starting third-review fix on job/moneyfu-984, base d33d45f2a3537de27ad1eb1113ff2e2ba1f8530a. The supplied refs/reviews/rev3-moneyfu-984 is absent locally and on origin; the detached review worktree was removed. Recovering its exact route and card-to-Tracking arithmetic patches from the retained review job log into a review commit, then cherry-picking before reproducing the two failures. No dependency changes are required.

Starting third-review fix on `job/moneyfu-984`, base `d33d45f2a3537de27ad1eb1113ff2e2ba1f8530a`. The supplied refs/reviews/rev3-moneyfu-984 is absent locally and on origin; the detached review worktree was removed. Recovering its exact route and card-to-Tracking arithmetic patches from the retained review job log into a review commit, then cherry-picking before reproducing the two failures. No dependency changes are required.
Author
Owner

Third-review failure reproduced after cherry-picking recovered review commit 52c4741d7bed65e02def618445174cec608441de as ff4d0f777. Both original probes failed: future create 400 instead of 201; future edit/delete (400, 400) instead of (200, 204), all with the current month could not be calculated. The 128-case source-range property also failed before the fix, shrinking to today 2000-01 with source 1999-12.

Fix: validate only the chronological source range, retain those exact after totals, and skip the optional overspend comparison when today is outside that range. This also avoids the unnecessary before replay for past-only/future-only/empty Budgets. No calculation errors are swallowed. Existing in-range event checks remain unchanged. The real-file CRUD regression checks past/future create, healing, recrossing and delete, no current overspend events, exact edit amounts, zero after delete, and no synthetic current source file.

git fetch origin then git merge origin/dev: Already up to date.

Plugin gates: Finished dev profile [unoptimized + debuginfo] target(s) in 1m 54s; test result: ok. 43 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 28.34s. Core and web verification follow.

Third-review failure reproduced after cherry-picking recovered review commit `52c4741d7bed65e02def618445174cec608441de` as `ff4d0f777`. Both original probes failed: future create 400 instead of 201; future edit/delete (400, 400) instead of (200, 204), all with `the current month could not be calculated`. The 128-case source-range property also failed before the fix, shrinking to today 2000-01 with source 1999-12. Fix: validate only the chronological source range, retain those exact after totals, and skip the optional overspend comparison when today is outside that range. This also avoids the unnecessary before replay for past-only/future-only/empty Budgets. No calculation errors are swallowed. Existing in-range event checks remain unchanged. The real-file CRUD regression checks past/future create, healing, recrossing and delete, no current overspend events, exact edit amounts, zero after delete, and no synthetic current source file. `git fetch origin` then `git merge origin/dev`: `Already up to date.` Plugin gates: `Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 54s`; `test result: ok. 43 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 28.34s`. Core and web verification follow.
Author
Owner

Finished third-review fix for #984 on job/moneyfu-984.
Head: 9250c187ddb39cc55b87aeb295c807af9b2d7488.

Built: transaction validation retains the exact source-month range. The optional current-month overspend check returns no event outside that range, including past-only, future-only and empty Budgets. It skips the before replay when today is absent, while preserving all source-month arithmetic validation and in-range events. Future transaction create/edit/delete now succeed.

Commits:

  • ff4d0f777: cherry-picked the recovered third-review route and card-to-Tracking arithmetic probes.
  • 9250c187d: range fix, generated regression and real-file CRUD/event assertions.

Files: crates/plugins/money/src/routes.rs, crates/plugins/money/src/review_984.rs, crates/plugins/money/proptest-regressions/routes.txt, crates/calternal-money/tests/review_984.rs.

Reproduction: both original future-only route probes failed before the fix with 400 the current month could not be calculated (create expected 201; edit/delete expected 200/204). The generated source-range test also failed before the fix, shrinking to today 2000-01 with source 1999-12. After the fix it checks 128 generated cases, each with past-only, future-only, spanning and empty source ranges; projected totals equal an independent source-range replay. The saved shrinking seed is committed.

All three review suites remain passing: real Money router checks, exact paired arithmetic (including the review's card-to-Tracking case and 10,000-row replay), and browser-state review tests. No existing test expectations were relaxed. The recovered arithmetic patch adds a second transfer and therefore its exact expected Tracking total, as in the review.

Before final gates: git fetch origin then git merge origin/dev returned Already up to date. No push, deployment or merge into dev/main occurred. No dependencies changed.

Gate output excerpts (verbatim; full logs in artifacts/moneyfu-rev3/):

cargo fmt --check: exit 0, no output.

cargo clippy -p calternal-plugin-money --all-targets -- -D warnings:

    Checking calternal-path v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-path)
    Checking calternal-fs v0.1.0 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-fs)
    Checking calternal-db v0.1.0 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-db)
    Checking calternal-api v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-api)
    Checking calternal-money v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-money)
    Checking calternal-notes-core v0.1.0 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-notes-core)
    Checking calternal-plugin v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-plugin)
    Checking calternal-plugin-money v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/plugins/money)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 54s

cargo test -p calternal-plugin-money -- --test-threads=4:

test routes::replay_reuse_tests::crossings_cover_source_ranges_relative_to_today ... ok
test tests::review_984::review3_first_future_transaction_keeps_current_event_month ... ok
test tests::review_984::review3_future_only_edit_and_delete_keep_current_event_month ... ok
test tests::review_984::review3_outside_current_range_writes_emit_no_overspend ... ok
test result: ok. 43 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 28.34s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s

cargo clippy -p calternal-money --all-targets -- -D warnings:

    Checking calternal-money v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-money)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 29.79s

cargo test -p calternal-money -- --test-threads=4:

test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.07s
test review_pair_performance_profile ... ignored, performance measurements belong to the merge round on the perf VM
test review_pair_rejects_bad_months_and_amounts_without_rounding ... ok
test review_split_remainders_and_tracking_transfers_are_exact ... ok
test review_mixed_pair_matches_independent_replays ... ok
test review_large_ledger_pair_keeps_exact_totals ... ok
test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 5.40s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.71s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

bunx vitest run src/lib/money/review-984.svelte.test.ts src/lib/money/review-session-984.svelte.test.ts src/lib/money/acknowledged-month.svelte.test.ts --maxWorkers=2 (from apps/web):

 Test Files  3 passed (3)
      Tests  37 passed (37)

bun run check (from apps/web):

svelte-check found 0 errors and 0 warnings

cargo clean:

     Removed 4141 files, 1.6GiB total

Web build output removed. Working tree clean. Re-read the changed module/function documentation. No UI files or layout changed, so no new screenshots were needed.

UX gaps closed: valid future/past transaction writes no longer depend on a current-month source file; out-of-range writes emit no current overspend event and create no synthetic current-month file. The real-file test checks creates, edits in both directions, deletion, exact edited amounts and zero balance after deletion.

UX gaps left / known gaps: no known defect remains in this fix; fourth independent review is pending. The review's performance profile remains intentionally ignored under the latest verification policy.

Decisions: no new product decision. Per the job instruction, event range means the continuous range from the first source month to the last (month files plus Assignment months). Empty ranges emit no event. The supplied third-review ref was absent locally and on origin and the review worktree had been removed; recovered its exact route/core patches from the retained job log, saved them as refs/reviews/rev3-moneyfu-984 (52c4741d7bed65e02def618445174cec608441de), then cherry-picked before production changes. The unrelated production browser probe was not rebuilt or rerun.

For the merge round (deferred by the latest owner verification policy):

  • cargo clippy -p calternal-server --all-targets -- -D warnings and cargo test -p calternal-server -- --test-threads=4: combined server integration/contract gates.
  • From apps/web, bun run test --maxWorkers=2 and bun run test:e2e:money: full browser-state coverage and production Money flow.
  • bash tests/adversarial/run.sh and bun tests/adversarial/money_api.mjs: combined real-server authorization, robustness and Money write probes, with one time-boxed round.
  • On the perf VM with a prebuilt release review test binary, flock /root/perf.lock bash bench/money-pair-review-984.sh with MONEY_REVIEW_BIN set: deferred pair/independent profile, load average, raw samples, p50/p95, CPU and RSS. No matching Money baseline exists. No performance measurement was run in this non-performance job.
Finished third-review fix for #984 on `job/moneyfu-984`. Head: `9250c187ddb39cc55b87aeb295c807af9b2d7488`. Built: transaction validation retains the exact source-month range. The optional current-month overspend check returns no event outside that range, including past-only, future-only and empty Budgets. It skips the before replay when today is absent, while preserving all source-month arithmetic validation and in-range events. Future transaction create/edit/delete now succeed. Commits: - `ff4d0f777`: cherry-picked the recovered third-review route and card-to-Tracking arithmetic probes. - `9250c187d`: range fix, generated regression and real-file CRUD/event assertions. Files: `crates/plugins/money/src/routes.rs`, `crates/plugins/money/src/review_984.rs`, `crates/plugins/money/proptest-regressions/routes.txt`, `crates/calternal-money/tests/review_984.rs`. Reproduction: both original future-only route probes failed before the fix with 400 `the current month could not be calculated` (create expected 201; edit/delete expected 200/204). The generated source-range test also failed before the fix, shrinking to today 2000-01 with source 1999-12. After the fix it checks 128 generated cases, each with past-only, future-only, spanning and empty source ranges; projected totals equal an independent source-range replay. The saved shrinking seed is committed. All three review suites remain passing: real Money router checks, exact paired arithmetic (including the review's card-to-Tracking case and 10,000-row replay), and browser-state review tests. No existing test expectations were relaxed. The recovered arithmetic patch adds a second transfer and therefore its exact expected Tracking total, as in the review. Before final gates: `git fetch origin` then `git merge origin/dev` returned `Already up to date.` No push, deployment or merge into dev/main occurred. No dependencies changed. Gate output excerpts (verbatim; full logs in `artifacts/moneyfu-rev3/`): `cargo fmt --check`: exit 0, no output. `cargo clippy -p calternal-plugin-money --all-targets -- -D warnings`: ```text Checking calternal-path v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-path) Checking calternal-fs v0.1.0 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-fs) Checking calternal-db v0.1.0 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-db) Checking calternal-api v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-api) Checking calternal-money v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-money) Checking calternal-notes-core v0.1.0 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-notes-core) Checking calternal-plugin v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-plugin) Checking calternal-plugin-money v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/plugins/money) Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 54s ``` `cargo test -p calternal-plugin-money -- --test-threads=4`: ```text test routes::replay_reuse_tests::crossings_cover_source_ranges_relative_to_today ... ok test tests::review_984::review3_first_future_transaction_keeps_current_event_month ... ok test tests::review_984::review3_future_only_edit_and_delete_keep_current_event_month ... ok test tests::review_984::review3_outside_current_range_writes_emit_no_overspend ... ok test result: ok. 43 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 28.34s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s ``` `cargo clippy -p calternal-money --all-targets -- -D warnings`: ```text Checking calternal-money v0.0.1 (/home/kayg/Developer/calternal-wt/moneyfu-984/crates/calternal-money) Finished `dev` profile [unoptimized + debuginfo] target(s) in 29.79s ``` `cargo test -p calternal-money -- --test-threads=4`: ```text test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.07s test review_pair_performance_profile ... ignored, performance measurements belong to the merge round on the perf VM test review_pair_rejects_bad_months_and_amounts_without_rounding ... ok test review_split_remainders_and_tracking_transfers_are_exact ... ok test review_mixed_pair_matches_independent_replays ... ok test review_large_ledger_pair_keeps_exact_totals ... ok test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 5.40s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.71s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `bunx vitest run src/lib/money/review-984.svelte.test.ts src/lib/money/review-session-984.svelte.test.ts src/lib/money/acknowledged-month.svelte.test.ts --maxWorkers=2` (from apps/web): ```text Test Files 3 passed (3) Tests 37 passed (37) ``` `bun run check` (from apps/web): ```text svelte-check found 0 errors and 0 warnings ``` `cargo clean`: ```text Removed 4141 files, 1.6GiB total ``` Web build output removed. Working tree clean. Re-read the changed module/function documentation. No UI files or layout changed, so no new screenshots were needed. UX gaps closed: valid future/past transaction writes no longer depend on a current-month source file; out-of-range writes emit no current overspend event and create no synthetic current-month file. The real-file test checks creates, edits in both directions, deletion, exact edited amounts and zero balance after deletion. UX gaps left / known gaps: no known defect remains in this fix; fourth independent review is pending. The review's performance profile remains intentionally ignored under the latest verification policy. Decisions: no new product decision. Per the job instruction, event range means the continuous range from the first source month to the last (month files plus Assignment months). Empty ranges emit no event. The supplied third-review ref was absent locally and on origin and the review worktree had been removed; recovered its exact route/core patches from the retained job log, saved them as `refs/reviews/rev3-moneyfu-984` (`52c4741d7bed65e02def618445174cec608441de`), then cherry-picked before production changes. The unrelated production browser probe was not rebuilt or rerun. For the merge round (deferred by the latest owner verification policy): - `cargo clippy -p calternal-server --all-targets -- -D warnings` and `cargo test -p calternal-server -- --test-threads=4`: combined server integration/contract gates. - From apps/web, `bun run test --maxWorkers=2` and `bun run test:e2e:money`: full browser-state coverage and production Money flow. - `bash tests/adversarial/run.sh` and `bun tests/adversarial/money_api.mjs`: combined real-server authorization, robustness and Money write probes, with one time-boxed round. - On the perf VM with a prebuilt release review test binary, `flock /root/perf.lock bash bench/money-pair-review-984.sh` with MONEY_REVIEW_BIN set: deferred pair/independent profile, load average, raw samples, p50/p95, CPU and RSS. No matching Money baseline exists. No performance measurement was run in this non-performance job.
Author
Owner

Fourth independent Money review started in detached worktree /home/kayg/Developer/calternal-wt/rev4-moneyfu at 9250c187ddb39cc55b87aeb295c807af9b2d7488, comparison base job/datafix2 (ff8e857c27207d724c92d978ce22d53801e0b510). All three local review refs are available. Production source branch remains unchanged. Scope: re-run preserved assertions, independently check out-of-range write/event behavior, and focused production two-tab/two-browser reconciliation with closed tabs and refused storage. No private data will be accessed. Full merge-round suites and performance measurement remain deferred by the current verification policy.

Fourth independent Money review started in detached worktree `/home/kayg/Developer/calternal-wt/rev4-moneyfu` at `9250c187ddb39cc55b87aeb295c807af9b2d7488`, comparison base `job/datafix2` (`ff8e857c27207d724c92d978ce22d53801e0b510`). All three local review refs are available. Production source branch remains unchanged. Scope: re-run preserved assertions, independently check out-of-range write/event behavior, and focused production two-tab/two-browser reconciliation with closed tabs and refused storage. No private data will be accessed. Full merge-round suites and performance measurement remain deferred by the current verification policy.
Author
Owner

Fourth-review evidence: all earlier browser ordering/session assertions plus three new coordination-failure probes pass: Test Files 3 passed (3); Tests 40 passed (40). bun run check: svelte-check found 0 errors and 0 warnings. Review-only browser test commit: 3d4744bfeb68686fa43280b668567595de16ef82. Production web build completed (✓ built in 49.90s, Wrote site to "build"). The one-time git fetch origin / detached git merge origin/dev returned Already up to date. Core/router tests and focused production browser checks are next; the required shared prebuilt manifest is absent, so the server is being built locally from the reviewed production code. No verdict yet.

Fourth-review evidence: all earlier browser ordering/session assertions plus three new coordination-failure probes pass: `Test Files 3 passed (3); Tests 40 passed (40)`. `bun run check`: `svelte-check found 0 errors and 0 warnings`. Review-only browser test commit: `3d4744bfeb68686fa43280b668567595de16ef82`. Production web build completed (`✓ built in 49.90s`, `Wrote site to "build"`). The one-time `git fetch origin` / detached `git merge origin/dev` returned `Already up to date.` Core/router tests and focused production browser checks are next; the required shared prebuilt manifest is absent, so the server is being built locally from the reviewed production code. No verdict yet.
Author
Owner

Fourth independent Money correctness review — #984

Verdict: PASS. No failing correctness case remains in this review. All three earlier review suites pass against the current implementation, including the two rev3 future-only failures. No wrong server arithmetic, lost durable write or decreasing published revision was found.

Reviewed source: job/moneyfu-984 at 9250c187ddb39cc55b87aeb295c807af9b2d7488.
Comparison base: job/datafix2 at ff8e857c27207d724c92d978ce22d53801e0b510.
Review HEAD: 52199994aa046c8152cccfec025b0b85ccdef472, retained locally as refs/reviews/rev4-moneyfu-984.
Work: detached /home/kayg/Developer/calternal-wt/rev4-moneyfu. The source branch was not changed. No push or deployment occurred. No private files were read.

Expected versus actual

Probe Expected Actual
Original reversed Assign responses, duplicates and category-create read race Route, memory and browser snapshot retain greatest revision; new Category appears PASS: preserved first review assertions and real production HTTP-response ordering
External Budget.md / Accounts.md / month replacement, addition, deletion and restoration Changed source bytes advance revision; equal bytes remain stable PASS: preserved real-router source-generation assertions
Original cross-tab 200 overwritten by 150 race Retain 200 inside the acquired lock and in mounted subscribers PASS: preserved second review interleaving/property tests and real two-tab lock-contention run
Rev3 first future transaction; future-only edit/delete Create 201; edit 200; delete 204 PASS: original recovered third review tests, unchanged assertions
Past-only, future-only, spanning and empty source ranges Validate exact source totals; no out-of-range current overspend event PASS: 128 generated range cases and real-file CRUD regression
Empty Budget GET Zero Available; no current month file created PASS: new fourth-review router probe
Move first future expense into today, out again and back Available -101, 0, -101; two exact -101 crossing events with distinct IDs; deletion heals to 0 PASS: new fourth-review router probe
Backdated create, category/month edits, deletes, zero/healing/recrossing Only current-month nonnegative-to-negative crossings emit events after durable writes PASS: preserved event suite
User/Budget/month revision separation; browser restore; delayed old-User writes Independent keys; greatest valid revision; lifecycle fence PASS: preserved browser/session tests and new queued User-switch test
Denied Web Lock and quota setter Exact highest in-memory report remains usable PASS: new focused unit assertions
Close native Web Lock holder mid-publication Queued acknowledgement publishes 606 minor units PASS in production browser
Close queued publishing tab after durable acknowledgement Server restores 707 minor units PASS in production browser
Native Storage event Other mounted tab updates to 808 minor units PASS; actual native event observed
Two independent browser processes, separate localStorage Both recover latest 909/808 minor units PASS; second Chromium process received cookies only
Quota error, unavailable localStorage, absent Web Locks Exact writes and reload remain usable; no page error PASS in production SPA; failures injected before app boot
Exact paired replay, negative split remainder, cash/card/Tracking transfers, currency scales and invalid precision/month ranges Equal independent minor-unit calculations; no rounding PASS: preserved review properties, including rev3 card-to-Tracking case
10,000-row source set Both paired totals equal independent replay PASS; timing/CPU/RSS profile remains deferred

Built and files

Review-only tests were added; production files and existing expectations were not changed.

  • apps/web/src/lib/money/review-984.svelte.test.ts: denied coordination, quota setter and queued User-switch probes.
  • crates/plugins/money/src/review_984.rs: empty report and future/current cross-month event probe.
  • apps/web/e2e/review4-money-984.mjs: native tab closure, Storage events, two browser processes and unavailable persistence.

Atomic review commits: 3d4744bfe (browser unit tests), dbb1d9bb3 (router test), 52199994a (production probe).
The review ref suites were already integrated: the core suite is byte-identical to rev3; the rev3 router assertions are retained with the later range regression added. Earlier browser/session tests retain their expectations and use the branch's Web Lock fixture.

Gate output (verbatim)

cargo fmt --check: exit 0, no output.

cargo clippy -p calternal-plugin-money --all-targets -- -D warnings:

    Checking calternal-plugin-money v0.0.1 (/home/kayg/Developer/calternal-wt/rev4-moneyfu/crates/plugins/money)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 21s

cargo test -p calternal-plugin-money -- --test-threads=4:

test tests::review_984::review3_first_future_transaction_keeps_current_event_month ... ok
test tests::review_984::review3_future_only_edit_and_delete_keep_current_event_month ... ok
test tests::review_984::review_concurrent_assign_revisions_match_final_report ... ok
test tests::review_984::review_category_edit_emits_for_old_category_only ... ok
test tests::review_984::review4_empty_and_future_moves_cross_current_threshold ... ok
test tests::review_984::review3_outside_current_range_writes_emit_no_overspend ... ok
test tests::review_984::review_file_replacement_advances_month_revision ... ok
test tests::review_984::review_cross_month_refund_move_emits_current_crossing ... ok
test tests::review_984::review_user_zone_month_and_year_edges ... ok
test tests::review_984::review_exact_zero_healing_recrossing_and_delete ... ok
test tests::review_984::review_source_generation_tracks_all_files_and_restoration ... ok
test tests::review_984::review_split_and_tracking_transfer_writes_are_rejected_without_events ... ok
test result: ok. 44 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 29.99s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-money --all-targets -- -D warnings:

    Checking calternal-money v0.0.1 (/home/kayg/Developer/calternal-wt/rev4-moneyfu/crates/calternal-money)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 10.66s

cargo test -p calternal-money -- --test-threads=4:

test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.12s
test review_pair_performance_profile ... ignored, performance measurements belong to the merge round on the perf VM
test review_pair_rejects_bad_months_and_amounts_without_rounding ... ok
test review_split_remainders_and_tracking_transfers_are_exact ... ok
test review_mixed_pair_matches_independent_replays ... ok
test review_large_ledger_pair_keeps_exact_totals ... ok
test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.07s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.30s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

bunx vitest run src/lib/money/review-984.svelte.test.ts src/lib/money/review-session-984.svelte.test.ts src/lib/money/acknowledged-month.svelte.test.ts --maxWorkers=2:

 Test Files  3 passed (3)
      Tests  40 passed (40)

bun run check:

svelte-check found 0 errors and 0 warnings

cargo build -p calternal-server:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 8m 56s

bun apps/web/e2e/money-revisions-984.mjs:

PASS production route: reversed assign responses keep the newest displayed values and browser report
PASS production route: a superseded forced refresh keeps the acknowledged report without an error state
PASS production two-tab publication: both mounted views and reload retain the newest revision under lock contention
PASS production screenshots: macOS, 390/820/1440px, Light/Dark

bun apps/web/e2e/review4-money-984.mjs:

PASS closing lock holder releases queued publication and preserves 606 minor units
PASS closing queued publisher restores its durable 707 minor units from server
PASS native Storage event updates another mounted tab to 808 minor units
PASS two independent browser processes recover the latest 909/808 minor units
PASS quota: exact writes stay usable and restore from server without page errors
PASS private: exact writes stay usable and restore from server without page errors
PASS no-locks: exact writes stay usable and restore from server without page errors

cargo clean:

     Removed 10399 files, 5.9GiB total

Evidence, cleanup and known gaps

The production SPA and local debug server use the reviewed production source. The required shared-server CURRENT manifest was absent, so the server was built locally. Binary SHA-256: d8c875ffa9539a3f072a8962db9b485a90f8106c36b18d3a23652488de71a465.

Six production screenshots cover 390/820/1440 px, Light/Dark, with macOS platform emulation. Logs, screenshots and a review patch are retained at /home/kayg/Developer/calternal/artifacts/rev4-moneyfu/. Screenshots are not committed. The installed fj issue comment interface has no attachment option; they remain local for the orchestrator. This is a correctness review, not a visual-quality verdict.

The one-time git fetch origin and detached git merge origin/dev returned Already up to date. No dependency was added or version changed. Build output was cleaned; the detached review worktree was removed after retaining the review ref and artifacts.

Known gaps: latency/CPU/RSS measurements are deferred by the current verification policy; the 100,000-row performance test remains ignored. No matching Money baseline exists in docs/perf/baseline.json. Local-month/year primitives pass, but the HTTP route clock is not injectable, so a frozen-clock HTTP month-boundary test was not added. Storage refusal was injected in Chromium; native Apple-client interop was not run. No BroadcastChannel path exists: this implementation uses Web Locks and Storage events. A nonblocking documentation follow-up remains: calculate_pair still describes use by event routes, although those routes now reuse validated after totals and replay only the before state.

UX gaps closed / left

Verified closed: valid future/past CRUD does not require today's source file; closed publishing tabs recover durable writes; storage failure remains silent; cross-tab updates reach mounted views. This review makes no production UX changes. No new runtime UX gap was demonstrated.

Decisions

No new product decision. Preserve the implementation branch and keep review tests in a local detached-history ref. Treat the continuous source-month range as the event range, as specified by the fix; verify that entering today's range restores normal event crossings. Use separate Chromium processes with cookies only to test independent browser storage. Test optional Storage failures by injecting only the Storage seam, while keeping the server, writes, response bodies and production SPA real.

For the merge round

  • cargo clippy -p calternal-server --all-targets -- -D warnings and cargo test -p calternal-server -- --test-threads=4: combined server/contract verification.
  • From apps/web: bun run test --maxWorkers=2 and bun run test:e2e:money: full browser-state suite and complete Money flow.
  • bash tests/adversarial/run.sh and bun tests/adversarial/money_api.mjs: one combined real-server authorization/robustness round.
  • With a prebuilt release review test binary on the perf VM: flock /root/perf.lock bash bench/money-pair-review-984.sh with MONEY_REVIEW_BIN set. Record load average inside the lock, paired/independent 1,000/100,000-row raw samples, p50/p95, CPU and RSS. No compilation on the perf VM.
# Fourth independent Money correctness review — #984 Verdict: **PASS**. No failing correctness case remains in this review. All three earlier review suites pass against the current implementation, including the two rev3 future-only failures. No wrong server arithmetic, lost durable write or decreasing published revision was found. Reviewed source: `job/moneyfu-984` at `9250c187ddb39cc55b87aeb295c807af9b2d7488`. Comparison base: `job/datafix2` at `ff8e857c27207d724c92d978ce22d53801e0b510`. Review HEAD: `52199994aa046c8152cccfec025b0b85ccdef472`, retained locally as `refs/reviews/rev4-moneyfu-984`. Work: detached `/home/kayg/Developer/calternal-wt/rev4-moneyfu`. The source branch was not changed. No push or deployment occurred. No private files were read. ## Expected versus actual | Probe | Expected | Actual | | --- | --- | --- | | Original reversed Assign responses, duplicates and category-create read race | Route, memory and browser snapshot retain greatest revision; new Category appears | PASS: preserved first review assertions and real production HTTP-response ordering | | External Budget.md / Accounts.md / month replacement, addition, deletion and restoration | Changed source bytes advance revision; equal bytes remain stable | PASS: preserved real-router source-generation assertions | | Original cross-tab 200 overwritten by 150 race | Retain 200 inside the acquired lock and in mounted subscribers | PASS: preserved second review interleaving/property tests and real two-tab lock-contention run | | Rev3 first future transaction; future-only edit/delete | Create 201; edit 200; delete 204 | PASS: original recovered third review tests, unchanged assertions | | Past-only, future-only, spanning and empty source ranges | Validate exact source totals; no out-of-range current overspend event | PASS: 128 generated range cases and real-file CRUD regression | | Empty Budget GET | Zero Available; no current month file created | PASS: new fourth-review router probe | | Move first future expense into today, out again and back | Available -101, 0, -101; two exact -101 crossing events with distinct IDs; deletion heals to 0 | PASS: new fourth-review router probe | | Backdated create, category/month edits, deletes, zero/healing/recrossing | Only current-month nonnegative-to-negative crossings emit events after durable writes | PASS: preserved event suite | | User/Budget/month revision separation; browser restore; delayed old-User writes | Independent keys; greatest valid revision; lifecycle fence | PASS: preserved browser/session tests and new queued User-switch test | | Denied Web Lock and quota setter | Exact highest in-memory report remains usable | PASS: new focused unit assertions | | Close native Web Lock holder mid-publication | Queued acknowledgement publishes 606 minor units | PASS in production browser | | Close queued publishing tab after durable acknowledgement | Server restores 707 minor units | PASS in production browser | | Native Storage event | Other mounted tab updates to 808 minor units | PASS; actual native event observed | | Two independent browser processes, separate localStorage | Both recover latest 909/808 minor units | PASS; second Chromium process received cookies only | | Quota error, unavailable localStorage, absent Web Locks | Exact writes and reload remain usable; no page error | PASS in production SPA; failures injected before app boot | | Exact paired replay, negative split remainder, cash/card/Tracking transfers, currency scales and invalid precision/month ranges | Equal independent minor-unit calculations; no rounding | PASS: preserved review properties, including rev3 card-to-Tracking case | | 10,000-row source set | Both paired totals equal independent replay | PASS; timing/CPU/RSS profile remains deferred | ## Built and files Review-only tests were added; production files and existing expectations were not changed. - `apps/web/src/lib/money/review-984.svelte.test.ts`: denied coordination, quota setter and queued User-switch probes. - `crates/plugins/money/src/review_984.rs`: empty report and future/current cross-month event probe. - `apps/web/e2e/review4-money-984.mjs`: native tab closure, Storage events, two browser processes and unavailable persistence. Atomic review commits: `3d4744bfe` (browser unit tests), `dbb1d9bb3` (router test), `52199994a` (production probe). The review ref suites were already integrated: the core suite is byte-identical to rev3; the rev3 router assertions are retained with the later range regression added. Earlier browser/session tests retain their expectations and use the branch's Web Lock fixture. ## Gate output (verbatim) `cargo fmt --check`: exit 0, no output. `cargo clippy -p calternal-plugin-money --all-targets -- -D warnings`: ```text Checking calternal-plugin-money v0.0.1 (/home/kayg/Developer/calternal-wt/rev4-moneyfu/crates/plugins/money) Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 21s ``` `cargo test -p calternal-plugin-money -- --test-threads=4`: ```text test tests::review_984::review3_first_future_transaction_keeps_current_event_month ... ok test tests::review_984::review3_future_only_edit_and_delete_keep_current_event_month ... ok test tests::review_984::review_concurrent_assign_revisions_match_final_report ... ok test tests::review_984::review_category_edit_emits_for_old_category_only ... ok test tests::review_984::review4_empty_and_future_moves_cross_current_threshold ... ok test tests::review_984::review3_outside_current_range_writes_emit_no_overspend ... ok test tests::review_984::review_file_replacement_advances_month_revision ... ok test tests::review_984::review_cross_month_refund_move_emits_current_crossing ... ok test tests::review_984::review_user_zone_month_and_year_edges ... ok test tests::review_984::review_exact_zero_healing_recrossing_and_delete ... ok test tests::review_984::review_source_generation_tracks_all_files_and_restoration ... ok test tests::review_984::review_split_and_tracking_transfer_writes_are_rejected_without_events ... ok test result: ok. 44 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 29.99s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-money --all-targets -- -D warnings`: ```text Checking calternal-money v0.0.1 (/home/kayg/Developer/calternal-wt/rev4-moneyfu/crates/calternal-money) Finished `dev` profile [unoptimized + debuginfo] target(s) in 10.66s ``` `cargo test -p calternal-money -- --test-threads=4`: ```text test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.12s test review_pair_performance_profile ... ignored, performance measurements belong to the merge round on the perf VM test review_pair_rejects_bad_months_and_amounts_without_rounding ... ok test review_split_remainders_and_tracking_transfers_are_exact ... ok test review_mixed_pair_matches_independent_replays ... ok test review_large_ledger_pair_keeps_exact_totals ... ok test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.07s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.30s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `bunx vitest run src/lib/money/review-984.svelte.test.ts src/lib/money/review-session-984.svelte.test.ts src/lib/money/acknowledged-month.svelte.test.ts --maxWorkers=2`: ```text Test Files 3 passed (3) Tests 40 passed (40) ``` `bun run check`: ```text svelte-check found 0 errors and 0 warnings ``` `cargo build -p calternal-server`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 8m 56s ``` `bun apps/web/e2e/money-revisions-984.mjs`: ```text PASS production route: reversed assign responses keep the newest displayed values and browser report PASS production route: a superseded forced refresh keeps the acknowledged report without an error state PASS production two-tab publication: both mounted views and reload retain the newest revision under lock contention PASS production screenshots: macOS, 390/820/1440px, Light/Dark ``` `bun apps/web/e2e/review4-money-984.mjs`: ```text PASS closing lock holder releases queued publication and preserves 606 minor units PASS closing queued publisher restores its durable 707 minor units from server PASS native Storage event updates another mounted tab to 808 minor units PASS two independent browser processes recover the latest 909/808 minor units PASS quota: exact writes stay usable and restore from server without page errors PASS private: exact writes stay usable and restore from server without page errors PASS no-locks: exact writes stay usable and restore from server without page errors ``` `cargo clean`: ```text Removed 10399 files, 5.9GiB total ``` ## Evidence, cleanup and known gaps The production SPA and local debug server use the reviewed production source. The required shared-server CURRENT manifest was absent, so the server was built locally. Binary SHA-256: `d8c875ffa9539a3f072a8962db9b485a90f8106c36b18d3a23652488de71a465`. Six production screenshots cover 390/820/1440 px, Light/Dark, with macOS platform emulation. Logs, screenshots and a review patch are retained at `/home/kayg/Developer/calternal/artifacts/rev4-moneyfu/`. Screenshots are not committed. The installed `fj issue comment` interface has no attachment option; they remain local for the orchestrator. This is a correctness review, not a visual-quality verdict. The one-time `git fetch origin` and detached `git merge origin/dev` returned `Already up to date.` No dependency was added or version changed. Build output was cleaned; the detached review worktree was removed after retaining the review ref and artifacts. Known gaps: latency/CPU/RSS measurements are deferred by the current verification policy; the 100,000-row performance test remains ignored. No matching Money baseline exists in `docs/perf/baseline.json`. Local-month/year primitives pass, but the HTTP route clock is not injectable, so a frozen-clock HTTP month-boundary test was not added. Storage refusal was injected in Chromium; native Apple-client interop was not run. No BroadcastChannel path exists: this implementation uses Web Locks and Storage events. A nonblocking documentation follow-up remains: `calculate_pair` still describes use by event routes, although those routes now reuse validated after totals and replay only the before state. ## UX gaps closed / left Verified closed: valid future/past CRUD does not require today's source file; closed publishing tabs recover durable writes; storage failure remains silent; cross-tab updates reach mounted views. This review makes no production UX changes. No new runtime UX gap was demonstrated. ## Decisions No new product decision. Preserve the implementation branch and keep review tests in a local detached-history ref. Treat the continuous source-month range as the event range, as specified by the fix; verify that entering today's range restores normal event crossings. Use separate Chromium processes with cookies only to test independent browser storage. Test optional Storage failures by injecting only the Storage seam, while keeping the server, writes, response bodies and production SPA real. ## For the merge round - `cargo clippy -p calternal-server --all-targets -- -D warnings` and `cargo test -p calternal-server -- --test-threads=4`: combined server/contract verification. - From `apps/web`: `bun run test --maxWorkers=2` and `bun run test:e2e:money`: full browser-state suite and complete Money flow. - `bash tests/adversarial/run.sh` and `bun tests/adversarial/money_api.mjs`: one combined real-server authorization/robustness round. - With a prebuilt release review test binary on the perf VM: `flock /root/perf.lock bash bench/money-pair-review-984.sh` with `MONEY_REVIEW_BIN` set. Record load average inside the lock, paired/independent 1,000/100,000-row raw samples, p50/p95, CPU and RSS. No compilation on the perf VM.
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#984
No description provided.