Skip to content

fix: share setup-prefix coefficients and inner rows - #261

Merged
RadNi merged 7 commits into
mainfrom
codex/share-setup-prefix-storage
Oct 26, 2026
Merged

RadNi merged 7 commits into
mainfrom
codex/share-setup-prefix-storage

Conversation

@RadNi

@RadNi RadNi commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Share setup-prefix coefficients through bounded views of the expanded setup. Store equal inner ring commitments once across prefix hints, including clones and imports.

Motivation

Verifier preprocessing retains duplicate source coefficients and inner commitments across prefixes. Shared storage reduces memory use while keeping setup ownership within each backend.

Testing

Tests cover source lifetime, bounds, zero padding, shared rows, hash collisions, concurrent access, imports, and serialized byte equality.

Security Considerations

Verifier acceptance, transcripts, serialization, and decoding limits remain unchanged. Hashes select sharing candidates only; every coefficient must match before storage is shared.

No dependencies or unsafe code are added.

Breaking Changes

None.

@RadNi
RadNi requested a review from a team October 25, 2026 06:37
@github-actions

Copy link
Copy Markdown

Warning

This PR has more than 500 changed lines and does not include a spec.

Large features and architectural changes benefit from a short spec before implementation review.
See CONTRIBUTING.md for the spec workflow.

If this PR is a bug fix, small cleanup, or otherwise does not warrant a spec, feel free to ignore this message.

@github-actions github-actions Bot added the no-spec PR has no spec file label Oct 25, 2026
@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Documentation blast radius (advisory)

These regions may need doc/spec/book updates based on changed paths.
This is not a merge gate. See docs/documentation.md.

Changed files in this PR: 19

commitment-setup

Setup expansion and Ajtai commitment

Code paths touched:

  • crates/akita-cpu-backend/src/commitment/executor.rs
  • crates/akita-cpu-backend/src/commitment/mod.rs
  • crates/akita-cpu-backend/src/commitment/portable.rs
  • crates/akita-cpu-backend/src/commitment/shared_inner.rs
  • crates/akita-cpu-backend/src/commitment/state_policy.rs
  • crates/akita-cpu-backend/src/commitment/tests/api.rs
  • crates/akita-cpu-backend/src/commitment/tests/fusion.rs
  • crates/akita-cpu-backend/src/opaque/backend.rs
  • crates/akita-cpu-backend/src/opaque/owned_prefix.rs
  • crates/akita-cpu-backend/src/opaque/owned_prefix/streaming.rs
  • crates/akita-cpu-backend/src/opaque/owned_prefix/streaming/products.rs
  • crates/akita-cpu-backend/src/opaque/owned_prefix/streaming/tests.rs

Consider updating:

  • book/src/how/commitment.md
  • book/src/usage/commitment-api.md
  • book/src/usage/setup-runtime.md
  • specs/family-agnostic-cpu-backend.md
  • specs/setup-*.md

Per-PR checklist: spec Status / acceptance criteria; book owning page; AGENTS.md if contracts changed; archive spec after fold.

@RadNi
RadNi force-pushed the codex/share-setup-prefix-storage branch from e61b1c0 to 12fcf74 Compare October 25, 2026 06:41
@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

PCS Profile Benchmark

13 of 13 profiles passed.

Times are medians of 3 measured runs after 1 discarded warmup run. Peak RSS is the largest measured value.

Each sample verifies the same proof first with the configured multi-threaded pool and then with one thread. Both timings reuse the same verifier setup.

Merge-base comparisons are available for 13 of 13 profiles. For matching profiles, the head and merge-base binaries ran interleaved on the same runner.

Benchmark shards

CI shard Profiles
1-fp32-base Fp32 dense nv30, direct setup check
Fp32 one-hot nv34, direct setup check
2-fp64-base Fp64 dense nv29, direct setup check
Fp64 one-hot nv35, direct setup check
3-fp128-base Fp128 dense nv28, direct setup check
Fp128 one-hot nv36, direct setup check
Fp128 one-hot nv36, recursive setup check
4-multi-group-direct Fp128 multi-group (final nv34, 4 polys total), direct setup check
5-multi-group-recursive Fp128 multi-group (final nv34, 4 polys total), recursive setup check
6-multi-group-recursive-w8r2 Fp128 multi-group W8R2 (final nv32, 4 polys total), recursive setup check
7-distributed Fp128 one-hot nv32 W2R2, direct setup check
Fp128 one-hot nv32 W4R2, direct setup check
Fp128 one-hot nv32 W8R2, direct setup check

