From 4f577cd1f5cb5a898b26a875999127593e7f79e9 Mon Sep 17 00:00:00 2001 From: Nils Homer Date: Wed, 7 Oct 2026 23:16:22 -0700 Subject: [PATCH] chore: release v0.8.0 --- CHANGELOG.md | 167 +++++++++++ Cargo.lock | 356 ++++++++++++------------ Cargo.toml | 34 +-- crates/fgumi-bam-io/CHANGELOG.md | 27 ++ crates/fgumi-bgzf/CHANGELOG.md | 13 + crates/fgumi-cli-common/CHANGELOG.md | 7 + crates/fgumi-cli-macros/CHANGELOG.md | 7 + crates/fgumi-consensus/CHANGELOG.md | 32 +++ crates/fgumi-dna/CHANGELOG.md | 8 + crates/fgumi-fmt/CHANGELOG.md | 7 + crates/fgumi-metrics/CHANGELOG.md | 19 ++ crates/fgumi-pipeline-core/CHANGELOG.md | 26 ++ crates/fgumi-pipeline-io/CHANGELOG.md | 39 +++ crates/fgumi-raw-bam/CHANGELOG.md | 24 ++ crates/fgumi-sam/CHANGELOG.md | 22 ++ crates/fgumi-simd-fastq/CHANGELOG.md | 8 + crates/fgumi-sort/CHANGELOG.md | 36 +++ crates/fgumi-tag/CHANGELOG.md | 10 + crates/fgumi-umi/CHANGELOG.md | 19 ++ 19 files changed, 667 insertions(+), 194 deletions(-) create mode 100644 crates/fgumi-cli-common/CHANGELOG.md create mode 100644 crates/fgumi-cli-macros/CHANGELOG.md create mode 100644 crates/fgumi-fmt/CHANGELOG.md create mode 100644 crates/fgumi-pipeline-core/CHANGELOG.md create mode 100644 crates/fgumi-pipeline-io/CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md index fc2b96aec..ce37c07d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,173 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +## [0.8.0] - 2026-10-08 + +### Bug Fixes + +- Fall back to a name-only group key on an unreadable aux offset ([#880](https://github.com/fulcrumgenomics/fgumi/pull/880)) +- Thread --max-memory into the pipeline queue budget ([#888](https://github.com/fulcrumgenomics/fgumi/pull/888)) +- Resolve --max-temp-files once and bake it into the chain spec ([#891](https://github.com/fulcrumgenomics/fgumi/pull/891)) +- Filter secondary/supplementary reads by flag, not UNKNOWN_REF ([#903](https://github.com/fulcrumgenomics/fgumi/pull/903)) +- Group by molecule by default, add --per-strand opt-out ([#904](https://github.com/fulcrumgenomics/fgumi/pull/904)) ([#906](https://github.com/fulcrumgenomics/fgumi/pull/906)) +- Restore chain-path diagnostic parity (dedup index-threshold banner, copy_umi unwired-flags warning, pair_fastq docstring) ([#914](https://github.com/fulcrumgenomics/fgumi/pull/914)) +- Log the missing/wrong-length-UMI banner at error level on the chain path ([#912](https://github.com/fulcrumgenomics/fgumi/pull/912)) +- Error on --min-corrected with empty input on the legacy paths (parity with the chain/fgbio) ([#919](https://github.com/fulcrumgenomics/fgumi/pull/919)) +- Write --metrics only on success on the chain path (match clip/retag) ([#921](https://github.com/fulcrumgenomics/fgumi/pull/921)) +- Consult the UMI-position cache by assigning UMI groups before clearing duplicate flags ([#918](https://github.com/fulcrumgenomics/fgumi/pull/918)) +- Wire --methylation-mode/--ref into the fused filter stage ([#944](https://github.com/fulcrumgenomics/fgumi/pull/944)) +- Restore the === Sort Phase Timing === per-phase diagnostic ([#945](https://github.com/fulcrumgenomics/fgumi/pull/945)) +- Return an error instead of panicking on >65,535 libraries ([#956](https://github.com/fulcrumgenomics/fgumi/pull/956)) +- Honor --check-crc/--no-check-crc on the BGZF FASTQ split decode ([#959](https://github.com/fulcrumgenomics/fgumi/pull/959)) +- Replace deprecated wide swizzle_relaxed with shuffle ([#992](https://github.com/fulcrumgenomics/fgumi/pull/992)) +- Honor --correct::rejects when correct is fused mid-chain ([#995](https://github.com/fulcrumgenomics/fgumi/pull/995)) +- [**breaking**] Enforce --max-temp-files on the arena spill path ([#993](https://github.com/fulcrumgenomics/fgumi/pull/993)) + - fgumi-pipeline-io's SpillBlockEvent::Block gains a required key_kind field, and SpillWrite now emits SpillReady for its surviving runs at AllAnnounced (with slot_count set to their number) instead of as each run closes. RunMergerDyn::step takes a byte budget. +- Honor --extract::no-check-crc on BGZF FASTQ input ([#996](https://github.com/fulcrumgenomics/fgumi/pull/996)) +- [**breaking**] Reject duplex/codec flags the callers never honor ([#997](https://github.com/fulcrumgenomics/fgumi/pull/997)) + - `fgumi duplex --min-consensus-base-quality`, `fgumi codec --min-consensus-base-quality`, `fgumi codec --trim` and their `runall` forms are removed. `ConsensusCallingOptions` loses `trim` and `min_consensus_base_quality` (now in `QualityTrimOptions` / `MinConsensusBaseQualityOptions`); `DuplexOptions` loses `min_consensus_base_quality`; `CodecOptions` and +- [**breaking**] Reject the zipper flags the chain never reads ([#998](https://github.com/fulcrumgenomics/fgumi/pull/998)) + - `fgumi runall --zipper::buffer` and +- [**breaking**] Enforce the shared consensus Phred bounds ([#1001](https://github.com/fulcrumgenomics/fgumi/pull/1001)) +- Honor both async-reader flags on both FASTQ paths ([#1000](https://github.com/fulcrumgenomics/fgumi/pull/1000)) +- [**breaking**] Reject --clipping-attribute, which extract never honors ([#1004](https://github.com/fulcrumgenomics/fgumi/pull/1004)) + - `fgumi extract --clipping-attribute` and `fgumi runall --extract::clipping-attribute` are removed. `ExtractRunallOptions` loses the public `clipping_attribute` field. +- Honor the --zipper:: merge rules on fused align chains ([#1005](https://github.com/fulcrumgenomics/fgumi/pull/1005)) +- Leave no output files behind when a chain fails to build ([#1006](https://github.com/fulcrumgenomics/fgumi/pull/1006)) +- Accept bwa's mid-pair -K split; emit BAM from the bwa-mem3 preset; keep mimalloc from purging ([#988](https://github.com/fulcrumgenomics/fgumi/pull/988)) +- [**breaking**] Store reverse-strand reads in reference orientation ([#1008](https://github.com/fulcrumgenomics/fgumi/pull/1008)) + - for a given seed, simulate mapped-reads, grouped-reads and consensus-reads now write reverse-strand SEQ and QUAL in reference orientation, soft-clip read-through padding when the insert is shorter than the read (changing CIGAR, MC and bin for those records), and consensus-reads writes reverse-strand per-base arrays reversed. +- [**breaking**] Give each methylation consensus caller one SEQ convention and make filters, simulate and docs follow it ([#1010](https://github.com/fulcrumgenomics/fgumi/pull/1010)) + - methylation::query_to_ref_positions takes the CIGAR as aligned (with its clips) and no longer takes the simplified CIGAR. * fix(consensus)!: emit observed bases from simplex methylation consensus Simplex EM-seq/TAPs consensus rewrote converted bases in the source reads (T->C / A->G at reference cytosines) before calling, so the emitted SEQ reported every site as unconverted. SEQ-based methylation callers and bisulfite-aware aligners read methylation from SEQ and saw every cytosine as methylated. The rewrite also hid real disagreements: all reads of a single-strand family copy one converted strand, so a C/T split is an error (or a UMI collision) and must lower quality like any other. Consensus is now always called on the observed bases, and simplex emits them as they are, with the evidence in cu/ct. MM/ML are no longer emitted for simplex: MM can only describe bases present in SEQ, and a converted cytosine is not one. A simplex consensus also cannot tell a converted cytosine from a C>T mutation, so restoring it would assert a base the molecule may not have. The shared MM builder now writes the SAM-spec '?' flag (unlisted bases are unknown), takes the conversion pattern from the read type (R1 C->T, R2 G->A) instead of the alignment strand, encodes each ML probability p as floor(256 p) capped at 255 (the SAM spec's [N/256, (N+1)/256) bins; it used floor(255 p), which put 1/2 and 3/4 in the bin below), and MN is available as a tag constant. +- [**breaking**] Reverse the methylation counts with the Consensus tag set ([#1011](https://github.com/fulcrumgenomics/fgumi/pull/1011)) + - zipper --tags-to-reverse Consensus now also reverses cu, ct, au, at, bu and bt, and fgumi_umi::TagSets::CONSENSUS_REVERSE lists those six tags after fgbio's eight; a pipeline that reverses with both zipper Consensus and filter --reverse-per-base-tags now reverses those counts twice as well, so reverse in only one of the two. +- Keep MM/ML in step with hard-clipped and unmapped reads ([#1012](https://github.com/fulcrumgenomics/fgumi/pull/1012)) +- Label paired strands by read orientation in the parallel assigner ([#1013](https://github.com/fulcrumgenomics/fgumi/pull/1013)) +- Bound the mimalloc purge delay instead of never purging ([#1017](https://github.com/fulcrumgenomics/fgumi/pull/1017)) +- Never auto-clip RG, MI and other non-per-base tags ([#1019](https://github.com/fulcrumgenomics/fgumi/pull/1019)) +- Classify dovetail FR pairs with coincident 5' ends as FR ([#1022](https://github.com/fulcrumgenomics/fgumi/pull/1022)) +- Add one @PG per command instead of one per chain leaf ([#1023](https://github.com/fulcrumgenomics/fgumi/pull/1023)) +- Accept empty input and sample an unterminated final FASTQ record ([#1024](https://github.com/fulcrumgenomics/fgumi/pull/1024)) +- Keep dotted output prefixes intact ([#1026](https://github.com/fulcrumgenomics/fgumi/pull/1026)) +- Decide read-level rejection before masking, and short-circuit templates like fgbio ([#1028](https://github.com/fulcrumgenomics/fgumi/pull/1028)) +- Report mixed UMI lengths as an error instead of panicking ([#1030](https://github.com/fulcrumgenomics/fgumi/pull/1030)) +- Pair duplex UMI halves by /A,/B strand family ([#1031](https://github.com/fulcrumgenomics/fgumi/pull/1031)) +- Validate UMI lengths before reading input ([#1035](https://github.com/fulcrumgenomics/fgumi/pull/1035)) +- Truncate read names at any whitespace and validate UMI field count ([#1040](https://github.com/fulcrumgenomics/fgumi/pull/1040)) +- Trim read-through bases when the mate cigar tag is missing ([#1041](https://github.com/fulcrumgenomics/fgumi/pull/1041)) + +### Documentation + +- Add NanoSeq (Duplex-Seq) pipeline guide ([#910](https://github.com/fulcrumgenomics/fgumi/pull/910)) +- Remove in-tree design docs and gitignore docs/design/ ([#934](https://github.com/fulcrumgenomics/fgumi/pull/934)) +- Document fgumi runall and add Reference guide pages ([#938](https://github.com/fulcrumgenomics/fgumi/pull/938)) +- Stop calling the duplication ladder a saturation curve ([#980](https://github.com/fulcrumgenomics/fgumi/pull/980)) +- Leave CHANGELOG.md to release-plz ([#1003](https://github.com/fulcrumgenomics/fgumi/pull/1003)) + +### Features + +- Add --threads and route through the unified pipeline ([#871](https://github.com/fulcrumgenomics/fgumi/pull/871)) +- Accept interleaved FASTQ input via --interleaved ([#874](https://github.com/fulcrumgenomics/fgumi/pull/874)) +- Typed-step pipeline foundation ([#870](https://github.com/fulcrumgenomics/fgumi/pull/870)) +- Warn when an explicit memory budget crowds the host ([#867](https://github.com/fulcrumgenomics/fgumi/pull/867)) +- Declarative chain-builder layer + group --threads pilot ([#872](https://github.com/fulcrumgenomics/fgumi/pull/872)) +- Wire dedup --threads onto the declarative chain builder ([#876](https://github.com/fulcrumgenomics/fgumi/pull/876)) +- Add command to copy the read-name UMI into the RX tag ([#873](https://github.com/fulcrumgenomics/fgumi/pull/873)) +- Inline BAI indexer on the arena sink ([#883](https://github.com/fulcrumgenomics/fgumi/pull/883)) +- Route the sort command onto the declarative chain builder ([#885](https://github.com/fulcrumgenomics/fgumi/pull/885)) +- Restore --read-streams on the arena chain via a concurrent scatter reader ([#889](https://github.com/fulcrumgenomics/fgumi/pull/889)) +- Route the correct command onto the declarative chain builder ([#893](https://github.com/fulcrumgenomics/fgumi/pull/893)) +- Route the filter command onto the declarative chain builder ([#892](https://github.com/fulcrumgenomics/fgumi/pull/892)) +- Route the simplex command onto the declarative chain builder ([#894](https://github.com/fulcrumgenomics/fgumi/pull/894)) +- Route the clip command onto the declarative chain builder ([#897](https://github.com/fulcrumgenomics/fgumi/pull/897)) +- Route the codec command onto the declarative chain builder ([#895](https://github.com/fulcrumgenomics/fgumi/pull/895)) +- Route the duplex command onto the declarative chain builder ([#896](https://github.com/fulcrumgenomics/fgumi/pull/896)) +- Route the retag command onto the declarative chain builder ([#898](https://github.com/fulcrumgenomics/fgumi/pull/898)) +- Route the copy-umi command onto the declarative chain builder ([#899](https://github.com/fulcrumgenomics/fgumi/pull/899)) +- Route the extract command onto the declarative chain builder ([#900](https://github.com/fulcrumgenomics/fgumi/pull/900)) +- Add opt-in --verify for strict template-coordinate order ([#909](https://github.com/fulcrumgenomics/fgumi/pull/909)) +- Thread --sort-stats diagnostics through the chain ([#913](https://github.com/fulcrumgenomics/fgumi/pull/913)) +- Give stage option structs a clap::Args surface for runall (PR A) ([#907](https://github.com/fulcrumgenomics/fgumi/pull/907)) +- Fused multi-stage `fgumi runall` command ([#911](https://github.com/fulcrumgenomics/fgumi/pull/911)) +- Produce --metrics on the multi-threaded chain path ([#915](https://github.com/fulcrumgenomics/fgumi/pull/915)) +- Add --check-crc / --no-check-crc with the file-vs-stdin default ([#933](https://github.com/fulcrumgenomics/fgumi/pull/933)) +- Add the aligner replay subcommand ([#935](https://github.com/fulcrumgenomics/fgumi/pull/935)) +- Add the bam-roundtrip subcommand ([#936](https://github.com/fulcrumgenomics/fgumi/pull/936)) +- Wire --pipeline-trace through the chain builder ([#937](https://github.com/fulcrumgenomics/fgumi/pull/937)) +- Add hidden --pool-scheduler override for A/B benchmarking ([#942](https://github.com/fulcrumgenomics/fgumi/pull/942)) +- Run BAM→FASTQ on the typed-step chain and add paired split output ([#939](https://github.com/fulcrumgenomics/fgumi/pull/939)) +- Expose --block-batch and --file-granularity as hidden flags ([#943](https://github.com/fulcrumgenomics/fgumi/pull/943)) +- Compute consensus QC metrics inline in fused runall and standalone consensus ([#948](https://github.com/fulcrumgenomics/fgumi/pull/948)) +- Thread-utilization and per-step bandwidth telemetry for the chain-builder engine ([#951](https://github.com/fulcrumgenomics/fgumi/pull/951)) +- Park idle pool workers to fix the thread-oversubscription cliff ([#955](https://github.com/fulcrumgenomics/fgumi/pull/955)) +- Add --threads to simplex-metrics and duplex-metrics ([#968](https://github.com/fulcrumgenomics/fgumi/pull/968)) +- [**breaking**] Publish metric column manifest; headered filter --stats ([#979](https://github.com/fulcrumgenomics/fgumi/pull/979)) + - `fgumi filter --stats` now writes a headered fgbio-Metric TSV (a total_reads/passed_reads/failed_reads/pass_rate header row plus one data row) instead of the previous headerless two-column key/value layout. Column names and semantics are unchanged; downstream parsers of the old vertical format must be updated. * test(metrics): round-trip conformance tests for all emitters * feat(metrics): publish metric column manifest with contract tests Adds crates/fgumi-metrics/metric_columns.json, the ordered column contract for every metric file fgumi emits, keyed . because group, simplex, duplex and dedup each write a differently shaped *.family_sizes.txt. tests/integration/test_metric_contract.rs parses the workspace with syn and fails in three cases: the manifest drifts from the live structs; a struct deriving serde's Serialize is neither listed nor explicitly allowlisted; or a serialized f64 field lacks the fgbio float encoding (Infinity/NaN rather than inf). downsample's --histogram-kept/--histogram-rejected were hand-formatted with writeln!. They now serialize a DownsampleHistogramMetric through the shared writer, so they are covered by the contract. The output is byte-identical. * fix(metrics): write headers for empty group and dedup histogram outputs group (--family-size-histogram, and the --metrics family- and position-group-size histograms) and dedup (--metrics, --family-size-histogram, --duplication-ladder) wrote through a bare DelimFile, which emits the header lazily. An empty histogram or ladder was therefore a 0-byte file that fgbio's Metric.read rejects ("No header found"). Route them through the shared write_metrics, which always writes the header. * docs(changelog): note filter --stats format break and metrics fixes * fix(metrics): honor .gz, special-file and symlink destinations in write_metrics write_metrics wrote rows to an extension-less temp file and renamed it into place. That had three problems. A .gz destination received plain text under a .gz name, which the metrics reader then failed to decompress. A non-regular destination such as /dev/stdout, a FIFO or a >(...) process substitution failed at rename time, after the whole run. A symlinked destination was replaced by a regular file. The temp file now carries the destination's extension so compression follows it. Non-regular destinations are written in place. Symlinks are resolved before the atomic rename. Empty outputs derive their header from a plain scratch file, so the gzip path keeps its header too. +- [**breaking**] Add pair op to build a paired UMI from own/mate tags ([#985](https://github.com/fulcrumgenomics/fgumi/pull/985)) + - `RetagOp` gains a `Pair` variant, and its public `src()` accessor is replaced by a crate-private `sources()`. +- Add the aligner-bwa-mem3 feature, cohort math and the AlignEngine abstraction ([#989](https://github.com/fulcrumgenomics/fgumi/pull/989)) +- Align in process with bwa-mem3 (--aligner::preset bwa-mem3-inproc) ([#990](https://github.com/fulcrumgenomics/fgumi/pull/990)) +- Align EM-seq bisulfite-aware under --methylation-mode; bump bwa-mem3-rs to 0.4.2 ([#1016](https://github.com/fulcrumgenomics/fgumi/pull/1016)) + +### Miscellaneous Tasks + +- Mark the BGZF CRC verification policy as intentional ([#932](https://github.com/fulcrumgenomics/fgumi/pull/932)) +- Publish only when a push bumps the workspace version ([#983](https://github.com/fulcrumgenomics/fgumi/pull/983)) +- Bump codecov/codecov-action to v7.1.1 ([#1020](https://github.com/fulcrumgenomics/fgumi/pull/1020)) + +### Performance + +- Use fixed-seed ahash on hot per-item maps to remove RandomState global-counter contention ([#865](https://github.com/fulcrumgenomics/fgumi/pull/865)) +- Skip per-record group-key computation for key-agnostic groupers ([#875](https://github.com/fulcrumgenomics/fgumi/pull/875)) +- Build the merge tag bitsets once per batch, not per template ([#917](https://github.com/fulcrumgenomics/fgumi/pull/917)) +- Skip the discarded group key on the chain filter path ([#916](https://github.com/fulcrumgenomics/fgumi/pull/916)) +- Use DrainFirstScheduler for terminal grouping chains ([#941](https://github.com/fulcrumgenomics/fgumi/pull/941)) +- Single-pass aux-tag rebuild (RawTagsEditor::rebuild_with) for zipper merge and NM/UQ/MD strip ([#962](https://github.com/fulcrumgenomics/fgumi/pull/962)) +- Parallel queryname grouping for the correct/align/filter chains ([#957](https://github.com/fulcrumgenomics/fgumi/pull/957)) +- Resolve the template UMI from the primary read ([#958](https://github.com/fulcrumgenomics/fgumi/pull/958)) +- Fold per-record PG/AS/XS aux scans into single-pass walks ([#964](https://github.com/fulcrumgenomics/fgumi/pull/964)) +- Drop the discarded decode key and add skippable input CRC ([#960](https://github.com/fulcrumgenomics/fgumi/pull/960)) +- Decode-free BAM fast path for single-record filter ([#961](https://github.com/fulcrumgenomics/fgumi/pull/961)) +- Decode-free BAM fast path for copy-umi ([#963](https://github.com/fulcrumgenomics/fgumi/pull/963)) +- Parallel gather for the in-memory sort fast path ([#966](https://github.com/fulcrumgenomics/fgumi/pull/966)) +- Reduce per-record allocation (zero-copy segment views + reused Phred scratch) ([#967](https://github.com/fulcrumgenomics/fgumi/pull/967)) +- Decode-free BAM fast path for retag ([#965](https://github.com/fulcrumgenomics/fgumi/pull/965)) +- Single-pass scalar consensus-tag extraction ([#969](https://github.com/fulcrumgenomics/fgumi/pull/969)) +- Reduce serial-merge CPU and allocations at 1-2 threads ([#971](https://github.com/fulcrumgenomics/fgumi/pull/971)) +- Gated multi-base fast path for simplex consensus ([#973](https://github.com/fulcrumgenomics/fgumi/pull/973)) +- Scale the per-template merge past ~4.5 cores at 4+ threads ([#975](https://github.com/fulcrumgenomics/fgumi/pull/975)) +- Fold UMI-position cache into the group-key aux scan ([#976](https://github.com/fulcrumgenomics/fgumi/pull/976)) + +### Refactor + +- Delete the CLI's throwaway sorter construction ([#890](https://github.com/fulcrumgenomics/fgumi/pull/890)) +- Retire the legacy single-threaded path; the chain is the only path ([#920](https://github.com/fulcrumgenomics/fgumi/pull/920)) +- Retire the legacy single-threaded path; the chain is the only path ([#922](https://github.com/fulcrumgenomics/fgumi/pull/922)) +- Retire the legacy single-threaded path; the chain is the only path ([#923](https://github.com/fulcrumgenomics/fgumi/pull/923)) +- Retire the legacy single-threaded path; the chain is the only path ([#924](https://github.com/fulcrumgenomics/fgumi/pull/924)) +- Retire the legacy single-threaded path; the chain is the only path ([#925](https://github.com/fulcrumgenomics/fgumi/pull/925)) +- [**breaking**] Collapse simplex/duplex/codec into a single consensus feature and retire the legacy single-threaded paths ([#926](https://github.com/fulcrumgenomics/fgumi/pull/926)) +- Retire the legacy single-threaded path; the chain is the only path ([#927](https://github.com/fulcrumgenomics/fgumi/pull/927)) +- Retire the legacy single-threaded paths; the chain is the only path ([#928](https://github.com/fulcrumgenomics/fgumi/pull/928)) +- Relocate reusable types out of unified_pipeline (R6a) ([#929](https://github.com/fulcrumgenomics/fgumi/pull/929)) +- [**breaking**] Remove the legacy unified_pipeline engine ([#947](https://github.com/fulcrumgenomics/fgumi/pull/947)) +- Split align+merge into a backend trait and a shared merge ([#987](https://github.com/fulcrumgenomics/fgumi/pull/987)) +- Stop configuring the chain sort through RawExternalSorter ([#999](https://github.com/fulcrumgenomics/fgumi/pull/999)) + +### Testing + +- Speed up the slow-test tail without weakening invariants ([#881](https://github.com/fulcrumgenomics/fgumi/pull/881)) +- Pin TLEN + pair orientation against htsjdk across a broad matrix ([#905](https://github.com/fulcrumgenomics/fgumi/pull/905)) +- Fix inconsistent mate-strand flags in duplicate-group fixtures ([#908](https://github.com/fulcrumgenomics/fgumi/pull/908)) +- Consolidate the byte-identity file-compare idiom into a shared helper ([#950](https://github.com/fulcrumgenomics/fgumi/pull/950)) +- Close --all-metrics and group-metrics integration coverage gaps ([#949](https://github.com/fulcrumgenomics/fgumi/pull/949)) +- Shrink the BGZF no-check-crc fixture below the slow timeout ([#1007](https://github.com/fulcrumgenomics/fgumi/pull/1007)) +- Port missing fgbio SamRecordClipper and ClipBam tests ([#1018](https://github.com/fulcrumgenomics/fgumi/pull/1018)) +- Pin read-order independence of alignment grouping ([#1037](https://github.com/fulcrumgenomics/fgumi/pull/1037)) +- Pin output order on every path ([#1038](https://github.com/fulcrumgenomics/fgumi/pull/1038)) + + + ## [0.7.0] - 2026-08-24 ### Bug Fixes diff --git a/Cargo.lock b/Cargo.lock index 827e04fe4..2a69e3f1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,12 +48,6 @@ dependencies = [ "cc", ] -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - [[package]] name = "android_system_properties" version = "0.1.6" @@ -155,7 +149,7 @@ dependencies = [ "addr2line", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.8.9", "object", "rustc-demangle", "windows-link", @@ -206,15 +200,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.13.1" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" [[package]] name = "borsh" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88b7ea17d208c4193f2c1e6de3c35fe71f98c96982d5ced308bdcc749ff6e1f" +checksum = "553c5d846a6ba5150c65e3b1b8ec073bcf1abc20f9b7220de384a4443ea4e20a" dependencies = [ "borsh-derive", "bytes", @@ -223,15 +217,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8f347189c62a579b8cd5f80714efa178f52e461dc2e6d701d264f5ff22e566c" +checksum = "12cdfe656708a01f89b451a7d36466e6fe6c414de0aa18fc54f864f6f9ca9f56" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.6", ] [[package]] @@ -313,13 +307,13 @@ dependencies = [ [[package]] name = "bytemuck_derive" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0e56a716f1e132ff6bf4bdac1c944a3fcdc1cae65f70a4a2a1ac3b401d2d1f" +checksum = "6a1f896587b6f2c069c73d2f0913e2d590c3990285cd2f0b6aa02b786b4c679c" dependencies = [ "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.6", ] [[package]] @@ -348,9 +342,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.4.4" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" +checksum = "f74872d07caf508b30a21f6836e7d7016a2eaf7d9ff4f48deaa58cd8a0407630" dependencies = [ "find-msvc-tools", "jobserver", @@ -360,9 +354,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" [[package]] name = "cfg_aliases" @@ -372,9 +366,9 @@ checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "chacha20" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ "cfg-if", "cpufeatures", @@ -421,9 +415,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca" +checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" dependencies = [ "clap_builder", "clap_derive", @@ -431,9 +425,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889" +checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" dependencies = [ "anstream", "anstyle", @@ -443,21 +437,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.6.4" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061" +checksum = "f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.6", ] [[package]] name = "clap_lex" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486" [[package]] name = "colorchoice" @@ -473,18 +467,18 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8498c871161e1742aaa9d52551b2d6ebdd4c3d45a3be423e3728f33b955be550" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" dependencies = [ "cfg-if", ] @@ -526,18 +520,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.16" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" +checksum = "98b0cc327b5bc766e7fda9c9260cc0fa81b43a8e240440422dff70788e3f9ef1" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -545,27 +539,27 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.20" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-queue" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "803d13fb3b09d88be9f4dbc29062c66b19bf7170867ceb746d2a8689bf6c7a26" +checksum = "03e8bd762f7479489c70ed6c768ddca99d7296857de437a68dcb2a94365b3fae" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.22" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" [[package]] name = "crunchy" @@ -629,7 +623,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" dependencies = [ - "thiserror 2.0.20", + "thiserror 2.0.21", ] [[package]] @@ -650,9 +644,9 @@ dependencies = [ [[package]] name = "either" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" +checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be" [[package]] name = "enum_dispatch" @@ -726,7 +720,7 @@ dependencies = [ [[package]] name = "fgumi" -version = "0.7.0" +version = "0.8.0" dependencies = [ "ahash", "anyhow", @@ -779,7 +773,7 @@ dependencies = [ "parking_lot", "proptest", "quote", - "rand 0.10.2", + "rand 0.10.3", "rand_distr 0.6.0", "rayon", "read-structure", @@ -787,16 +781,16 @@ dependencies = [ "serde", "serde_json", "statrs", - "syn 3.0.4", + "syn 3.0.6", "sysinfo", "tempfile", - "thiserror 2.0.20", + "thiserror 2.0.21", "which", ] [[package]] name = "fgumi-bam-io" -version = "0.7.0" +version = "0.8.0" dependencies = [ "ahash", "anyhow", @@ -820,7 +814,7 @@ dependencies = [ [[package]] name = "fgumi-bgzf" -version = "0.7.0" +version = "0.8.0" dependencies = [ "bgzf", "crc32fast", @@ -831,7 +825,7 @@ dependencies = [ [[package]] name = "fgumi-cli-common" -version = "0.7.0" +version = "0.8.0" dependencies = [ "anyhow", "bytesize", @@ -841,12 +835,12 @@ dependencies = [ "rstest", "sysinfo", "tempfile", - "thiserror 2.0.20", + "thiserror 2.0.21", ] [[package]] name = "fgumi-cli-macros" -version = "0.7.0" +version = "0.8.0" dependencies = [ "anyhow", "clap", @@ -859,7 +853,7 @@ dependencies = [ [[package]] name = "fgumi-consensus" -version = "0.7.0" +version = "0.8.0" dependencies = [ "ahash", "anyhow", @@ -876,13 +870,13 @@ dependencies = [ "proptest", "rstest", "tempfile", - "thiserror 2.0.20", + "thiserror 2.0.21", "wide 1.7.1", ] [[package]] name = "fgumi-dna" -version = "0.7.0" +version = "0.8.0" dependencies = [ "ahash", "rstest", @@ -890,7 +884,7 @@ dependencies = [ [[package]] name = "fgumi-fmt" -version = "0.7.0" +version = "0.8.0" dependencies = [ "num-format", "rstest", @@ -898,7 +892,7 @@ dependencies = [ [[package]] name = "fgumi-metrics" -version = "0.7.0" +version = "0.8.0" dependencies = [ "anyhow", "csv", @@ -917,7 +911,7 @@ dependencies = [ [[package]] name = "fgumi-pipeline-core" -version = "0.7.0" +version = "0.8.0" dependencies = [ "ahash", "anyhow", @@ -932,7 +926,7 @@ dependencies = [ [[package]] name = "fgumi-pipeline-io" -version = "0.7.0" +version = "0.8.0" dependencies = [ "anyhow", "criterion", @@ -952,7 +946,7 @@ dependencies = [ [[package]] name = "fgumi-raw-bam" -version = "0.7.0" +version = "0.8.0" dependencies = [ "anyhow", "bstr 1.13.1", @@ -970,7 +964,7 @@ dependencies = [ [[package]] name = "fgumi-sam" -version = "0.7.0" +version = "0.8.0" dependencies = [ "anyhow", "bstr 1.13.1", @@ -987,7 +981,7 @@ dependencies = [ [[package]] name = "fgumi-simd-fastq" -version = "0.7.0" +version = "0.8.0" dependencies = [ "criterion", "memchr", @@ -998,7 +992,7 @@ dependencies = [ [[package]] name = "fgumi-sort" -version = "0.7.0" +version = "0.8.0" dependencies = [ "ahash", "anyhow", @@ -1037,7 +1031,7 @@ dependencies = [ [[package]] name = "fgumi-tag" -version = "0.7.0" +version = "0.8.0" dependencies = [ "anyhow", "noodles", @@ -1045,7 +1039,7 @@ dependencies = [ [[package]] name = "fgumi-umi" -version = "0.7.0" +version = "0.8.0" dependencies = [ "ahash", "anyhow", @@ -1058,18 +1052,18 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" +checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484" [[package]] name = "flate2" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.9.1", "zlib-rs", ] @@ -1109,7 +1103,7 @@ checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.6", ] [[package]] @@ -1139,9 +1133,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" +checksum = "54ade96dc9003043bce7c035c85a9df5a858bfb2039c5a2e6fdf00f324f6c551" dependencies = [ "cc", "cfg-if", @@ -1199,7 +1193,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddddbf932745a6be37109b6112d3ee09696106f848449069d3a57bba937ab82e" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "libc", "libgit2-sys", "log", @@ -1228,8 +1222,6 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" dependencies = [ - "allocator-api2", - "equivalent", "foldhash", ] @@ -1271,9 +1263,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.14.0" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", "hashbrown", @@ -1317,9 +1309,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.35" +version = "0.2.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" +checksum = "b2b005715dcbeb0089a3c0dab99f2ff1cc3b2525323552703d648585d342a383" dependencies = [ "defmt", "jiff-core", @@ -1332,18 +1324,19 @@ dependencies = [ [[package]] name = "jiff-core" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" dependencies = [ "defmt", + "log", ] [[package]] name = "jiff-static" -version = "0.2.35" +version = "0.2.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" +checksum = "2cc9817253cf7c7ee4684451bd327e88d6f3658014e54a29198625590650695c" dependencies = [ "jiff-core", "proc-macro2", @@ -1363,9 +1356,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.104" +version = "0.3.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" +checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5" dependencies = [ "cfg-if", "futures-util", @@ -1374,9 +1367,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "20870f649af7073d53e38067b2a84312175d56ea15217e1b15bc83506ec50afb" [[package]] name = "lexical-core" @@ -1437,24 +1430,24 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.189" +version = "0.2.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" [[package]] name = "libdeflate-sys" -version = "1.26.0" +version = "1.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6949d73714ba8c32d2757405b89c94e427f64f078a4041debe07e1b8e9e850e9" +checksum = "d7870e5fbd2766179a937c725fb11f4ca0ef025d982beb61bd3ce755425bd19c" dependencies = [ "cc", ] [[package]] name = "libdeflater" -version = "1.26.0" +version = "1.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b72b274104f747cb65358c918e38c6cd4a69937937a36c8ad3cfd516c9c471e" +checksum = "0cbb8285d2e2bd4b8d4155840ae81929354b4ba0d7b3c272c84761ffa2141e1f" dependencies = [ "libdeflate-sys", ] @@ -1535,9 +1528,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.18.2" +version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2f2f9b4ba7e6b24d95e7e899329d35be83bcded72c8540cdd5368932d1d90a" +checksum = "ef9ac18847474e638e3702b76c65d4eb93428471a74778ef0f1be711717f89b5" dependencies = [ "hashbrown", ] @@ -1587,6 +1580,15 @@ name = "miniz_oxide" version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" dependencies = [ "adler2", "simd-adler32", @@ -1609,7 +1611,7 @@ dependencies = [ "num-complex", "num-rational", "num-traits", - "rand 0.8.7", + "rand 0.8.8", "rand_distr 0.4.3", "simba", "typenum", @@ -1621,7 +1623,7 @@ version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "cfg-if", "cfg_aliases", "libc", @@ -1710,7 +1712,7 @@ version = "0.89.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8063dd9e92825db46ae21813525589d41cff9ce2dcb2a0d25d99af86b274a1c5" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "bstr 1.13.1", "indexmap", "lexical-core", @@ -1831,7 +1833,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", ] [[package]] @@ -1973,9 +1975,9 @@ checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" dependencies = [ "portable-atomic", ] @@ -2015,7 +2017,7 @@ checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ "bit-set", "bit-vec 0.8.0", - "bitflags 2.13.1", + "bitflags 2.13.2", "num-traits", "rand 0.9.5", "rand_chacha 0.9.0", @@ -2055,9 +2057,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" +checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -2076,9 +2078,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af" dependencies = [ "chacha20", "getrandom 0.4.3", @@ -2136,7 +2138,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" dependencies = [ "num-traits", - "rand 0.8.7", + "rand 0.8.8", ] [[package]] @@ -2146,7 +2148,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d431c2703ccf129de4d45253c03f49ebb22b97d6ad79ee3ecfc7e3f4862c1d8" dependencies = [ "num-traits", - "rand 0.10.2", + "rand 0.10.3", ] [[package]] @@ -2202,7 +2204,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", ] [[package]] @@ -2298,11 +2300,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "errno", "libc", "linux-raw-sys", @@ -2447,7 +2449,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.6", ] [[package]] @@ -2465,9 +2467,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +checksum = "4e7523beb55eece201a2356bee0bbca0d1ab466c14c07703b2e0ee6d42cb0c2c" dependencies = [ "serde_core", ] @@ -2514,9 +2516,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.2" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +checksum = "f9395f0f0eee849a9b707b2f06bb92a6a422090e2123bb2ef8e87a0e61892a8e" [[package]] name = "statrs" @@ -2527,7 +2529,7 @@ dependencies = [ "approx", "nalgebra", "num-traits", - "rand 0.8.7", + "rand 0.8.8", ] [[package]] @@ -2600,9 +2602,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" dependencies = [ "proc-macro2", "quote", @@ -2624,10 +2626,10 @@ dependencies = [ ] [[package]] -name = "target-triple" -version = "1.0.1" +name = "target-tuple" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a6bfce3d99adfa72d24750a61f782f3036a81e7f86d8841ee1326deaebd171" +checksum = "876fef147edbcbddc8ac5cbbba92c7b86519e314e86638596c09673b2ed01e7f" [[package]] name = "tempfile" @@ -2636,7 +2638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys", @@ -2662,11 +2664,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.20" +version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" dependencies = [ - "thiserror-impl 2.0.20", + "thiserror-impl 2.0.21", ] [[package]] @@ -2682,13 +2684,13 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.20" +version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" dependencies = [ "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.6", ] [[package]] @@ -2718,9 +2720,9 @@ dependencies = [ [[package]] name = "toml" -version = "1.1.4+spec-1.1.0" +version = "1.1.7+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5" +checksum = "7874cd34dd99040fc24e30923aa64a60a81ff3ddfe2b8129ccc84ba24949deed" dependencies = [ "indexmap", "serde_core", @@ -2733,18 +2735,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.25.13+spec-1.1.0" +version = "0.25.16+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" +checksum = "88f38f3af8bf71841c67a990f4e2b52143b2d0a1a994c72513ff4c14977fc722" dependencies = [ "indexmap", "toml_datetime", @@ -2754,18 +2756,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.1.3+spec-1.1.0" +version = "1.1.4+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" +checksum = "bed810ee007d8e7f9cf20b4774e7198142fa27186e0f805871da7f3c39eaf333" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" [[package]] name = "tracing" @@ -2818,15 +2820,15 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.118" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06649c6f63d86604ba0c8950d5a1829fc9a17afd70fc6629f481d75b6a624c78" +checksum = "62db9c92d704393fbf2132041720cc80b689f2d3f28521015c2ac866223c11b8" dependencies = [ "glob", "serde", "serde_derive", "serde_json", - "target-triple", + "target-tuple", "termcolor", "toml", ] @@ -2845,9 +2847,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" [[package]] name = "utf8parse" @@ -2918,9 +2920,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.127" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" +checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409" dependencies = [ "cfg-if", "once_cell", @@ -2931,9 +2933,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.127" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" +checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2941,31 +2943,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.127" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" +checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.6", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.127" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" +checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.104" +version = "0.3.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30" +checksum = "88261b9deccee56594c11a3460c462c41f58d148598fe70ad77070126a68aba4" dependencies = [ "js-sys", "wasm-bindgen", @@ -2973,9 +2975,9 @@ dependencies = [ [[package]] name = "which" -version = "8.0.5" +version = "8.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3ef584124b911bcc3875c2f1472e80f24361ceb789bd1c62b3e9a3df9ff43c" +checksum = "bae2f2b2b816647a1cab1acc91f5bd20812d53cb344382635ec2181940c8034f" dependencies = [ "libc", ] @@ -3167,30 +3169,30 @@ checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "xtask" -version = "0.7.0" +version = "0.8.0" dependencies = [ "anyhow", "clap", "fgumi", "quote", - "syn 3.0.4", + "syn 3.0.6", "tempfile", ] [[package]] name = "zerocopy" -version = "0.8.56" +version = "0.8.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" +checksum = "879fb705ce98c32e41ebdb970fbe1204f8492423b314c6ab0354c3e7b5542866" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.56" +version = "0.8.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" +checksum = "708882a28301d604fa039cc7727607a98d04c4b86dc76ec9cc683f805d709759" dependencies = [ "proc-macro2", "quote", @@ -3199,9 +3201,9 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34b31d188d9d685a4f9c7b46d6e36631b07058d2cfe190267adce54dc230bf12" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" [[package]] name = "zmij" @@ -3220,18 +3222,18 @@ dependencies = [ [[package]] name = "zstd-safe" -version = "7.2.4" +version = "7.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +checksum = "64d80649ab6db9d9f6f9c80a40becd948eda4714a0a5ac8c4d157a32231c7882" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" +version = "2.1.0+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +checksum = "0ef0a8027ec3ee71300ab3bcbcd0393f434aa72b91ca6d635a39941deae8eea0" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index 4e4969663..694bf617f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [".", "crates/fgumi-raw-bam", "crates/fgumi-dna", "crates/fgumi-bgzf", resolver = "2" [workspace.package] -version = "0.7.0" +version = "0.8.0" edition = "2024" rust-version = "1.93.0" repository = "https://github.com/fulcrumgenomics/fgumi" @@ -20,22 +20,22 @@ license = "MIT" flate2 = { version = "1.1", features = ["zlib-rs"] } # Internal crates. Versions are bumped in lockstep by release-plz. -fgumi-bam-io = { version = "0.7.0", path = "crates/fgumi-bam-io" } -fgumi-bgzf = { version = "0.7.0", path = "crates/fgumi-bgzf" } -fgumi-cli-common = { version = "0.7.0", path = "crates/fgumi-cli-common" } -fgumi-cli-macros = { version = "0.7.0", path = "crates/fgumi-cli-macros" } -fgumi-fmt = { version = "0.7.0", path = "crates/fgumi-fmt" } -fgumi-consensus = { version = "0.7.0", path = "crates/fgumi-consensus", default-features = false } -fgumi-dna = { version = "0.7.0", path = "crates/fgumi-dna" } -fgumi-metrics = { version = "0.7.0", path = "crates/fgumi-metrics" } -fgumi-pipeline-core = { version = "0.7.0", path = "crates/fgumi-pipeline-core" } -fgumi-pipeline-io = { version = "0.7.0", path = "crates/fgumi-pipeline-io" } -fgumi-raw-bam = { version = "0.7.0", path = "crates/fgumi-raw-bam" } -fgumi-sam = { version = "0.7.0", path = "crates/fgumi-sam" } -fgumi-simd-fastq = { version = "0.7.0", path = "crates/fgumi-simd-fastq" } -fgumi-sort = { version = "0.7.0", path = "crates/fgumi-sort" } -fgumi-tag = { version = "0.7.0", path = "crates/fgumi-tag" } -fgumi-umi = { version = "0.7.0", path = "crates/fgumi-umi" } +fgumi-bam-io = { version = "0.8.0", path = "crates/fgumi-bam-io" } +fgumi-bgzf = { version = "0.8.0", path = "crates/fgumi-bgzf" } +fgumi-cli-common = { version = "0.8.0", path = "crates/fgumi-cli-common" } +fgumi-cli-macros = { version = "0.8.0", path = "crates/fgumi-cli-macros" } +fgumi-fmt = { version = "0.8.0", path = "crates/fgumi-fmt" } +fgumi-consensus = { version = "0.8.0", path = "crates/fgumi-consensus", default-features = false } +fgumi-dna = { version = "0.8.0", path = "crates/fgumi-dna" } +fgumi-metrics = { version = "0.8.0", path = "crates/fgumi-metrics" } +fgumi-pipeline-core = { version = "0.8.0", path = "crates/fgumi-pipeline-core" } +fgumi-pipeline-io = { version = "0.8.0", path = "crates/fgumi-pipeline-io" } +fgumi-raw-bam = { version = "0.8.0", path = "crates/fgumi-raw-bam" } +fgumi-sam = { version = "0.8.0", path = "crates/fgumi-sam" } +fgumi-simd-fastq = { version = "0.8.0", path = "crates/fgumi-simd-fastq" } +fgumi-sort = { version = "0.8.0", path = "crates/fgumi-sort" } +fgumi-tag = { version = "0.8.0", path = "crates/fgumi-tag" } +fgumi-umi = { version = "0.8.0", path = "crates/fgumi-umi" } # Third-party crates shared by two or more members. Declared once here so a member can # never drift onto a different version: two versions of a crate whose types cross crate diff --git a/crates/fgumi-bam-io/CHANGELOG.md b/crates/fgumi-bam-io/CHANGELOG.md index 48fea715d..d0780cf3d 100644 --- a/crates/fgumi-bam-io/CHANGELOG.md +++ b/crates/fgumi-bam-io/CHANGELOG.md @@ -4,6 +4,33 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +## [0.8.0] - 2026-10-08 + +### Bug Fixes + +- Point empty stdin/pipe input at the upstream stage ([#866](https://github.com/fulcrumgenomics/fgumi/pull/866)) +- Return an error instead of panicking on >65,535 libraries ([#956](https://github.com/fulcrumgenomics/fgumi/pull/956)) +- Add one @PG per command instead of one per chain leaf ([#1023](https://github.com/fulcrumgenomics/fgumi/pull/1023)) +- Propagate errors writing the final BGZF EOF block ([#1046](https://github.com/fulcrumgenomics/fgumi/pull/1046)) + +### Features + +- Typed-step pipeline foundation ([#870](https://github.com/fulcrumgenomics/fgumi/pull/870)) +- Inline BAI indexer on the arena sink ([#883](https://github.com/fulcrumgenomics/fgumi/pull/883)) +- Restore --read-streams on the arena chain via a concurrent scatter reader ([#889](https://github.com/fulcrumgenomics/fgumi/pull/889)) +- Add the bam-roundtrip subcommand ([#936](https://github.com/fulcrumgenomics/fgumi/pull/936)) + +### Performance + +- Drop the discarded decode key and add skippable input CRC ([#960](https://github.com/fulcrumgenomics/fgumi/pull/960)) +- Fold UMI-position cache into the group-key aux scan ([#976](https://github.com/fulcrumgenomics/fgumi/pull/976)) + +### Refactor + +- [**breaking**] Remove the legacy unified_pipeline engine ([#947](https://github.com/fulcrumgenomics/fgumi/pull/947)) + + + ## [0.7.0] - 2026-08-24 ### Bug Fixes diff --git a/crates/fgumi-bgzf/CHANGELOG.md b/crates/fgumi-bgzf/CHANGELOG.md index 1dcc84f01..f112a0932 100644 --- a/crates/fgumi-bgzf/CHANGELOG.md +++ b/crates/fgumi-bgzf/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to this project will be documented in this file. +## [0.8.0] - 2026-10-08 + +### Features + +- Typed-step pipeline foundation ([#870](https://github.com/fulcrumgenomics/fgumi/pull/870)) +- Add --check-crc / --no-check-crc with the file-vs-stdin default ([#933](https://github.com/fulcrumgenomics/fgumi/pull/933)) + +### Refactor + +- [**breaking**] Remove the legacy unified_pipeline engine ([#947](https://github.com/fulcrumgenomics/fgumi/pull/947)) + + + ## [0.7.0] - 2026-08-24 ### Features diff --git a/crates/fgumi-cli-common/CHANGELOG.md b/crates/fgumi-cli-common/CHANGELOG.md new file mode 100644 index 000000000..975cbf187 --- /dev/null +++ b/crates/fgumi-cli-common/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [0.8.0] - 2026-10-08 + + diff --git a/crates/fgumi-cli-macros/CHANGELOG.md b/crates/fgumi-cli-macros/CHANGELOG.md new file mode 100644 index 000000000..975cbf187 --- /dev/null +++ b/crates/fgumi-cli-macros/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [0.8.0] - 2026-10-08 + + diff --git a/crates/fgumi-consensus/CHANGELOG.md b/crates/fgumi-consensus/CHANGELOG.md index a16dc5cca..af00761e8 100644 --- a/crates/fgumi-consensus/CHANGELOG.md +++ b/crates/fgumi-consensus/CHANGELOG.md @@ -2,6 +2,38 @@ All notable changes to this project will be documented in this file. +## [0.8.0] - 2026-10-08 + +### Bug Fixes + +- [**breaking**] Reject duplex/codec flags the callers never honor ([#997](https://github.com/fulcrumgenomics/fgumi/pull/997)) + - `fgumi duplex --min-consensus-base-quality`, `fgumi codec --min-consensus-base-quality`, `fgumi codec --trim` and their `runall` forms are removed. `ConsensusCallingOptions` loses `trim` and `min_consensus_base_quality` (now in `QualityTrimOptions` / `MinConsensusBaseQualityOptions`); `DuplexOptions` loses `min_consensus_base_quality`; `CodecOptions` and +- [**breaking**] Give each methylation consensus caller one SEQ convention and make filters, simulate and docs follow it ([#1010](https://github.com/fulcrumgenomics/fgumi/pull/1010)) + - methylation::query_to_ref_positions takes the CIGAR as aligned (with its clips) and no longer takes the simplified CIGAR. * fix(consensus)!: emit observed bases from simplex methylation consensus Simplex EM-seq/TAPs consensus rewrote converted bases in the source reads (T->C / A->G at reference cytosines) before calling, so the emitted SEQ reported every site as unconverted. SEQ-based methylation callers and bisulfite-aware aligners read methylation from SEQ and saw every cytosine as methylated. The rewrite also hid real disagreements: all reads of a single-strand family copy one converted strand, so a C/T split is an error (or a UMI collision) and must lower quality like any other. Consensus is now always called on the observed bases, and simplex emits them as they are, with the evidence in cu/ct. MM/ML are no longer emitted for simplex: MM can only describe bases present in SEQ, and a converted cytosine is not one. A simplex consensus also cannot tell a converted cytosine from a C>T mutation, so restoring it would assert a base the molecule may not have. The shared MM builder now writes the SAM-spec '?' flag (unlisted bases are unknown), takes the conversion pattern from the read type (R1 C->T, R2 G->A) instead of the alignment strand, encodes each ML probability p as floor(256 p) capped at 255 (the SAM spec's [N/256, (N+1)/256) bins; it used floor(255 p), which put 1/2 and 3/4 in the bin below), and MN is available as a tag constant. +- Keep MM/ML in step with hard-clipped and unmapped reads ([#1012](https://github.com/fulcrumgenomics/fgumi/pull/1012)) +- Classify dovetail FR pairs with coincident 5' ends as FR ([#1022](https://github.com/fulcrumgenomics/fgumi/pull/1022)) +- Decide read-level rejection before masking, and short-circuit templates like fgbio ([#1028](https://github.com/fulcrumgenomics/fgumi/pull/1028)) +- Handle NaN likelihoods like fgbio ([#1029](https://github.com/fulcrumgenomics/fgumi/pull/1029)) +- Truncate source-read cigars before converting hard clips, like fgbio ([#1042](https://github.com/fulcrumgenomics/fgumi/pull/1042)) +- Trim read-through bases when the mate cigar tag is missing ([#1041](https://github.com/fulcrumgenomics/fgumi/pull/1041)) + +### Features + +- Typed-step pipeline foundation ([#870](https://github.com/fulcrumgenomics/fgumi/pull/870)) + +### Performance + +- Use fixed-seed ahash on hot per-item maps to remove RandomState global-counter contention ([#865](https://github.com/fulcrumgenomics/fgumi/pull/865)) +- Single-pass scalar consensus-tag extraction ([#969](https://github.com/fulcrumgenomics/fgumi/pull/969)) +- Gated multi-base fast path for simplex consensus ([#973](https://github.com/fulcrumgenomics/fgumi/pull/973)) + +### Testing + +- Speed up the slow-test tail without weakening invariants ([#881](https://github.com/fulcrumgenomics/fgumi/pull/881)) +- Pin read-order independence of alignment grouping ([#1037](https://github.com/fulcrumgenomics/fgumi/pull/1037)) + + + ## [0.7.0] - 2026-08-24 ### Bug Fixes diff --git a/crates/fgumi-dna/CHANGELOG.md b/crates/fgumi-dna/CHANGELOG.md index c6e809783..b29da2c77 100644 --- a/crates/fgumi-dna/CHANGELOG.md +++ b/crates/fgumi-dna/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. +## [0.8.0] - 2026-10-08 + +### Performance + +- Use fixed-seed ahash on hot per-item maps to remove RandomState global-counter contention ([#865](https://github.com/fulcrumgenomics/fgumi/pull/865)) + + + ## [0.7.0] - 2026-08-24 diff --git a/crates/fgumi-fmt/CHANGELOG.md b/crates/fgumi-fmt/CHANGELOG.md new file mode 100644 index 000000000..975cbf187 --- /dev/null +++ b/crates/fgumi-fmt/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [0.8.0] - 2026-10-08 + + diff --git a/crates/fgumi-metrics/CHANGELOG.md b/crates/fgumi-metrics/CHANGELOG.md index 4a8acc02f..ceeccf591 100644 --- a/crates/fgumi-metrics/CHANGELOG.md +++ b/crates/fgumi-metrics/CHANGELOG.md @@ -2,6 +2,25 @@ All notable changes to this project will be documented in this file. +## [0.8.0] - 2026-10-08 + +### Documentation + +- Stop calling the duplication ladder a saturation curve ([#980](https://github.com/fulcrumgenomics/fgumi/pull/980)) + +### Features + +- Produce --metrics on the multi-threaded chain path ([#915](https://github.com/fulcrumgenomics/fgumi/pull/915)) +- Compute consensus QC metrics inline in fused runall and standalone consensus ([#948](https://github.com/fulcrumgenomics/fgumi/pull/948)) +- [**breaking**] Publish metric column manifest; headered filter --stats ([#979](https://github.com/fulcrumgenomics/fgumi/pull/979)) + - `fgumi filter --stats` now writes a headered fgbio-Metric TSV (a total_reads/passed_reads/failed_reads/pass_rate header row plus one data row) instead of the previous headerless two-column key/value layout. Column names and semantics are unchanged; downstream parsers of the old vertical format must be updated. * test(metrics): round-trip conformance tests for all emitters * feat(metrics): publish metric column manifest with contract tests Adds crates/fgumi-metrics/metric_columns.json, the ordered column contract for every metric file fgumi emits, keyed . because group, simplex, duplex and dedup each write a differently shaped *.family_sizes.txt. tests/integration/test_metric_contract.rs parses the workspace with syn and fails in three cases: the manifest drifts from the live structs; a struct deriving serde's Serialize is neither listed nor explicitly allowlisted; or a serialized f64 field lacks the fgbio float encoding (Infinity/NaN rather than inf). downsample's --histogram-kept/--histogram-rejected were hand-formatted with writeln!. They now serialize a DownsampleHistogramMetric through the shared writer, so they are covered by the contract. The output is byte-identical. * fix(metrics): write headers for empty group and dedup histogram outputs group (--family-size-histogram, and the --metrics family- and position-group-size histograms) and dedup (--metrics, --family-size-histogram, --duplication-ladder) wrote through a bare DelimFile, which emits the header lazily. An empty histogram or ladder was therefore a 0-byte file that fgbio's Metric.read rejects ("No header found"). Route them through the shared write_metrics, which always writes the header. * docs(changelog): note filter --stats format break and metrics fixes * fix(metrics): honor .gz, special-file and symlink destinations in write_metrics write_metrics wrote rows to an extension-less temp file and renamed it into place. That had three problems. A .gz destination received plain text under a .gz name, which the metrics reader then failed to decompress. A non-regular destination such as /dev/stdout, a FIFO or a >(...) process substitution failed at rename time, after the whole run. A symlinked destination was replaced by a regular file. The temp file now carries the destination's extension so compression follows it. Non-regular destinations are written in place. Symlinks are resolved before the atomic rename. Empty outputs derive their header from a plain scratch file, so the gzip path keeps its header too. + +### Testing + +- Fix inconsistent mate-strand flags in duplicate-group fixtures ([#908](https://github.com/fulcrumgenomics/fgumi/pull/908)) + + + ## [0.7.0] - 2026-08-24 ### Bug Fixes diff --git a/crates/fgumi-pipeline-core/CHANGELOG.md b/crates/fgumi-pipeline-core/CHANGELOG.md new file mode 100644 index 000000000..7b92ef896 --- /dev/null +++ b/crates/fgumi-pipeline-core/CHANGELOG.md @@ -0,0 +1,26 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [0.8.0] - 2026-10-08 + +### Features + +- Wire --pipeline-trace through the chain builder ([#937](https://github.com/fulcrumgenomics/fgumi/pull/937)) +- Thread-utilization and per-step bandwidth telemetry for the chain-builder engine ([#951](https://github.com/fulcrumgenomics/fgumi/pull/951)) +- Park idle pool workers to fix the thread-oversubscription cliff ([#955](https://github.com/fulcrumgenomics/fgumi/pull/955)) +- Add a refill-aware drain-first scheduler ([#986](https://github.com/fulcrumgenomics/fgumi/pull/986)) + +### Performance + +- Don't fuse single-thread chains that declare Detached steps ([#884](https://github.com/fulcrumgenomics/fgumi/pull/884)) + +### Refactor + +- [**breaking**] Remove the legacy unified_pipeline engine ([#947](https://github.com/fulcrumgenomics/fgumi/pull/947)) + +### Testing + +- Read drained state once in pair-summer test steps ([#981](https://github.com/fulcrumgenomics/fgumi/pull/981)) + + diff --git a/crates/fgumi-pipeline-io/CHANGELOG.md b/crates/fgumi-pipeline-io/CHANGELOG.md new file mode 100644 index 000000000..b485337f2 --- /dev/null +++ b/crates/fgumi-pipeline-io/CHANGELOG.md @@ -0,0 +1,39 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [0.8.0] - 2026-10-08 + +### Bug Fixes + +- [**breaking**] Enforce --max-temp-files on the arena spill path ([#993](https://github.com/fulcrumgenomics/fgumi/pull/993)) + - fgumi-pipeline-io's SpillBlockEvent::Block gains a required key_kind field, and SpillWrite now emits SpillReady for its surviving runs at AllAnnounced (with slot_count set to their number) instead of as each run closes. RunMergerDyn::step takes a byte budget. +- Leave no output files behind when a chain fails to build ([#1006](https://github.com/fulcrumgenomics/fgumi/pull/1006)) + +### Features + +- Typed-step pipeline foundation ([#870](https://github.com/fulcrumgenomics/fgumi/pull/870)) +- Inline BAI indexer on the arena sink ([#883](https://github.com/fulcrumgenomics/fgumi/pull/883)) +- Route the sort command onto the declarative chain builder ([#885](https://github.com/fulcrumgenomics/fgumi/pull/885)) +- Restore --read-streams on the arena chain via a concurrent scatter reader ([#889](https://github.com/fulcrumgenomics/fgumi/pull/889)) +- Thread --sort-stats diagnostics through the chain ([#913](https://github.com/fulcrumgenomics/fgumi/pull/913)) +- Add --check-crc / --no-check-crc with the file-vs-stdin default ([#933](https://github.com/fulcrumgenomics/fgumi/pull/933)) +- Expose --block-batch and --file-granularity as hidden flags ([#943](https://github.com/fulcrumgenomics/fgumi/pull/943)) +- Thread-utilization and per-step bandwidth telemetry for the chain-builder engine ([#951](https://github.com/fulcrumgenomics/fgumi/pull/951)) + +### Performance + +- Don't fuse single-thread chains that declare Detached steps ([#884](https://github.com/fulcrumgenomics/fgumi/pull/884)) +- Extend runs in the arena spill path (t16 parity) ([#886](https://github.com/fulcrumgenomics/fgumi/pull/886)) +- Parallel gather for the in-memory sort fast path ([#966](https://github.com/fulcrumgenomics/fgumi/pull/966)) + +### Refactor + +- [**breaking**] Remove the legacy unified_pipeline engine ([#947](https://github.com/fulcrumgenomics/fgumi/pull/947)) +- Stop configuring the chain sort through RawExternalSorter ([#999](https://github.com/fulcrumgenomics/fgumi/pull/999)) + +### Testing + +- Speed up the slow-test tail without weakening invariants ([#881](https://github.com/fulcrumgenomics/fgumi/pull/881)) + + diff --git a/crates/fgumi-raw-bam/CHANGELOG.md b/crates/fgumi-raw-bam/CHANGELOG.md index 91293615c..f97a21294 100644 --- a/crates/fgumi-raw-bam/CHANGELOG.md +++ b/crates/fgumi-raw-bam/CHANGELOG.md @@ -2,6 +2,30 @@ All notable changes to this project will be documented in this file. +## [0.8.0] - 2026-10-08 + +### Bug Fixes + +- Replace deprecated wide swizzle_relaxed with shuffle ([#992](https://github.com/fulcrumgenomics/fgumi/pull/992)) +- [**breaking**] Give each methylation consensus caller one SEQ convention and make filters, simulate and docs follow it ([#1010](https://github.com/fulcrumgenomics/fgumi/pull/1010)) + - methylation::query_to_ref_positions takes the CIGAR as aligned (with its clips) and no longer takes the simplified CIGAR. * fix(consensus)!: emit observed bases from simplex methylation consensus Simplex EM-seq/TAPs consensus rewrote converted bases in the source reads (T->C / A->G at reference cytosines) before calling, so the emitted SEQ reported every site as unconverted. SEQ-based methylation callers and bisulfite-aware aligners read methylation from SEQ and saw every cytosine as methylated. The rewrite also hid real disagreements: all reads of a single-strand family copy one converted strand, so a C/T split is an error (or a UMI collision) and must lower quality like any other. Consensus is now always called on the observed bases, and simplex emits them as they are, with the evidence in cu/ct. MM/ML are no longer emitted for simplex: MM can only describe bases present in SEQ, and a converted cytosine is not one. A simplex consensus also cannot tell a converted cytosine from a C>T mutation, so restoring it would assert a base the molecule may not have. The shared MM builder now writes the SAM-spec '?' flag (unlisted bases are unknown), takes the conversion pattern from the read type (R1 C->T, R2 G->A) instead of the alignment strand, encodes each ML probability p as floor(256 p) capped at 255 (the SAM spec's [N/256, (N+1)/256) bins; it used floor(255 p), which put 1/2 and 3/4 in the bin below), and MN is available as a tag constant. +- Classify dovetail FR pairs with coincident 5' ends as FR ([#1022](https://github.com/fulcrumgenomics/fgumi/pull/1022)) +- Truncate source-read cigars before converting hard clips, like fgbio ([#1042](https://github.com/fulcrumgenomics/fgumi/pull/1042)) +- Trim read-through bases when the mate cigar tag is missing ([#1041](https://github.com/fulcrumgenomics/fgumi/pull/1041)) + +### Features + +- Typed-step pipeline foundation ([#870](https://github.com/fulcrumgenomics/fgumi/pull/870)) +- Declarative chain-builder layer + group --threads pilot ([#872](https://github.com/fulcrumgenomics/fgumi/pull/872)) + +### Performance + +- Single-pass aux-tag rebuild (RawTagsEditor::rebuild_with) for zipper merge and NM/UQ/MD strip ([#962](https://github.com/fulcrumgenomics/fgumi/pull/962)) +- Fold per-record PG/AS/XS aux scans into single-pass walks ([#964](https://github.com/fulcrumgenomics/fgumi/pull/964)) +- Reduce serial-merge CPU and allocations at 1-2 threads ([#971](https://github.com/fulcrumgenomics/fgumi/pull/971)) + + + ## [0.7.0] - 2026-08-24 ### Bug Fixes diff --git a/crates/fgumi-sam/CHANGELOG.md b/crates/fgumi-sam/CHANGELOG.md index 4b649d56d..6d1be2761 100644 --- a/crates/fgumi-sam/CHANGELOG.md +++ b/crates/fgumi-sam/CHANGELOG.md @@ -2,6 +2,28 @@ All notable changes to this project will be documented in this file. +## [0.8.0] - 2026-10-08 + +### Bug Fixes + +- [**breaking**] Give each methylation consensus caller one SEQ convention and make filters, simulate and docs follow it ([#1010](https://github.com/fulcrumgenomics/fgumi/pull/1010)) + - methylation::query_to_ref_positions takes the CIGAR as aligned (with its clips) and no longer takes the simplified CIGAR. * fix(consensus)!: emit observed bases from simplex methylation consensus Simplex EM-seq/TAPs consensus rewrote converted bases in the source reads (T->C / A->G at reference cytosines) before calling, so the emitted SEQ reported every site as unconverted. SEQ-based methylation callers and bisulfite-aware aligners read methylation from SEQ and saw every cytosine as methylated. The rewrite also hid real disagreements: all reads of a single-strand family copy one converted strand, so a C/T split is an error (or a UMI collision) and must lower quality like any other. Consensus is now always called on the observed bases, and simplex emits them as they are, with the evidence in cu/ct. MM/ML are no longer emitted for simplex: MM can only describe bases present in SEQ, and a converted cytosine is not one. A simplex consensus also cannot tell a converted cytosine from a C>T mutation, so restoring it would assert a base the molecule may not have. The shared MM builder now writes the SAM-spec '?' flag (unlisted bases are unknown), takes the conversion pattern from the read type (R1 C->T, R2 G->A) instead of the alignment strand, encodes each ML probability p as floor(256 p) capped at 255 (the SAM spec's [N/256, (N+1)/256) bins; it used floor(255 p), which put 1/2 and 3/4 in the bin below), and MN is available as a tag constant. +- Keep MM/ML in step with hard-clipped and unmapped reads ([#1012](https://github.com/fulcrumgenomics/fgumi/pull/1012)) +- Upgrade soft clips only at the mate-facing end when clipping overlaps ([#1015](https://github.com/fulcrumgenomics/fgumi/pull/1015)) +- Never auto-clip RG, MI and other non-per-base tags ([#1019](https://github.com/fulcrumgenomics/fgumi/pull/1019)) +- Classify dovetail FR pairs with coincident 5' ends as FR ([#1022](https://github.com/fulcrumgenomics/fgumi/pull/1022)) +- Truncate source-read cigars before converting hard clips, like fgbio ([#1042](https://github.com/fulcrumgenomics/fgumi/pull/1042)) + +### Performance + +- Single-pass aux-tag rebuild (RawTagsEditor::rebuild_with) for zipper merge and NM/UQ/MD strip ([#962](https://github.com/fulcrumgenomics/fgumi/pull/962)) + +### Testing + +- Port missing fgbio SamRecordClipper and ClipBam tests ([#1018](https://github.com/fulcrumgenomics/fgumi/pull/1018)) + + + ## [0.7.0] - 2026-08-24 ### Bug Fixes diff --git a/crates/fgumi-simd-fastq/CHANGELOG.md b/crates/fgumi-simd-fastq/CHANGELOG.md index f106c2d89..a1ecb95cb 100644 --- a/crates/fgumi-simd-fastq/CHANGELOG.md +++ b/crates/fgumi-simd-fastq/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. +## [0.8.0] - 2026-10-08 + +### Bug Fixes + +- Accept empty input and sample an unterminated final FASTQ record ([#1024](https://github.com/fulcrumgenomics/fgumi/pull/1024)) + + + ## [0.7.0] - 2026-08-24 diff --git a/crates/fgumi-sort/CHANGELOG.md b/crates/fgumi-sort/CHANGELOG.md index e94d2c532..1df338eed 100644 --- a/crates/fgumi-sort/CHANGELOG.md +++ b/crates/fgumi-sort/CHANGELOG.md @@ -4,6 +4,42 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +## [0.8.0] - 2026-10-08 + +### Bug Fixes + +- [**breaking**] Enforce --max-temp-files on the arena spill path ([#993](https://github.com/fulcrumgenomics/fgumi/pull/993)) + - fgumi-pipeline-io's SpillBlockEvent::Block gains a required key_kind field, and SpillWrite now emits SpillReady for its surviving runs at AllAnnounced (with slot_count set to their number) instead of as each run closes. RunMergerDyn::step takes a byte budget. +- Accept bwa's mid-pair -K split; emit BAM from the bwa-mem3 preset; keep mimalloc from purging ([#988](https://github.com/fulcrumgenomics/fgumi/pull/988)) +- Bound the mimalloc purge delay instead of never purging ([#1017](https://github.com/fulcrumgenomics/fgumi/pull/1017)) + +### Documentation + +- Remove in-tree design docs and gitignore docs/design/ ([#934](https://github.com/fulcrumgenomics/fgumi/pull/934)) + +### Features + +- Typed-step pipeline foundation ([#870](https://github.com/fulcrumgenomics/fgumi/pull/870)) +- Declarative chain-builder layer + group --threads pilot ([#872](https://github.com/fulcrumgenomics/fgumi/pull/872)) +- Restore --read-streams on the arena chain via a concurrent scatter reader ([#889](https://github.com/fulcrumgenomics/fgumi/pull/889)) +- Give stage option structs a clap::Args surface for runall (PR A) ([#907](https://github.com/fulcrumgenomics/fgumi/pull/907)) +- Add the bam-roundtrip subcommand ([#936](https://github.com/fulcrumgenomics/fgumi/pull/936)) +- Thread-utilization and per-step bandwidth telemetry for the chain-builder engine ([#951](https://github.com/fulcrumgenomics/fgumi/pull/951)) +- Align in process with bwa-mem3 (--aligner::preset bwa-mem3-inproc) ([#990](https://github.com/fulcrumgenomics/fgumi/pull/990)) + +### Performance + +- Use fixed-seed ahash on hot per-item maps to remove RandomState global-counter contention ([#865](https://github.com/fulcrumgenomics/fgumi/pull/865)) +- Extend runs in the arena spill path (t16 parity) ([#886](https://github.com/fulcrumgenomics/fgumi/pull/886)) +- Parallel gather for the in-memory sort fast path ([#966](https://github.com/fulcrumgenomics/fgumi/pull/966)) + +### Refactor + +- [**breaking**] Remove the legacy unified_pipeline engine ([#947](https://github.com/fulcrumgenomics/fgumi/pull/947)) +- Stop configuring the chain sort through RawExternalSorter ([#999](https://github.com/fulcrumgenomics/fgumi/pull/999)) + + + ## [0.7.0] - 2026-08-24 ### Features diff --git a/crates/fgumi-tag/CHANGELOG.md b/crates/fgumi-tag/CHANGELOG.md index 29bb15e09..935708cf1 100644 --- a/crates/fgumi-tag/CHANGELOG.md +++ b/crates/fgumi-tag/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. +## [0.8.0] - 2026-10-08 + +### Bug Fixes + +- [**breaking**] Give each methylation consensus caller one SEQ convention and make filters, simulate and docs follow it ([#1010](https://github.com/fulcrumgenomics/fgumi/pull/1010)) + - methylation::query_to_ref_positions takes the CIGAR as aligned (with its clips) and no longer takes the simplified CIGAR. * fix(consensus)!: emit observed bases from simplex methylation consensus Simplex EM-seq/TAPs consensus rewrote converted bases in the source reads (T->C / A->G at reference cytosines) before calling, so the emitted SEQ reported every site as unconverted. SEQ-based methylation callers and bisulfite-aware aligners read methylation from SEQ and saw every cytosine as methylated. The rewrite also hid real disagreements: all reads of a single-strand family copy one converted strand, so a C/T split is an error (or a UMI collision) and must lower quality like any other. Consensus is now always called on the observed bases, and simplex emits them as they are, with the evidence in cu/ct. MM/ML are no longer emitted for simplex: MM can only describe bases present in SEQ, and a converted cytosine is not one. A simplex consensus also cannot tell a converted cytosine from a C>T mutation, so restoring it would assert a base the molecule may not have. The shared MM builder now writes the SAM-spec '?' flag (unlisted bases are unknown), takes the conversion pattern from the read type (R1 C->T, R2 G->A) instead of the alignment strand, encodes each ML probability p as floor(256 p) capped at 255 (the SAM spec's [N/256, (N+1)/256) bins; it used floor(255 p), which put 1/2 and 3/4 in the bin below), and MN is available as a tag constant. +- Never auto-clip RG, MI and other non-per-base tags ([#1019](https://github.com/fulcrumgenomics/fgumi/pull/1019)) + + + ## [0.7.0] - 2026-08-24 ### Miscellaneous Tasks diff --git a/crates/fgumi-umi/CHANGELOG.md b/crates/fgumi-umi/CHANGELOG.md index dfee5642b..9ad934348 100644 --- a/crates/fgumi-umi/CHANGELOG.md +++ b/crates/fgumi-umi/CHANGELOG.md @@ -2,6 +2,25 @@ All notable changes to this project will be documented in this file. +## [0.8.0] - 2026-10-08 + +### Bug Fixes + +- [**breaking**] Reverse the methylation counts with the Consensus tag set ([#1011](https://github.com/fulcrumgenomics/fgumi/pull/1011)) + - zipper --tags-to-reverse Consensus now also reverses cu, ct, au, at, bu and bt, and fgumi_umi::TagSets::CONSENSUS_REVERSE lists those six tags after fgbio's eight; a pipeline that reverses with both zipper Consensus and filter --reverse-per-base-tags now reverses those counts twice as well, so reverse in only one of the two. +- Report mixed UMI lengths as an error instead of panicking ([#1030](https://github.com/fulcrumgenomics/fgumi/pull/1030)) + +### Features + +- Typed-step pipeline foundation ([#870](https://github.com/fulcrumgenomics/fgumi/pull/870)) +- Declarative chain-builder layer + group --threads pilot ([#872](https://github.com/fulcrumgenomics/fgumi/pull/872)) + +### Performance + +- Use fixed-seed ahash on hot per-item maps to remove RandomState global-counter contention ([#865](https://github.com/fulcrumgenomics/fgumi/pull/865)) + + + ## [0.7.0] - 2026-08-24 ### Documentation