Skip to content

Make modification-code ordering traits consistent - #707

Open
SuhasSrinivasan wants to merge 1 commit into
nanoporetech:masterfrom
SuhasSrinivasan:codex/fix-mod-code-ordering
Open

Make modification-code ordering traits consistent#707
SuhasSrinivasan wants to merge 1 commit into
nanoporetech:masterfrom
SuhasSrinivasan:codex/fix-mod-code-ordering

Conversation

@SuhasSrinivasan

@SuhasSrinivasan SuhasSrinivasan commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review status: Author-reviewed and ready for ONT review.

Fixes #673.

Summary

  • Makes ModCodeRepr::partial_cmp delegate to its existing total Ord implementation.
  • Prevents comparator-dependent reversal when letter modification codes and numeric ChEBI identifiers are mixed.
  • Adds exhaustive representative pair/triple law checks and an exact rendered-order control.

Severity

Severity: Low — latent logical/API consistency

Rationale: The current implementation violates Rust's ordering-law expectation and can reverse mixed-code ordering for external or future callers using PartialOrd. Current in-tree production sorting uses Ord, so no current biological result or file is known to be wrong.

Root cause

ModCodeRepr derives Ord, whose enum variant order places Code before ChEbi, but manually implements mixed-variant PartialOrd in the opposite direction. Therefore a.cmp(&b) and a.partial_cmp(&b) disagree for the same mixed pair.

Implementation

PartialOrd::partial_cmp now returns Some(self.cmp(other)). This is the conventional total-order implementation and makes equality, antisymmetry, and transitivity consistent without introducing a second ordering policy.

The tests cover representative uppercase/lowercase letter codes, ordinary and boundary ChEBI values, every pair, and every ordered triple.

Preserved behavior

  • Existing Ord, Vec::sort, BTreeMap, and BTreeSet behavior remains letter codes first, then numeric ChEBI identifiers.
  • Same-kind letter ordering remains lexicographical; same-kind ChEBI ordering remains numeric.
  • Parsing, display, hashing, equality, and biological code meaning remain unchanged.

Non-goals

  • No chemical, ontology, or biological ranking is implied.
  • No Summary-specific formatting, sampling, threshold, parsing, or performance change.
  • No change to the existing derived Ord policy.

Behavior before and after

Case Before After Expected oracle
Code('m') versus ChEbi(1) cmp returns Less; partial_cmp returns Some(Greater) Both return Less partial_cmp(a,b) == Some(cmp(a,b))
sort_by(partial_cmp) on 2,m,1,a Numeric identifiers can sort before letter codes a,m,1,2 Matches ordinary sort() and derived Ord
Letter/letter and ChEBI/ChEBI comparisons Internally consistent Unchanged Existing lexicographical/numeric order

Testing

Test environment

  • Revision tested: 790a88661ca19f322f3ee0741706ed10fb2de2cb
  • Tree tested and worktree state: 9d865640e53f7099248d5f2c8ed59200337cf6fc; clean after testing
  • Toolchain: rustc/cargo 1.90.0
  • Platform: platform-independent implementation; verified on macOS 26.6 arm64
  • Reference binary: modkit 0.6.4 behavior represented by the exact parent revision
  • External tools: none
  • Dependency resolution identity: ignored worktree Cargo.lock SHA-256 49c08c4c51b6f4320726551146d971fa9ef2183d40c3f6c631b2005965e242c0; rust-htslib 0.46.0 and hts-sys 2.2.0
Test layer Exact command, fixture, or matrix Result and evidence
Core: parent-red regression Exact parent 5cecc3fb3a9336068d9e3c68d5c08d678153dd2c; replay mod_code_ordering_obeys_total_order_laws Mixed Code/ChEbi assertion fails because partial_cmp reverses cmp; a partial_cmp sort disagrees with ordinary sort()
Core: focused regression TMPDIR=/private/tmp/modkit-u60-test-tmp cargo test -p mod_kit mod_base_code::tests -- --nocapture --test-threads=1 2 passed, 0 failed; all representative pairs/triples satisfy total-order laws; rendered control is exactly a,m,1,2
Core: applicable full workspace gate TMPDIR=/private/tmp/modkit-u60-test-tmp cargo test --workspace --all-targets --no-fail-fast -- --test-threads=1 181 passed, 14 ignored, 0 failed
Consumer audit Search and review of in-tree sorting/ordered-collection consumers Existing production consumers use preserved Ord behavior; no current output relies on the reversed mixed-kind PartialOrd behavior
Core: formatting/diff checks rustfmt --edition 2021 --check modkit-core/src/mod_base_code.rs; git diff --check upstream/master...HEAD Both passed; clean one-file diff, 86 insertions and 6 deletions

Tests not performed

  • No sequencing-data, CLI, performance, memory, or I/O test was run because this is an in-memory trait-law correction with no CLI or file-processing path.
  • No exhaustive enumeration of every Unicode char and all u32 values was performed; boundary representatives plus exhaustive pair/triple combinations exercise the ordering implementation directly.

Scientific validation

  • Population/eligibility invariant: no reads, sites, bases, or modification categories are added or removed.
  • Count/category conservation invariant: no scientific counter is touched.
  • Coordinate/strand/interval invariant: not applicable; no coordinate code changes.
  • Determinism invariant: every public ordering trait now exposes the same deterministic order.
  • Independent oracle or specialist review: Rust ordering laws and all in-tree consumers were independently audited on the frozen one-commit branch.

Output and compatibility

  • User-visible change: mixed-kind <, >, and explicit partial_cmp now follow the existing Ord order.
  • Expected output differences: only callers that directly used the inconsistent cross-variant PartialOrd behavior can observe a reversal.
  • Byte-identical controls: existing Ord-based sort and ordered-collection behavior is unchanged.
  • CLI/API/schema compatibility: no type, function, option, serialization, or schema change.
  • Partial-output or failure semantics: unchanged.

Reviewer guide

  1. Confirm derived enum Ord places Code before ChEbi.
  2. Review the one-line PartialOrd delegation.
  3. Review the representative pair/triple law test and exact rendered control.
  4. Rerun: cargo test -p mod_kit mod_base_code::tests -- --nocapture --test-threads=1.
  5. Confirm the PR documents the intentional compatibility effect for direct mixed-kind PartialOrd callers.

Checklist

  • The issue contains reproducible observed and expected behavior.
  • The change is limited to the linked issue's approved scope.
  • The regression is demonstrably red on the exact parent revision.
  • All tests actually performed are listed above with their results.
  • Unrun or inapplicable tests are disclosed.
  • Scientific counts/statistics and output compatibility are explicitly checked.
  • Formatting and diff-hygiene checks pass, or unrelated findings are documented.
  • No generated data, private sample identifiers, or unrelated changes are included.

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.

ModCodeRepr implements conflicting Ord and PartialOrd orderings

1 participant