seqpro 0.15.2__tar.gz → 0.17.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. seqpro-0.17.0/.github/workflows/bench.yaml +60 -0
  2. {seqpro-0.15.2 → seqpro-0.17.0}/.github/workflows/lint.yaml +2 -2
  3. {seqpro-0.15.2 → seqpro-0.17.0}/.github/workflows/test.yaml +2 -2
  4. {seqpro-0.15.2 → seqpro-0.17.0}/.pre-commit-config.yaml +18 -0
  5. {seqpro-0.15.2 → seqpro-0.17.0}/CHANGELOG.md +104 -0
  6. {seqpro-0.15.2 → seqpro-0.17.0}/Cargo.lock +221 -36
  7. {seqpro-0.15.2 → seqpro-0.17.0}/Cargo.toml +1 -1
  8. {seqpro-0.15.2 → seqpro-0.17.0}/PKG-INFO +1 -1
  9. {seqpro-0.15.2 → seqpro-0.17.0}/README.md +1 -0
  10. seqpro-0.17.0/benches/bench_tokenize_translate.py +30 -0
  11. seqpro-0.17.0/benchmarks/bench_ragged_backends.py +481 -0
  12. seqpro-0.17.0/docs/roadmap/rust-ragged.md +388 -0
  13. seqpro-0.17.0/docs/superpowers/plans/2026-06-18-rust-tokenize-translate.md +1391 -0
  14. seqpro-0.17.0/docs/superpowers/plans/2026-06-19-rust-ragged-core.md +1347 -0
  15. seqpro-0.17.0/docs/superpowers/plans/2026-06-20-rust-ragged-records.md +1583 -0
  16. seqpro-0.17.0/docs/superpowers/plans/2026-06-20-rust-ragged-spec-c.md +1556 -0
  17. seqpro-0.17.0/docs/superpowers/plans/2026-06-21-ragged-throughput-gate.md +656 -0
  18. seqpro-0.17.0/docs/superpowers/plans/2026-06-21-rust-ragged-consumer-audit.md +492 -0
  19. seqpro-0.17.0/docs/superpowers/specs/2026-06-18-rust-tokenize-translate-design.md +360 -0
  20. seqpro-0.17.0/docs/superpowers/specs/2026-06-19-rust-ragged-core-design.md +260 -0
  21. seqpro-0.17.0/docs/superpowers/specs/2026-06-20-rust-ragged-nested-design.md +364 -0
  22. seqpro-0.17.0/docs/superpowers/specs/2026-06-20-rust-ragged-records-design.md +327 -0
  23. seqpro-0.17.0/docs/superpowers/specs/2026-06-21-ragged-throughput-gate-design.md +166 -0
  24. seqpro-0.17.0/docs/superpowers/specs/2026-06-21-rust-ragged-audit-ledger.md +75 -0
  25. seqpro-0.17.0/docs/superpowers/specs/2026-06-21-rust-ragged-consumer-audit-design.md +121 -0
  26. {seqpro-0.15.2 → seqpro-0.17.0}/pixi.lock +38 -16
  27. {seqpro-0.15.2 → seqpro-0.17.0}/pixi.toml +6 -1
  28. {seqpro-0.15.2 → seqpro-0.17.0}/pyproject.toml +7 -1
  29. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/_encoders.py +33 -8
  30. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/alphabets/_alphabets.py +137 -92
  31. seqpro-0.17.0/python/seqpro/rag/__init__.py +29 -0
  32. seqpro-0.17.0/python/seqpro/rag/_ak_interop.py +208 -0
  33. seqpro-0.17.0/python/seqpro/rag/_core.py +1559 -0
  34. seqpro-0.17.0/python/seqpro/rag/_ingest.py +252 -0
  35. seqpro-0.17.0/python/seqpro/rag/_layout.py +172 -0
  36. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/rag/_ops.py +161 -49
  37. {seqpro-0.15.2 → seqpro-0.17.0}/skills/seqpro/SKILL.md +36 -25
  38. {seqpro-0.15.2 → seqpro-0.17.0}/src/kshuffle.rs +132 -65
  39. seqpro-0.17.0/src/lib.rs +212 -0
  40. seqpro-0.17.0/src/ragged.rs +612 -0
  41. seqpro-0.17.0/src/translate.rs +510 -0
  42. seqpro-0.17.0/tests/test_concatenate.py +29 -0
  43. seqpro-0.17.0/tests/test_core_ragged_surface.py +36 -0
  44. seqpro-0.17.0/tests/test_ingest.py +19 -0
  45. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_rag_to_packed.py +93 -28
  46. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_ragged.py +57 -34
  47. seqpro-0.17.0/tests/test_ragged_core.py +810 -0
  48. seqpro-0.17.0/tests/test_ragged_core_records.py +682 -0
  49. seqpro-0.17.0/tests/test_ragged_nested_consumers.py +68 -0
  50. seqpro-0.17.0/tests/test_ragged_nested_diff.py +297 -0
  51. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_ragged_rc.py +20 -26
  52. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_ragged_to_padded.py +66 -6
  53. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_tokenize.py +50 -0
  54. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_translate.py +48 -19
  55. seqpro-0.17.0/tests/test_translate_rust.py +135 -0
  56. seqpro-0.15.2/.github/workflows/bench.yaml +0 -31
  57. seqpro-0.15.2/python/seqpro/rag/__init__.py +0 -15
  58. seqpro-0.15.2/python/seqpro/rag/_array.py +0 -904
  59. seqpro-0.15.2/python/seqpro/rag/_gufuncs.py +0 -14
  60. seqpro-0.15.2/src/lib.rs +0 -44
  61. {seqpro-0.15.2 → seqpro-0.17.0}/.claude/skills/zensical/SKILL.md +0 -0
  62. {seqpro-0.15.2 → seqpro-0.17.0}/.gitattributes +0 -0
  63. {seqpro-0.15.2 → seqpro-0.17.0}/.github/workflows/bump.yaml +0 -0
  64. {seqpro-0.15.2 → seqpro-0.17.0}/.github/workflows/docs.yml +0 -0
  65. {seqpro-0.15.2 → seqpro-0.17.0}/.github/workflows/merge.yaml +0 -0
  66. {seqpro-0.15.2 → seqpro-0.17.0}/.github/workflows/publish.yaml +0 -0
  67. {seqpro-0.15.2 → seqpro-0.17.0}/.github/workflows/release-pipeline.yaml +0 -0
  68. {seqpro-0.15.2 → seqpro-0.17.0}/.github/workflows/release.yaml +0 -0
  69. {seqpro-0.15.2 → seqpro-0.17.0}/.gitignore +0 -0
  70. {seqpro-0.15.2 → seqpro-0.17.0}/CLAUDE.md +0 -0
  71. {seqpro-0.15.2 → seqpro-0.17.0}/LICENSE +0 -0
  72. {seqpro-0.15.2 → seqpro-0.17.0}/benches/kshuffle.rs +0 -0
  73. {seqpro-0.15.2 → seqpro-0.17.0}/benchmarks/bench_to_packed.py +0 -0
  74. {seqpro-0.15.2 → seqpro-0.17.0}/docs/api/alphabets.md +0 -0
  75. {seqpro-0.15.2 → seqpro-0.17.0}/docs/api/bed.md +0 -0
  76. {seqpro-0.15.2 → seqpro-0.17.0}/docs/api/gtf.md +0 -0
  77. {seqpro-0.15.2 → seqpro-0.17.0}/docs/api/index.md +0 -0
  78. {seqpro-0.15.2 → seqpro-0.17.0}/docs/api/ragged.md +0 -0
  79. {seqpro-0.15.2 → seqpro-0.17.0}/docs/api/types.md +0 -0
  80. {seqpro-0.15.2 → seqpro-0.17.0}/docs/index.md +0 -0
  81. {seqpro-0.15.2 → seqpro-0.17.0}/docs/ragged.md +0 -0
  82. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-05-04-ragged-record-array.md +0 -0
  83. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-05-05-documentation-site.md +0 -0
  84. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-05-05-narwhals-coord-schema.md +0 -0
  85. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-05-05-ragged-zip-and-record-introspection.md +0 -0
  86. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-05-20-kshuffle-optimization.md +0 -0
  87. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-05-20-kshuffle-pooled-buffers-and-k2-fast-path.md +0 -0
  88. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-05-20-kshuffle-wilson-single-pass.md +0 -0
  89. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-05-20-release-pipeline.md +0 -0
  90. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-05-28-translate-lut-validation.md +0 -0
  91. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-05-31-flat-buffer-to-padded.md +0 -0
  92. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-05-31-rag-to-packed.md +0 -0
  93. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-06-05-translate-unknown-codon-policy.md +0 -0
  94. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/plans/2026-06-12-tokenize-lut-codspeed.md +0 -0
  95. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-05-04-ragged-record-array-design.md +0 -0
  96. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-05-05-documentation-site-design.md +0 -0
  97. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-05-05-narwhals-coord-schema-design.md +0 -0
  98. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-05-05-ragged-zip-and-record-introspection-design.md +0 -0
  99. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-05-20-kshuffle-optimization-design.md +0 -0
  100. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-05-20-kshuffle-pooled-buffers-and-k2-fast-path-design.md +0 -0
  101. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-05-20-kshuffle-wilson-single-pass-design.md +0 -0
  102. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-05-20-release-pipeline-design.md +0 -0
  103. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-05-28-translate-lut-and-validation-design.md +0 -0
  104. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-05-31-flat-buffer-to-padded-design.md +0 -0
  105. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-05-31-rag-to-packed-design.md +0 -0
  106. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-06-05-translate-unknown-codon-policy-design.md +0 -0
  107. {seqpro-0.15.2 → seqpro-0.17.0}/docs/superpowers/specs/2026-06-12-tokenize-lut-codspeed-design.md +0 -0
  108. {seqpro-0.15.2 → seqpro-0.17.0}/meta.yaml +0 -0
  109. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/__init__.py +0 -0
  110. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/_analyzers.py +0 -0
  111. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/_cleaners.py +0 -0
  112. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/_coords.py +0 -0
  113. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/_modifiers.py +0 -0
  114. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/_numba.py +0 -0
  115. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/_types.py +0 -0
  116. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/_utils.py +0 -0
  117. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/alphabets/__init__.py +0 -0
  118. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/bed.py +0 -0
  119. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/experimental/_experimental.py +0 -0
  120. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/experimental/_visualizers.py +0 -0
  121. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/gtf.py +0 -0
  122. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/py.typed +0 -0
  123. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/rag/_types.py +0 -0
  124. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/rag/_utils.py +0 -0
  125. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/transforms/__init__.py +0 -0
  126. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/transforms/augmentation.py +0 -0
  127. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/transforms/tmm.py +0 -0
  128. {seqpro-0.15.2 → seqpro-0.17.0}/python/seqpro/xr/__init__.py +0 -0
  129. {seqpro-0.15.2 → seqpro-0.17.0}/scratch_bench_rc.py +0 -0
  130. {seqpro-0.15.2 → seqpro-0.17.0}/scratch_bench_to_padded.py +0 -0
  131. {seqpro-0.15.2 → seqpro-0.17.0}/src/kmer_encode.rs +0 -0
  132. {seqpro-0.15.2 → seqpro-0.17.0}/src/kshuffle_ref.rs +0 -0
  133. {seqpro-0.15.2 → seqpro-0.17.0}/tests/_shape_fixtures.py +0 -0
  134. {seqpro-0.15.2 → seqpro-0.17.0}/tests/bed/test_pyranges.py +0 -0
  135. {seqpro-0.15.2 → seqpro-0.17.0}/tests/bed/test_read.py +0 -0
  136. {seqpro-0.15.2 → seqpro-0.17.0}/tests/bed/test_sort.py +0 -0
  137. {seqpro-0.15.2 → seqpro-0.17.0}/tests/bed/test_with_length.py +0 -0
  138. {seqpro-0.15.2 → seqpro-0.17.0}/tests/bench_translate_lut.py +0 -0
  139. {seqpro-0.15.2 → seqpro-0.17.0}/tests/conftest.py +0 -0
  140. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_analyzers.py +0 -0
  141. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_bench_tokenize.py +0 -0
  142. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_coords.py +0 -0
  143. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_encoders.py +0 -0
  144. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_modifiers.py +0 -0
  145. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_ohe.py +0 -0
  146. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_shape_matrix.py +0 -0
  147. {seqpro-0.15.2 → seqpro-0.17.0}/tests/test_transforms.py +0 -0
  148. {seqpro-0.15.2 → seqpro-0.17.0}/zensical.toml +0 -0
