merge: P10, the re-audit runbook and its CI mirror (branch P10, 7fe8570a)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
This commit is contained in:
commit
5d49fe8f0d
4 files changed
+485
-1
No files matched your search
@@ -0,0 +1,265 @@
|
||||
//! The re-audit's engineering mirror (plan P10; `docs/runbooks/re-audit.md`):
|
||||
//! every defect the 2026-10-16 audit found (1 to 20), P0 (21, 22) and P3
|
||||
//! (23, 24) has a named regression test somewhere in the workspace, and the
|
||||
//! runbook names only tools and commands that exist.
|
||||
//!
|
||||
//! The list below is the single place that says which test stands guard for
|
||||
//! which defect. A test renamed or deleted fails here, so a defect's
|
||||
//! reproduction cannot be lost quietly. This proves the tests exist, are
|
||||
//! real `#[test]`s and are not ignored; that they pass is `cargo test`'s
|
||||
//! job (the runbook's step 4 runs them by name).
|
||||
//!
|
||||
//! SOURCE: plan/served.md 8.0 ("defect n") and P10 step 2.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn root() -> PathBuf {
|
||||
Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../..")
|
||||
.canonicalize()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn read(rel: &str) -> String {
|
||||
std::fs::read_to_string(root().join(rel)).unwrap_or_else(|e| panic!("{rel}: {e}"))
|
||||
}
|
||||
|
||||
/// `(defect, test name, file)`. Defect 2 is closed by D-12 and D-47 (the
|
||||
/// rule it now shows is that a reversal needs no receipt of its own);
|
||||
/// defect 20 (the migration scripts) was retired at the cutover and is
|
||||
/// checked separately below.
|
||||
const DEFECTS: [(u32, &str, &str); 23] = [
|
||||
(
|
||||
1,
|
||||
"defect1_two_member_llc_first_year_regression",
|
||||
"crates/ledger-core/tests/spec_cash_flow.rs",
|
||||
),
|
||||
(
|
||||
2,
|
||||
"a_reversal_needs_no_receipt_of_its_own",
|
||||
"crates/ledger-cli/tests/drafts.rs",
|
||||
),
|
||||
(
|
||||
3,
|
||||
"get_receipt_default_has_text_and_no_bytes",
|
||||
"crates/ledger-cli/tests/evidence.rs",
|
||||
),
|
||||
(
|
||||
4,
|
||||
"same_bytes_one_record_many_links",
|
||||
"crates/ledger-store/tests/attachments.rs",
|
||||
),
|
||||
(
|
||||
5,
|
||||
"a_draft_waits_for_its_receipt_and_posts",
|
||||
"crates/ledger-cli/tests/drafts.rs",
|
||||
),
|
||||
(
|
||||
6,
|
||||
"digest_since_seq_is_posting_time",
|
||||
"crates/ledger-cli/tests/drafts.rs",
|
||||
),
|
||||
(
|
||||
7,
|
||||
"the_readme_lists_what_the_iif_writes_differently",
|
||||
"crates/ledger-package/tests/package.rs",
|
||||
),
|
||||
(
|
||||
8,
|
||||
"add_account_warns_without_tax_category_defect_8",
|
||||
"crates/ledger-cli/tests/spec_tax_policy.rs",
|
||||
),
|
||||
(
|
||||
9,
|
||||
"defect9_a_new_schedule_spreads_by_the_day",
|
||||
"crates/ledger-core/tests/schedules.rs",
|
||||
),
|
||||
(
|
||||
10,
|
||||
"annotations_replay_and_project",
|
||||
"crates/ledger-store/tests/attachments.rs",
|
||||
),
|
||||
(
|
||||
11,
|
||||
"defect11_the_directory_shows_a_members_tin_last4",
|
||||
"crates/ledger-cli/tests/spec_vault.rs",
|
||||
),
|
||||
(
|
||||
12,
|
||||
"payment_methods_round_trip_and_classify_payments",
|
||||
"crates/ledger-cli/tests/spec_1099.rs",
|
||||
),
|
||||
(
|
||||
13,
|
||||
"four_contributed_devices_each_take_the_lower_of_value_and_basis",
|
||||
"crates/ledger-core/tests/spec_asset_basis.rs",
|
||||
),
|
||||
(
|
||||
14,
|
||||
"defect14_party_totals_take_a_basis",
|
||||
"crates/ledger-cli/tests/spec_party_totals.rs",
|
||||
),
|
||||
(
|
||||
15,
|
||||
"rename_account_end_to_end_defect_15",
|
||||
"crates/ledger-cli/tests/mcp_journeys.rs",
|
||||
),
|
||||
(
|
||||
16,
|
||||
"one_default_period_everywhere_defect_16",
|
||||
"crates/ledger-cli/tests/mcp_journeys.rs",
|
||||
),
|
||||
(
|
||||
17,
|
||||
"the_audit_odd_cent_never_piles_up_across_closes",
|
||||
"crates/ledger-core/tests/odd_cent.rs",
|
||||
),
|
||||
(
|
||||
18,
|
||||
"undecided_is_not_not_reportable",
|
||||
"crates/ledger-core/tests/form1099.rs",
|
||||
),
|
||||
(
|
||||
19,
|
||||
"no_tool_takes_a_path",
|
||||
"crates/ledger-mcp/src/server_tests.rs",
|
||||
),
|
||||
(
|
||||
21,
|
||||
"as_of_package_iif_stops_at_as_of",
|
||||
"crates/ledger-package/tests/package.rs",
|
||||
),
|
||||
(
|
||||
22,
|
||||
"defect22_depreciation_through_mid_final_month_is_prorated_not_plugged",
|
||||
"crates/ledger-core/tests/spec_assets_payroll.rs",
|
||||
),
|
||||
(
|
||||
23,
|
||||
"a_vendor_marked_no_1099_is_not_undecided",
|
||||
"crates/ledger-cli/tests/spec_1099.rs",
|
||||
),
|
||||
(
|
||||
24,
|
||||
"defect24_an_accrual_through_another_liability_counts_once",
|
||||
"crates/ledger-core/tests/spec_party_totals.rs",
|
||||
),
|
||||
];
|
||||
|
||||
/// Defects 1 to 24 each have a named test that exists, is a test, and is
|
||||
/// not ignored (defect 20 is the retired scripts, below).
|
||||
#[test]
|
||||
fn every_defect_reproduction_is_a_named_test() {
|
||||
let mut covered: Vec<u32> = DEFECTS.iter().map(|d| d.0).collect();
|
||||
covered.push(20);
|
||||
covered.sort_unstable();
|
||||
assert_eq!(
|
||||
covered,
|
||||
(1..=24).collect::<Vec<u32>>(),
|
||||
"a defect is missing"
|
||||
);
|
||||
|
||||
let mut missing = Vec::new();
|
||||
for (defect, name, file) in DEFECTS {
|
||||
let text = read(file);
|
||||
let lines: Vec<&str> = text.lines().collect();
|
||||
let needle = format!("fn {name}(");
|
||||
let Some(at) = lines.iter().position(|l| {
|
||||
l.trim_start().starts_with(&needle)
|
||||
|| l.trim_start().starts_with(&format!("pub {needle}"))
|
||||
}) else {
|
||||
missing.push(format!("defect {defect}: no `fn {name}` in {file}"));
|
||||
continue;
|
||||
};
|
||||
// The attributes and doc lines above the function, up to the
|
||||
// previous blank line or item.
|
||||
let above: String = lines[at.saturating_sub(8)..at].join("\n");
|
||||
let in_proptest = text.contains("proptest!");
|
||||
if !above.contains("#[test]") && !in_proptest {
|
||||
missing.push(format!(
|
||||
"defect {defect}: `{name}` in {file} is not a #[test]"
|
||||
));
|
||||
}
|
||||
if above.contains("#[ignore") {
|
||||
missing.push(format!("defect {defect}: `{name}` in {file} is ignored"));
|
||||
}
|
||||
}
|
||||
assert!(missing.is_empty(), "{}", missing.join("\n"));
|
||||
}
|
||||
|
||||
/// Defect 20, the migration scripts, was retired at the cutover: there is
|
||||
/// no tool for them, and none may come back as a way past the journal.
|
||||
/// The defect 19 mirror (`import_local_file` and every path parameter) is
|
||||
/// `no_tool_takes_a_path` above.
|
||||
#[test]
|
||||
fn defect_20_no_migration_tool_exists() {
|
||||
let scopes = read("crates/ledger-mcp/src/scopes.rs");
|
||||
for line in scopes.lines().filter(|l| l.contains("(\"books.")) {
|
||||
for banned in [
|
||||
"migrate",
|
||||
"import_local_file",
|
||||
"import_sheet",
|
||||
"verify_sheet",
|
||||
] {
|
||||
assert!(!line.contains(banned), "a retired tool is back: {line}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The runbook names only tools and commands that exist: each
|
||||
/// `books.<name>` is in the scopes table (the 8.0.3 list of tools), each
|
||||
/// `wanderbooks <command>` is a command `main.rs` dispatches, and each
|
||||
/// test file it names is a file.
|
||||
#[test]
|
||||
fn the_re_audit_runbook_names_only_what_exists() {
|
||||
let runbook = read("docs/runbooks/re-audit.md");
|
||||
let scopes = read("crates/ledger-mcp/src/scopes.rs");
|
||||
let main = read("crates/ledger-cli/src/main.rs");
|
||||
|
||||
let mut tools = Vec::new();
|
||||
let mut rest = runbook.as_str();
|
||||
while let Some(i) = rest.find("books.") {
|
||||
let tail = &rest[i..];
|
||||
let end = tail
|
||||
.find(|c: char| !(c.is_ascii_alphanumeric() || c == '_' || c == '.'))
|
||||
.unwrap_or(tail.len());
|
||||
let name = tail[..end].trim_end_matches('.');
|
||||
// Prose such as "books.start's" ends at the apostrophe; a bare
|
||||
// "books." (the company's books followed by a full stop) is not a name.
|
||||
if name.len() > "books.".len() && !tools.contains(&name.to_string()) {
|
||||
tools.push(name.to_string());
|
||||
}
|
||||
rest = &tail[end.max(1)..];
|
||||
}
|
||||
assert!(
|
||||
tools.len() > 20,
|
||||
"the runbook should name its tools: {tools:?}"
|
||||
);
|
||||
let unknown: Vec<&String> = tools
|
||||
.iter()
|
||||
.filter(|t| !scopes.contains(&format!("(\"{t}\"")))
|
||||
.collect();
|
||||
assert!(
|
||||
unknown.is_empty(),
|
||||
"tools the runbook names that do not exist: {unknown:?}"
|
||||
);
|
||||
|
||||
for cmd in ["gui", "connect"] {
|
||||
if runbook.contains(&format!("wanderbooks {cmd}")) {
|
||||
assert!(main.contains(&format!("\"{cmd}\"")), "no command {cmd}");
|
||||
}
|
||||
}
|
||||
assert!(
|
||||
runbook.contains("wanderbooks gui"),
|
||||
"step 6 names the viewer"
|
||||
);
|
||||
|
||||
for step in 1..=8 {
|
||||
assert!(
|
||||
runbook.contains(&format!("## Step {step}.")),
|
||||
"the runbook lost step {step}"
|
||||
);
|
||||
}
|
||||
// The runbook must not point at the data root or tell anyone to read it.
|
||||
assert!(!runbook.contains("wanderbooks.v"), "names a database file");
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
# The re-audit, through the MCP alone
|
||||
|
||||
The owner's acceptance of the whole programme (plan/served.md, P10). An
|
||||
agent audits a company's books using only the books tools, the books' own
|
||||
filed documents and the viewer's Export menu. Nothing here reads the data
|
||||
root, a database file or the journal file. The engineering mirror of this
|
||||
runbook is `crates/ledger-cli/tests/defects.rs` (every tool named below
|
||||
exists; every defect has a named regression test); the run itself is the
|
||||
owner's, on the owner's books.
|
||||
|
||||
Money is a decimal string everywhere. Every tool named is a tool in
|
||||
`books.start`'s list; if one is missing, stop: the runbook is stale, not
|
||||
the books.
|
||||
|
||||
## Before you start
|
||||
|
||||
- Two roles. The **auditor** runs `books.audit`, reads, and proposes fixes.
|
||||
The **verifiers** (at least two agents, not the auditor, not whoever made
|
||||
the entry) attest. The human confirms every correction.
|
||||
- The bar is `policy.attestation_bar` (default `effort=high verifiers=2
|
||||
adversarial=true`, D-9). Read it with `books.settings`. A verifier's
|
||||
`method` is its own claim, said truthfully: `{ model, reasoning_effort,
|
||||
adversarial, verifier_agents }`. A reading that differs from the entry is
|
||||
recorded with `disagrees: true` and never counts; never bend a reading to
|
||||
fit.
|
||||
- Context discipline. A receipt is read as text first
|
||||
(`books.get_receipt`, the default `meta` view is under 8 KiB, `view:
|
||||
"text"` gives the whole text), as one page picture (`view: "page_image"`,
|
||||
`page`, `max_px`) only when the text is empty or looks wrong, and never as
|
||||
`bytes`. Record each verifier's own token count for receipts; the exit
|
||||
bar is under 100K tokens per verifier.
|
||||
- Start with `books.start` (rules, conventions, open items, its `next_steps`)
|
||||
and `books.handbook` section `attestations-and-audit`. The `audit` prompt
|
||||
(`scope`: `month`, `annual`, `cpa_handoff` or `full`) is the same
|
||||
procedure for a client that offers prompts.
|
||||
- Audits and attestations need the books' `audits` feature (the owner's
|
||||
format upgrade). Without it the tools refuse with `format_upgrade_pending`:
|
||||
do the upgrade first, as its own step, with the owner.
|
||||
|
||||
## The two cases
|
||||
|
||||
- **T1, desktop only.** Claude Code and Codex on the owner's machine, through
|
||||
`wanderbooks connect`. Separation between the agent and the data root is
|
||||
advisory. The evidence that it held is the access log
|
||||
(`books.access_log`, `books:admin`) and the agents' transcripts, which never
|
||||
name the data root or a path into it.
|
||||
- **T2, a self-host machine running** (D-30, D-31; `deploy/README.md`). The
|
||||
same steps, plus claude.ai through the tunnel once P9b exists. Separation
|
||||
is enforced by the machine's account split. Until P9b, T2 is T1 with the
|
||||
server on its own machine.
|
||||
|
||||
The steps are identical; only the evidence in step 8 differs.
|
||||
|
||||
## Step 1. The first audit and its fixes
|
||||
|
||||
1. `books.audit { scope: "full", through: <the last month end> }` without
|
||||
`confirmed`: it lists the checks and changes nothing. Show the human.
|
||||
Then run it with `confirmed: true` and the `preview` digest. Do the same
|
||||
for `{ scope: "cpa_handoff", through: <the fiscal year end> }`.
|
||||
2. `books.workpaper { id }` for each run: the findings and the PDF as filed.
|
||||
3. Fix every finding through journaled corrections, never an edit:
|
||||
- a wrong posted entry: `books.reverse_entry { entry_id, date,
|
||||
description }`, previewed, then `confirmed: true`; then the right entry
|
||||
through `books.draft_entry`, `books.add_line`, `books.post_entry`
|
||||
(preview, then `confirmed`);
|
||||
- a reversal with no receipt of its own (an old one, `legacy_reversal_exempt`):
|
||||
its evidence is its original's (D-12, D-47). Link the original's receipt
|
||||
to the reversal with `books.link_attachment { attachment_id, subject }`;
|
||||
`books.list_receipts { entry_id }` finds the receipt;
|
||||
- a duplicate file: `books.consolidate_duplicates` (preview, then
|
||||
`confirmed`); `books.find_attachment` to look one up by hash or number;
|
||||
- a receipt's facts: `books.annotate_attachment`;
|
||||
- an open draft: post it, or `books.discard_draft { reason }`;
|
||||
- an undecided 1099 vendor: `books.set_vendor_1099`;
|
||||
- a missing tax category: `books.set_tax_category`;
|
||||
- a judgment the books should remember: `books.record_decision`.
|
||||
Nothing is fixed without the human's confirmation.
|
||||
4. Audit again at the new head. An audit is idempotent on the same books
|
||||
(`already_run`), so a new run means the books changed. Repeat until the
|
||||
`full` and `cpa_handoff` runs have no error findings; keep the final two
|
||||
run ids. Each journaled fix can be traced with `books.journal_history
|
||||
{ subject }`.
|
||||
|
||||
## Step 2. Every receipt attested
|
||||
|
||||
For every receipt on a posted entry (`books.list_receipts`, entry by entry,
|
||||
or `books.search_entries` then `books.get_entry`):
|
||||
|
||||
1. Verifier A reads `books.get_receipt` (text; a page image only if needed)
|
||||
and calls `books.attest_receipt { attachment_id, entry_id, amount, date,
|
||||
method, note? }` with the total and the date as read off the receipt.
|
||||
2. Verifier B does the same independently, without seeing A's reading.
|
||||
3. `books.attestations { kind: "receipt" }` shows each claim with
|
||||
`counted`. A claim below the bar, or with `disagrees: true`, does not
|
||||
count; the disagreement is a finding: reopen step 1 for that entry.
|
||||
|
||||
## Step 3. Every entry reviewed, every period attested
|
||||
|
||||
1. `books.review_entry { entry_id, method }` for every posted entry, by a
|
||||
verifier that did not make it.
|
||||
2. `books.attest_period { period, method }` for each month since the
|
||||
company's formation (`books.list_periods`), each against a standing
|
||||
audit at the current head (`scope: "month"` or `"full"`), then once for
|
||||
the fiscal year against the `cpa_handoff` run. A period attestation is
|
||||
refused when the books changed since the audit: audit again, then attest.
|
||||
3. `books.attestations` with no filter: every row has `counted: true` and
|
||||
none has `disagrees`.
|
||||
|
||||
## Step 4. The defect regressions
|
||||
|
||||
The 2026-10-16 audit found 20 defects; P0 found two more (21, 22) and P3
|
||||
two (23, 24). Each has a named regression test in the workspace;
|
||||
`crates/ledger-cli/tests/defects.rs` holds the list `(defect, test, file)`
|
||||
and proves each name exists. Show them green, from a checkout of the build
|
||||
under audit:
|
||||
|
||||
```
|
||||
cargo test -p ledger-cli --test defects
|
||||
```
|
||||
|
||||
then each test named in that list, by name, for example
|
||||
`cargo test -p ledger-core --test spec_cash_flow
|
||||
defect1_two_member_llc_first_year_regression`. Two defects have no code
|
||||
fix to test: defect 2 (reversals without their own evidence) is closed by
|
||||
D-12 and D-47 (its test shows the rule now) and defect 20 (the migration
|
||||
scripts) was retired at the cutover (no tool exists; the test checks none
|
||||
came back). Record the test run's output in the sign-off decision (step 7).
|
||||
|
||||
## Step 5. The Sheet comparison
|
||||
|
||||
The old Google Sheet and the books were frozen as of 2026-10-11 and
|
||||
compared a final time before the cutover (P2, `verify-sheet`); that run is
|
||||
filed as a document. There is no comparison tool and this
|
||||
runbook builds none.
|
||||
|
||||
1. `books.find_attachment { text: "verify-sheet" }` finds the filed run
|
||||
(its extracted text names the tool); `books.get_receipt { attachment_id }`
|
||||
reads it (text view; its `links` and `sha256` identify it). Cite it by
|
||||
attachment id and sha256. If it is not found, stop: the comparison was
|
||||
not filed at the cutover and the owner decides what stands in for it.
|
||||
2. `books.record_decision { subject: "Sheet comparison as of 2026-10-11",
|
||||
decision_md, decided_by: [<the owner>], decided_on, evidence_attachment:
|
||||
<that workpaper's id> }` stating that the frozen Sheet and the books
|
||||
agreed then, and nothing newer is claimed.
|
||||
|
||||
## Step 6. The CPA package from both doors
|
||||
|
||||
1. The agent's door: `books.export_cpa_package { as_of: <the year end>,
|
||||
include_tins: true }` (TINs are included by default, D-29). Without a
|
||||
counted audit it is refused (`audit_required`); never use
|
||||
`without_audit_reason` for the re-audit, the point is that it is not
|
||||
needed. Save the zip with the download command in its `file`.
|
||||
2. The viewer's door: `wanderbooks gui <book>`, the Export menu, the CPA
|
||||
package as of the same day. It lands in the Downloads folder.
|
||||
3. Compare the two zips file by file: byte-identical except for timestamps
|
||||
(the README's generated-at line and the zip entries' times). A difference
|
||||
in any figure is a defect: stop and report it.
|
||||
|
||||
## Step 7. Verify, back up, sign off
|
||||
|
||||
1. `books.verify { blobs: true }`: `status: "ok"` (not `healed`: a healed
|
||||
result means a torn tail was set aside; note it and look at
|
||||
`books.journal_history`'s `tail_repairs`).
|
||||
2. `books.backup`: every target not `stale`, `last_error` empty, and
|
||||
`last_drill_at` set with no `drill_error`. If not, `books.back_up_now`
|
||||
(an admin action) and read it again. The drill is the restore test; a
|
||||
backup that was never restored is not a backup.
|
||||
3. The owner's sign-off: `books.record_decision { subject: "Re-audit
|
||||
sign-off", decision_md, decided_by: [<the owner>], decided_on }` naming
|
||||
the final `cpa_handoff` and `full` run ids, the journal head
|
||||
(`books.verify`'s `head`), the defects run, and the CPA package's sha256.
|
||||
|
||||
## Step 8. The exit evidence
|
||||
|
||||
The re-audit passes only when all of these are true. The owner checks them;
|
||||
the agent presents the proof for each.
|
||||
|
||||
| Exit bar | Proof |
|
||||
|---|---|
|
||||
| Zero failing workpaper checks | the final `full` and `cpa_handoff` workpapers (`books.workpaper`) |
|
||||
| Cash flow difference 0.00 | `books.cash_flow` for the year; no `cash_flow_unfooted` finding |
|
||||
| Every receipt and posted entry has a counted attestation, none disagrees | `books.attestations` (step 3.3) |
|
||||
| Every action under the right principal | `books.access_log`: the auditor's token and each verifier's token appear on their own calls; no action by an admin token that an agent token did |
|
||||
| No transcript names the data root | grep each agent's transcript for the root path before sign-off (T1); T2: the tenant root is not readable by the agent's account |
|
||||
| No result carried a full TIN to a client that should not see one | `books.access_log` shows `include_tins` only on `books.export_cpa_package` and `books.get_w9`/`books.vendor_1099` calls by the owner's agent; the agents' exports may carry them (D-29), nothing else |
|
||||
| Receipt reading stayed under 100K tokens per verifier | each verifier's own token count for its receipt calls (the harness's count, written into the attestation `note`) |
|
||||
| The sign-off is journaled | `books.decisions` shows it |
|
||||
|
||||
When all are true the books are re-audited through the MCP alone.
|
||||
@@ -3922,3 +3922,33 @@ export gate (`cpa_audit_standing`'s four conditions and its feature test,
|
||||
the `refuse`/`warn` split, the reason's trim); `audit_items` in Needs
|
||||
attention (the declared test, the attested set, the last-ended fiscal
|
||||
year, the three year conditions).
|
||||
|
||||
## P10: the re-audit runbook's mirror
|
||||
|
||||
`docs/runbooks/re-audit.md` is the owner's acceptance, run on his books
|
||||
through the MCP alone. What CI can check of it is in
|
||||
`crates/ledger-cli/tests/defects.rs`:
|
||||
|
||||
- `every_defect_reproduction_is_a_named_test`: a table of `(defect, test
|
||||
name, file)` for the 2026-10-16 audit's defects 1 to 19, P0's 21 and 22
|
||||
and P3's 23 and 24 (23 rows); each named function exists in its file, is
|
||||
a `#[test]` (or inside `proptest!`) and is not `#[ignore]`d. Defect 2 is
|
||||
closed by D-12 and D-47, so its row is the rule as it now stands
|
||||
(`a_reversal_needs_no_receipt_of_its_own`).
|
||||
- `defect_20_no_migration_tool_exists`: defect 20 (the migration scripts)
|
||||
was retired at the cutover; no tool of that kind is in the scopes table.
|
||||
- `the_re_audit_runbook_names_only_what_exists`: every `books.<name>` in
|
||||
the runbook is in `crates/ledger-mcp/src/scopes.rs`, the commands it
|
||||
names are dispatched by `main.rs`, and its eight steps are present.
|
||||
|
||||
The mirror proves the tests exist, not that they pass; the runbook's step 4
|
||||
runs them by name. No CI job was added: the test runs in the existing
|
||||
`check` job's `cargo test --workspace`. The run itself (a counted
|
||||
attestation on every receipt and entry, the two CPA packages equal, the
|
||||
sign-off) is the owner's and has no CI equivalent.
|
||||
|
||||
**For P12 (mutation targets):** the `DEFECTS` table's file/name lookup (a
|
||||
`starts_with` on `fn <name>(`; the `#[test]`/`#[ignore]` window of eight
|
||||
lines above it) and the scopes-line scan in `defect_20_*`. A mutant that
|
||||
widens the window or drops the `ignore` check survives only if no ignored
|
||||
or untested name is in the table; the table is the oracle.
|
||||
+1
-1
@@ -1639,7 +1639,7 @@ Each unit follows the 8.0.4 template. "A-n" is an owner answer numbered in 8.3.1
|
||||
5. **Files:** owns `docs/runbooks/re-audit.md`, `crates/ledger-cli/tests/defects.rs`.
|
||||
6. **Tests and proofs:** the one test.
|
||||
7. **Done when (engineering):** the runbook exists and names only tools and commands that exist; the test passes. **Exit (the owner's run):** zero failing workpaper checks; cash flow difference 0.00; every receipt and posted entry carries a counted attestation and none disagrees; the access log shows every action under the right principal and no transcript names the data root; no result carried a full TIN to a client that should not see one (D-29: the agent's exports may); agent context on receipts stayed under 100K tokens per the harness's own token count; the sign-off journaled.
|
||||
8. **As built:** none yet.
|
||||
8. **As built:** (2026-10-29, branch `P10`.) `docs/runbooks/re-audit.md`: eight steps (the audit and its fixes; receipts attested; entries reviewed and periods attested; the defect regressions; the Sheet comparison; the CPA package from both doors; verify, backup drill and sign-off; the exit table), T1 and T2, every tool named is in the scopes table. `crates/ledger-cli/tests/defects.rs`: `every_defect_reproduction_is_a_named_test` (23 rows, defects 1 to 19 and 21 to 24), plus two the unit did not list: `defect_20_no_migration_tool_exists` and `the_re_audit_runbook_names_only_what_exists` (Done-when "names only tools that exist" needed a check). Departures: (a) **`books.inherit_evidence` does not exist** (only the event type is gated in `format.rs`; no tool, no scope row); the runbook links the original's receipt to the old reversal with `books.link_attachment`, which journals `attachment.linked` and satisfies the evidence rule, and `legacy_reversal_exempt` is informational so the audit is clean either way. If the owner wants the D-12 annotation as such, a tool is a later unit. (b) Defect 2 (closed by D-12/D-47) maps to `a_reversal_needs_no_receipt_of_its_own`'s rule; defect 20 has no test of its own and gets the no-tool check. (c) The Sheet workpaper is found with `books.find_attachment { text }` because `workpaper` is not a `books.file_document` category (the audit files its own). (d) No CI job added: `check` runs the new test. **Owner's, not checked here:** the run itself (zero failing checks, counted attestations, equal CPA packages, backup drill, sign-off, transcripts free of the data root, token counts).
|
||||
|
||||
#### P11a: packaging and updates (D-19, D-22, D-24, D-25, D-26)
|
||||
|
||||
|
||||
Reference in new issue
Block a user