feat(package): one attention engine over PackageBooks (U0b)
Needs attention was computed by the viewer alone, while books.start hand-picked a handful of next steps. The human's list and the agent's could disagree, and a new item had to be written twice (or, as books.start showed, not at all). Move the engine to ledger-package over PackageBooks: one function, find/find_with(books, today, settings, integrity), reads the ledger, the journal's event types (an entry's origin), the attachments and their links, the statements, the reconciliations, and the database check. The viewer's attention module now only maps Target to Route; books.start turns the same items into its next steps (why = the item's title, top 12), so the list the human sees and the steps the agent gets cannot drift. PackageBooks gains settings, journal, statements, reconciliations and disk_check, implemented for Store and Snapshot, so both views answer alike. The W-9, reconciliation and 1099 predicates move beside the items to keep one copy. ledger-package gains ledger-config and serde_json (the receipt policy and the tool arguments the items carry). Tests: view_model.rs and spec_kept.rs pass unchanged; the new attention_parity.rs compares the viewer and books.start item for item on the demo books and on a book written entry by entry. just check green.
This commit is contained in:
1 parent
eeee9658da
commit
0cf2f8f5c5
17 files changed
+2026
-895
No files matched your search
@@ -81,6 +81,20 @@ appended journal lines; the UI renders an immutable view model rebuilt per
|
||||
change. Statements and series come from `ledger-core` (`reports`,
|
||||
`analysis`); the GUI only arranges them. See `plan/gui.md`.
|
||||
|
||||
## Shared read-only views (`ledger-package`)
|
||||
|
||||
`ledger-package` is the shared read-only view: packages, the invoice PDF,
|
||||
and Needs attention, over `Store` or `Snapshot`. Its `PackageBooks` trait
|
||||
is what those builders read of the books (ledger, settings, journal,
|
||||
attachments and their links and bytes, statements, reconciliations), so the
|
||||
server and the viewer make the same package, the same invoice, and the same
|
||||
attention list from one piece of code; nothing in it writes. The viewer's
|
||||
`attention` module only maps each item's `Target` to its own route, and
|
||||
`books.start` turns the items into its next steps, so the human's list and
|
||||
the agent's cannot drift apart. The crate depends inward (`ledger-core`,
|
||||
`ledger-store`, `ledger-config`, `ledger-import`, `ledger-vault`), never on
|
||||
`ledger-mcp` or `ledger-gui`.
|
||||
|
||||
## The journal format gate (`ledger-store`, P0)
|
||||
|
||||
Every journal line passes a gate after its parse, seq and chain checks
|
||||
|
||||
@@ -124,7 +124,12 @@ settings-and-conventions section says how to use them.
|
||||
onboarding step (`books.handbook {section: "contract"}`, when the chart
|
||||
is empty or `focus` is `onboarding`); `books.open_items` (an item due
|
||||
within 30 days or overdue); `books.backup` (none set up, or one stale,
|
||||
failing, paused or failing its drill); the focus's step (`close`:
|
||||
failing, paused or failing its drill); then Needs attention, by
|
||||
severity, at most 12, each one `{tool, args?, why}` whose `why` is the
|
||||
item's title (the same list the viewer draws: `ledger_package::
|
||||
attention`, so the two can't differ; `books.verify` items are the
|
||||
server's own damage check and are not repeated); then the focus's step
|
||||
(`close`:
|
||||
`books.conventions {kind: "close_step"}`; `audit`: `books.verify`); then
|
||||
always `books.handbook {section: "contract"}` and `books.digest`.
|
||||
`focus` is `daily` (the default), `onboarding`, `close` or `audit`;
|
||||
|
||||
@@ -63,6 +63,16 @@ D-46); no file with a full TIN is filed into the books (B-26); the agent is
|
||||
told the rules in force in a short connect text and a handbook, and no
|
||||
agent text points at the books' files, git or the repo.
|
||||
|
||||
## U0b: one attention engine (D-53, 2026-10-26)
|
||||
|
||||
No semantic feature changed, so no status moved and the floor stands (10
|
||||
done). Needs attention used to be computed by the viewer alone; it now
|
||||
lives in `ledger-package::attention`, over `PackageBooks`, and both the
|
||||
viewer and `books.start` read it (the same items, the same prompts), so the
|
||||
list the human sees and the next steps the agent gets cannot drift. The
|
||||
parity test `the_viewer_and_books_start_see_the_same_attention` compares
|
||||
them item for item on the demo books and on a book written entry by entry.
|
||||
|
||||
## Capability parity (AI-first phase)
|
||||
|
||||
Semantic parity (above) is about *correctness*: the engine computes the
|
||||
|
||||
@@ -2915,3 +2915,50 @@ example" arm; the adapter's `event_of`, its `depreciation_schedule` month
|
||||
span (acquisition through as-of, 0.00 where the schedule reaches no month)
|
||||
and every `answer_*` figure against the loader's same check (the two must
|
||||
agree on all 56 examples).
|
||||
|
||||
## U0b: one attention engine over `PackageBooks` (2026-10-26)
|
||||
|
||||
Needs attention moved out of the viewer into `ledger-package::attention`
|
||||
(D-53): one function, `find`/`find_with(books, today, settings, integrity)`,
|
||||
over the `PackageBooks` trait (`Store` and `Snapshot`). The viewer's
|
||||
`ledger-gui::attention::find` is now a mapping (`Target` → `Route`,
|
||||
`Severity` → the viewer's); `books.start` turns the same items into next
|
||||
steps, `why` equal to the title, at most 12. `PackageBooks` gained
|
||||
`settings`, `journal`, `statements`, `reconciliations` and `disk_check`, so
|
||||
the engine can read an entry's origin from the journal's event types (as
|
||||
the viewer's builder did) and the same statements, reconciliations and
|
||||
database check through either view.
|
||||
|
||||
- **ledger-package (unit tests in `src/attention.rs`):** none of its own
|
||||
(the engine's conditions are exercised end to end); the crate's tests
|
||||
(`cargo test -p ledger-package`) keep the package over `Store` and
|
||||
`Snapshot` equal.
|
||||
- **ledger-gui:** `tests/view_model.rs` passes unchanged (the viewer's
|
||||
list is the engine's); `src/attention.rs`'s unit tests
|
||||
(`cash_flow_warnings_are_items`,
|
||||
`a_stale_rule_asks_for_the_authority_and_the_humans_confirmation`) move
|
||||
with it and pass; `tests/assets.rs`, `tests/attachments.rs`,
|
||||
`tests/edges.rs`, `tests/old_books.rs`, `tests/parties.rs`,
|
||||
`tests/spec_gui.rs` exercise the items through the viewer's wrapper.
|
||||
- **ledger-cli:** `tests/attention_parity.rs`
|
||||
`the_viewer_and_books_start_see_the_same_attention` (the demo books and a
|
||||
book written entry by entry: the viewer's titles, in order, are exactly
|
||||
`books.start`'s attention steps).
|
||||
- **unchanged:** `crates/ledger-cli/tests/spec_kept.rs`'s `books.start`
|
||||
tests (the fixed steps keep their order; attention items sit between the
|
||||
backup step and the focus).
|
||||
|
||||
**For P12 (mutation targets, none run, D-33):**
|
||||
`ledger-package attention`: `origin`'s arm order (a reversal before its
|
||||
schedule, a bill before its payment) and `entry_refs`' keys;
|
||||
`missing_receipt`'s conjunction (the `Journal entry | Recurring` origin,
|
||||
`reversal_of` none, no receipts, the policy); the `> 3` combine and its
|
||||
`try_fold`; `w9_missing`'s three clauses (no W-9, files a 1099, the vendor
|
||||
not marked on file) and `files_1099`'s `any`; `paid_this_year`'s `max`
|
||||
(today) and `min` (Dec 31) and its `paid - received`; `depreciation_due`'s
|
||||
`in_effect` filter, its `period_month` (`1..=12`) and its `!is_zero`;
|
||||
`period_month`'s split; the severity arms (undetermined 1099, refuse
|
||||
tax category, parties require); `dollars`' thousands grouping and its
|
||||
negative-zero test; `filter(|a| a.tool.is_some()).take(12)` and
|
||||
`step_title`'s 160-character cut in `start_out`; the viewer wrapper's
|
||||
`Target` arms.
|
||||
Reference in new issue
Block a user