@@ -0,0 +1,60 @@
1
+ name: Benchmarks
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ branches:
9
+ - main
10
+ workflow_dispatch:
11
+
12
+ permissions:
13
+ contents: read
14
+ id-token: write # for OpenID Connect authentication with CodSpeed
15
+
16
+ jobs:
17
+ python-benchmarks:
18
+ runs-on: ubuntu-latest
19
+ name: "Run Python CodSpeed benchmarks"
20
+ steps:
21
+ - name: Check out
22
+ uses: actions/checkout@v4
23
+ with:
24
+ fetch-depth: 0
25
+ - name: Setup pixi
26
+ uses: prefix-dev/setup-pixi@v0.9.5
27
+ with:
28
+ pixi-version: v0.70.1
29
+ cache: true
30
+ environments: bench
31
+ locked: true
32
+ - name: Build extension
33
+ run: pixi run -e bench maturin develop --uv
34
+ - name: Run benchmarks
35
+ uses: CodSpeedHQ/action@v4
36
+ with:
37
+ mode: simulation
38
+ run: pixi run -e bench bench
39
+
40
+ rust-benchmarks:
41
+ runs-on: ubuntu-latest
42
+ name: "Run Rust CodSpeed benchmarks"
43
+ steps:
44
+ - name: Check out
45
+ uses: actions/checkout@v4
46
+ with:
47
+ fetch-depth: 0
48
+ - name: Setup rust toolchain, cache and cargo-codspeed binary
49
+ uses: moonrepo/setup-rust@v0
50
+ with:
51
+ channel: stable
52
+ cache-target: release
53
+ bins: cargo-codspeed
54
+ - name: Build the benchmark target(s)
55
+ run: cargo codspeed build
56
+ - name: Run benchmarks
57
+ uses: CodSpeedHQ/action@v4
58
+ with:
59
+ mode: simulation
60
+ run: cargo codspeed run
@@ -11,8 +11,8 @@ jobs:
11
11
  - name: Setup pixi
