Skip to content

Verify the effective date Bridge writes on Payment, Receipt and Contra - #482

Merged
lamemustafa merged 1 commit into
masterfrom
verify-effective-date
Sep 17, 2026
Merged

lamemustafa merged 1 commit into
masterfrom
verify-effective-date

Conversation

@lamemustafa

Copy link
Copy Markdown
Owner

Closes #469.

Outcome

verify_import and the amendment compare-and-swap now check the EFFECTIVEDATE Bridge writes on Payment, Receipt and Contra. Before this change, a voucher whose effective date Tally rewrote, or an operator later edited, still reported posted_verified, and an amendment would silently overwrite that edit.

Change

  • Request. The §9.8 verification read appends EFFECTIVEDATE to its FETCH. PARTYLEDGERNAME stays out, because Record that bank vouchers return EFFECTIVEDATE but not the written party #467's live read returned a bank ledger there, not the written counterparty. A test pins both halves.
  • Parse. A new parse_import_verification_rows emits effective_date, and import verification is its only caller. The public voucher tools keep parse_agent_rows and parse_agent_changed_rows, whose rows don't carry the field; a test asserts that on the capture.
    • EFFECTIVEDATE is now a claimed voucher scalar, so a voucher carrying it twice refuses (agent_read_protocol_invalid). This also applies to the public tools. No committed capture those tools parse repeats it: the review grepped every fixture.
    • A present value is trimmed and must be a date, like DATE. A malformed one refuses the read (voucher_effective_date_invalidimport_verification_export_invalid).
    • An empty element is treated as absent.
  • Diff. For a non-Journal voucher, a returned value that differs from the written date is an effective_date diff. verify_import reports it as posted_divergent, and an amendment as book_voucher_diverged, because the compare-and-swap reuses voucher_diffs.
  • Not observed. If a bank voucher's response doesn't return the element, it is not a diff: requiring it would refuse every verification on a release that doesn't return it. The row carries "not_observed": ["effective_date"] instead, on every matched verification status and on an admitted amendment row. A Journal is written without the element, so it is neither compared nor flagged.
  • Docs. A scoped correction in TALLY_PROTOCOL_REFERENCE.md §9.8, beside the limit paragraph it closes. Record that bank vouchers return EFFECTIVEDATE but not the written party #467's correction said "verify_import still does not fetch it"; that sentence now points to this change. The original "Two written elements are not verified" paragraph gains a note that it predates both corrections.

Measured

Evidence the element comes back.

  • Record that bank vouchers return EFFECTIVEDATE but not the written party #467's live read on licensed 7.1 Silver, in the synthetic lab: EFFECTIVEDATE TYPE="Date", equal to DATE, on a Bridge-built Receipt, Payment and Contra, from the exact §9.8 request with EFFECTIVEDATE and PARTYLEDGERNAME appended. That capture is not committed; the bank-import lane holds it.
  • The committed native-three-vouchers.utf16le.xml already carries EFFECTIVEDATE on two of its three vouchers. The new tests read it directly: Some, Some, None.

Tests.

  • Parser boundary, on the capture:
    • present, absent, empty, padded, invalid and repeated elements;
    • public rows exclude the field.
  • parse_import_vouchers: reads the capture's effective dates, and maps an invalid one to import_verification_export_invalid.
  • Verify, for Payment, Receipt and Contra:
    • absent: posted_verified plus not_observed;
    • equal: posted_verified with no caveat;
    • different: posted_divergent with ["effective_date"];
    • Journal: no compare and no flag;
    • matching_content_observed and posted_not_effective rows also carry not_observed.
  • Amendment:
    • an edited effective date is refused as book_voucher_diverged with ["effective_date"];
    • an unchanged one is admitted with no caveat;
    • an absent one is admitted with not_observed.
  • Request: the verification request fetches EFFECTIVEDATE and not PARTYLEDGERNAME.

