P2 slice 6: the viewer
`wanderbooks gui [BOOK]` finds the data root, reads settings from the journal, the vault of the book, presence through ops/, Save a copy / Open on every document, Save the W-9, the Export menu, and colour schemes. One builder for the CPA package and the 1099 worksheet (ledger-package), shared by the server and the viewer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3gXMVt7XJPi6ens1or9Dj
This commit is contained in:
1 parent
b26c099a68
commit
5bc0633cdd
77 files changed
+5833
-2427
No files matched your search
+78
-48
@@ -196,9 +196,10 @@ settings-and-conventions section says how to use them.
|
||||
in the data root, on a socket in the root's private `run/` folder that
|
||||
only this account can connect to. Every request carries a bearer token
|
||||
live for that book (refused 401 without one, 403 with another book's).
|
||||
Refusals at the door, tool calls, uploads and downloads are recorded
|
||||
in the book's access log; when a record can't be written the book
|
||||
stops taking requests (an upload or download is then refused, 503).
|
||||
Refusals at the door, tool calls, uploads, downloads and exports are
|
||||
recorded in the book's access log; when a record can't be written the
|
||||
book stops taking requests (an upload, download or export is then
|
||||
refused, 503).
|
||||
- `/b/{book}/mcp`: the book's MCP service. A request is at most 1 MiB.
|
||||
- `PUT /b/{book}/u/{upload}`: an upload's bytes (`books.begin_upload`),
|
||||
from the token that began it; what `wanderbooks upload --book B
|
||||
@@ -233,13 +234,25 @@ settings-and-conventions section says how to use them.
|
||||
(a HEAD is 405, unrecorded). Logged as
|
||||
action `download` with the attachment's id, a refusal at the door
|
||||
too.
|
||||
`wanderbooks download --book B [--token NAME] ATTACHMENT --to DIR`
|
||||
asks for it, checks the digest before saving, and saves it under the
|
||||
- `GET /b/{book}/x/{export}`: a file the books made for an agent (the
|
||||
CPA package, a 1099 worksheet, a W-9: a `HandedFile`, "Tools — the
|
||||
TIN vault"), as `/a/` (the same door, the same headers,
|
||||
`Repr-Digest` included, GET only), but only for the token it was made
|
||||
for (403 `not_yours`), with no scope of its own to check (the tool
|
||||
that made it checked its scope); 404 `no_such_export` (unknown or
|
||||
lapsed), 503 `stopped`. An export's id is `ex_` and 32 letters
|
||||
`a`-`p`; it is kept 15 minutes, fetched as often as wanted until
|
||||
then, at most 16 per token, and swept like uploads. Logged as action
|
||||
`export` with the export's id.
|
||||
- `wanderbooks download --book B [--token NAME] ID --to DIR` takes an
|
||||
attachment's id (a number, `/a/`) or an export's (`ex_…`, `/x/`),
|
||||
checks the digest before saving, and saves it under the
|
||||
server's name (`filename*` first) made plain: separators and control
|
||||
characters made `_`, invisible (Unicode format) characters and
|
||||
leading dots and spaces dropped, at most 200 bytes with the extension
|
||||
kept. Beside a file of that name it is `name (1).ext`, and so on;
|
||||
`attachment-N` if the folder takes no such name. It is written to a
|
||||
`attachment-<id>` or `export-<id>` if the folder takes no such name.
|
||||
It is written to a
|
||||
hidden file and hard-linked in: never a partial file under the real
|
||||
name, never over another file.
|
||||
|
||||
@@ -339,15 +352,19 @@ seals a new vault record, every time, so none carries it;
|
||||
`idempotent_tools_change_nothing_when_repeated` calls each candidate twice
|
||||
to check). Every tool's
|
||||
`openWorldHint` is false: the books are a closed world, and no tool
|
||||
reaches beyond them. `books.export_cpa_package` writes a file, so it is
|
||||
not read-only. No tool carries `requiresUserInteraction` (owner decision
|
||||
reaches beyond them. `books.export_cpa_package`, `books.vendor_1099`
|
||||
and `books.get_w9` keep a file for the agent (an export) and record the
|
||||
ones with TINs, so they are not read-only. No tool carries
|
||||
`requiresUserInteraction` (owner decision
|
||||
2026-10-16: no added prompts). `annotations_complete` pins all of this.
|
||||
The read-only hint is true in behaviour: `spec_mcp` checks, on every call,
|
||||
that a read-only tool leaves the journal, the contents of every file under
|
||||
the data dir (the database by every row of every table; SQLite's -wal and
|
||||
-shm files, which move pages and hold read marks on their own, aside),
|
||||
the vault and the settings file as they were
|
||||
(`read_only_tools_change_nothing`).
|
||||
(`read_only_tools_change_nothing`). `books.show` is read-only though it
|
||||
writes the viewer's request into the books' `ops/` folder: that folder
|
||||
is a side channel, never journaled, and moves only the view.
|
||||
|
||||
**Failing closed.** Tool bodies run on blocking threads, one at a time on
|
||||
the store. If a request panics (an internal error), the journal may hold a
|
||||
@@ -538,18 +555,23 @@ through the policy.
|
||||
|
||||
- `books.show { entry_id | account | report | attachment_id | asset |
|
||||
party | reconciliation | search | page, start?, end? }` → `{ shown,
|
||||
note }`. Asks the human's viewer (`ledger-gui`) to open an entry, an
|
||||
account register or a report (for start/end dates if given), a stored
|
||||
file, an asset, a party (by id or name, resolved as in "Tools —
|
||||
parties"), a reconciliation (by id: its account's page, with its
|
||||
statements and reconciliations; viewer target `{show: "reconciliation",
|
||||
id}`), a transactions search, or a page (`parties` among them). Exactly
|
||||
one target; entries, accounts, attachments, assets, parties, and
|
||||
reconciliations are checked to exist. Never touches the books: the request is a small JSON file in
|
||||
the user's runtime directory (`$XDG_RUNTIME_DIR/wanderbooks/viewer-<hash
|
||||
of the data dir>.json`), written atomically, watched by the viewer. A
|
||||
viewer started within two minutes of a request opens it; older requests
|
||||
are ignored.
|
||||
viewer_open, note }`. Asks the human's viewer (`ledger-gui`) to open an
|
||||
entry, an account register or a report (for start/end dates if given),
|
||||
a stored file, an asset, a party (by id or name, resolved as in "Tools
|
||||
— parties"), a reconciliation (by id: its account's page, with its
|
||||
statements and reconciliations; viewer target `{show:
|
||||
"reconciliation", id}`), a transactions search, or a page (`parties`
|
||||
among them). Exactly one target; entries, accounts, attachments,
|
||||
assets, parties, and reconciliations are checked to exist. Never
|
||||
journaled: the request is a line `{seq, at, target}` of the books' own
|
||||
`ops/show.jsonl` (at most 32 lines, replaced whole, so a reader sees
|
||||
each line whole), which the viewer reads and never writes. The server
|
||||
makes `ops/` and `ops/viewer.lock` when it opens the books (and on a
|
||||
request); the viewer holds a shared lock on `ops/viewer.lock`, through
|
||||
a read-only descriptor, while it has the books open, and
|
||||
`viewer_open` says whether one does. The note says "The viewer shows
|
||||
…", or "No viewer has these books open: ask the human to open it
|
||||
(opened within a couple of minutes, it shows …)".
|
||||
|
||||
## Tools — integrity
|
||||
|
||||
@@ -602,10 +624,10 @@ is on file and the TIN's last four; full TINs live only in the TIN vault
|
||||
is; tagging a vendor whose party isn't named, or clearing the tag while
|
||||
its party is named, is refused (drop or add the party with `parties`
|
||||
instead). An entry and its reversal always carry the same tags.
|
||||
- `books.vendor_1099 { year, threshold?, include_tins?, save_csv_to? }` →
|
||||
- `books.vendor_1099 { year, threshold?, include_tins?, csv? }` →
|
||||
`{ year, threshold, vendors: [{ vendor_id, name, form_1099?, tin_on_file,
|
||||
paid, reportable, party_id?, tin_last4?, tin?, tin_type?, tin_note? }],
|
||||
missing_w9, notes, warning?, saved_csv? }`. For a year whose threshold
|
||||
missing_w9, notes, warning?, csv? }`. For a year whose threshold
|
||||
wanderbooks doesn't know (after 2026 until the indexed amount is added)
|
||||
it refuses with what to do; pass `threshold` explicitly once the figure
|
||||
is confirmed. On an entry naming several parties, `paid` counts only
|
||||
@@ -616,10 +638,13 @@ is on file and the TIN's last four; full TINs live only in the TIN vault
|
||||
TIN formatted as the IRS writes it (123-45-6789; 12-3456789 for an
|
||||
EIN), and `tin_type`, read from the vault, or `tin_note` saying why not
|
||||
(not in the vault, the vault locked, a record whose last four or hash
|
||||
disagree with the books); `warning` then says the output holds full
|
||||
TINs, for the CPA only. This is the only tool output that ever holds a
|
||||
full TIN. `save_csv_to` also writes the worksheet as CSV (TINs only with
|
||||
`include_tins`) to a new file outside the books dir, mode 0600.
|
||||
disagree with the books); `warning` then says "This worksheet holds
|
||||
full TINs, for the CPA; keep it out of the books.". This is the only
|
||||
tool output that ever holds a full TIN. `csv: true` (default false)
|
||||
also hands the worksheet over as a CSV file, `csv` (a `HandedFile`,
|
||||
"Tools — the TIN vault"), named `1099-worksheet-<year>.csv`, or
|
||||
`1099-worksheet-<year>-with-tins.csv` with `include_tins` (TINs only
|
||||
then).
|
||||
|
||||
## Tools — parties
|
||||
|
||||
@@ -788,7 +813,8 @@ and the CPA package carries them.
|
||||
missing.
|
||||
- **Never out:** no tool output, error, or log holds more than a TIN's
|
||||
last four, except `books.vendor_1099 { include_tins: true }`; the CPA
|
||||
package carries them only in its zip, written outside the books dir.
|
||||
package carries them only in its zip, handed over as an export (or
|
||||
inline over stdio), never written to a path.
|
||||
The tool arguments that take a TIN never echo it, even when refused.
|
||||
- **TIN facts:** any party (any role) may have `tin` facts:
|
||||
`{ tin_type: "ssn" | "ein" | "itin", last4, vault_record?, purged? }`,
|
||||
@@ -822,15 +848,19 @@ and the CPA package carries them.
|
||||
and are refused when they don't (pass the new TIN, or purge). Clearing
|
||||
the facts (`clear: true`) is refused while the vault holds the party's
|
||||
TIN or form: purge first.
|
||||
- `books.get_w9 { party, save_to }` → `{ party_id, path, file_name,
|
||||
size_bytes, note }`. Writes the party's form from the vault to
|
||||
`save_to`: a new file (an existing one is refused), in a folder that
|
||||
exists, outside the books dir (where it really leads, every link
|
||||
followed), mode 0600. Returns the path, never the contents. Journals
|
||||
nothing. The same holds for `books.vendor_1099`'s `save_csv_to` with
|
||||
`include_tins` and `books.export_cpa_package`'s `save_to` with TINs: a
|
||||
file with full TINs never lands inside the books. Nor does one go in
|
||||
from elsewhere: the server keeps, beside the vault, the SHA-256 of every
|
||||
- `books.get_w9 { party }` → `{ party_id, file }`: the party's form from
|
||||
the vault, handed over. Journals nothing.
|
||||
- **Handed files** (D-29): no tool takes a path. A file the books make
|
||||
for an agent (`books.get_w9`'s form, `books.vendor_1099`'s `csv`,
|
||||
`books.export_cpa_package`'s zip) comes back as a `HandedFile {
|
||||
file_name, mime_type, size_bytes, sha256, download?, expires_at?,
|
||||
content_base64? }`. On books served by `wanderbooks mcp` it is an
|
||||
export, kept 15 minutes for the token that asked (at most 16 per
|
||||
token, swept like uploads), and `download` is the command that saves
|
||||
it in a folder the human names: `wanderbooks download --book B
|
||||
[--token NAME] ex_… --to <a folder>` (`GET /b/{book}/x/{export}`,
|
||||
"Transports"). Over stdio it comes back inline as `content_base64`.
|
||||
A file with full TINs never goes into the books: the server keeps, beside the vault, the SHA-256 of every
|
||||
file it read or wrote with full TINs (the W-9 `books.set_w9` reads,
|
||||
recorded once the call has passed every check, just before the vault
|
||||
keeps it, so a refused call marks no file; each of these outputs; each
|
||||
@@ -852,8 +882,7 @@ and the CPA package carries them.
|
||||
the same words whether or not one is that TIN, so the vault is compared
|
||||
against at most two candidates a filing (rules.md B-26). An altered copy
|
||||
of a binary file (a W-9 PDF re-saved or re-scanned), and a TIN the vault
|
||||
doesn't hold written another way, are not detected: P2 slice 6 moves the
|
||||
TIN outputs (`save_to`, `save_csv_to`) to the viewer, and P7 takes full
|
||||
doesn't hold written another way, are not detected: P7 takes full
|
||||
TINs out of the agent's reach.
|
||||
- `books.purge_tin { party, reason, confirmed? }` → `{ status: "preview" |
|
||||
"purged", party_id, name, tin_in_vault, w9_file_in_vault, tin_last4?,
|
||||
@@ -1283,8 +1312,9 @@ entries.
|
||||
## Tools — CPA handoff
|
||||
|
||||
- `books.export_cpa_package { as_of?, cash_accounts?, financing_accounts?,
|
||||
investing_accounts?, include_receipts?, include_tins?, save_to? }` →
|
||||
`{ file_name, content_base64?, saved_to?, tins_included, tin_gaps, note }`.
|
||||
investing_accounts?, include_receipts?, include_tins? }` → `{ file,
|
||||
tins_included, tin_gaps, note }`: the zip, `cpa-package-<as_of>.zip`,
|
||||
handed over as `file` (a `HandedFile`, "Tools — the TIN vault").
|
||||
**Receipts** (`include_receipts`, default true): `receipts/` holds every
|
||||
current file behind each posted entry of the fiscal year to date, filed
|
||||
on it or linked to it (`books.link_attachment`; a linked file counts as
|
||||
@@ -1293,16 +1323,16 @@ entries.
|
||||
entry, receipts excepted.
|
||||
**TINs** (`include_tins`, default true; DECISION, the owner, 2026-10-15):
|
||||
the K-1 worksheet and the 1099 worksheet carry every member's and
|
||||
payee's full TIN from the vault, so the zip is written to `save_to` (a
|
||||
new `.zip` path, or an existing folder it goes in as
|
||||
`cpa-package-<as_of>.zip`; outside the books dir, `exports/` included;
|
||||
mode 0600) and the output is its path, never its bytes; without
|
||||
`save_to` it is refused. A locked vault or a missing TIN never fails the
|
||||
payee's full TIN from the vault; the zip, and each file in it with a
|
||||
TIN, is recorded so that, given back to be filed, it is refused. A
|
||||
locked vault or a missing TIN never fails the
|
||||
package: the row says why ("TIN not in the vault", "the TIN vault is
|
||||
locked", a record that disagrees with the books), the README lists it,
|
||||
and `tin_gaps` names each member and each reportable payee without one.
|
||||
`include_tins: false`: last fours only, returned as `content_base64`
|
||||
unless `save_to` is given. **K-1 worksheet** (`k1-members.csv`, with
|
||||
`include_tins: false`: last fours only. `note` is "The package, with
|
||||
last fours only.", or "The package, with full TINs, for the CPA.",
|
||||
followed, with gaps, by "N TIN(s) are missing (tin_gaps): collect them
|
||||
with books.set_tin or books.set_w9 and export again." **K-1 worksheet** (`k1-members.csv`, with
|
||||
`[[company.members]]`): one row per member, in order: `member,
|
||||
party_id, share, capital_account, tin, tin_type, tin_note` (without
|
||||
TINs: `tin_last4, tin_type`), then `beginning_capital,
|
||||
|
||||
@@ -234,8 +234,9 @@ damn CPA package."
|
||||
|
||||
- **Where:** `vault/` in the books dir, listed in `.gitignore`. Never in
|
||||
the hash-chained journal, the SQLite projection, git, an export other
|
||||
than the 1099 worksheet and the CPA package (saved outside the books
|
||||
dir), or anything the viewer draws. Nothing outside the vault holds
|
||||
than the 1099 worksheet and the CPA package (handed to the agent as a
|
||||
file to download, never saved in the books), or anything the viewer
|
||||
draws. Nothing outside the vault holds
|
||||
more than the last four digits.
|
||||
- **Who:** any party, whatever its roles: every member (their K-1 needs
|
||||
it) and every 1099 payee. The books keep the party's TIN facts (type,
|
||||
@@ -267,8 +268,9 @@ damn CPA package."
|
||||
- **Use:** `books.vendor_1099` with `include_tins: true` and
|
||||
`books.export_cpa_package` (its K-1 worksheet, `k1-members.csv`, and its
|
||||
1099 worksheet; `include_tins` defaults to true there) decrypt them.
|
||||
The package is written only to `save_to`, outside the books dir, and
|
||||
the tool returns its path; it is refused without one. The MCP server
|
||||
The package is handed over as a file (an export the asking token
|
||||
fetches with `wanderbooks download`, or inline over stdio); no tool
|
||||
takes a path. The MCP server
|
||||
never returns a TIN in any other tool, log, or error. Tests check that
|
||||
no other output contains a nine-digit run.
|
||||
- **Books without a vault** (another machine, a restored backup) still
|
||||
@@ -284,16 +286,16 @@ damn CPA package."
|
||||
{party, tin, tin_type}` stores any party's TIN (a member's SSN, say) the
|
||||
same way and journals `party.tin_set`; a party whose W-9 facts name
|
||||
another last four is refused (a payee's new TIN comes with its W-9).
|
||||
`books.get_w9 {party, save_to}` writes the form to a new file outside the
|
||||
books dir and returns only the path. `books.purge_tin {party, reason,
|
||||
`books.get_w9 {party}` hands the form over the same way.
|
||||
`books.purge_tin {party, reason,
|
||||
confirmed?}` previews, then deletes the records (no key needed) and
|
||||
journals the purge as `party.w9_set` with `vault_record` cleared and
|
||||
`kept_at` saying when and why, and `party.tin_set` with `vault_record`
|
||||
cleared and `purged` saying when and why. `books.vendor_1099 {include_tins: true}`
|
||||
is the one tool output with full TINs (with a warning; `save_csv_to`
|
||||
writes the CSV outside the books dir); `books.export_cpa_package
|
||||
{save_to}` writes them in its zip, outside the books dir, and returns
|
||||
only the path. A key file inside the books dir is
|
||||
is the one tool output with full TINs (with a warning; `csv: true`
|
||||
also hands the worksheet over as a CSV file);
|
||||
`books.export_cpa_package` carries them in its zip, handed over the
|
||||
same way. A key file inside the books dir is
|
||||
refused. `tests/spec_vault.rs` scans every tool response, the server's
|
||||
log, and every file in the books dir outside `vault/` for the TINs in
|
||||
any formatting.
|
||||
|
||||
+9
-7
@@ -581,13 +581,15 @@ with `include_tins` (DECISION, the owner, 2026-10-15: for the CPA, when
|
||||
asked): a refusal that quotes its input masks any TIN in it
|
||||
(`parties::redact_full_tins`, checked by `refusals_never_echo_a_tin`),
|
||||
and a party text field refuses nine digits however they are separated
|
||||
(space, hyphen, dot, slash, underscore; `has_full_tin`). Files holding one (`books.get_w9`, `save_csv_to`, and the CPA
|
||||
package, whose K-1 and 1099 worksheets carry every member's and payee's
|
||||
TIN by default) are written only outside the books dir (DECISION, P0
|
||||
review, 2026-10-16: so none can be filed back in as a receipt and read
|
||||
out again; the server's import folders, refused then too, went with
|
||||
`books.import_local_file` in P2 slice 5), and the package comes back
|
||||
only as its path. No file holding a full TIN is filed into the books
|
||||
(space, hyphen, dot, slash, underscore; `has_full_tin`). Files holding one (`books.get_w9`, `books.vendor_1099`'s
|
||||
`csv` with `include_tins`, and the CPA package, whose K-1 and 1099
|
||||
worksheets carry every member's and payee's TIN by default) are never
|
||||
written to a path: no tool takes one (D-29, P2 slice 6). Each is handed
|
||||
over as an export the asking token fetches with `wanderbooks download`
|
||||
(kept 15 minutes), or inline over stdio. (Until slice 6 they were
|
||||
written only outside the books dir: DECISION, P0 review, 2026-10-16, so
|
||||
none could be filed back in as a receipt and read out again.) No file
|
||||
holding a full TIN is filed into the books
|
||||
(DECISION, P0 review round 2, 2026-10-16): the server keeps, beside the
|
||||
vault, the SHA-256 of every file it read or wrote with full TINs (the W-9
|
||||
`books.set_w9` reads, recorded once the call has passed every check, just
|
||||
|
||||
+6
-4
@@ -68,12 +68,12 @@ that would fail if it broke:
|
||||
| UTF-16 text without a byte-order mark is scanned like any text; a refused `books.set_w9` marks no file; a refused resource read never echoes a TIN | `tin_files.rs` (tests) `utf16_text_without_a_byte_order_mark_is_scanned_either_way_round`, `a_refused_set_w9_never_marks_its_file`, unit test `only_nul_interleaved_bytes_read_as_utf16_without_a_mark`; `spec_vault.rs` `resource_refusals_never_echo_a_tin` |
|
||||
| idempotentHint only where a repeat with the same arguments leaves the journal and the vault as they were; every tool's hints pinned in one table | `spec_vault.rs` `idempotent_tools_change_nothing_when_repeated`; `annotations_complete` |
|
||||
| books.settings lists every receipt-required and exempt account, uncut; a fresh company is "a new company"; the lint catches `just` however it ends and where the books are | `mcp_stdio.rs` `every_receipt_account_left_out_of_the_connect_text_is_in_books_settings`; `handbook.rs` `a_fresh_company_is_a_new_company`; `tool_text_lint_catches_helpers_and_locations` |
|
||||
| A file with full TINs is never written inside the books, and never filed into the books: every file the server read or wrote with TINs (from any session, after a restart, out of a CPA package), by every filing tool | `mcp_stdio.rs` `tin_bearing_files_never_land_where_they_could_be_filed_back_in`; `tin_files.rs` (tests) `a_tin_bearing_file_is_refused_from_every_session_and_after_a_restart`; unit test `a_recorded_tin_file_is_refused_by_every_reader_of_the_registry` |
|
||||
| A file with full TINs is never written to a path (handed over instead, D-29), and never filed into the books: every file the server read or wrote with TINs (from any session, after a restart, out of a CPA package), by every filing tool | `mcp_stdio.rs` `tin_bearing_files_are_refused_when_given_back_to_be_filed`; `spec_vault.rs` `a_package_is_handed_over_and_never_written`; `tin_files.rs` (tests) `a_tin_bearing_file_is_refused_from_every_session_and_after_a_restart`; unit test `a_recorded_tin_file_is_refused_by_every_reader_of_the_registry` |
|
||||
| Text filed into the books is refused when it holds a TIN the vault keeps (nine digits, 3-2-4 by hyphen, space or dot, 2-7 by hyphen or space, anywhere) or a stand-alone printed SSN or EIN (123-45-6789, 12-3456789), and only then: a bank export (routing numbers, long references, a date next to an amount) and a longer number holding an SSN shape go in; a locked vault leaves the printed shapes (rules.md B-26) | `tin_files.rs` (tests) `text_with_a_vault_tin_or_a_printed_one_is_refused_and_a_bank_export_is_not`; unit tests `text_holding_a_vault_tin_is_refused_in_every_rendering`, `a_printed_ssn_or_ein_is_refused`, `a_longer_number_holding_a_tin_shape_passes`, `an_ordinary_bank_export_passes`, `binary_bytes_are_not_scanned` |
|
||||
| Filing is no TIN oracle: text with more than two TIN-shaped numbers ending in a known TIN's last four (the books' TIN and W-9 facts, then the vault's own) is refused before the vault is opened, byte for byte alike whether one is the vault's TIN or none is, the vault open or locked, by every filing tool; one or two such numbers are compared against the vault, one number written many ways counts once, and other last fours never count (rules.md B-26) | `tin_files.rs` (tests) `text_probing_for_a_tin_is_refused_alike_by_every_filing_tool`; unit tests `text_probing_for_a_tin_is_refused_alike_whether_or_not_it_holds_it` (the vault never opened for a probe), `one_or_two_candidates_are_compared_against_the_vault` |
|
||||
| The connect text fits its budgets, its lead stands alone, it states the receipt rule enforced (exact threshold in the base currency, required and exempt accounts, reversals) and the parties rule in force, and the company name can't break it (control and format characters) | `handbook.rs` `instructions_budget`, `a_typical_company_gets_the_whole_connect_text`, `the_company_name_is_one_plain_line`; `receipt_policy.rs` `the_rule_told_is_the_rule_enforced`, `a_long_or_odd_account_list_stays_short_and_plain`; a new session is told the settings in force: `a_new_session_is_told_the_settings_in_force` |
|
||||
| No text the agent is given (whole tool JSON, resources, connect text, handbook, every error template and refusal) points at files, git, GitHub, repo docs, flags or helper commands; descriptions fit 700 characters (listed exceptions, P5) | `tool_text_lint`, `tool_descriptions_fit_700_characters`; `ledger-core` `an_unknown_year_threshold_is_never_guessed` |
|
||||
| Every tool is annotated (openWorldHint false on all), and the read-only hint is true in behaviour (journal, every data-dir file's contents, the database's rows, the vault and the settings unchanged) | `annotations_complete`; `spec_mcp.rs` `read_only_tools_change_nothing` (checked on every call in `Mcp::tool`) |
|
||||
| Every tool is annotated (openWorldHint false on all), and the read-only hint is true in behaviour (journal, every data-dir file's contents but `ops/`, the viewer's side channel for `books.show`, which is not the books; the database's rows, the vault and the settings unchanged) | `annotations_complete`; `spec_mcp.rs` `read_only_tools_change_nothing` (checked on every call in `Mcp::tool`) |
|
||||
| A bare (or empty-`since`) digest covers this month so far, on any day of it, as the server counts it (the stdio test reads the server's own month, and starts over if it turns) | `a_bare_digest_covers_this_month_so_far`; `mcp_stdio.rs` `digest_resource_bare_reads` |
|
||||
| The handbook: every section, "all" in order, the schema names every id | `handbook_sections_render_the_rule_in_force`, `the_whole_handbook_is_every_section_in_order`, `mcp_stdio.rs` `handbook_tool_and_resources_over_stdio` |
|
||||
|
||||
@@ -121,8 +121,10 @@ broke, removed by simpler code, or is equivalent:
|
||||
(`resolved_follows_forty_links_and_no_more`). A file is saved only to
|
||||
a new file in a folder that exists, and a missing folder or a taken
|
||||
file is refused as such, never as a failed write
|
||||
(`a_package_goes_only_to_a_new_file_in_a_folder_that_exists`,
|
||||
`the_w9_file_goes_to_the_vault_never_the_documents`). The CPA package
|
||||
(a CPA package test, and
|
||||
`the_w9_file_goes_to_the_vault_never_the_documents`; P2 slice 6 took
|
||||
the paths out of the tools, and the package test with them). The CPA
|
||||
package
|
||||
marks only its own TIN files: a statement it carries still goes in
|
||||
afterwards (`a_tin_bearing_file_is_refused_from_every_session_and_after_a_restart`).
|
||||
An unreadable TIN-file registry refuses every file
|
||||
|
||||
Reference in new issue
Block a user