Recovery-mode coverage matrix + E005 lenient-mode fix (bd-0x73.3)#176
Merged
Conversation
…3.3) Closes the recovery-mode test dimension for every error code that already has an end-to-end fixture, and fixes a real diagnostic gap the new tests surfaced. ## Coverage extension `validation_level_matrix.rs` now asserts each behavioral contract: * `run_fatal_matrix` — code fires in every cell of the 2x3 grid. Wired for E001/E003/E004 and E002 (structural shape). * `run_strict_only_matrix` — code fires at strict in every validation_level; lenient/permissive recovery cap absorbs. Wired for E006 per the changelog's documented contract. `per_record_diagnostics_matrix.rs` adds E005/E101/E106 captures: mid-record recoverable errors land on `record.errors` in lenient mode rather than being silently dropped. `tests/python/test_iter_with_errors.py` mirrors the contracts on the Python side via a parametrized matrix. ## Bug fixed: E005 silently swallowed in lenient/permissive The truncated-record dispatch in `parse_iso2709_record` was guarded on `record_data.len() < expected_data_len`, but `read_record_data` zero-pads the buffer to `expected_data_len` regardless of how many bytes were actually read. The guard was never reachable; the zero-padded region instead surfaced as a cascading E201 with no E005 trail. Now `read_record_data` returns `(Vec<u8>, usize)` (bytes_read instead of a was_truncated bool), and the dispatch consults the actual count. Strict mode is unchanged. ## Deferred Two follow-up beads filed under bd-0x73: * bd-mk6z — implement io_error / recovery_cap / writer trigger mechanisms in the error_coverage harness (E007/E099/E404). * bd-vwlp — align the Python backend's truncation pre-detection (`src-python/src/backend.rs::read_record_bytes`) with the parser's recovery_mode contract. Currently raises eagerly on short stream reads regardless of recovery_mode, which is why the Python parametrize set excludes E005. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merging this PR will improve performance by 15.28%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ⚡ | WallTime | test_pipeline_parallel_4x_10k_threaded |
120.4 ms | 105.9 ms | +13.7% |
| ⚡ | WallTime | test_pipeline_sequential_1x_10k |
22.9 ms | 19.9 ms | +15.28% |
| ⚡ | WallTime | test_pipeline_sequential_4x_10k |
95.5 ms | 84 ms | +13.66% |
Comparing feat/bd-0x73.3-error-coverage (d3e87bf) with main (9ebb39e)
Footnotes
-
16 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
dchud
added a commit
that referenced
this pull request
May 10, 2026
bd-0x73.3 closed as implemented by PR #176. Two follow-up beads filed under the bd-0x73 epic for the deferred work: - bd-mk6z (P2) — implement io_error / recovery_cap / writer trigger mechanisms in error_coverage harness (E007/E099/E404). - bd-vwlp (P2) — align Python backend truncation pre-detection with parser recovery_mode (currently bypasses lenient/permissive for E005). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes bd-0x73.3 — the error-coverage recovery-mode dimension.
The bd-0x73.8 manifest harness already asserted "every documented code fires its variant in strict mode." This PR closes the rest of the contract — fatal vs. strict-only vs. recoverable across
recovery_mode— for every code that already has an end-to-end fixture. While doing it, the new tests surfaced a real bug: E005 (TruncatedRecord) was silently swallowed in lenient/permissive. That fix is in scope (per the bead's "test failure precisely identifies code-X-fireable-but-no-input-triggers" criterion).Coverage extension
run_fatal_matrix— asserts the code fires in every cell of the 2×3{validation_level} × {recovery_mode}grid. Wired for E001 / E003 / E004 / E002 structural: leader/structural errors that prevent establishing a record boundary are unrecoverable.run_strict_only_matrix— asserts the code fires at strict in every validation_level; lenient/permissive recovery cap absorbs. Wired for E006 per the v0.8.1 changelog contract.per_record_diagnostics_matrix— adds E005 / E101 / E106 captures: mid-record recoverable errors land onrecord.errorsin lenient mode.test_iter_with_errors.py: parametrized matrix for fatal, strict-only, and recoverable contracts.Bug fixed: E005 silently swallowed in lenient/permissive
parse_iso2709_record's truncated-record dispatch was guarded onrecord_data.len() < expected_data_len. Butread_record_datazero-pads the buffer toexpected_data_lenregardless of how many bytes were actually read, so the guard was never reachable. The zero-padded region instead surfaced as a cascading E201 with no E005 trail. Nowread_record_datareturns(Vec<u8>, usize /* bytes_read */)and the dispatch consults the actual count. Strict mode unchanged. (Surfaced exactly because of the new lenient-mode test for E005.)Deferred (two follow-up beads filed under bd-0x73)
io_error/recovery_cap/writertrigger mechanisms in the error_coverage harness so E007/E099/E404 can drop their skip notes.src-python/src/backend.rs::read_record_bytes) with the parser'srecovery_modecontract. It currently raises eagerly on short stream reads regardless of recovery_mode; that's why the Python parametrize set excludes E005.Test plan
cargo test --test validation_level_matrix— 10 tests pass (5 existing + 5 new fatal/strict-only).cargo test --test per_record_diagnostics_matrix— 20 tests pass (17 existing + 3 new: E005/E101/E106).cargo test --test error_coverage— manifest harness still passes..cargo/check.sh(full): rust + python + clippy + ruff + mkdocs all green.🤖 Generated with Claude Code