check / check (push) Canceled after 0s
The refusal property gained the converse law (an accepted command journals something; only batch runs may find nothing to do) and checks the store's class and payroll listings. It found a schedule registered with an out-of-range total whose first month was refused after its entry was begun: the live ledger kept a draft the journal never had. - Core: compound commands (post_schedule_month, reverse_entry, close_period_to, create_invoice, create_bill, receive_payment, pay_bill, run_payroll, remit_payroll_taxes) run inside Ledger::atomically, so a refusal partway leaves the ledger exactly as it was. - Core: a schedule total no line could carry, or finer than a cent, and an asset cost beyond the line range, are refused at registration. Replay keeps older schedules (replay_register_schedule). - Store: add_line, add_line_fx, mark_cleared, set_fx_rate, post_schedule_month and close_period_to changed the live ledger before journaling; they now run on a copy, journal what it produced, then swap it in, so a failed write leaves the live books as journaled. New spec-blind suite tests/spec_store.rs (57 tests written from the store's specs alone). Its two findings, adjudicated: - A file filed twice under different names listed the first name and type for both (the projection kept them per blob). Schema v8 gives each attachment its own; older databases backfill and heal by verify. - Withdrawn attachments stay in the store's listing, marked (the MCP listing hides them): the spec and doc said "omit" and are corrected. Also removes journal::truncate_to_last_good_seq: unused, and it dropped everything after the first bad complete line, which the books now treat as corruption for a person, never repaired automatically. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GWVo7x3UHw5kwCUaWxiejX
67 lines
1.1 KiB
TOML
67 lines
1.1 KiB
TOML
[package]
|
|
name = "ledger-core-fuzz"
|
|
version = "0.0.0"
|
|
publish = false
|
|
edition = "2024"
|
|
|
|
[package.metadata]
|
|
cargo-fuzz = true
|
|
|
|
[dependencies]
|
|
libfuzzer-sys = "0.4"
|
|
arbitrary = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
serde = "1"
|
|
rust_decimal = "1"
|
|
chrono = "0.4"
|
|
|
|
[dependencies.ledger-core]
|
|
path = "../crates/ledger-core"
|
|
|
|
[dependencies.ledger-store]
|
|
path = "../crates/ledger-store"
|
|
|
|
[[bin]]
|
|
name = "fuzz_journal_line"
|
|
path = "fuzz_targets/fuzz_journal_line.rs"
|
|
test = false
|
|
doc = false
|
|
bench = false
|
|
|
|
[[bin]]
|
|
name = "fuzz_entry_validate"
|
|
path = "fuzz_targets/fuzz_entry_validate.rs"
|
|
test = false
|
|
doc = false
|
|
bench = false
|
|
|
|
[[bin]]
|
|
name = "fuzz_op_sequence"
|
|
path = "fuzz_targets/fuzz_op_sequence.rs"
|
|
test = false
|
|
doc = false
|
|
bench = false
|
|
|
|
[workspace]
|
|
|
|
[[bin]]
|
|
name = "fuzz_core_serde"
|
|
path = "fuzz_targets/fuzz_core_serde.rs"
|
|
test = false
|
|
doc = false
|
|
bench = false
|
|
|
|
[[bin]]
|
|
name = "fuzz_store_open"
|
|
path = "fuzz_targets/fuzz_store_open.rs"
|
|
test = false
|
|
doc = false
|
|
bench = false
|
|
|
|
[[bin]]
|
|
name = "fuzz_store_replay"
|
|
path = "fuzz_targets/fuzz_store_replay.rs"
|
|
test = false
|
|
doc = false
|
|
bench = false
|