Files
wanderbooks/plan/review-2026-10-26/comprehension_report.md
T

107 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Stage 6: Comprehension review of `plan/served.md` (DetailedRange 766-2058)
Reviewer: `egm-comprehension`, 2026-10-26, as the entry-level engineer handed ONE unit in a worktree. Symbols checked under crates/, docs/, verify/, bookspec/, fuzz/.
**Verdict:** no remaining unit (P4b S4..S7, P4, P5..P13) can be re-implemented from the text alone without guessing. The P4b slices come closest (P4b.3-P4b.11 carry real contracts); P5-P13 are scope lists, not specifications.
## A. Cross-cutting gaps (every unit)
- **A1 Blocker. Numbered references that resolve to nothing.** "defect 2" (P4 title) is never described; "defects 4, 10, 20" (P6) only by a phrase; "decision 1, 8, 9, 11, 12" (P4b.5/7/8/14/17) do not match the numbered owner answers 1-5 (they come from a question-tool session not in the repo); "the private change log" (909, 1486, 1623, 641, 969) and `goldens/p4-arap-before/`, `goldens/p4-arap-sN/` (1477, 1495) are outside the repo (the only in-repo thing with that name is a journal fixture under `crates/ledger-store/tests/fixtures/`).
- **A2 Blocker. "Done" is not defined per unit.** P4b S4-S7 have no Accept block; P4b.15 lists ~55 tests for seven slices without saying which slice lands which (`an_invoice_from_issue_to_paid` spans S4, S5 and S6). P5-P9 Accepts are mostly live-session or private-data checks.
- **A3 Major. Stale source anchors.** Every `S:NNNN`, `ledger.rs ~NNNN`, `types.rs:NNNN`, `docs/mcp-interface.md (24-95, …)` anchor; "schema v12" vs `SCHEMA_VERSION = 15`.
- **A4 Major. "for one release" (83, 442, 1294, 1933) is undefined**; no release versioning scheme is stated.
- **A5 Major. Where "Needs attention" items live is undefined** for P4, S5, P6, P7, P8: `ledger-view` does not exist and no phase's scope creates it.
- **A6 Major. Dependencies and parallelism are never stated as a graph.** Hidden: S5/S6/S7 "take preview_token once P4 lands"; S7 adopt/move hits P4's gate; P5's `next_steps::decorate` needs the attention engine; P8 cross-checks need P6; P10 needs P6, P8, P9; P11's updater needs `books.job` and `wanderbooks rollback` (listed in P2 scope at 859 but never built). Shared files every slice edits: `server.rs`, `types.rs`, `scopes.rs`, `format.rs` KNOWN_FEATURES, `schema.rs`, `docs/mcp-interface.md`, `docs/spec/rules.md`, `docs/testing.md`.
## B. P4b S4 `documents_v2`
- **B1 Blocker (1002 vs 1215/1631).** Answer 3 requires `invoicing.payment_methods` list with QR; P4b.4/11/17 specify a single `invoicing.payment_instructions` string and "that key only" exempt. `qrcode` 0.14.1 already in `ledger-import`.
- **B2 Blocker (1289-1298, 1236).** Preview-then-confirm changes today's `create_invoice`/`create_bill` contract (`CreateDocumentParams {party_id, date, due_date, lines}`). Unstated: behaviour on books without `documents_v2`; whether `due_date` becomes optional; `terms? | due_date?` with both or neither; fallback order (party default → `invoicing.default_terms`); the type of `terms` (string to parse or object).
- **B3 Major (1159-1163).** `Terms.text` has no composer; `EarlyDiscount.days < net` meaningless for NetEom/DueOnReceipt; `due_date -> Result` error cases; `0..=3650` vs `u16`; reuse of `validate_due_date` (arap.rs:599) not said.
- **B4 Major (1194-1198, 1492).** Zero-pad width; behaviour at 10000; `first_number` "after the highest legacy id" while legacy invoices have no number; prefix change after first issue; preview number vs confirm number.
- **B5 Major (1170).** `quantity × unit_price == amount exactly`: decimal scale unspecified (3 × 33.333).
- **B6 Major (1291, 1371-1373).** Filing a server-generated PDF "in the same store call" needs a new store path (D-46: all attachments arrive by upload). File name, MIME, uploader principal, and how the DRAFT preview PDF is returned (HandedFile? counted against the 64 cap?) unstated.
- **B7 Major (1362, 1218).** Seller snapshot wants "email or website"; no `company.email`/`company.website` setting exists.
- **B8 Major (1296-1297).** `create_bill`: `vendor_ref` required but legacy bills lack one; omission of `upload_id | attachment_id` refused or allowed; `received_on` has no stated use.
- **B9 Major (1290, 1311).** `bill_to?` type; `update_party` `default_terms` one value for both customer and vendor sides?
- **B10 Major (1331-1337, 1595).** "The handbook procedure": no section id; `crates/ledger-mcp/handbook/` has 21 sections and 4.3's list (407) names different ids. B-39/B-40 need writing; B-38 already exists (rules.md:2872) so "new rules B-38 to B-41" is partly stale.
- **B11 Major (1268).** Which crate gates `settings.set` of `invoicing.*` behind the feature (`setting_feature` is `pub(crate)` in ledger-store; the registry is in ledger-core); the exact list of writes that must still work without the feature is not enumerated.
- **B12 Nit.** arap `Snapshot` collides with `ledger_store::Snapshot`. **B13 Nit.** `customer` name resolution when a name matches two (precedent `inv6_ambiguous_vendor_reference_refused`).
- **B14.** No Accept; candidate tests exist by name only.
## C. P4b S5 sent tracking
- **C1 Blocker (1003 vs 1185-1186/1269).** Answer 4 requires who sent and the channel's reference; `Sent`/`invoice.sent` carry neither.
- **C2 Major (1325).** Defaults for `on`, `via`, `kind`; `to` when the party has no email; mark_sent on Void/Paid/legacy; whether bills get sends.
- **C3 Major (1330).** "never sent (after 2 days)": from issue date or today, which timezone, calendar days; `reminder_days` is in S4's settings list.
- **C4 Major (1342).** mailto body "about 1,800 characters" is not a contract; S3 already built the mailto link; S5's delta unclear.
- **C5.** No Accept.
## D. P4b S6 paying on terms
- **D1 Blocker (1003 vs 1597/1244/1300).** The processor fee (gross to A/R, fee to expense, net deposited) is assigned to S6 by STATUS but appears in no S6 line, posting row or argument; no fee role/account in the role table.
- **D2 Major (1300, 1304).** Top-level `amount` vs Σ applications; whether application `amount` is cash only or cash+discount; `paid_in_full_marking?` type and slice.
- **D3 Major (1323).** `books.bills_due` output has no schema; "amount needed by each date" undefined.
- **D4 Major (1352-1353).** Aging CSV columns, tie-out line format, README text, xlsx/pdf templates; `detail?` and `control{}` on the aging tools have no slice.
- **D5 Major (1204-1210).** "Expense (credit balance)" has no account-type variant; roles "re-checked against the live chart" is the owner's private books.
- **D6 Major (1259).** Is `discount_reason` journaled (feature row names only `discount`)?
- **D7 Nit.** Bill flags `due_soon`/`discount_open`: S5 or S6?
- **D8.** No Accept.
## E. P4b S7 bad debts and legacy lines
- **E1 Blocker (1326).** `write_off_invoice` "needs evidence attached in the same call" but has no `upload_id`/`attachment_id` argument.
- **E2 Blocker (1327, 1272).** `adopt_control_line`: how the Invoice/Bill record is built (date, lines, customer/vendor creation), what `record_id` is, numbering, replay determinism.
- **E3 Blocker (1312, 1251, 1272).** `assign_role move_balance`: entry dates, description, party tag, evidence under P4's gate, unattached legacy lines, zero balance, atomicity.
- **E4 Major.** Cash-basis refusal: error code/guard name. **E5 Major (1249).** Recovery reversal vs P4's reversal-as-draft. **E6 Major (1208).** On-demand role creation when 6990 is taken. **E7 Nit.** B-41 and Lean `bounds_preserved` are names only.
- **E8.** No Accept.
## F. P4 drafts, reversal as draft, evidence gate, digest
- **F1 Blocker (971).** "defect 2" undefined; exemptions named by stale line numbers; the live handbook (`drafts-and-reversals.md:4`) says reversals need no receipt while I-5 says they are not exempt.
- **F2 Blocker (978, 66, 83, 512).** `preview_token`: "canonical draft state" undefined; "all confirm tools" not enumerated; 83 vs 512 contradict on whether `confirmed` without a token is accepted; `preview_entry`'s output unstated.
- **F3 Blocker (974, 1109, 1316, 1228).** Does `void_document` become a draft after P4? Draft-time vs post-time for `check_reversal`/`check_item_bounds`.
- **F4 Major (974).** `ledger_core::evidence::requirement` does not exist (gate is `ledger_config::ReceiptPolicy`); signature and return unstated; "exemption is sourced" names no source.
- **F5 Major (513, 574).** How `link_original` is journaled; what posting a lineless reversal draft journals; replay rebuilds lines from which original state.
- **F6 Major (976-977).** `list_drafts` shape; `as_of_status` on which reports; `strict` semantics; `posted_seq`/`entry_meta` do not exist; "zero-net touched accounts", "reconciliation_tracked", "never_reconciled" undefined.
- **F7 Major (981-985).** Lean draft-state notion absent; `Step.discard` obligations; `tests/model.rs` extension unstated.
- **F8 Major.** Attention location (A5). **F9 Major (993).** "0 unexplained drafts" is private. **F10 Nit.** "gains the new ops" lists none.
## G. P5 agent surface
- **G1 Blocker.** `ledger-view` never created by any scope while `next_steps::decorate` and `books.start` v2 need it.
- **G2 Blocker (1643, 411-423).** Prompt texts, argument validation and outputs unspecified; "golden render per prompt" impossible.
- **G3 Major (1644, 444-460).** Guard code list, per-tool next-step rules, merging with existing `warnings`; `books.start` already returns `next_steps`.
- **G4 Major.** `books.job` retention, id, polling, cancellation, which tools; `journal_history` output and `subject` grammar.
- **G5 Major (1646).** Source-only revision: no event name or feature. **G6 Major (1647).** URL-mode elicitation has no local use (D-28). **G7 Major (1649).** Agent-eval harness mechanics; depends on P4. **G8 Major.** Accept on a nonexistent fixture and manual sessions. **G9 Nit.** Which eight descriptions exceed 700 characters.
## H. P6 evidence pipeline
- **H1 Blocker.** Sandboxed `ledger-extract` contradicts D-32. **H2 Blocker (1682).** Migration tools' inputs are private scripts and files; formats unspecified.
- **H3 Major.** `inline_base64_requires_sha` contradicts D-46; `get_receipt` views `text`, `page_image` outputs unstated; `books.download_link` ambiguous under D-46.
- **H4 Major.** `attach_email`: no `eml` upload purpose; decision 5 defers email-in; Typst template unstated.
- **H5 Major.** `text_extracted` fields; backfill trigger; receipt numbering field; FIFO `reimbursed` inputs undefined; `annotate_attachment` validation.
- **H6 Major.** Consolidation event names absent from 5.2. **H7 Major.** Company record category list. **H8 Major.** Accepts are private data; hayro already present, not mentioned.
## I. P7
- **I1 Blocker.** Contradicts D-28, D-29, 3.6 as-built; which parts survive is undecided. **I2 Blocker.** Keyslot formats, `rekey`, HPKE crate; 4.1 still names `request_tin_entry`. **I3 Major.** Accept against private goldens. **I4 Major (644 vs D-31).** "No vault key material on disk" is false for backups.
## J. P8
- **J1 Blocker (1727-1734).** Each check is a noun phrase; no predicates, finding codes, workpaper schema or Typst template; "2100 aging" is a company-specific code in a generic engine.
- **J2 Blocker (1738-1742).** Attest tools have no argument lists; `policy.attestation_bar` has no value schema; which P6 fields the cross-check reads.
- **J3 Major.** `workpaper` category, `books.workpaper`, `books.attestations` not in scope. **J4 Major.** The refuse-without-audit override parameter is unnamed. **J5 Major.** "access-log tooling" in the title, none in scope. **J6 Nit.** Lean lemma has no statement.
## K. P9
- **K1 Blocker.** D-7 undecided, determines most of the code. **K2 Blocker.** Archive unit, seccomp/Landlock, `fetch` do not exist (D-31, D-32). **K3 Major.** `tunnel` command or doc; MCP App widget unspecified; `/h/inbox` built here or not. **K4 Major.** Replica traits, headers, events unnamed; `invite` sends mail though the books never send. **K5 Major.** No two-user CI job exists.
## L. P10
- **L1 Blocker.** Entirely on private books by live agents; depends on P6, P8, P9; "22 defect reproductions" stale (23 and 24 exist). **L2 Blocker.** "No TINs through the agent" contradicts D-29. **L3 Major.** `fetch`/`verify-archive` never existed. **L4 Major.** "100K tokens" has no measurement method.
## M. P11
- **M1 Blocker.** Dock built on the helper and confinement D-32 removed. **M2 Blocker.** Signing identities, repository keys, hardware token, GitHub Releases: outside the repo and the engineer's authority; the unit begins with research. **M3 Major.** `rollback`, `update.lock`, `update`, manifest format, staged layout unstated. **M4 Major.** Books-home file contents not given. **M5 Major.** Tests need clean VMs; no CI definition.
## N. P12
- **N1 Major.** Hardware external. **N2 Major.** "set time" never set; location of documented maxima. **N3 Nit.** `--jobserver-tasks` unverified. **N4 Nit.** §6 promises recipes for crates that don't exist.
## O. P13
- **O1 Blocker (1886).** The in-repo seed (`bookspec/`, 56 examples, checked by `cargo test`) is never mentioned; an engineer would start from zero. **O2 Blocker (1873).** `Engine` trait has no signature; TOML schema is prose. **O3 Major.** Rule identifier scheme; mapping from B-1..B-38; no done-line for a first edition; Lean consistency claim has no formalization hint. **O4 Major.** Claims list and the GnuCash run undefined.
## P. Contradictions
P1 reversal-as-draft vs `void_document` posts at once. P2 `payment_instructions` string vs `payment_methods` list. P3 `Sent` without sender/reference vs answer 4. P4 fee in STATUS/S6 vs absent from S6. P5 PDF stamps: three different lists; `invoice_pdf(&InvoiceDoc, &DocMeta)` vs built `invoice_pdf(&InvoiceDoc)`. P6 "slice S1 next" vs S1-S3 landed. P7 P7's scope vs D-28/D-29/3.6. P8 sandbox/archive unit/helper vs D-31/D-32. P9 `inline_base64_requires_sha`, `download_link` vs D-46. P10 P10 step 6 vs D-29. P11 `verify-archive`/`fetch`/`heads.jsonl` vs D-31. P12 `confirmed` without token accepted (83) vs required (512). P13 schema v12 vs 15. P14 "22 defects" vs 24. P15 P8 title vs scope. P16 4.3 handbook ids vs 21 files. P17 drop page: P2 scope vs 4.7 as-built vs P9 Accept. P18 "new B-38" vs existing. P19 `ledger-view` in P5 per P1 as-built vs absent from P5 scope. P20 `goldens/p4-arap-before/` vs private goldens vs same-named fixture.
## Q. Symbol verification
**Exists:** arap.rs (DocRef, Movement, DocTag, DocState, DocStatus, ControlCheck, aging_bucket, document_parts, validate_due_date, derive_status); `Ledger::stands_on`, `in_effect`, `check_reversal`, `check_item_bounds` (private), `control_check`, `void_document`, `invoice_state`/`bill_state`; `UntaggedControlLine`, `PaymentBeforeDocument`; KNOWN_FEATURES with `document_standing`, `document_line_projects`; `setting_feature` (pub(crate)), `ensure_feature`; `CreateDocumentParams`, `PaymentParams {instrument?, reference?}`; `invoice_pdf(&InvoiceDoc)`, `InvoiceStamp` (5 variants), `invoice_document`, `PackageBooks`; `Subject::Invoice/Bill`; `has_full_tin`/`redact_full_tins`; `company.duns` exemption, `company.name`, `company.address`, `books.accounting_basis`; `qrcode`, `hayro`; Lean `control_agrees`, `control_agrees_through`, `Step.document_unattached`, `cashflow_sections_sum_to_cash_change`, `draftsOpen`; `tests/model.rs`; fuzz targets; `local_server.rs`, `tests/common/mod.rs`, `projects_parity.rs`; `receipt_policy.rs`; `tools/{access,backup,files,instruments,kept,projects}.rs`; `books.start` with `next_steps`; docs/testing.md "For P12" sections; scheduled.yml; `bookspec/` seed; docs/oracle.md; rules.md B-38.
**Missing:** `Terms`, `TermsKind`, `EarlyDiscount`, `Sent`, `SentVia`, `SendKind`, arap `Snapshot`, `issued_pdf`, `vendor_ref`, `customer_ref`, `duplicate_reason`, `default_terms`, `check_document_line_account`, every `invoicing.*`/`bills.*` key, `company.email`/`company.website`; features `documents_v2`/`invoice_sent`/`settlements`/`write_offs`/`control_lines`; events `invoice.sent`/`invoice.written_off`/`control_line.adopted`/`role.balance_moved`; tools `mark_sent`/`bills_due`/`write_off_invoice`/`adopt_control_line`; `ledger_core::evidence`; `preview_token`/`preview_entry`/`list_drafts`/`set_draft_state`/`discard_draft`/`inherit_evidence`/`as_of_status`/`posted_seq`/`entry_meta`; `ledger-view`, `ledger-extract`, `lopdf`, `mail-parser`; `text_extracted`/`find_attachment` tool/`consolidate_duplicates`/`annotate_attachment`/`compare_reference`/`record_inventory`/`check_inventory`/`attach_email`; `journal_history`/`books.job`/`guards` envelope; `audit.rs`/`attest_*`/`workpaper`/`attestation_bar`; hpke/`keyring.json`/`request_tin_entry`/`set_w9_facts`/`/h/` routes; `fetch`/`tunnel`/`invite`/`verify-archive`/`rollback`/`update`/`update.lock`; replica routes; `scripts/*`; `goldens/*`; rules B-39/B-40/B-41; a handbook section for invoices.