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 at44ee4083: 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
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 checkreported green by its worker on the branch rebased oned637f0e. P6 says "not started" and is built to every step on branchP6, checkpointed asce366408("wip: pause checkpoint, P6 feature complete, gate interrupted (not for merge)"): itsjust checknever finished. - The merge hazards of the pause are not recorded anywhere. Dry-run merges onto
mainin plan order: S4.4 clean; then S5 conflicts incrates/ledger-cli/tests/documents.rs(add/add) andcrates/ledger-mcp/src/types.rs; S6 indocuments.rs(add/add) anddocs/mcp-interface.md; S7 indocuments.rs(add/add),types.rs,crates/ledger-store/src/lib.rs; P6 intypes.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 ontomaincleanly 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 fortypes.rscollides whenever two units append; P6 branched before S4.3 and took schema 16, which S4.3 holds onmain(S5 took 17), so P6 must retake 18 at its rebase. S5 and S6 both numbered their new law 34 indocs/verification.md(S5Step.markSent, S6settle_is_exact); S1's documents law, which was never written up, is 34 onmainas 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) andtools/settlements.rs(S6, which also movedbooks.receive_payment,books.pay_bill,books.ar_aging,books.ap_agingout ofdocuments.rs);books.mark_sent's recipients parameter isrecipients, notto(theno_tool_takes_a_pathlint refusesto); P6 builtbooks.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 tobooks.receive_paymentandbooks.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-storenow depends onledger-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_invoiceandbooks.create_billnow needconfirmed: true; the connect text and handbook onmainstill 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 ishandbook.rs). - Q-5 is due and unasked. Its trigger is "when S4 lands"; S4.1-S4.3 are on
mainand 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.rsreturns "kept in the keyring on Linux only, until the macOS and Windows apps (P11)" on every other OS, sowanderbooks connectand 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 runubuntu-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 arewanderbooks serve --httpand--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, S5p4_s5_before, S7p4_s7_before, P6p6_evidence; S4.4 and S6 wrote none of their own (S6 reusesp4-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 checkmust 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 oracleruns 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::payrolland 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-packageand only routed by the viewer (U0b), the data root as the only source (wanderbooks gui <book>;--data-dirand--books-tomlremoved, 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 connectand 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-coredepends only onrust_decimal,thiserror,chrono,serde,serde_json": it also depends onjiff(the time-zone database forcompany.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-corealone with six files; the workspace has ten crates (plus the bookspec workspace of two), andledger-corehas about 25 modules. "Future crates (do not create until the roadmap says so)" listsledger-store,ledger-import,ledger-export,ledger-oracleas future: the first two exist,ledger-exportwas folded intoledger-import, and the GnuCash cross-check istests/oracle_gnucash.rswithoracle/gnucash/, not a crate.ledger-config,ledger-mcp,ledger-cli,ledger-host,ledger-vault,ledger-gui,ledger-packageare 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-mcpgroups list will needsentandsettlementswhen S5 and S6 merge (their branches add them). - The P6 branch's
ledger-store→ledger-importdependency 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
donerows. - 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 updatesdocs/parity.mdin 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 oracleruns 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-sheetrun 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_abovewith a default of"25.00"enforced by the MCP layer; the policy is the journaled settingpolicy.evidence.*(P1, B-29), evaluated byledger-config'sReceiptPolicytoday and moving intoledger_core::evidencein 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_v2adds 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-oraclecrate will run fixture books ...cargo xtask oracle"; there is no crate and none is planned (the harness istests/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 callsledger-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 proveruns 48 harnesses andprove-slow8; the code has 60 (#[kani::proof]), 51 inproveand 9 in the justfile'skani_slow. - The mutation rows say "weekly" with no mention of D-33 (development runs paused until P12; CI's
scheduled.ymlstill 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_definitionandbounds_kept_is_the_definition_on_books_in_bounds(kernel::running_bounds,bounds_kept), and there is no section for S1's law (Leancontrol_agrees,control_agrees_through,Reachable.control_is_documentsinDocuments.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 undersite/distlags 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 refusedlinesentry); 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 (wanderbooks196 GB;wb-S6220 GB,wb-S5194 GB,wb-P6167 GB,wb-S4.4117 GB,wb-S7109 GB) with 1.7 TB free. Once the branches merge,cargo cleanin each worktree andgit worktree removerecover it. - 27 jj workspaces are registered (
p3-*,p4-*) whose directories under~/.cache/wanderbooks/no longer exist:jj workspace forgeteach. - Branch
rescue/p4-invproj-20261026("wip: rescue uncommitted p4-invproj work before cache cleanup, never merged", 51 files) sits besidemain, which holds that work's landed form (528c0706, including its bookspec exampleprojects-invoice-and-bill-lines-count-by-project); nothing on it is missing frommain. 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_v2early (the settings writes needed the gate); S4.3 skipping the parties columns (no parties table exists; replay anddiffers_fromcarry the facts) and the_withcarriers; S4.4 requiring the new bill fields only underdocuments_v2(8.0.4's "everything else works at once"); S5's Lean step formark_sent(I-13 wins over the unit's "no Lean change") and therecipientsrename (the lint is older than the unit); S6'stools/settlements.rs(the EM approved it to keepdocuments.rssingle-owner) and the fee's processor in the description; S7'sleast_owed_frombound (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 extraPackageBooksreads 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'sEngine::changeand 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
confirmedto P4 (right, since P4's sweep touches every confirm tool, but P4 must now add it rather than onlypreview); 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 fromdocs/verification.md. - Needs a decision: P6's
ledger-store→ledger-importdependency (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 outsidekernel.rswas introduced by the landed units; no unit touched the owner's books.
Where to go next (the order)
- Resume and land the paused branches, in this order, each rebased on
mainandjust check(andjust provewhere it says) re-run after the rebase: S4.4 → S5 (resolvedocuments.rsby concatenation,types.rsby keeping both appends; schema 17 stands) → S6 (documents.rs,docs/mcp-interface.md) → S7 (documents.rs,types.rs,store/lib.rs;just proveforwriteOff_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. - Ask the owner Q-5 and Q-8 (served.md 10.3) when S4.4 lands; the
documents_v2upgrade of the live books follows the answer (after S7 and P4 under D-52). - 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.
- Then the chain as planned: P4 (now also adding
confirmedto the settlement tools) → P5 → P8 → P10; P13 steps 4-6 beside; P11b after P11a; P12 last. - 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).