Public opening statements

Public opening statement Profiles
Over Fp32, one committed 30 variable multilinear polynomial with 2^30 coefficients is opened at one 30 coordinate point. Fp32 dense nv30, direct setup check
Over Fp32, one committed 34 variable multilinear polynomial with 2^34 coefficients is opened at one 34 coordinate point. Fp32 one-hot nv34, direct setup check
Over Fp64, one committed 29 variable multilinear polynomial with 2^29 coefficients is opened at one 29 coordinate point. Fp64 dense nv29, direct setup check
Over Fp64, one committed 35 variable multilinear polynomial with 2^35 coefficients is opened at one 35 coordinate point. Fp64 one-hot nv35, direct setup check
Over Fp128, one committed 28 variable multilinear polynomial with 2^28 coefficients is opened at one 28 coordinate point. Fp128 dense nv28, direct setup check
Over Fp128, one committed 36 variable multilinear polynomial with 2^36 coefficients is opened at one 36 coordinate point. Fp128 one-hot nv36, direct setup check
Fp128 one-hot nv36, recursive setup check
Over Fp128, 4 polynomials in 3 groups: one 16 variable polynomial at its own point, one 16 variable polynomial at its own point, and 2 34 variable polynomials at one shared point. Fp128 multi-group (final nv34, 4 polys total), direct setup check
Fp128 multi-group (final nv34, 4 polys total), recursive setup check
Over Fp128, 4 polynomials in 3 groups: one 16 variable polynomial at its own point, one 16 variable polynomial at its own point, and 2 32 variable polynomials at one shared point. Fp128 multi-group W8R2 (final nv32, 4 polys total), recursive setup check
Over Fp128, one committed 32 variable multilinear polynomial with 2^32 coefficients is opened at one 32 coordinate point. Fp128 one-hot nv32 W2R2, direct setup check
Fp128 one-hot nv32 W4R2, direct setup check
Fp128 one-hot nv32 W8R2, direct setup check

One-hot profiles generate deterministic witnesses with one 1 in every consecutive chunk of 256 coefficients. This witness shape is not a separate public claim.

Direct evaluates the public setup contribution during Stage 2. Recursive carries the same check through a Stage 3 setup-product sumcheck. Both modes execute the complete fold schedule and terminal verification.

The chunked profiles W2R2, W4R2, W8R2 divide the witness relation into the stated number of exact chunks for the first two fold levels.

Generated profiles may select different A, B, and D ring dimensions at different fold levels. The short profile names omit those dimensions.

Each sample generates deterministic witnesses and opening points, prepares setup, commits, proves, serializes the proof, checks its size, prepares verifier setup, and verifies the claimed openings. It does not test malformed proofs.

Phase time

