Files
wanderbooks/justfile
T
swaitsandClaude Opus 5.5 ccec4e9439
check / check (push) Canceled after 0s
import: XLSX layout spec and tests; mutation 53% -> one equivalent left
report_to_xlsx gains INVARIANTS 4-6 (header block, right-aligned amount
headings, spacer and account spacing, footer one empty row down, rules
exactly where rule_above says, exact text grouped in threes), tested by
reading the workbook's styles, merges and column widths. The general
ledger's footer now sits one empty row down like the other sheets.

Also killed: IIF transliteration arms, tax summary's optional sections,
and day-equals-month bank dates. `just mutants-import`, weekly in CI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GWVo7x3UHw5kwCUaWxiejX
2026-10-13 23:01:07 -06:00

121 lines
5.0 KiB
Makefile

# wanderbooks repo recipes. `just` lists them.
set shell := ["bash", "-cu"]
# The Netlify CLI, fetched on demand.
netlify := "npx --yes netlify-cli@27"
# List recipes
default:
@just --list
# Everything CI should check: format, clippy and rustdoc (zero warnings), tests
check:
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --quiet
cargo test --workspace
# Formal proofs: Kani on the accounting kernel, Lean for books of any size (docs/verification.md)
prove:
#!/usr/bin/env bash
set -euo pipefail
# Capped: a harness that blows up should fail, not eat the machine.
log=$(mktemp)
(ulimit -v 12000000; cd crates/ledger-core &&
timeout 1800 cargo kani -j "$(nproc)" --output-format terse | tee "$log")
# A cover that can't be satisfied means a proof is vacuous.
if grep -E "\*\* [0-9]+ of [0-9]+ cover properties satisfied" "$log" |
awk '{ if ($2 != $4) bad = 1 } END { exit !bad }'; then
echo "Kani: an unsatisfiable cover; some proof is vacuous" >&2
exit 1
fi
rm -f "$log"
cd verify/lean
lake build
audit=$(lake env lean Audit.lean)
if grep -v -E "depends on axioms: \[(propext|Quot.sound|Classical.choice)(, (propext|Quot.sound|Classical.choice))*\]$|does not depend on any axioms" <<<"$audit"; then
echo "Lean audit: a theorem rests on something beyond the standard axioms" >&2
exit 1
fi
echo "Lean: $(wc -l <<<"$audit") headline theorems, standard axioms only"
# Random books through wanderbooks and GnuCash 5.10, compared exactly (Docker)
oracle:
docker build -q -t wanderbooks-gnucash-oracle oracle/gnucash
cargo test -p ledger-core --test oracle_gnucash -- --ignored --nocapture
# Fuzz one target for some seconds (nightly; corpus in fuzz/corpus/<target>)
fuzz target="fuzz_op_sequence" seconds="300":
#!/usr/bin/env bash
set -euo pipefail
# Call the binary directly: mise's shim would pin stable rustc.
fuzz=$(mise which cargo-fuzz)
cd fuzz && mkdir -p corpus/{{target}} seeds/{{target}}
# corpus/ grows (git-ignored); seeds/ holds the checked-in minimal inputs.
RUSTUP_TOOLCHAIN=nightly-2026-10-01 "$fuzz" fuzz run {{target}} corpus/{{target}} seeds/{{target}} -- \
-max_total_time={{seconds}} -timeout=10 -rss_limit_mb=2048
# Undefined-behavior check of the core's tests under Miri (nightly)
miri:
PROPTEST_CASES=4 MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly-2026-10-01 miri test -p ledger-core --lib --test kernel_bridge --test invariants
# Mutation testing of the core: do the tests catch planted bugs?
mutants:
# Core and store tests (the store's replay tests reach Ledger::replay_*);
# the whole workspace would rebuild the viewer for every mutant.
cargo mutants -p ledger-core --exclude crates/ledger-core/src/proofs.rs --test-package ledger-core --test-package ledger-store -j 4 --timeout 120
# Mutation testing of the store. Fewer random cases per mutant (each needs
# a run that catches it, not the deep sweep); temp books on a RAM disk if
# TMPDIR is one, since every journal append is synced.
mutants-store:
STORE_CASES=64 cargo mutants -p ledger-store --test-package ledger-store -j 3 --timeout 300 -o mutants-store
# Mutation testing of the importers and report renderers.
mutants-import:
cargo mutants -p ledger-import --test-package ledger-import -j 4 --timeout 300 -o mutants-import
# Benchmarks of the core's hot paths (no budget gates them yet)
bench:
cargo bench -p ledger-core --bench books
cargo bench -p ledger-store --bench store
# Build the release binaries (CLI, MCP server, GUI)
build:
cargo build --release -p ledger-cli -p ledger-mcp -p ledger-gui
# Install the binaries from this checkout into ~/.cargo/bin
install:
for c in ledger-cli ledger-mcp ledger-gui; do cargo install --locked --path crates/$c; done
# Open the GUI on the demo company
demo:
cargo run --release -p ledger-gui -- --demo
# Regenerate the website's screenshots (dark) from the demo company
site-shots:
#!/usr/bin/env bash
set -euo pipefail
tmp=$(mktemp -d)
SHOT_DIR="$tmp" SHOT_DARK=1 SHOT_LIVE=1 SHOT_ONLY=overview,pnl,cash cargo test -p ledger-gui --test screens
# The hero's viewer pane: taller, to sit beside the session.
SHOT_DIR="$tmp" SHOT_DARK=1 SHOT_LIVE=1 SHOT_ONLY=entry SHOT_ENTRY=245 SHOT_HEIGHT=1150 cargo test -p ledger-gui --test screens
for f in overview entry pnl cash; do cp "$tmp/$f.png" site/assets/; done
rm -f site/assets/overview-dark.png
rm -rf "$tmp"
# Assemble the website in site/dist (index.html, install.sh, assets)
site:
rm -rf site/dist && mkdir -p site/dist
cp site/index.html install.sh site/dist/
cp -r site/assets site/dist/
# Deploy the website to wanderbooks.ai (Netlify; `netlify login` once first)
deploy: site
{{netlify}} deploy --prod --dir site/dist --no-build
# Deploy a preview of the website and print its URL
deploy-preview: site
{{netlify}} deploy --dir site/dist --no-build