Files
wanderbooks/plan/2026-10-28_DRIFT_REPORT.md
T
swaitsandClaude Fable 5.1 af553a3706
check / check (push) Canceled after 0s
two-user / two-user (push) Canceled after 0s
docs: the 2026-10-28 drift review; the plan, status and docs brought to date
The planning session read plan/served.md, every design document and the
five branches the owner paused on 2026-10-27 against main (44ee4083),
with dry-run merges touching no branch. plan/2026-10-28_DRIFT_REPORT.md
lists every divergence and judges every recorded departure (all kept;
three owed back; one needs a decision: P6 made ledger-store depend on
ledger-import).

The plan: section 0 "What changed on 2026-10-28"; 8.0.1 and the unit
Status lines name S4.4, S5, S6, S7 and P6 as built but unmerged; 8.0.2
records the destination (D-56: the installed app, P11a starts now) and
the resume order with the known conflicts (the shared documents.rs
test file, the types.rs appends, P6 retaking schema 18, the law numbers
34 to 37); 8.0.3 lists the names the EM approved during the wave; P11a
gains step 0 (the macOS and Windows keyring stores, the Windows data
root and pipes, a cross-platform CI build: today the agent path runs on
Linux alone); Q-5 is due and Q-8 asks whether D-47 to D-54 stand; the
Landlock sentences in section 2 and server.toml are struck.