Profile Setup Commit Prove Verify, multi-threaded Verify, single-threaded
Fp32 dense nv30, direct setup check 0.020 s
+0.9%
0.950 s
-0.3%
1.141 s
+0.4%
16.2 ms
+3.4%
40.2 ms
+0.1%
Fp32 one-hot nv34, direct setup check 0.039 s
-0.6%
0.582 s
-0.7%
1.162 s
+1.5%
16.8 ms
-1.6%
76.8 ms
+0.1%
Fp64 dense nv29, direct setup check 0.051 s
-4.4%
0.790 s
-0.8%
0.891 s
-0.5%
13.5 ms
-4.8%
36.1 ms
-0.5%
Fp64 one-hot nv35, direct setup check 0.093 s
+0.5%
1.654 s
-1.3%
1.295 s
-0.3%
17.5 ms
+0.9%
86.4 ms
+0.5%
Fp128 dense nv28, direct setup check 0.064 s
-2.6%
0.714 s
-1.5%
0.759 s
-7.9%
11.4 ms
+2.4%
41.0 ms
-0.2%
Fp128 one-hot nv36, direct setup check 0.243 s
-1.8%
3.505 s
-0.3%
1.584 s
-9.8%
22.1 ms
+2.6%
136.7 ms
-0.2%
Fp128 one-hot nv36, recursive setup check 0.772 s
+11.8%
3.808 s
-4.1%
1.777 s
+3.3%
15.0 ms
-1.0%
41.5 ms
+0.1%
Fp128 multi-group (final nv34, 4 polys total), direct setup check 0.139 s
+1.2%
2.409 s
+0.7%
1.127 s
-0.5%
20.0 ms
+4.1%
106.4 ms
-0.6%
Fp128 multi-group (final nv34, 4 polys total), recursive setup check 0.472 s
+0.4%
2.190 s
-8.7%
1.623 s
+3.7%
17.0 ms
-5.5%
35.9 ms
+1.3%
Fp128 multi-group W8R2 (final nv32, 4 polys total), recursive setup check 0.382 s
+48.8%
0.473 s
+5.6%
1.508 s
-0.3%
22.4 ms
-2.3%
66.4 ms
+0.3%
Fp128 one-hot nv32 W2R2, direct setup check 0.051 s
+0.4%
0.250 s
-7.3%
0.541 s
+1.7%
13.6 ms
+1.4%
40.7 ms
-0.2%
Fp128 one-hot nv32 W4R2, direct setup check 0.054 s
-0.8%
0.250 s
+0.3%
0.645 s
+0.4%
15.1 ms
-2.0%
48.2 ms
-0.3%
Fp128 one-hot nv32 W8R2, direct setup check 0.054 s
+0.6%
0.248 s
+0.1%
0.844 s
-0.3%
17.2 ms
+0.4%
57.2 ms
+0.5%

Proof size and protocol shape

Profile Fold A/B/D schedule Total proof Terminal response Terminal response planned maximum Fold levels Grinding retries
Fp32 dense nv30, direct setup check 2048/256/256 → 128/128/128 75,294 bytes
+0.0%
43,729 bytes
+0.0%
45,688 bytes
+0.0%
7
+0.0%
None
Fp32 one-hot nv34, direct setup check 2048/256/256 → 256/128/256 → 128/128/128 75,398 bytes
+0.0%
43,718 bytes
+0.0%
45,688 bytes
+0.0%
7
+0.0%
None
Fp64 dense nv29, direct setup check 2048/128/128 → 1024/128/128 → 128/128/128 → 64/64/64 77,301 bytes
+0.0%
45,155 bytes
+0.0%
47,620 bytes
+0.0%
8
+0.0%
None
Fp64 one-hot nv35, direct setup check 1024/256/128 → 256/128/128 → 128/128/128 → 64/64/64 77,438 bytes
+0.0%
45,181 bytes
+0.0%
47,620 bytes
+0.0%
8
+0.0%
L6: 1 / 1 / 1
Fp128 dense nv28, direct setup check 1024/64/64 → 128/64/64 → 64/64/64 80,581 bytes
+0.0%
51,978 bytes
+0.0%
54,262 bytes
+0.0%
7
+0.0%
None
Fp128 one-hot nv36, direct setup check 512/128/64 → 512/64/64 → 64/64/64 81,777 bytes
+0.0%
51,987 bytes
+0.0%
54,262 bytes
+0.0%
8
+0.0%
None
Fp128 one-hot nv36, recursive setup check 512/128/64 → 64/64/64 84,962 bytes
+0.0%
51,984 bytes
+0.0%
54,262 bytes
+0.0%
8
+0.0%
None
Fp128 multi-group (final nv34, 4 polys total), direct setup check 512/128/128 → 512/64/64 → 64/64/64 81,624 bytes
+0.0%
51,948 bytes
+0.0%
54,262 bytes
+0.0%
8
+0.0%
None
Fp128 multi-group (final nv34, 4 polys total), recursive setup check 512/128/128 → 64/64/64 89,769 bytes
+0.0%
51,963 bytes
+0.0%
54,262 bytes
+0.0%
8
+0.0%
None
Fp128 multi-group W8R2 (final nv32, 4 polys total), recursive setup check 512/64/64 → 128/64/64 → 64/64/64 83,746 bytes
+0.0%
52,016 bytes
+0.0%
54,262 bytes
+0.0%
8
+0.0%
None
Fp128 one-hot nv32 W2R2, direct setup check 512/64/64 → 64/64/64 81,550 bytes
+0.0%
51,986 bytes
+0.0%
54,262 bytes
+0.0%
8
+0.0%
None
Fp128 one-hot nv32 W4R2, direct setup check 512/64/64 → 256/64/64 → 64/64/64 81,782 bytes
+0.0%
51,992 bytes
+0.0%
54,262 bytes
+0.0%
8
+0.0%
None
Fp128 one-hot nv32 W8R2, direct setup check 512/64/64 → 256/64/64 → 64/64/64 82,329 bytes
+0.0%
51,970 bytes
+0.0%
54,262 bytes
+0.0%
8
+0.0%
None