12
12
  uses: prefix-dev/setup-pixi@v0.9.5
13
13
  with:
14
- pixi-version: v0.67.2
14
+ pixi-version: v0.70.1
15
15
  cache: true
16
16
  environments: default
17
- locked: false
17
+ locked: true
18
18
  - uses: j178/prek-action@v2
@@ -21,9 +21,9 @@ jobs:
21
21
  - name: Setup pixi
22
22
  uses: prefix-dev/setup-pixi@v0.9.5
23
23
  with:
24
- pixi-version: v0.67.2
24
+ pixi-version: v0.70.1
25
25
  cache: true
26
26
  environments: ${{ matrix.environment }}
27
- locked: false
27
+ locked: true
28
28
  - name: Test
29
29
  run: pixi run -e ${{ matrix.environment }} test
@@ -33,3 +33,21 @@ repos:
33
33
  language: system
34
34
  stages: [pre-push]
35
35
  pass_filenames: false
36
+ - id: cargo-check
37
+ name: Type-check Rust with cargo check
38
+ entry: cargo check --all-targets --all-features
39
+ language: system
40
+ types: [rust]
41
+ pass_filenames: false
42
+ - id: cargo-fmt
43
+ name: Format Rust with cargo fmt
44
+ entry: cargo fmt --all
45
+ language: system
46
+ types: [rust]
47
+ pass_filenames: false
48
+ - id: cargo-clippy
49
+ name: Lint Rust with cargo clippy
50
+ entry: cargo clippy --all-targets -- -D warnings
51
+ language: system
52
+ types: [rust]
53
+ pass_filenames: false
@@ -1,3 +1,107 @@
1
+ ## 0.17.0 (2026-06-23)
2
+
3
+ ### Feat
4
+
5
+ - **rag**: concatenate() along ragged axis (Rust kernel)
6
+ - **rag**: to_packed() on record and opaque-string-under-axis Ragged
7
+ - wire rag-gate pixi task; record throughput gate outcome
8
+ - string-conversion op cells for Ragged throughput gate
9
+ - nested R=2 op cells for Ragged throughput gate
10
+ - record (SoA) op cells for Ragged throughput gate
11
+ - single-level op cells for Ragged throughput gate
12
+ - harness core for rust-vs-awkward Ragged throughput gate
13
+ - _ingest bridge for R=2 + string-under-axis (oracle interop)
14
+ - nested record indexing + record-aware to_packed/to_padded/to_numpy
15
+ - nested + string-under-axis record fields sharing full offsets list
16
+ - R=2 lengths/squeeze/reshape
17
+ - per-axis nested to_padded + rectangular to_numpy (R=2); trailing-dim support in to_padded
18
+ - nested to_packed via nested_pack kernel
19
+ - nested_pack Rust kernel + binding for two-level pack
20
+ - per-group inner mask/int-array indexing via nested_gather
21
+ - nested_gather Rust kernel + binding for per-group middle selection
22
+ - per-group inner int/slice indexing (rag[:, k], rag[:, a:b])
23
+ - R=2 tuple indexing + leaf access via peel chaining
24
+ - R=2 outer-row indexing (lazy gather, peel to 1-level)
25
+ - string-under-axis leaf + nested to_chars/to_strings
26
+ - nested constructors from_offsets(list)/from_lengths(tuple) for R=2
27
+ - validate R=2 nested ragged layouts; cap at R<=2
28
+ - ingest/emit record layouts via awkward bridge (oracle interop)
29
+ - record to_numpy/to_padded dicts; raise view/ufunc on records
30
+ - record-aware to_packed (one shared packed offsets across fields)
31
+ - per-field squeeze/reshape on record Ragged
32
+ - record row-axis indexing (slice/mask -> record, int -> dict)
33
+ - record field access (key/attr) and __setitem__ mutation
34
+ - record-branch properties (data/dtype/offsets/shape/fields/state)
35
+ - add Ragged.from_fields record constructor and rag.zip alias
36
+ - add RecordLayout value object and validation arm
37
+ - add zero-copy to_chars/to_strings between opaque-string and char Ragged
38
+ - disambiguate opaque-string vs char layout by presence of None in shape
39
+ - report np.dtype('S') for opaque-string Ragged (string/char duality)
40
+ - **rust**: ragged_validate and ragged_select kernels
41
+ - **rag**: awkward ingestion and to_ak shim
42
+ - **rag**: to_numpy, to_packed, to_padded
43
+ - **rag**: squeeze and reshape on regular dims
44
+ - **rag**: element-wise ufunc interop
45
+ - **rag**: __getitem__ indexing and slicing
46
+ - **rag**: state predicates and view
47
+ - **rag**: Ragged constructors and core properties
48
+ - **rag**: RaggedLayout value object + validation
49
+ - **translate**: self-contained Rust OHE<->AA path with native drop
50
+ - **translate**: route truncate_stop through Rust
51
+ - **translate**: route unknown=drop compaction through Rust
52
+ - **translate**: route ragged bytes pad path through Rust
53
+ - **translate**: route dense pad path through Rust
54
+ - **rust**: add codon-stride translate kernels
55
+ - **tokenize**: route ragged path through Rust, drop Numba gather
56
+ - **tokenize**: route dense path through Rust _tokenize
57
+ - **rust**: add tokenize LUT gather kernel
58
+
59
+ ### Fix
60
+
61
+ - **rag**: to_ak() on multi-leading-axis record Ragged
62
+ - **rag**: _core.Ragged/tokenize fixes found via genvarformer audit
63
+ - **rag**: add __len__, np.newaxis support, and element-wise fancy indexing to _core.Ragged
64
+ - **rag**: _ops.to_padded record detection works for both _array and _core backends
65
+ - **rag**: _core.to_numpy returns dict for records (restore designed contract); update _array-era test
66
+ - **rag**: correct _core getitem tuple routing for rag_dim==1 found via SeqPro own-suite audit
67
+ - **rag**: port _ops + _core to_packed/is_rag_dtype/to_numpy to _core object model
68
+ - **rag**: precise _core getitem routing — _core contract + genoray parity both green
69
+ - **rag**: repair _core.Ragged getitem regressions (string leaf, to_strings, r2 int array)
70
+ - **rag**: match _array is_base semantics for non-ndarray base
71
+ - **rag**: _core.Ragged fixes found via genoray audit
72
+ - **bench**: time to_packed on unpacked input so single-level pack compares equal work
73
+ - forward --repeats CLI flag into time_callable
74
+ - R=2 is_contiguous checks all offset levels; guard string-under-axis to_packed/to_numpy
75
+ - panic-safety in nested_pack (checked_mul, elem>0, o0-range guard)
76
+ - reject negative inner-slice bounds in rag[:, a:b]
77
+ - -O-safe record guards on is_string/to_chars/to_strings; note latent S4 over-acceptance
78
+ - raise TypeError on np.asarray of a record Ragged (-O-safe, was a bare assert)
79
+ - **rag**: reject mismatched boolean masks and bounds-check ragged_select
80
+ - **translate**: handle empty dense input in unknown=drop path
81
+
82
+ ### Refactor
83
+
84
+ - **rag**: delete awkward _array backend; relocate interop to _ak_interop
85
+ - resolve clippy findings for -D warnings
86
+ - **rag**: route index/validate hot paths through Rust
87
+ - **rag**: use NDArrayOperatorsMixin for operator dunders
88
+ - **tokenize**: restore np.take/Numba path; Rust port regressed vs baseline
89
+
90
+ ### Perf
91
+
92
+ - validate pack output size up-front; test parallel pack path
93
+ - Rust single-level pack kernel for to_packed (parallel gather)
94
+ - opt-in Ragged validation (default off) + slice indexing fast-path
95
+ - drop redundant per-field copy in record to_packed; align record is_base with single-level one-indirection rule
96
+ - **translate**: optimize LUT gather kernel (validity table + coarse chunking)
97
+ - **translate**: add rayon parallel path for large inputs
98
+
99
+ ## 0.16.0 (2026-06-14)
100
+
101
+ ### Feat
102
+
103
+ - **tokenize**: add parallel escape hatch overriding the size heuristic
104
+
1
105
  ## 0.15.2 (2026-06-13)
2
106
 
3
107
  ### Fix