Skip to content

Recovery-mode coverage matrix + E005 lenient-mode fix (bd-0x73.3)#176

Merged
dchud merged 1 commit into
mainfrom
feat/bd-0x73.3-error-coverage
May 8, 2026
Merged

Recovery-mode coverage matrix + E005 lenient-mode fix (bd-0x73.3)#176
dchud merged 1 commit into
mainfrom
feat/bd-0x73.3-error-coverage

Conversation

@dchud
Copy link
Copy Markdown
Owner

@dchud dchud commented May 8, 2026

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 on record.errors in lenient mode.
  • Python mirror in 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 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, so 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 */) 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)

  • bd-mk6z — implement io_error / recovery_cap / writer trigger mechanisms in the error_coverage harness so E007/E099/E404 can drop their skip notes.
  • 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. 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.
  • Python suite: 14 tests in test_iter_with_errors.py pass (8 existing + 6 new parametric).

🤖 Generated with Claude Code

…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>
@dchud dchud self-assigned this May 8, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 8, 2026

Merging this PR will improve performance by 15.28%

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

⚡ 3 improved benchmarks
✅ 57 untouched benchmarks
⏩ 16 skipped benchmarks1

Performance Changes

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)

Open in CodSpeed

Footnotes

  1. 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 dchud merged commit f2e3c06 into main May 8, 2026
49 checks passed
@dchud dchud deleted the feat/bd-0x73.3-error-coverage branch May 8, 2026 23:41
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>
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.

1 participant