Grinding retries are rejected attempts at each fold, listed in measured-run order. Zero means the first sampled nonce was accepted.

Each multi-group profile has two precommitted nv16 singleton polynomials and two polynomials in the displayed final group.

Native proof accounting

Profile Non-nonce proof Nonce messages Nonce maximum
Fp32 dense nv30, direct setup check 74,785 bytes
+0.0%
509 bytes
+0.0%
1,016 bytes
+0.0%
Fp32 one-hot nv34, direct setup check 74,886 bytes
+0.0%
512 bytes
+0.0%
1,020 bytes
+0.0%
Fp64 dense nv29, direct setup check 76,803 bytes
+0.0%
498 bytes
+0.0%
992 bytes
+0.0%
Fp64 one-hot nv35, direct setup check 76,941 bytes
+0.0%
497 bytes
+0.0%
996 bytes
+0.0%
Fp128 dense nv28, direct setup check 80,202 bytes
+0.0%
379 bytes
+0.0%
758 bytes
+0.0%
Fp128 one-hot nv36, direct setup check 81,347 bytes
+0.0%
430 bytes
+0.0%
856 bytes
+0.0%
Fp128 one-hot nv36, recursive setup check 84,432 bytes
+0.0%
530 bytes
+0.0%
1,048 bytes
+0.0%
Fp128 multi-group (final nv34, 4 polys total), direct setup check 81,196 bytes
+0.0%
428 bytes
+0.0%
854 bytes
+0.0%
Fp128 multi-group (final nv34, 4 polys total), recursive setup check 89,163 bytes
+0.0%
606 bytes
+0.0%
1,204 bytes
+0.0%
Fp128 multi-group W8R2 (final nv32, 4 polys total), recursive setup check 83,280 bytes
+0.0%
466 bytes
+0.0%
930 bytes
+0.0%
Fp128 one-hot nv32 W2R2, direct setup check 81,122 bytes
+0.0%
428 bytes
+0.0%
848 bytes
+0.0%
Fp128 one-hot nv32 W4R2, direct setup check 81,352 bytes
+0.0%
430 bytes
+0.0%
856 bytes
+0.0%
Fp128 one-hot nv32 W8R2, direct setup check 81,890 bytes
+0.0%
439 bytes
+0.0%
868 bytes
+0.0%

Memory and setup size