Mutation. I disabled each of these 12 controls in turn, and a named test failed every time:

  • the FETCH entry;
  • which parser verification uses;
  • the diff itself, and its Journal exemption;
  • the not_observed bank-type rule, and its reporting in verify and amend;
  • public-row exclusion;
  • date validation;
  • trimming;
  • empty-as-absent;
  • the scalar claim.

At first 3 survived: the scalar claim, which parser verification uses, and (after a pattern fix) empty-as-absent. The tests that now catch them were added for those.

Suites. On master d84e2070, cargo test --workspace gave 1,636 passed, 0 failed, 10 ignored; cargo fmt --check and clippy (-D warnings -A clippy::pedantic) were clean. After the final rebase onto c299b4a5 (#480 changed only sync/reconciliation.rs), the targeted agent_import, effective_date and voucher_parse tests pass. The seal is current at 266 pins, with pin paths equal to master's.

Not measured

  • The simulator responses Bridge's end-to-end import tests use carry no EFFECTIVEDATE. Those paths now report not_observed on bank vouchers; no test drives a full import through the simulator with the element present.
  • What Tally returns after a UI edit to the effective date. Not captured; Record that bank vouchers return EFFECTIVEDATE but not the written party #467 records the same limit.
  • Other releases. One read, on 7.1 Silver.

Review

A Sonnet subagent reviewed the change against the issue and ran 201 targeted tests.

  • P1, fixed. The presence check trimmed, but the parse used the untrimmed value, so a whitespace-padded date would have refused the whole window. The value is now trimmed, a test covers it, and the fix was proven by mutation. A present but malformed value still refuses, exactly as DATE does. This is deliberate: accepting it as "not observed" would hide a corrupted response.
  • P3, fixed. not_observed on matching_content_observed and posted_not_effective was untested. Both existing tests now assert it.
  • Confirmed correct:
    • the amend and verify Journal checks cannot disagree on an admitted row;
    • the new scalar claim changes no committed capture's parse;
    • an effective date matching an older build's date still matches that build;
    • the docs claim matches the code.

🤖 Generated with Claude Code

#469)

Fetch EFFECTIVEDATE in the import verification read. A returned value that differs from the
written date is an effective_date diff in verify_import and the amendment compare-and-swap; an
absent or empty one is reported as not_observed, never refused. Journal is out of scope, and
the public voucher tools neither fetch nor return it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@lamemustafa
lamemustafa merged commit 7e95deb into master Sep 17, 2026
13 checks passed
@lamemustafa
lamemustafa deleted the verify-effective-date branch September 17, 2026 03:47
lamemustafa added a commit that referenced this pull request Sep 17, 2026
…ation.rs (#484)

Moves the import read-back verification family, `parse_import_vouchers`
through `render_proof_markdown` (18 functions, 606 lines), out of
`src-tauri/src/agent_import.rs` into `agent_import_verification.rs`, declared
as `agent_import::verification`. Regenerated on 2481ed0 by script, so it
carries #482's effective-date verification.

Only two kinds of edit are made to the moved code: `pub(super)` on the 17
functions reached from outside the module, and its two `super::` paths
rewritten to `super::super::`. With those undone and both sides run through
rustfmt, the block is byte-identical to master's. Unformatted, the only other
difference is rustfmt rewrapping `parse_import_vouchers` and `verify_batch`,
whose signatures the prefix pushed past 100 columns. `effective_date_not_observed`, `VerificationCandidates` and
`VerificationFingerprint` stay private.

The parent imports the functions explicitly:
- 13 reached from production code: 8 from Server methods in agent_import.rs
  (build, verify, persist, pre-import mark), 4 of which the posting path
  (agent_import_post.rs) also calls; 5 from the amendment compare-and-swap
  (agent_import_amend.rs).
- 4 reached only from sibling test modules, under `#[cfg(test)]`:
  batch_duplicate_sets, duplicates, observed_fingerprint,
  observed_voucher_identity.

The new file is pinned in the compatibility surface (267 -> 268 pins) and
MAX_SURFACE_FILES rises by one with a named reason.

Co-authored-by: t <dev@example.invalid>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Verify EFFECTIVEDATE on Bridge-built bank vouchers

1 participant