docs(architecture): name the ledger-mcp tool groups (U0a)

The layout paragraph the unit asks for: server.rs as the server, the
router and the request machinery; one tools/<group>.rs per tool group
with its router; tools/helpers.rs for the helpers several groups share;
server_tests.rs for the tests that span the surface and each group's own
tests in its file. plan/served.md's U0a "As built" block records the
split, the two departures (settings_tools as the module name, the test
bodies beside server.rs) and the stale 118-tool count (the surface is
122, identical to main's).
This commit is contained in:
swaits committed 2026-10-27 04:15:47 -06:00
1 parent 3cab75c494
commit 45396bdce8
2 files changed
+41 -1

No files matched your search

+40
View File
@@ -122,6 +122,46 @@ takes them whenever their last `settings.set` changes (on every lock of
the store), the viewer reads them from the journal it shows, and neither the store), the viewer reads them from the journal it shows, and neither
reads a file; "today" is the company's time zone's, set per request. Rule: `docs/spec/rules.md` B-29. reads a file; "today" is the company's time zone's, set per request. Rule: `docs/spec/rules.md` B-29.
## The MCP server's layout (`ledger-mcp`, P0; U0a)
`crates/ledger-mcp/src/server.rs` is the server itself: `BooksServer`, the
shared store and its lock, `call_tool` and `get_info` (the `ServerHandler`),
`tool_router`, the request machinery and the helpers that cross groups.
Tool handlers live one file per group in `crates/ledger-mcp/src/tools/`,
each declared with `#[path]`, opening with `use super::*`, and holding a
`#[tool_router(router = <group>_router, vis = "pub(super)")] impl
BooksServer`; `server.rs`'s `tool_router` adds every group's router. The
groups are:
- `documents` — invoices, bills, payments, voids, `books.documents`,
`books.document`, the control check and the agings;
- `entries` — `books.draft_entry`, `books.add_line`, `books.post_entry`,
`books.reverse_entry`, `books.get_entry`, `books.search_entries`, the
bank CSV import;
- `reports` — the statements, `books.show`, `books.verify`,
`books.digest`, `books.export`, the CPA package, the P&L by class, and
the export builders;
- `assets`, `schedules` (schedules and recurring), `periods`,
`reconciliation`, `payroll`, `payouts`, `tax`;
- `parties` — parties, vendors, customers, roles, W-9s, the TIN vault,
1099s, entry parties;
- `attachments` — receipts, filed documents, and their links;
- `settings` — the handbook, `books.settings` and the recorded FX rates
(the module is `settings_tools`, since `crate::settings` is the live
settings);
- `chart` — the chart of accounts, the template and CSV import, renaming
and renumbering, and the control roles;
plus the groups split earlier: `kept` (`books.start`, settings changes,
conventions, decisions, open items, posting templates, approvals),
`projects`, `files` (uploads), `instruments`, `access` and `backup`. A
helper only one group uses lives in that group's file; the ones several
groups share live in `tools/helpers.rs` and `server.rs` re-exports them,
so no group file reaches into another group's. The tests that span the
whole tool surface sit beside `server.rs` in `server_tests.rs`; a group's
own tests live in its group file. The split changed no tool's name,
description, annotations or behaviour.
## The MCP server's store lock (`ledger-mcp`, P0) ## The MCP server's store lock (`ledger-mcp`, P0)
One `Store` is shared by every session (`SharedStore`: a One `Store` is shared by every session (`SharedStore`: a
+1 -1
View File
@@ -1214,7 +1214,7 @@ Each unit follows the 8.0.4 template. "A-n" is an owner answer numbered in 8.3.1
5. **Files:** owns `crates/ledger-mcp/src/server.rs`, `crates/ledger-mcp/src/tools/*`; touches nothing else. 5. **Files:** owns `crates/ledger-mcp/src/server.rs`, `crates/ledger-mcp/src/tools/*`; touches nothing else.
6. **Tests and proofs:** no new tests; every existing test passes unchanged (`cargo test -p ledger-mcp`, `cargo test -p ledger-cli`). `every_tool_is_documented_and_every_documented_tool_exists`, `annotations_complete`, `tool_text_lint` and `tool_descriptions_fit_700_characters` prove the surface is identical. 6. **Tests and proofs:** no new tests; every existing test passes unchanged (`cargo test -p ledger-mcp`, `cargo test -p ledger-cli`). `every_tool_is_documented_and_every_documented_tool_exists`, `annotations_complete`, `tool_text_lint` and `tool_descriptions_fit_700_characters` prove the surface is identical.
7. **Done when:** (1) `server.rs` is under 3,000 lines and holds no `#[tool(..)]` handler that belongs to a group; (2) `BooksServer::tool_router().list_all()` names the same 118 tools, in the same order, with identical descriptions and annotations (write a one-off comparison against `main` in the PR and paste the result); (3) `just check` green; (4) the architecture doc names the groups. 7. **Done when:** (1) `server.rs` is under 3,000 lines and holds no `#[tool(..)]` handler that belongs to a group; (2) `BooksServer::tool_router().list_all()` names the same 118 tools, in the same order, with identical descriptions and annotations (write a one-off comparison against `main` in the PR and paste the result); (3) `just check` green; (4) the architecture doc names the groups.
8. **As built:** none yet. 8. **As built:** (2026-10-26, branch `U0a`) Build steps 1-3 as written. The 98 handlers `server.rs` still held moved to `tools/documents.rs`, `tools/entries.rs`, `tools/reports.rs`, `tools/assets.rs`, `tools/schedules.rs`, `tools/periods.rs`, `tools/reconciliation.rs`, `tools/parties.rs`, `tools/attachments.rs`, `tools/settings.rs`, `tools/chart.rs`, `tools/payroll.rs`, `tools/payouts.rs` and `tools/tax.rs`; `books.add_class` and `books.list_classes` joined the existing `tools/projects.rs` (a project is a class with its facts), and `books.handbook`, `books.settings` and `books.set_fx_rate` make up `settings.rs` (`books.verify` and `books.digest` are in `reports.rs`). `server.rs` is under 2,000 lines (1,909) and holds no `#[tool(..)]` handler; `tool_router` composes the group routers, and `core_router` is gone because `server.rs` has no tools left. The helpers only one group uses moved into that group's file; the ones several groups share moved to `tools/helpers.rs`, which `server.rs` re-exports (`pub(crate) use helpers::*;`), and `server.rs` keeps the named shared helpers (`as_of`, `hand_over`, `resolve_vendor`, `parse_doc_ref`, `preview_lines_for`) and the request machinery. Two departures: (1) `settings.rs` is the module `settings_tools`, because `crate::settings` already names the live settings; (2) the test bodies sit in `crates/ledger-mcp/src/server_tests.rs`, a `#[path]` module of `server.rs`, with their fixtures in `server::test_support`, and each group's own tests moved into its group file: `server.rs` keeps the tests module (and the cross-group ones are the server's) but reaches 3,000 lines only with the bodies beside it. Done-when 2's count is stale: the surface is 122 tools, not 118, and a one-off dump of every tool's name, title, description, input and output schema and annotations, in `list_all()` order, diffs empty against `main`'s.
#### U0b: the attention engine over `PackageBooks` #### U0b: the attention engine over `PackageBooks`