Profile Setup vector Prepared NTT cache Verifier NTT cache Peak RSS
Fp32 dense nv30, direct setup check 20.0 MiB
+0.0%
154.0 MiB
+0.0%
1.2 MiB
+0.0%
4628.6 MiB
-0.1%
Fp32 one-hot nv34, direct setup check 64.0 MiB
+0.0%
354.1 MiB
+0.0%
1.2 MiB
+0.0%
1039.9 MiB
+0.1%
Fp64 dense nv29, direct setup check 32.0 MiB
+0.0%
291.2 MiB
+0.0%
1.8 MiB
+0.0%
4859.1 MiB
-0.2%
Fp64 one-hot nv35, direct setup check 128.0 MiB
+0.0%
917.2 MiB
+0.0%
1.8 MiB
+0.0%
1858.8 MiB
+0.0%
Fp128 dense nv28, direct setup check 64.0 MiB
+0.0%
585.0 MiB
+0.0%
1.6 MiB
+0.0%
5179.4 MiB
-0.1%
Fp128 one-hot nv36, direct setup check 344.0 MiB
+0.0%
3344.0 MiB
+0.0%
3.2 MiB
+0.0%
4926.1 MiB
+0.0%
Fp128 one-hot nv36, recursive setup check 512.0 MiB
+0.0%
4700.0 MiB
+0.0%
1.6 MiB
+0.0%
6424.9 MiB
-7.4%
Fp128 multi-group (final nv34, 4 polys total), direct setup check 256.0 MiB
+0.0%
1319.9 MiB
+0.0%
3.0 MiB
+0.0%
2394.0 MiB
+0.2%
Fp128 multi-group (final nv34, 4 polys total), recursive setup check 256.0 MiB
+0.0%
1400.0 MiB
+0.0%
1.5 MiB
+0.0%
2700.2 MiB
-8.7%
Fp128 multi-group W8R2 (final nv32, 4 polys total), recursive setup check 128.0 MiB
+0.0%
914.5 MiB
+0.0%
1.6 MiB
+0.0%
1863.0 MiB
-8.4%
Fp128 one-hot nv32 W2R2, direct setup check 64.0 MiB
+0.0%
449.0 MiB
+0.0%
1.6 MiB
+0.0%
814.9 MiB
-1.6%
Fp128 one-hot nv32 W4R2, direct setup check 64.0 MiB
+0.0%
473.0 MiB
+0.0%
1.6 MiB
+0.0%
881.8 MiB
-0.0%
Fp128 one-hot nv32 W8R2, direct setup check 64.0 MiB
+0.0%
473.0 MiB
+0.0%
1.6 MiB
+0.0%
968.1 MiB
+0.1%

Deltas are shown only for profiles with a matching merge-base case. Negative is smaller or faster.

The uploaded report.md benchmark artifact contains the detailed fold schedule, proof-size breakdown, terminal response segments, and Golomb diagnostics.

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

CI test timing

  • Report generated: 2026-10-26T20:09:25Z.
  • Source: d631913 on codex/share-setup-prefix-storage.
  • Workflow run: 40383869460.
  • Main baseline: a4c7e09.
  • Previous run: 2ec993b.

Run summary

Wall s Main wall s Main Δ Ratio Tests Skipped Failed Status
1645.0 1423.0 +15.6% 1.16x 2022 0 0 ok

Wall time spans 2 parallel nextest slice shards.

Slowest tests

Rank Duration s Test
1 451.1 akita-planner::schedule_params::suffix_dp::chunk_ownership_tests::contracting_chunk_search_matches_unpruned_complete_objective
2 144.1 akita-planner::schedule_params::adaptive_search_tests::adaptive_frontier_matches_unpruned_traversal_and_hand_priced_role_optima
3 78.8 akita-planner::planner::setup_prefix_challenge_hook_tests::catalog_binding_revalidates_recursive_setup_prefix_challenge_hook
4 58.4 akita-planner::planner::totality_tests::contractive_winner_remains_selected
5 33.1 akita-planner::schedule_params::adaptive_search_tests::relation_cutover::bounded_suffix_dp_matches_unpruned_fixed_cutover_search
6 22.2 akita-planner::planner::totality_tests::noncontractive_multi_chunk_root_can_beat_contractive_candidates
7 21.2 akita-planner::generated_families::tests::generation_uses_requested_geometry_for_preplans_and_grouped_producers
8 20.4 akita-pcs::dynamic_backends::portable::offloaded_route_uses_only_local_prefix_handles
9 16.4 akita-pcs::akita_fp128_e2e::heterogeneous::bounded_dense_roundtrip_over_u64_coefficients_at_every_catalog_size
10 16.3 akita-pcs::akita_small_field_e2e::combined_recursive::fp32_combined_setup_proves_recursive_and_onehot_families
11 15.2 akita-planner::schedule_params::adaptive_search_tests::adaptive_nv36_minimizes_setup_envelope_before_first_direct_setup
12 14.3 akita-planner::planner::totality_tests::valid_small_grouped_root_has_a_schedule
13 13.3 akita-pcs::transcript_hardening_proptest::seed_corpus_covers_nv_basis_and_batch_shapes
14 13.1 akita-pcs::scheme::tests::cross_mode::proofs_cannot_replay_across_valid_quotient_and_reduced_schedules
15 12.9 akita-planner::schedule_params::adaptive_search_tests::production_suffix_selects_l2_with_the_typed_response_model
16 12.5 akita-planner::schedule_params::adaptive_search_tests::adaptive_search_supports_direct_multi_chunk_policy
17 12.3 akita-pcs::dynamic_backends::dynamic_backend_failures_cleanup_and_retry
18 9.9 akita-pcs::akita_fp128_e2e::fp128_onehot
19 9.9 akita-pcs::akita_small_field_e2e::selective_l2::fp32_ext4_l2_pcs_roundtrip_and_stage2_rejections
20 9.7 akita-planner::planner::adapted_schedule_tests::adapted_schedule_falls_back_to_the_full_search_when_the_frozen_suffix_is_infeasible

