merge: P6, the evidence pipeline (branch P6, checkpoint ce366408)
The last of the paused branches, from its "not for merge" checkpoint:
extraction in ledger-import (text, pages, page images; capped, caught),
journaled as attachment.text_extracted; dedup by hash with
books.find_attachment and books.consolidate_duplicates; annotations and
books.set_entry_settles; the company record categories; the two fuzz
targets; feature attachment_text. Nineteen files conflicted with the
four P4b merges, resolved as plan 8.0.2 says: P6 retakes schema 18 (it
had taken 16, which S4.3 holds; S5 holds 17); the tool table is 129 and
the destructive count 31; both sides' appends kept with their seams
restored; one B-27 paragraph naming every feature; in the old-books
fixture P6's hand-written reimbursement is entry 7 (its ids collided
with S4.3's invoice); the replay fuzzer's list gains S7's
invoice.written_off; S4.3's issued-PDF test expects the extraction
record P6 journals right after a filing.
One integration defect between S7 and P6, found by the arap property
test and fixed here: under P6's dedup, a write-off whose evidence bytes
were filed already (the same collection letter for a second write-off of
the same invoice) was refused only after its entry had been journaled,
at the final link to the invoice ("already linked"). The write-off now
resolves the dedup before anything is journaled and keeps a link the
record already has to the invoice instead of refusing it; an explicit
existing_attachment_id already on an entry is still refused (S7's
one-receipt-once rule). P6's gate never ran before the pause; it runs on
main after this merge, and its ledger-store -> ledger-import dependency
is the open review point (plan 8.0.1).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
This commit is contained in:
commit
2ad192bbcd
70 files changed
+4618
-384
No files matched your search
@@ -42,7 +42,7 @@ fn annotations_complete() {
|
||||
const D: Hints = (Some(false), Some(true), None);
|
||||
const WI: Hints = (Some(false), Some(false), Some(true));
|
||||
const DI: Hints = (Some(false), Some(true), Some(true));
|
||||
let table: [(&str, Hints); 125] = [
|
||||
let table: [(&str, Hints); 129] = [
|
||||
("books.handbook", R),
|
||||
("books.start", R),
|
||||
("books.set_setting", DI),
|
||||
@@ -164,6 +164,11 @@ fn annotations_complete() {
|
||||
("books.project", R),
|
||||
("books.profit_and_loss_by_class", R),
|
||||
("books.export_cpa_package", W),
|
||||
// P6: evidence (plan/served.md P6).
|
||||
("books.find_attachment", R),
|
||||
("books.annotate_attachment", W),
|
||||
("books.set_entry_settles", W),
|
||||
("books.consolidate_duplicates", D),
|
||||
("books.access_log", R),
|
||||
("books.backup", R),
|
||||
("books.back_up_now", WI),
|
||||
@@ -208,8 +213,8 @@ fn annotations_complete() {
|
||||
"{name}: openWorldHint"
|
||||
);
|
||||
}
|
||||
// docs/mcp-interface.md names the 30 destructive tools.
|
||||
assert_eq!(table.iter().filter(|(_, h)| h.1 == Some(true)).count(), 30);
|
||||
// docs/mcp-interface.md names the 31 destructive tools.
|
||||
assert_eq!(table.iter().filter(|(_, h)| h.1 == Some(true)).count(), 31);
|
||||
}
|
||||
|
||||
/// Every refusal an agent can be given whose text is fixed here, or
|
||||
@@ -472,6 +477,12 @@ fn no_tool_takes_a_path() {
|
||||
&mut props,
|
||||
);
|
||||
for p in props {
|
||||
// An annotation's `source` (plan P6 step 5) is what a human
|
||||
// says a receipt came from ("the owner's email"), kept as text
|
||||
// and never read as a place on this computer.
|
||||
if t.name == "books.annotate_attachment" && p == "source" {
|
||||
continue;
|
||||
}
|
||||
let lower = p.to_ascii_lowercase();
|
||||
// Names that hold a place to read or write: whole words,
|
||||
// so `link_to`, `*_file_name`, `tin_on_file` and `date_to`
|
||||
|
||||
Reference in new issue
Block a user