STATUS.md and HANDOFF.md say where things stand and how to resume;
roadmap.md and gui.md are rewritten to today. The docs lose their
stale facts: 122 tools, 2,700 tests, the parity floor at 21 with the
P4b notes the slices never wrote, the ten crates and their dependency
graph (jiff added to the core's allowed list), the cutover of
2026-10-20 recorded in capability-parity.md and parallel-run.md, the
P4b S1 law and its two Kani harnesses added to verification.md (law
34), the proof counts (51 and 9), and README, the site and install.sh
honest about macOS (the viewer runs; connecting an agent waits for
P11a's keyring store, and the installer now says so instead of failing).

just check on main at 44ee4083: exit 0 (167 suites, 2,871 passed, 0
failed, 7 ignored, the server-only build clean). No code changed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
2026-10-28 18:26:23 -06:00

21 KiB

Drift report, 2026-10-28: the plan, the code, and the documents

Written by the planning session on 2026-10-28, after the implementing team (an engineering-manager agent with worker agents in git worktrees, 2026-10-26 to 2026-10-27) was paused. Method: every plan and design document in plan/ and docs/ was read whole and compared with main (44ee4083), the five paused branches (S4.4, S5, S6, S7, P6), their worktrees, dry-run merges (git merge-tree, touching no branch), and the code. Only divergences are listed; what matches is not.

Where we are, in one paragraph

Of the plan's remaining units, nine landed on main in two days (U0a, U0b, U0c, P7, P9a, P13 steps 1-3, P4b S4.1, S4.2, S4.3) and five more are built to their "Done when" lists on unmerged branches (S4.4, S5, S6, S7; P6 is feature-complete with its gate interrupted). Not started: S4.5, P4, P5, P8, P10, P11a, P11b, P12, P13 steps 4-6. The owner's destination, stated 2026-10-28, is one installed app for Mac, Windows and Linux (P11a, then P11b), then the hosted service of section 11; today the executable is Linux-first (the keyring store exists for Linux only, so on macOS an agent cannot connect), nothing of P11a exists, and no macOS or Windows build runs in CI.

plan/served.md

  • 8.0.1 and the unit Status lines are stale. The S4 row says "S4.4-S4.5 open"; S4.4 is built on branch S4.4 (002fb9f8, 2 commits, 29 files) with its As-built block written. S5 (ad649be3, 10 commits, 44 files), S6 (6c4480cd, 4 commits, 45 files) and S7 (4b4fecb9, 12 commits, 49 files) say "not started" and are built, each with its As-built block, just check reported green by its worker on the branch rebased on ed637f0e. P6 says "not started" and is built to every step on branch P6, checkpointed as ce366408 ("wip: pause checkpoint, P6 feature complete, gate interrupted (not for merge)"): its just check never finished.
  • The merge hazards of the pause are not recorded anywhere. Dry-run merges onto main in plan order: S4.4 clean; then S5 conflicts in crates/ledger-cli/tests/documents.rs (add/add) and crates/ledger-mcp/src/types.rs; S6 in documents.rs (add/add) and docs/mcp-interface.md; S7 in documents.rs (add/add), types.rs, crates/ledger-store/src/lib.rs; P6 in types.rs, store/src/lib.rs, store/src/schema.rs, store/tests/store.rs, docs/parity.md, docs/receipt-store.md, docs/spec/rules.md, docs/testing.md. Each branch alone merges onto main cleanly except P6. Causes: 8.0.3 allocated one over-the-wire test file (crates/ledger-cli/tests/documents.rs) to four units, and each created it; the "append at the end" rule for types.rs collides whenever two units append; P6 branched before S4.3 and took schema 16, which S4.3 holds on main (S5 took 17), so P6 must retake 18 at its rebase. S5 and S6 both numbered their new law 34 in docs/verification.md (S5 Step.markSent, S6 settle_is_exact); S1's documents law, which was never written up, is 34 on main as of this report, so S5 becomes 35, S6 36 and S7's write-off 37 at merge.
  • 8.0.3's allocated names drifted, with the EM's approval, and the table was not updated: two new MCP groups, tools/sent.rs (S5) and tools/settlements.rs (S6, which also moved books.receive_payment, books.pay_bill, books.ar_aging, books.ap_aging out of documents.rs); books.mark_sent's recipients parameter is recipients, not to (the no_tool_takes_a_path lint refuses to); P6 built books.set_entry_settles, named in its Build step but absent from the new-tools row (P6 flagged it).
  • S6 departed from its Build in ways the owner should see: confirmed (preview then confirm) was not added to books.receive_payment and books.pay_bill (deferred to P4's one sweep); the processor's vendor on a fee is named in the entry's description, not tagged (tags are entry-wide); no schema change (18 not taken); the three bookspec examples were not written (two wait for journaled terms); the over-the-wire discount tests wait for S4.3's journaled terms, which have since landed.
  • P6 departed in a way that changes the crate graph: ledger-store now depends on ledger-import (Typst, the fonts, hayro enter the store's dependency closure) so the writer can extract at attach time. docs/architecture.md's dependency rules neither allow nor forbid it; it needs a decision at P6's review (the alternative is extraction in the server before the store call, with the backfill command doing the same).
  • S4.4 changes the live contract A-1 planned: existing callers of books.create_invoice and books.create_bill now need confirmed: true; the connect text and handbook on main still say "Invoice, bill, payment and payroll tools post at once, unchecked", so that sentence is stale the moment S4.4 merges (S4.5 owns the handbook; the connect text is handbook.rs).
  • Q-5 is due and unasked. Its trigger is "when S4 lands"; S4.1-S4.3 are on main and S4.4 is built. A-14 is still reserved for the answer.
  • D-47 to D-54 are the review's recommendations, never explicitly confirmed by the owner ("the owner may revisit"); S5, S6, S7 and P6 were built on them (D-47, D-49, D-52, D-53). Confirming them is now a one-line question (Q-8 below).
  • P11a's Build omits the groundwork the design assigns to P11 elsewhere: the macOS and Windows keyring stores (3.3 as built; D-19; crates/ledger-host/src/tokens.rs returns "kept in the keyring on Linux only, until the macOS and Windows apps (P11)" on every other OS, so wanderbooks connect and the bridge fail there), the Windows data root under %LOCALAPPDATA% with an owner-only DACL (3.4), named pipes with a SID check (3.9), and a CI build on macOS and Windows runners (none exists: all three workflows run ubuntu-24.04). None is a step in 8.2 P11a.
  • 8.0.2's priority statement is stale against the owner's destination. It names P10 as "the owner's goal" and leaves P11a as "any time"; the owner's statement of 2026-10-28 makes the installed app the destination, with P11a to start now beside the P4b finish (recorded as D-56).
  • Section 2 carries superseded sentences without the strike-through rule of section 0: I-1 "Landlock and seccomp confine the server itself where available", I-2 "Landlock harness no_tool_touches_outside_tenant", I-8 "gui_works_under_read_only_landlock" (all → D-32).
  • server.toml (3.2, 3.4) was never built; the deployment flags are wanderbooks serve --http and --isolation (P9a). The references read as if it exists.
  • 4.9's "The tool count is 118 (2026-10-26)" is 122 on main (U0a's As-built says so) and becomes 130 once the five branches merge (S5 +1, S6 +1, S7 +1, P6 +4, S4.4 +0).
  • 8.0.6 item 2 fixtures: S4.3 wrote p4_s43_documents, S5 p4_s5_before, S7 p4_s7_before, P6 p6_evidence; S4.4 and S6 wrote none of their own (S6 reuses p4-arap-before, which predates S1). Acceptable under the item's intent (no figure moves), recorded here so the EM does not look for them.

plan/STATUS.md

  • The title and the "Now" section are dated 2026-10-26 and say "P4b S4 next"; since then U0a, U0b, P9a, S4.1-S4.3 landed and S4.4, S5, S6, S7, P6 were built on branches. The pause paragraph (2026-10-27) is the last entry but the head of the file was not revised, so a reader is told the wrong next step.

plan/HANDOFF.md

  • "What is true today (2026-10-26)" says nothing after S3 is built. Nine units landed and five are on paused branches.
  • No procedure for resuming paused worktrees: the merge order of the five branches, the known conflicts (above), the schema renumbering P6 needs, and that every branch's just check must be re-run after the rebase (the pause killed the gates).
  • It does not say that P11a is to be staffed now (D-56).

plan/roadmap.md

  • Phase 2 says "27 tools" (122). Phase 3 (oracle harness) reads as not started; just oracle runs 200 random books through GnuCash 5.10 with 15,800 exact comparisons (docs/oracle.md Layer 5); the machine-readable parity catalog and CI floor are the part still open.
  • Phase 5 lists A/R and A/P, bank reconciliation and period close as future; all three exist (reconciliation and close since 2026-10-11, A/R and A/P first-class since P4b S1). Multi-currency is partial (foreign lines; no translation), as it says.
  • "Explicitly not on the roadmap: payroll" while ledger-core::payroll and the payroll tools exist (accounting only, no tax tables). The sentence means tax tables and filing; it does not say so.
  • Nothing names the destination: the installed app (P11a, P11b) and the hosted service (served.md section 11).

plan/gui.md

  • "Status (2026-10-12)" predates: the Books menu (back up, restore, new books, connect, close; P2 slice 8), 80 color schemes (D-19's family menu), Invoices & Bills pages and document pages with timelines (P4b S2, S3), Projects pages, old-books compatibility tests, Needs attention computed by ledger-package and only routed by the viewer (U0b), the data root as the only source (wanderbooks gui <book>; --data-dir and --books-toml removed, D-44), the W-9 and TIN clipboard copy (D-29), the format-upgrade dialog (D-39).
  • Principle 4 says the GUI "builds its own in-memory view" and offers prompts for the agent; the prompts now come from the shared attention engine.
  • The "Next" list (cash forecast, reconciliation view, receipt zoom, keyboard navigation, virtualized lists, web build) was never revisited; the reconciliation page exists; the web build is the hosted service's viewer (section 11).

README.md

  • "118 MCP tools" twice (122 on main); "190+ workspace tests" (about 2,700 test functions across the two workspaces).
  • The quickstart and the installer claim Linux and macOS. On macOS the executable builds and the viewer runs, but wanderbooks connect and the agent bridge fail: tokens live in the OS keyring and only the Linux Secret Service store is built (tokens.rs, NOT_YET). Windows is WSL2 only, as it says.
  • "Status" says the Google Sheet stays the system of record until a clean month and cutover approval; the cutover happened 2026-10-20 (P2 slice 9) and the Sheet is frozen as of 2026-10-11.
  • "Mutation testing via cargo-mutants" is paused for development until P12 (D-33; CI still runs its weekly shards).
  • The layout omits ledger-vault, bookspec/, verify/, deploy/, fuzz/, oracle/, site/.

AGENTS.md

  • "ledger-core depends only on rust_decimal, thiserror, chrono, serde, serde_json": it also depends on jiff (the time-zone database for company.timezone's "today", P1). The rule needs the sixth name or a justification recorded.
  • The docs index omits docs/testing.md, docs/parties-and-attachments.md, plan/served.md (the plan every remaining unit is built from), plan/HANDOFF.md, bookspec/, deploy/.

docs/architecture.md

  • "Current crate layout" shows ledger-core alone with six files; the workspace has ten crates (plus the bookspec workspace of two), and ledger-core has about 25 modules. "Future crates (do not create until the roadmap says so)" lists ledger-store, ledger-import, ledger-export, ledger-oracle as future: the first two exist, ledger-export was folded into ledger-import, and the GnuCash cross-check is tests/oracle_gnucash.rs with oracle/gnucash/, not a crate. ledger-config, ledger-mcp, ledger-cli, ledger-host, ledger-vault, ledger-gui, ledger-package are described in later sections or not at all; there is no dependency graph.
  • "the projection has a table for each (schema v12)": 16 (17 on branch S5).
  • The ledger-mcp groups list will need sent and settlements when S5 and S6 merge (their branches add them).
  • The P6 branch's ledger-store → ledger-import dependency is not covered by the dependency rules (see served.md above).

docs/parity.md

  • "Floor: 10 done (2026-10-10)" while the table holds 21 done rows.
  • No P4b entry at all. S1 (documents read their figures from standing lines, the control guard, books.void_document, books.control_check), S2 (books.documents, books.document, the viewer pages), S3 (the invoice PDF) and S4.1-S4.3 (terms, numbers, line accounts, the issued PDF filed) landed without touching the catalog, against AGENTS.md's "every feature change updates docs/parity.md in the same commit". The A/R and A/P rows' notes still read "R-FUTURE-5".
  • "Automated cross-implementation diff harness (GnuCash first) | todo" while just oracle runs it weekly (docs/oracle.md Layer 5); what remains is the fixture-book snapshot diff and the machine-readable catalog.
  • "Workflow/UI parity ... gets its own catalog when the egui phase starts": the viewer exists; no such catalog was started (not a defect: the owner made MCP the primary interface, 2026-10-10).

docs/capability-parity.md

  • The cutover rule reads as pending. The cutover happened 2026-10-20 (P2 slice 9); the Sheet is frozen as of 2026-10-11 and the final verify-sheet run is a filed workpaper (served.md 8.4). The document should say so and keep the rule for the record.

docs/parallel-run.md

  • Entirely pre-cutover ("70 workspace tests"; "delete the wanderbooks data dir" as rollback). Historical since 2026-10-20; it carries no banner saying so.

docs/requirements.md

  • R-13 names require_receipts_above with a default of "25.00" enforced by the MCP layer; the policy is the journaled setting policy.evidence.* (P1, B-29), evaluated by ledger-config's ReceiptPolicy today and moving into ledger_core::evidence in P4 (I-5 as amended by D-47).
  • "CPA handoff package: ... P&L and balance-sheet PDFs (printpdf, MIT)": Typst since 2026-10-11, and the package holds the cash flow, GL, journal IIF, receipts, documents, the 1099 worksheet and the K-1 worksheets.
  • "A/R and A/P workflows ... MCP tools for the full workflow" says nothing of D-45 (figures derived from tagged standing lines; hand lines on the control accounts refused) or of what documents_v2 adds behind the owner's upgrade.

docs/oracle.md

  • Layer 3 (mutation testing) is "live now"; development mutation runs are paused until P12 (D-33), CI's weekly shards aside.
  • Layer 5 both says the GnuCash differential is live and that "a ledger-oracle crate will run fixture books ... cargo xtask oracle"; there is no crate and none is planned (the harness is tests/oracle_gnucash.rs).
  • "What the oracle does NOT cover: workflows ... a UI concern for the egui phase, where storytold's screenshot-in-the-loop comes back": the viewer exists with screenshot tests (crates/ledger-gui/tests/*.rs, shot(..)).

docs/receipt-store.md

  • "Migration from Google Drive" is written as future work; the company records were filed at the P1 cutover (D-20) and the Drive manifest and comparison tools were struck (served.md 8.4). The schema notes (v16, a file per schema) are current.

docs/parties-and-attachments.md

  • "Status: design; built after asset tax basis": built (parties, roles, the TIN vault, attachments to any subject, 2026-10-15 to 2026-10-17); D-55's contact block is built on branch S4.4.

docs/mcp-interface.md

  • The per-tool sections are held to the code by every_tool_is_documented_and_every_documented_tool_exists; no drift there. The framing is stale: "Crates in this phase" lists two crates and calls ledger-store "SQLite persistence" (the journal is the source of truth); "Muse" among the clients; "Out of scope for this phase". P5 owns the overview rewrite (its step 6).

docs/testing.md

  • The Layers table says just prove runs 48 harnesses and prove-slow 8; the code has 60 (#[kani::proof]), 51 in prove and 9 in the justfile's kani_slow.
  • The mutation rows say "weekly" with no mention of D-33 (development runs paused until P12; CI's scheduled.yml still runs the shards).
  • Units U0a and S4.1-S4.3 have no section; U0a added no tests (none owed) and S4's For-P12 paragraph is S4.5's by the plan, so this is deferred, not missing.

docs/verification.md

  • The harness table lacks P4b S1's two Kani harnesses, bounds_check_matches_definition and bounds_kept_is_the_definition_on_books_in_bounds (kernel::running_bounds, bounds_kept), and there is no section for S1's law (Lean control_agrees, control_agrees_through, Reachable.control_is_documents in Documents.lean), against AGENTS.md's "every harness and theorem listed". S7's branch amends the "out of scope" list; S5's branch adds rule 34 (Step.markSent).
  • "Running it": 48 and 8 harnesses (51 and 9).

docs/spec/README.md, docs/spec/rules.md

  • No drift detected beyond the open sources already listed in 8.4 (B-38 to B-45 stay CONVENTION until vendored). The branches add B-41 (S7), B-42 (S6), B-44 (P6) and their bookspec ids.

site/index.html, install.sh

  • Both claim Linux and macOS. On macOS the install succeeds and the viewer runs, but wanderbooks connect claude (the installer's last step) fails on the keyring (see README above), so the one-line promise does not hold there until P11a's keyring stores. "Native Windows is on the way" is right. The site is deployed by hand (just deploy); the built copy under site/dist lags any source edit until then.

deploy/README.md, deploy/wanderbooks-server.service

  • No drift detected against P9a as built. Done-when 1 (the GitHub Actions job's first run) and 2 (the recipe walked on a clean VM by a non-author in under 30 minutes) are still the owner's to verify.

bookspec/README.md

  • No drift detected. Branch S7 extends the example schema (write_off, a refused lines entry); the README on that branch says so.

plan/review-2026-10-26/

  • Historical. No drift detected.

Housekeeping found on the way (not plan drift)

  • Build caches: about 1 TB under the six target/ directories (wanderbooks 196 GB; wb-S6 220 GB, wb-S5 194 GB, wb-P6 167 GB, wb-S4.4 117 GB, wb-S7 109 GB) with 1.7 TB free. Once the branches merge, cargo clean in each worktree and git worktree remove recover it.
  • 27 jj workspaces are registered (p3-*, p4-*) whose directories under ~/.cache/wanderbooks/ no longer exist: jj workspace forget each.
  • Branch rescue/p4-invproj-20261026 ("wip: rescue uncommitted p4-invproj work before cache cleanup, never merged", 51 files) sits beside main, which holds that work's landed form (528c0706, including its bookspec example projects-invoice-and-bill-lines-count-by-project); nothing on it is missing from main. Delete it after a last look.

The deviations, judged

Every departure recorded in an As-built block was read against the unit's text and AGENTS.md:

  • Reasonable, keep: S4.1's interim guard (removed by S4.3 as promised); S4.2 declaring documents_v2 early (the settings writes needed the gate); S4.3 skipping the parties columns (no parties table exists; replay and differs_from carry the facts) and the _with carriers; S4.4 requiring the new bill fields only under documents_v2 (8.0.4's "everything else works at once"); S5's Lean step for mark_sent (I-13 wins over the unit's "no Lean change") and the recipients rename (the lint is older than the unit); S6's tools/settlements.rs (the EM approved it to keep documents.rs single-owner) and the fee's processor in the description; S7's least_owed_from bound (B-38 invariant 2 at every later day, stricter than the unit) and the one-receipt-once rule; U0a's 122 (the unit's 118 was stale); U0b's extra PackageBooks reads and the integrity fix (a real parity gap found); P9a's loopback-only door (the review caught a plaintext static-bearer door bound to every address); P7 keeping the filing scan narrow (B-26's design); P13's Engine::change and the CHOICE vocabulary.
  • Reasonable but owed back: S4.3's missing journal transaction (an I/O failure between the invoice's lines and its attachment's is not rolled back: a property of every multi-line command, to be fixed once for all in P12 or a small unit of its own); S6 deferring confirmed to P4 (right, since P4's sweep touches every confirm tool, but P4 must now add it rather than only preview); S6's unwritten bookspec examples (owed to P13 step 4 or S6's follow-up now that terms are journaled); the two S1 harnesses missing from docs/verification.md.
  • Needs a decision: P6's ledger-store → ledger-import dependency (architecture), and P6's whole branch is a checkpoint whose gate never ran: it is not yet a reviewed unit.
  • Not reasonable, fix: none found. No golden moved on main; no kernel arithmetic outside kernel.rs was introduced by the landed units; no unit touched the owner's books.

Where to go next (the order)

  1. Resume and land the paused branches, in this order, each rebased on main and just check (and just prove where it says) re-run after the rebase: S4.4 → S5 (resolve documents.rs by concatenation, types.rs by keeping both appends; schema 17 stands) → S6 (documents.rs, docs/mcp-interface.md) → S7 (documents.rs, types.rs, store/lib.rs; just prove for writeOff_within_bounds) → P6 (eight files; retake schema 18; run its gate to the end; review the store → import dependency). Then S4.5, the only unstarted P4b slice.
  2. Ask the owner Q-5 and Q-8 (served.md 10.3) when S4.4 lands; the documents_v2 upgrade of the live books follows the answer (after S7 and P4 under D-52).
  3. Start P11a now (D-56), beginning with its new step 0 (the macOS and Windows keyring stores, the Windows data root and pipes, a CI matrix on macOS and Windows runners), then the cargo-packager trial. P11a is independent of the P4b and P4 chain and is the owner's destination.
  4. Then the chain as planned: P4 (now also adding confirmed to the settlement tools) → P5 → P8 → P10; P13 steps 4-6 beside; P11b after P11a; P12 last.
  5. Update the documents in this report's list (done in the same change as this report where the fix is a fact, not a decision).