Regressions vs main

Δ s Baseline s Current s Test
62.4 388.7 451.1 akita-planner::schedule_params::suffix_dp::chunk_ownership_tests::contracting_chunk_search_matches_unpruned_complete_objective
10.7 47.7 58.4 akita-planner::planner::totality_tests::contractive_winner_remains_selected
6.5 26.6 33.1 akita-planner::schedule_params::adaptive_search_tests::relation_cutover::bounded_suffix_dp_matches_unpruned_fixed_cutover_search
5.5 10.9 16.4 akita-pcs::akita_fp128_e2e::heterogeneous::bounded_dense_roundtrip_over_u64_coefficients_at_every_catalog_size

New slow tests

No new tests ≥30s vs main baseline.

@RadNi

RadNi commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

/ai-review

@github-actions

Copy link
Copy Markdown

AI review attempt 1/3 reserved. Failed or incomplete attempts also count toward this PR's limit.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usefulness: benefit supported. The memory-saving premise is supported: setup-prefix sources replace per-prefix coefficient copies with bounded Arc-backed views, and equal inner rings share storage after coefficient-by-coefficient comparison. Lazy source initialization also avoids retaining polynomial sources during export. These benefits justify the storage changes, although the new streaming arithmetic adds maintenance surface and validation currently introduces avoidable full-image copies.

Approval not recommended: new P0-P3 findings in this review.

let mut total_coefficients = 0usize;
for rows in &self.inner_rows {
for rows in self
.inner_rows()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] For shared hints, inner_rows() reconstructs every coefficient in a fresh buffer, so this shape check now copies the entire A image just to inspect its dimensions. Registry insertion and checking reach this through hint.check(), which then materializes the image a second time; serialization likewise materializes once here and again to write coefficients. Even a warm import of an exported registry or serialization directly to a file therefore needs an extra full-image allocation and repeated copies. Can we expose shape metadata and coefficient iteration on InnerRows, validate and serialize the shared blocks directly, and reserve materialization for consumers that actually require contiguous storage?

@github-actions github-actions Bot added the ai-reviewed An automated AI review has been published on this PR label Oct 26, 2026
@RadNi

RadNi commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

/ai-review

@github-actions

Copy link
Copy Markdown

AI review attempt 2/3 reserved. Failed or incomplete attempts also count toward this PR's limit.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usefulness: benefit supported. The memory-saving benefit is supported by the code: bounded Arc-backed setup views replace per-prefix coefficient copies, equality-checked interning shares inner rings across hints and imports, and export no longer eagerly retains polynomial sources. The added pooling and tiled-arithmetic complexity serves those savings while reusing existing sampling, decomposition, NTT, and compression primitives. The latest revision also removes the previously identified full-image allocations from validation and serialization, with regression assertions covering byte equality and zero materializations.

Recommended for approval: no unresolved findings in this automated review.

@github-actions github-actions Bot added the ai-approved Latest AI review recommends approval; informational, not a merge authorization label Oct 26, 2026
@RadNi
RadNi merged commit 55a4027 into main Oct 26, 2026
57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-approved Latest AI review recommends approval; informational, not a merge authorization ai-reviewed An automated AI review has been published on this PR no-spec PR has no spec file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants