Skip to content

fix(dnp3)!: rename output key total_parse_errors -> parse_errors [PC-014]#313

Merged
Zious11 merged 2 commits into
developfrom
fix/dnp3-parse-errors-key-rename
Jun 24, 2026
Merged

fix(dnp3)!: rename output key total_parse_errors -> parse_errors [PC-014]#313
Zious11 merged 2 commits into
developfrom
fix/dnp3-parse-errors-key-rename

Conversation

@Zious11

@Zious11 Zious11 commented Jun 24, 2026

Copy link
Copy Markdown
Owner

BREAKING CHANGE — DNP3 JSON Output Key Rename

Behavioral change: Dnp3Analyzer::summarize() now emits "parse_errors" in the detail map instead of "total_parse_errors". All JSON consumers reading DNP3 analyzer summary output must rename their key lookup.

Consumer Migration

Before (v0.9.4 and earlier): detail["total_parse_errors"]
After (this PR): detail["parse_errors"]

No other DNP3 summary keys changed. Sibling analyzers (HTTP, TLS, Modbus) already use "parse_errors" — this rename eliminates the DNP3 inconsistency.

Rationale

DNP3 was the sole analyzer using a divergent key name (total_parse_errors) while HTTP, TLS, and Modbus all use parse_errors. This inconsistency was a known defect tracked as PC-014 in the fix-pc-013-014-015 bundle. Aligning the key name enables uniform JSON consumer logic across all four analyzers.

Human approval: D-220 (breaking rename pre-approved).

Spec Traceability

BC-2.15.020 v1.4 postcondition 1 (key name = parse_errors) -> STORY-108 AC-010 (summarize() output keys) -> Red Gate test_BC_2_15_020_parse_errors_key_name_is_parse_errors -> src/analyzer/dnp3.rs:1425 detail.insert("parse_errors", ...)

Changes

File Change
src/analyzer/dnp3.rs L1382: local var rename; L1425: output map key renamed; L1372/1375: doc comment updated
tests/dnp3_detection_tests.rs Updated 3 existing tests + added Red Gate test
tests/bc_2_15_110_dnp3_dispatcher_tests.rs Local var rename in EC-003 assertion
CHANGELOG.md Breaking Changes entry under [Unreleased]

Test Evidence

  • Red Gate added: test_BC_2_15_020_parse_errors_key_name_is_parse_errors — asserts detail.contains_key("parse_errors") AND !detail.contains_key("total_parse_errors")
  • Existing tests updated: test_BC_2_15_020_summarize_includes_parse_errors, test_summarize_zero_flows (AC-011), bc_2_15_110_dnp3_dispatcher_tests EC-003
  • All local gates passed: cargo test --all-targets, cargo clippy --all-targets -- -D warnings, cargo fmt --check

Consumer-Completeness Audit

  • src/reporter/terminal.rs:275 iterates asummary.detail generically; no hardcoded key reference. Safe.
  • src/main.rs: no DNP3-key-specific reads of the detail map.
  • No other source files reference total_parse_errors (confirmed via grep).

Bundle Status

Final open item in fix-pc-013-014-015 bundle. PC-013 merged (#310), PC-015 merged (#312), PC-014 this PR.

Pre-Merge Checklist

  • BC-2.15.020 v1.4 postcondition 1 satisfied
  • Red Gate test added (positive + negative assertion)
  • All existing tests updated to use new key name
  • CHANGELOG.md Breaking Changes entry under [Unreleased]
  • Consumer-completeness audit: no hardcoded key consumers remain
  • All local gates: test, clippy, fmt
  • Breaking change pre-approved (D-220)

Zious11 added 2 commits June 24, 2026 08:19
…014, BC-2.15.020]

BREAKING CHANGE: DNP3 analyzer summarize() detail map now emits key
"parse_errors" instead of "total_parse_errors", aligning DNP3 with the
HTTP, TLS, and Modbus sibling analyzers. JSON consumers reading DNP3
summary output must update their key references.

- src/analyzer/dnp3.rs: rename local var total_parse_errors -> parse_errors,
  update doc comment, change string key literal "total_parse_errors" ->
  "parse_errors" (the single behavioral change, line ~1425)
- tests/dnp3_detection_tests.rs: update key lookups and assertions in
  test_BC_2_15_020_summarize_empty_zero_flows (~line 993) and
  test_BC_2_15_020_summarize_includes_parse_errors (~line 1362-1380) to
  use the new key name; Red Gate test
  test_BC_2_15_020_parse_errors_key_name_is_parse_errors now passes
- tests/bc_2_15_110_dnp3_dispatcher_tests.rs: rename local variable
  total_parse_errors -> parse_errors (~line 959/961, cosmetic only)
- CHANGELOG.md: document breaking change under [Unreleased]

Traces to: BC-2.15.020 v1.4 postcondition 1 (D-220); STORY-108 AC-010.
…w field; add migration note to CHANGELOG [PC-014]

CR-004: summarize() local `parse_errors` renamed to `aggregate_parse_errors` to
visually distinguish the cross-flow aggregate from Dnp3FlowState.parse_errors.
JSON output key "parse_errors" is unchanged.

CR-005: CHANGELOG breaking-change entry now includes a concrete migration
snippet (jq one-liner) for script/JSON consumers.
@Zious11 Zious11 merged commit f5c002a into develop Jun 24, 2026
10 checks passed
@Zious11 Zious11 deleted the fix/dnp3-parse-errors-key-rename branch June 24, 2026 13:30
Zious11 added a commit that referenced this pull request Jun 24, 2026
…peline QUIESCED

Decisions recorded:
- D-225: PC-014 DELIVERED & MERGED (PR #313 fix(dnp3)!: rename total_parse_errors->parse_errors,
  develop f5c002a). Post-merge consistency audit CONSISTENT (7/7). DRIFT-1/DRIFT-2 closed via
  PR #314 (develop 2b348a1) — AC-010/AC-011 demos re-recorded (VHS).
- D-226: v0.10.0 RELEASED (PR #315 → main 0cbe922, tag v0.10.0, run 28109367603 SUCCESS,
  4 binaries). develop back-merged ff4b82b. Cycle fix-pc-013-014-015 CONVERGED + CLOSED.

State changes:
- pipeline: ACTIVE → STEADY-STATE; phase: FIX-CYCLE → QUIESCED
- released_version: v0.9.4 → v0.10.0 (0cbe922); prior_* shifted to v0.9.4
- develop_head: e684889ff4b82b; main_head: 96b49e80cbe922
- current_cycle: NONE; current_wave: QUIESCED
- PC-013/PC-014/PC-015 all moved to resolved-do-not-reopen line
- Spec versions at close: BC-INDEX v1.73, BC-2.15.020 v1.4, BC-2.16.004 v1.10,
  BC-2.16.010 v1.8, BC-2.16.016 v1.0; STORY-108 v1.2, STORY-113 v1.3, STORY-114 v1.6
- D-219..D-224 archived to cycles/fix-pc-013-014-015/decisions-archive.md
- Fresh SAFE-TO-CLEAR / resume-procedure block written (D-226 ground truth)
- STATE.md: 187 lines (under 200-line target)

New cycle artifacts:
- cycles/fix-pc-013-014-015/lessons.md: 2 lessons (S-7.02 satisfied, no follow-up story)
- cycles/fix-pc-013-014-015/decisions-archive.md: D-219..D-224

Lessons (S-7.02):
- L1 [process-practice]: Backlog labels must be verified against actual code during F1/scoping.
  All three open-item descriptions were factually inaccurate; research caught all before wrong fix shipped.
- L2 [design-lesson]: .expect() on internal invariants is correct; silent-skip is fail-OPEN anti-pattern.
  No new engine story required — existing scoping gate already encodes correct behavior.

Backlog items added: DEMO-TAPE-PATH-001, DEMO-MEDIA-CHECKSUM-001, DEPENDABOT-311 (non-blocking).

Count-propagation sweep: no numeric BC/story count changed this burst.
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