Organisationsahrefsocannl951773 ()(lint-fmt)

(lint-fmt)

Logs

Show full logs
2026-01-20 15:50.47: New job: test ahrefs/ocannl https://github.com/ahrefs/ocannl.git#refs/heads/master (9517730f5abd78e4d3eb3d6e36149fa2aa7f9bf5) (linux-x86_64:(lint-fmt))
Base: ocaml/opam:debian-13-ocaml-4.08@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500
ocamlformat version: version 0.28.1 (from opam)

To reproduce locally:

git clone --recursive "https://github.com/ahrefs/ocannl.git" -b "master" && cd "ocannl" && git reset --hard 9517730f
cat > Dockerfile <<'END-OF-DOCKERFILE'
FROM ocaml/opam:debian-13-ocaml-4.08@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500
USER 1000:1000
RUN cd ~/opam-repository && (git cat-file -e 873cb18c37b308713d11ad3894c4bb78d73fb3e7 || git fetch origin master) && git reset -q --hard 873cb18c37b308713d11ad3894c4bb78d73fb3e7 && git log --no-decorate -n1 --oneline && opam update -u
RUN opam depext -i dune
WORKDIR /src
RUN opam depext -i ocamlformat=0.28.1
COPY --chown=1000:1000 . /src/
RUN opam exec -- dune build @fmt --ignore-promoted-rules || (echo "dune build @fmt failed"; exit 2)

END-OF-DOCKERFILE
docker build .
END-REPRO-BLOCK

2026-01-20 15:50.47: Using cache hint "ahrefs/ocannl-ocaml/opam:debian-13-ocaml-4.08@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500-debian-13-4.08_opam-2.5-ocamlformat-873cb18c37b308713d11ad3894c4bb78d73fb3e7"
2026-01-20 15:50.47: Using OBuilder spec:
((from ocaml/opam:debian-13-ocaml-4.08@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500)
 (user (uid 1000) (gid 1000))
 (run (cache (opam-archives (target /home/opam/.opam/download-cache)))
      (network host)
      (shell "cd ~/opam-repository && (git cat-file -e 873cb18c37b308713d11ad3894c4bb78d73fb3e7 || git fetch origin master) && git reset -q --hard 873cb18c37b308713d11ad3894c4bb78d73fb3e7 && git log --no-decorate -n1 --oneline && opam update -u"))
 (run (cache (opam-archives (target /home/opam/.opam/download-cache)))
      (network host)
      (shell "opam depext -i dune"))
 (workdir /src)
 (run (cache (opam-archives (target /home/opam/.opam/download-cache)))
      (network host)
      (shell "opam depext -i ocamlformat=0.28.1"))
 (copy (src .) (dst /src/))
 (run (shell "opam exec -- dune build @fmt --ignore-promoted-rules || (echo \"dune build @fmt failed\"; exit 2)"))
)

2026-01-20 15:50.47: Waiting for resource in pool OCluster
2026-01-20 15:50.47: Waiting for worker…
2026-01-20 15:50.47: Got resource from pool OCluster
Building on toxis.caelum.ci.dev
All commits already cached
HEAD is now at 9517730f Merge pull request #424 from ahrefs/codex-ambiguous-concat

(from ocaml/opam:debian-13-ocaml-4.08@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500)
Unable to find image 'ocaml/opam:debian-13-ocaml-4.08@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500' locally
docker.io/ocaml/opam@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500: Pulling from ocaml/opam
281b80c799de: Already exists
00fc4ac50d5e: Already exists
7dc48a314bea: Already exists
8f654937f9e3: Already exists
1240f6fbe8cc: Already exists
f77f967230a1: Already exists
1b4ac3d9a8c2: Already exists
27b61414175d: Already exists
26fabf9b20e0: Already exists
b4426e2c299b: Already exists
9c12df827e83: Already exists
9a5608646906: Already exists
2a83342677ae: Already exists
5cbaedd36b85: Already exists
750a9830ac77: Already exists
400560080670: Already exists
bad13195b6fa: Already exists
b51fe78b498e: Already exists
185ce27e889b: Already exists
8a483dc1e759: Already exists
4de9d6d54a13: Already exists
0c268a22c8a0: Already exists
4f4fb700ef54: Already exists
e61881bc2621: Already exists
c864a4af1ff0: Already exists
42d012f62ad9: Already exists
ccb2ed78fa2e: Already exists
84c22434b2f6: Already exists
18c972827b32: Already exists
4c6dcdff9e80: Already exists
280bf9d33ca6: Already exists
51ce8c29753c: Already exists
5ac80663b9d2: Already exists
93f877c915e3: Already exists
8573ccc6bb69: Already exists
d26192cd75ec: Already exists
c7cce15b715e: Already exists
c998ca7b5976: Already exists
3cd1b61d806b: Already exists
19a26ec5319e: Already exists
b1f6813045f3: Already exists
7a2b7a29296d: Pulling fs layer
94a0ebb2d223: Pulling fs layer
1c7f29f6d19a: Pulling fs layer
1493b442f343: Pulling fs layer
1493b442f343: Waiting
1c7f29f6d19a: Verifying Checksum
1c7f29f6d19a: Download complete
94a0ebb2d223: Download complete
1493b442f343: Verifying Checksum
1493b442f343: Download complete
7a2b7a29296d: Download complete
7a2b7a29296d: Pull complete
94a0ebb2d223: Pull complete
1c7f29f6d19a: Pull complete
1493b442f343: Pull complete
Digest: sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500
Status: Downloaded newer image for ocaml/opam@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500
2026-01-20 15:50.48 ---> using "4c1f60dc0cc5644c6a4c05cf3315bdbf9cc478b70e443b212a1220385bab8bba" from cache

/: (user (uid 1000) (gid 1000))

/: (run (cache (opam-archives (target /home/opam/.opam/download-cache)))
        (network host)
        (shell "cd ~/opam-repository && (git cat-file -e 873cb18c37b308713d11ad3894c4bb78d73fb3e7 || git fetch origin master) && git reset -q --hard 873cb18c37b308713d11ad3894c4bb78d73fb3e7 && git log --no-decorate -n1 --oneline && opam update -u"))
From https://github.com/ocaml/opam-repository
 * branch                  master     -> FETCH_HEAD
   a6b2f19780..10a02a697b  master     -> origin/master
873cb18c37 Merge pull request #29216 from shonfeder/release-dune-3.21.0

<><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><>
[default] Initialised
default (at git+file:///home/opam/opam-repository): 
    [INFO] opam 2.1 and 2.2 include many performance and security improvements over 2.0; please consider upgrading (https://opam.ocaml.org/doc/Install.html)


Everything as up-to-date as possible (run with --verbose to show unavailable upgrades).
However, you may "opam upgrade" these packages explicitly, which will ask permission to downgrade or uninstall the conflicting packages.
Nothing to do.
# Run eval $(opam env) to update the current shell environment
2026-01-20 15:52.08 ---> saved as "72a7cd495abee3d0659c15140c96fff42d035222fc9b794ad453f1a5292cd6f1"

/: (run (cache (opam-archives (target /home/opam/.opam/download-cache)))
        (network host)
        (shell "opam depext -i dune"))
# Detecting depexts using vars: arch=x86_64, os=linux, os-distribution=debian, os-family=debian
# No extra OS packages requirements found.
# All required OS packages found.
# Now letting opam install the packages
The following actions will be performed:
  - install dune 3.21.0

<><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
[dune.3.21.0] found in cache

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
-> installed dune.3.21.0
Done.
# Run eval $(opam env) to update the current shell environment
2026-01-20 15:52.45 ---> saved as "3b5aee51bb4636e6dab95deb6944478b896d0b06f021712424b773f7d70073ac"

/: (workdir /src)

/src: (run (cache (opam-archives (target /home/opam/.opam/download-cache)))
           (network host)
           (shell "opam depext -i ocamlformat=0.28.1"))
# Detecting depexts using vars: arch=x86_64, os=linux, os-distribution=debian, os-family=debian
# No extra OS packages requirements found.
# All required OS packages found.
# Now letting opam install the packages
The following actions will be performed:
  - install sexplib0          v0.14.0  [required by base]
  - install ocamlbuild        0.16.1   [required by fpath, astring, uuseg]
  - install either            1.0.0    [required by ocamlformat-lib]
  - install menhirLib         20250912 [required by ocamlformat-lib]
  - install csexp             1.5.2    [required by ocamlformat]
  - install dune-build-info   3.21.0   [required by ocamlformat-lib]
  - install camlp-streams     5.0.1    [required by ocamlformat-lib]
  - install seq               base     [required by re]
  - install menhirSdk         20250912 [required by ocamlformat-lib]
  - install fix               20250919 [required by ocamlformat-lib]
  - install menhirCST         20250912 [required by menhir]
  - install ocamlfind         1.9.8    [required by ocp-indent, astring, fpath, uuseg]
  - install ocaml-version     4.0.3    [required by ocamlformat-lib]
  - install cmdliner          2.1.0    [required by ocamlformat]
  - install dune-configurator 3.21.0   [required by base]
  - install re                1.11.0   [required by ocamlformat]
  - install menhir            20250912 [required by ocamlformat-lib]
  - install topkg             1.1.1    [required by fpath, astring, uuseg]
  - install ocp-indent        1.9.0    [required by ocamlformat-lib]
  - install base              v0.14.3  [required by ocamlformat-lib]
  - install uutf              1.0.4    [required by ocamlformat-lib]
  - install astring           0.8.5    [required by ocamlformat-lib]
  - install stdio             v0.14.0  [required by ocamlformat-lib]
  - install uucp              15.0.0   [required by uuseg]
  - install fpath             0.7.3    [required by ocamlformat-lib]
  - install uuseg             15.0.0   [required by ocamlformat-lib]
  - install ocamlformat-lib   0.28.1   [required by ocamlformat]
  - install ocamlformat       0.28.1
===== 28 to install =====

<><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
[astring.0.8.5] found in cache
[base.v0.14.3] found in cache
[camlp-streams.5.0.1] found in cache
[cmdliner.2.1.0] found in cache
[csexp.1.5.2] found in cache
[dune-build-info.3.21.0] found in cache
[dune-configurator.3.21.0] found in cache
[either.1.0.0] found in cache
[fix.20250919] found in cache
[fpath.0.7.3] found in cache
[menhir.20250912] found in cache
[menhirCST.20250912] found in cache
[menhirLib.20250912] found in cache
[menhirSdk.20250912] found in cache
[ocaml-version.4.0.3] found in cache
[ocamlbuild.0.16.1] found in cache
[ocamlfind.1.9.8] found in cache
[ocamlformat.0.28.1] found in cache
[ocamlformat-lib.0.28.1] found in cache
[ocp-indent.1.9.0] found in cache
[re.1.11.0] found in cache
[sexplib0.v0.14.0] found in cache
[stdio.v0.14.0] found in cache
[topkg.1.1.1] found in cache
[uucp.15.0.0] found in cache
[uuseg.15.0.0] found in cache
[uutf.1.0.4] found in cache

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
-> installed seq.base
-> installed camlp-streams.5.0.1
-> installed csexp.1.5.2
-> installed either.1.0.0
-> installed fix.20250919
-> installed menhirCST.20250912
-> installed menhirLib.20250912
-> installed menhirSdk.20250912
-> installed ocaml-version.4.0.3
-> installed sexplib0.v0.14.0
-> installed re.1.11.0
-> installed cmdliner.2.1.0
-> installed dune-build-info.3.21.0
-> installed dune-configurator.3.21.0
-> installed ocamlfind.1.9.8
-> installed ocp-indent.1.9.0
-> installed ocamlbuild.0.16.1
-> installed base.v0.14.3
-> installed topkg.1.1.1
-> installed stdio.v0.14.0
-> installed uutf.1.0.4
-> installed astring.0.8.5
-> installed menhir.20250912
-> installed fpath.0.7.3
-> installed uucp.15.0.0
-> installed uuseg.15.0.0
-> installed ocamlformat-lib.0.28.1
-> installed ocamlformat.0.28.1
Done.

<><> ocp-indent.1.9.0 installed successfully ><><><><><><><><><><><><><><><><><>
=> This package requires additional configuration for use in editors. Install package 'user-setup', or manually:

   * for Emacs, add these lines to ~/.emacs:
     (add-to-list 'load-path "/home/opam/.opam/4.08/share/emacs/site-lisp")
     (require 'ocp-indent)

   * for Vim, add this line to ~/.vimrc:
     set rtp^="/home/opam/.opam/4.08/share/ocp-indent/vim"
# Run eval $(opam env) to update the current shell environment
2026-01-20 15:54.10 ---> saved as "feaec41ae6674b5392c1669250b45e7c9432e92ab5fcb8c64fb0ca2bc77dcd2b"

/src: (copy (src .) (dst /src/))
2026-01-20 15:54.12 ---> saved as "984e39e63899a90706c1d35ebf5c8f8dedb7742bb0f34dc491a94a1fe2e52af5"

/src: (run (shell "opam exec -- dune build @fmt --ignore-promoted-rules || (echo \"dune build @fmt failed\"; exit 2)"))
Warning: Invalid documentation comment:
File "tensor/einsum_types.ml", line 39, characters 0-0:
End of text is not allowed in '[...]' (code).
File "test/ppx/test_ppx_op.ml", line 1, characters 0-0:
diff --git a/_build/default/test/ppx/test_ppx_op.ml b/_build/default/test/ppx/.formatted/test_ppx_op.ml
index 3663191..41e2cf1 100644
--- a/_build/default/test/ppx/test_ppx_op.ml
+++ b/_build/default/test/ppx/.formatted/test_ppx_op.ml
@@ -22,7 +22,6 @@ let z3 =
 
 let%op concat_single = { hey11 } ++^ "i=>i"
 let%op concat_pair = ({ hey12 }, { hey13 }) ++^ "i; j => i^j" [ "i"; "j" ]
-
 let () = ignore (y0, y1, y2, a, b, y)
 let () = ignore (z, z2, z3)
 let () = ignore (concat_single, concat_pair)
File "test/operations/test_concat_ppx.ml", line 1, characters 0-0:
diff --git a/_build/default/test/operations/test_concat_ppx.ml b/_build/default/test/operations/.formatted/test_concat_ppx.ml
index c9676f8..7775d28 100644
--- a/_build/default/test/operations/test_concat_ppx.ml
+++ b/_build/default/test/operations/.formatted/test_concat_ppx.ml
@@ -26,12 +26,8 @@ let () =
   let r3 = concat_capture t1 t2 in
   Stdio.printf "concat_capture id: %d\n" r3.Tensor.id;
 
-  let p1 =
-    PDSL.ndarray [| 1.0; 2.0; 3.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 3 ] ()
-  in
-  let p2 =
-    PDSL.ndarray [| 4.0; 5.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 2 ] ()
-  in
+  let p1 = PDSL.ndarray [| 1.0; 2.0; 3.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 3 ] () in
+  let p2 = PDSL.ndarray [| 4.0; 5.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 2 ] () in
   let loss = sum_all (concat2 p1 p2) in
   let ctx = Context.auto () in
   ignore (Train.update_once ctx loss);
File "test/operations/test_concat_graph.ml", line 1, characters 0-0:
diff --git a/_build/default/test/operations/test_concat_graph.ml b/_build/default/test/operations/.formatted/test_concat_graph.ml
index 8d6b84a..980219d 100644
--- a/_build/default/test/operations/test_concat_graph.ml
+++ b/_build/default/test/operations/.formatted/test_concat_graph.ml
@@ -12,9 +12,7 @@ let () =
   Tensor.unsafe_reinitialize ();
 
   (* Create two input tensors with different sizes *)
-  let x1 =
-    PDSL.ndarray [| 1.0; 2.0; 3.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 3 ] ()
-  in
+  let x1 = PDSL.ndarray [| 1.0; 2.0; 3.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 3 ] () in
   let x2 = PDSL.ndarray [| 4.0; 5.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 2 ] () in
 
   (* Concatenate and apply sin for a nice differentiable function *)
@@ -54,12 +52,8 @@ let () =
   printf "\n=== Three-way Concatenation Forward and Backprop Graph Test ===\n\n%!";
   (* Create three input tensors with different sizes *)
   let x1_3 = PDSL.ndarray [| 1.0; 2.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 2 ] () in
-  let x2_3 =
-    PDSL.ndarray [| 3.0; 4.0; 5.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 3 ] ()
-  in
-  let x3_3 =
-    PDSL.ndarray [| 6.0; 7.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 2 ] ()
-  in
+  let x2_3 = PDSL.ndarray [| 3.0; 4.0; 5.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 3 ] () in
+  let x3_3 = PDSL.ndarray [| 6.0; 7.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 2 ] () in
 
   (* Concatenate and apply sin *)
   let%op result3 = sin ((x1_3, x2_3, x3_3) ++^ "a; b; c => a^b^c") in
@@ -104,9 +98,7 @@ let () =
   (* One concatenated dimension is 1 to exercise Fixed_idx 0 behavior. *)
   let x1_u = PDSL.ndarray [| 1.0; 2.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 2 ] () in
   let x2_u = PDSL.ndarray [| 3.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 1 ] () in
-  let x3_u =
-    PDSL.ndarray [| 4.0; 5.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 2 ] ()
-  in
+  let x3_u = PDSL.ndarray [| 4.0; 5.0 |] ~batch_dims:[] ~input_dims:[] ~output_dims:[ 2 ] () in
 
   let%op result_u = sin ((x1_u, x2_u, x3_u) ++^ "a; b; c => a^b^c") in
   let%op loss_u = result_u ++ "...|... => 0" in
File "tensor/ppx_op.ml", line 1, characters 0-0:
diff --git a/_build/default/tensor/ppx_op.ml b/_build/default/tensor/.formatted/ppx_op.ml
index fadd7c3..28f8d84 100644
--- a/_build/default/tensor/ppx_op.ml
+++ b/_build/default/tensor/.formatted/ppx_op.ml
@@ -183,8 +183,7 @@ let rec translate ~no_grads_for_inline_defs ~num_configs ~is_toplevel ~opt_label
             (vbs, Ast_builder.Default.pexp_array ~loc [ e ])
       in
       let spec = substitute_identifiers_in_einsum_spec ~loc spec_str in
-      ( vbs1,
-        [%expr concat ?label:[%e opt_expr ~loc label] [%e spec] [%e rhses_expr]] )
+      (vbs1, [%expr concat ?label:[%e opt_expr ~loc label] [%e spec] [%e rhses_expr]])
   | [%expr
       [%e? { pexp_desc = Pexp_ident { txt = Lident "++^"; _ }; _ }]
         [%e? expr1]
File "tensor/operation.ml", line 1, characters 0-0:
diff --git a/_build/default/tensor/operation.ml b/_build/default/tensor/.formatted/operation.ml
index b390494..5dda887 100644
--- a/_build/default/tensor/operation.ml
+++ b/_build/default/tensor/.formatted/operation.ml
@@ -469,9 +469,9 @@ let concat_sum ?(capture_dims = []) ?(negated = false) spec ?grad_spec rhses =
            accum = Ir.Ops.Add;
            lhs = g;
            rhs = Asgns.Rev_sides { op; lhses };
-          projections = projections.Tensor.projections;
-          projections_debug = projections.Tensor.projections_debug;
-        }
+           projections = projections.Tensor.projections;
+           projections_debug = projections.Tensor.projections_debug;
+         }
   in
   Tensor.blockop ~op_label:"++^" ~spec ~delayed_vars:capture_dims ~op_asn ~grad_asn ?grad_spec rhses
 
@@ -816,10 +816,13 @@ struct
     let einsum1 ?label ?capture_dims spec t1 = einsum1 ?label ?capture_dims spec t1 ()
     let einmax1 ?label ?capture_dims spec t1 = einmax1 ?label ?capture_dims spec t1 ()
     let tropical ?label ?capture_dims spec t1 t2 = tropical ?label ?capture_dims spec t1 t2 ()
+
     let concat_sum ?label ?capture_dims ?negated spec rhses =
       concat_sum ?label ?capture_dims ?negated spec rhses ()
+
     let concat ?label ?capture_dims ?negated spec rhses =
       concat ?label ?capture_dims ?negated spec rhses ()
+
     let offsets ?label () = offsets ?label ()
     let uniform ?label () = uniform () ?label ()
     let uniform_at ?label counter = uniform_at ?label counter ()
File "arrayjit/lib/assignments.ml", line 1, characters 0-0:
diff --git a/_build/default/arrayjit/lib/assignments.ml b/_build/default/arrayjit/lib/.formatted/assignments.ml
index 449c853..185039d 100644
--- a/_build/default/arrayjit/lib/assignments.ml
+++ b/_build/default/arrayjit/lib/.formatted/assignments.ml
@@ -286,8 +286,7 @@ let%track4_sexp to_low_level code =
       Array.fold2_exn projections.product_space projections.product_iterators
         ~init:(Map.empty (module Indexing.Symbol))
         ~f:(fun acc ds its ->
-          List.fold2_exn ds its ~init:acc ~f:(fun acc d iter ->
-              Map.set acc ~key:iter ~data:d))
+          List.fold2_exn ds its ~init:acc ~f:(fun acc d iter -> Map.set acc ~key:iter ~data:d))
     in
     let concat_offset_for syms active =
       let _, offset =
@@ -302,8 +301,8 @@ let%track4_sexp to_low_level code =
       (* Create a substitution from product iterators to loop iterators. Fresh loop symbols are
          needed because product_iterators may be shared across different operations/tensors, but
          each lowered operation needs private loop symbols to avoid conflicts in low_level.ml's
-         symbol-to-tensor tracking.
-         Concat offsets are computed per Concat index using symbol order. *)
+         symbol-to-tensor tracking. Concat offsets are computed per Concat index using symbol
+         order. *)
       let exception Empty_block in
       let block_iters = Array.of_list_rev block_iters in
       let concat_syms_opt =
@@ -342,9 +341,9 @@ let%track4_sexp to_low_level code =
                   | Some (Indexing.Fixed_idx _) | Some Indexing.Sub_axis | None -> (coeff, s))
             in
             Indexing.Affine { symbols; offset }
-        | Indexing.Concat syms ->
-            (* For Block lowering: find the active component (in block_iters) and resolve to it
-               with the appropriate offset based on Concat symbol order. *)
+        | Indexing.Concat syms -> (
+            (* For Block lowering: find the active component (in block_iters) and resolve to it with
+               the appropriate offset based on Concat symbol order. *)
             let active =
               List.find_mapi syms ~f:(fun _i s ->
                   if Array.mem ~equal:Indexing.equal_symbol block_iters s then
@@ -355,13 +354,14 @@ let%track4_sexp to_low_level code =
                     | _ -> None
                   else None)
             in
-            (match active with
+            match active with
             | Some (s', 0) -> Indexing.Iterator s'
             | Some (s', offset) -> Indexing.Affine { symbols = [ (1, s') ]; offset }
             | None ->
                 raise
                 @@ Utils.User_error
-                     "Concat index could not be resolved to an active component during Block lowering")
+                     "Concat index could not be resolved to an active component during Block \
+                      lowering")
       in
       try
         let lhs_idcs : Indexing.axis_index array =
@@ -449,8 +449,8 @@ let%track4_sexp to_low_level code =
       let fetch_op = Constant neutral_value in
       Low_level.Seq (loop (Fetch { array = lhs; fetch_op; dims }), for_loops_with_resets)
     else for_loops_with_resets
-  and loop_accum_rev ~initialize_neutral ~accum ~(op : Ops.op) ~lhs ~lhses projections :
-      Low_level.t =
+  and loop_accum_rev ~initialize_neutral ~accum ~(op : Ops.op) ~lhs ~lhses projections : Low_level.t
+      =
     let projections : Indexing.projections = Lazy.force projections in
     let all_prod_iters =
       Array.to_list projections.product_iterators
@@ -466,15 +466,13 @@ let%track4_sexp to_low_level code =
     in
     let target_needs_init =
       Array.map target_projections ~f:(fun proj ->
-          initialize_neutral
-          && not (Indexing.is_surjective proj && Indexing.is_injective proj))
+          initialize_neutral && not (Indexing.is_surjective proj && Indexing.is_injective proj))
     in
     let iter_sizes =
       Array.fold2_exn projections.product_space projections.product_iterators
         ~init:(Map.empty (module Indexing.Symbol))
         ~f:(fun acc ds its ->
-          List.fold2_exn ds its ~init:acc ~f:(fun acc d iter ->
-              Map.set acc ~key:iter ~data:d))
+          List.fold2_exn ds its ~init:acc ~f:(fun acc d iter -> Map.set acc ~key:iter ~data:d))
     in
     let concat_offset_for syms active =
       let _, offset =
@@ -523,7 +521,7 @@ let%track4_sexp to_low_level code =
                   | Some (Indexing.Fixed_idx _) | Some Indexing.Sub_axis | None -> (coeff, s))
             in
             Indexing.Affine { symbols; offset }
-        | Indexing.Concat syms ->
+        | Indexing.Concat syms -> (
             (* For Rev_sides lowering: find the active component and resolve with offset *)
             let active =
               List.find_mapi syms ~f:(fun _i s ->
@@ -535,18 +533,18 @@ let%track4_sexp to_low_level code =
                     | _ -> None
                   else None)
             in
-            (match active with
+            match active with
             | Some (s', 0) -> Indexing.Iterator s'
             | Some (s', offset) -> Indexing.Affine { symbols = [ (1, s') ]; offset }
             | None ->
                 raise
                 @@ Utils.User_error
-                     "Concat index could not be resolved to an active component during Rev_sides lowering")
+                     "Concat index could not be resolved to an active component during Rev_sides \
+                      lowering")
       in
       let target_tn_exn = function
         | Node tn -> tn
-        | Merge_buffer _ ->
-            raise @@ Utils.User_error "Rev_sides cannot write to merge buffers"
+        | Merge_buffer _ -> raise @@ Utils.User_error "Rev_sides cannot write to merge buffers"
       in
       try
         let rhs_idcs : Indexing.axis_index array =
@@ -577,7 +575,8 @@ let%track4_sexp to_low_level code =
         let rhs2 = apply_op op [| rhs_ll |] in
         let target_tn = target_tn_exn target_buf in
         if initialize_neutral && target_can_skip.(i) then set target_tn lhs_idcs rhs2
-        else set target_tn lhs_idcs @@ apply_op (Ops.Binop accum) [| get target_buf lhs_idcs; rhs2 |]
+        else
+          set target_tn lhs_idcs @@ apply_op (Ops.Binop accum) [| get target_buf lhs_idcs; rhs2 |]
       with Empty_block -> Low_level.Noop
     in
     let rec for_loop block_iters rev_iters = function
@@ -621,14 +620,16 @@ let%track4_sexp to_low_level code =
               | Merge_buffer _ ->
                   raise @@ Utils.User_error "Rev_sides cannot initialize merge buffers"
             in
-            Some (Fetch { array; fetch_op = Constant neutral_value; dims = lazy projections.rhs_dims.(i) }))
+            Some
+              (Fetch
+                 { array; fetch_op = Constant neutral_value; dims = lazy projections.rhs_dims.(i) }))
       |> Array.to_list
     in
     if List.is_empty init_ops then for_loops_with_resets
     else Low_level.unflat_lines (List.map init_ops ~f:loop @ [ for_loops_with_resets ])
   and loop (code : t) : Low_level.t =
     match code with
-    | Accum_op { initialize_neutral; accum; lhs; rhs; projections; _ } ->
+    | Accum_op { initialize_neutral; accum; lhs; rhs; projections; _ } -> (
         let op, rhses =
           match rhs with
           | Unop { op; rhs } -> (Ops.Unop op, [| rhs |])
@@ -637,7 +638,7 @@ let%track4_sexp to_low_level code =
           | Block { op; rhses } -> (Ops.Unop op, rhses)
           | Rev_sides { op; lhses } -> (Ops.Unop op, lhses)
         in
-        (match rhs with
+        match rhs with
         | Rev_sides _ -> loop_accum_rev ~initialize_neutral ~accum ~op ~lhs ~lhses:rhses projections
         | _ -> loop_accum ~initialize_neutral ~accum ~op ~lhs ~rhses projections)
     | Set_vec_unop { op; lhs; rhs; projections; _ } ->
File "tensor/tensor.ml", line 1, characters 0-0:
diff --git a/_build/default/tensor/tensor.ml b/_build/default/tensor/.formatted/tensor.ml
index d8bdf41..ff82fef 100644
--- a/_build/default/tensor/tensor.ml
+++ b/_build/default/tensor/.formatted/tensor.ml
@@ -355,7 +355,7 @@ let%track7_sexp op ~(label : string list) ?(ternary_op = Shape.Pointwise_tern)
         | [ t1; t2; t3 ] -> Shape.Broadcast_tern (ternary_op, t1.shape, t2.shape, t3.shape)
         | _ ->
             (* Let's implement what we need when we need it. *)
-            assert false )
+            assert false)
   in
   let embedded_nodes = ref @@ Set.singleton (module Tn) v in
   let children =
@@ -370,7 +370,14 @@ let%track7_sexp op ~(label : string list) ?(ternary_op = Shape.Pointwise_tern)
   let params = Set.union_list (module T) @@ List.map ordered_ts ~f:(fun ti -> ti.params) in
   (* Create a preliminary shape_update to get projections_debug and projections for op_asn. *)
   let preliminary_shape_update =
-    Shape.{ shape; logic = shape_logic; id = get_update_id (); unsafe_projections = None; neutral_elem = None }
+    Shape.
+      {
+        shape;
+        logic = shape_logic;
+        id = get_update_id ();
+        unsafe_projections = None;
+        neutral_elem = None;
+      }
   in
   Shape.propagate_shapes preliminary_shape_update;
   let projections_debug = Shape.logic_to_spec preliminary_shape_update.logic in
@@ -527,6 +534,7 @@ let%track7_sexp blockop ?op_label ~spec ~delayed_vars ~op_asn ~grad_asn ?grad_sp
     (Shape.make ?batch_dims ?input_dims ?output_dims ?batch_axes ?input_axes ?output_axes ?deduced
        ())
     rhses_list
+
 let%track7_sexp unop ?op_label ?transpose_op ~op_asn ~grad_asn ?grad_spec t1 ?(label = [])
     ?top_down_prec ?batch_dims ?batch_axes ?input_dims ?output_dims ?input_axes ?output_axes
     ?deduced () : t =
File "tensor/shape.ml", line 1, characters 0-0:
diff --git a/_build/default/tensor/shape.ml b/_build/default/tensor/.formatted/shape.ml
index db46566..b1654fb 100644
--- a/_build/default/tensor/shape.ml
+++ b/_build/default/tensor/.formatted/shape.ml
@@ -269,7 +269,8 @@ let einsum_slot_spec_to_dims_bio ~original_spec ~sh_id ~row_var_env ~dim_var_env
         let dims =
           List.map labels ~f:(fun label ->
               Row.Var
-                (Hashtbl.find_or_add dim_var_env label ~default:(fun () -> Row.get_var ~name:label ())))
+                (Hashtbl.find_or_add dim_var_env label ~default:(fun () ->
+                     Row.get_var ~name:label ())))
         in
         Row.Concat dims
   in
@@ -284,14 +285,13 @@ let add_var_used_in_spec_or_compose row =
 let add_var_used_in_pointwise row =
   match row with Row.Row_var { v; _ } -> Row.add_used_in_pointwise v | _ -> ()
 
-(* For Block specs, compute invalid_vars: variables that are allowed to be 0.
-   A variable v is invalid if:
-   1. v appears in a component of a Concat dimension on one side
-   2. For ALL shapes on the other side, there EXISTS an axis such that for ALL components
-      of that axis, the complement of v's component has non-empty intersection.
-   This is a four-quantifier condition: ∀shapes ∃axis ∀components: complement ∩ component ≠ ∅ *)
-let compute_block_invalid_vars ~(this_side_rows : Row.t list)
-    ~(other_side_shapes : Row.t list list) : Row.dim_var_set =
+(* For Block specs, compute invalid_vars: variables that are allowed to be 0. A variable v is
+   invalid if: 1. v appears in a component of a Concat dimension on one side 2. For ALL shapes on
+   the other side, there EXISTS an axis such that for ALL components of that axis, the complement of
+   v's component has non-empty intersection. This is a four-quantifier condition: ∀shapes ∃axis
+   ∀components: complement ∩ component ≠ ∅ *)
+let compute_block_invalid_vars ~(this_side_rows : Row.t list) ~(other_side_shapes : Row.t list list)
+    : Row.dim_var_set =
   (* Extract all dims from rows (including beg_dims from bcast) *)
   let dims_of_rows rows =
     List.concat_map rows ~f:(fun (row : Row.t) ->
@@ -300,9 +300,8 @@ let compute_block_invalid_vars ~(this_side_rows : Row.t list)
         in
         row.dims @ dims_from_bcast)
   in
-  (* Get component var sets for each axis.
-     For non-Concat dims, there's one component with all vars of that dim.
-     For Concat dims, each element is a separate component. *)
+  (* Get component var sets for each axis. For non-Concat dims, there's one component with all vars
+     of that dim. For Concat dims, each element is a separate component. *)
   let axis_components_of_dim (dim : Row.dim) : Row.dim_var_set list =
     match dim with
     | Row.Concat dims -> List.map dims ~f:Row.vars_of_dim
@@ -313,8 +312,8 @@ let compute_block_invalid_vars ~(this_side_rows : Row.t list)
     List.map other_side_shapes ~f:(fun shape_rows ->
         List.map (dims_of_rows shape_rows) ~f:axis_components_of_dim)
   in
-  (* For each Concat on this side, find invalid vars.
-     Non-Concat dims cannot contribute invalid vars since their complement is empty. *)
+  (* For each Concat on this side, find invalid vars. Non-Concat dims cannot contribute invalid vars
+     since their complement is empty. *)
   let this_side_dims = dims_of_rows this_side_rows in
   List.fold this_side_dims ~init:Row.dim_var_set_empty ~f:(fun acc dim ->
       match dim with
@@ -1296,8 +1295,8 @@ let%debug4_sexp get_inequalities ?(for_projections = false)
       let rhs_results =
         List.mapi (List.zip_exn ls_rhses rhses) ~f:(fun i (ls_rhs, sh) ->
             let extras, proj_env, (b, inp, o) =
-              einsum_slot_spec_to_dims_bio ~original_spec:spec ~sh_id:sh.id ~row_var_env ~dim_var_env
-                ls_rhs
+              einsum_slot_spec_to_dims_bio ~original_spec:spec ~sh_id:sh.id ~row_var_env
+                ~dim_var_env ls_rhs
             in
             (i, sh, extras, proj_env, b, inp, o))
       in
@@ -1339,7 +1338,8 @@ let%debug4_sexp get_inequalities ?(for_projections = false)
                         Rows_constr
                           {
                             r = [ Row.get_row_for_var Row.empty_provenance var ];
-                            constr = Total_elems { numerator = Num_elems solved_dim; divided_by = [] };
+                            constr =
+                              Total_elems { numerator = Num_elems solved_dim; divided_by = [] };
                             origin =
                               [
                                 {
@@ -1416,17 +1416,18 @@ let%debug4_sexp get_inequalities ?(for_projections = false)
                   };
               ])
       in
-      (* Compute invalid_vars: variables that are allowed to be 0 (dimension 0 is invalid).
-         A variable is invalid if it's in a Concat component whose complement covers an axis
-         on the other side. We check both directions: RHS->LHS and LHS->RHS.
-         The four-quantifier condition: ∀shapes ∃axis ∀components: complement ∩ component ≠ ∅ *)
+      (* Compute invalid_vars: variables that are allowed to be 0 (dimension 0 is invalid). A
+         variable is invalid if it's in a Concat component whose complement covers an axis on the
+         other side. We check both directions: RHS->LHS and LHS->RHS. The four-quantifier condition:
+         ∀shapes ∃axis ∀components: complement ∩ component ≠ ∅ *)
       let rhs_shapes : Row.t list list =
         List.map rhs_results ~f:(fun (_, _, _, _, b_rhs, i_rhs, o_rhs) -> [ b_rhs; i_rhs; o_rhs ])
       in
       let lhs_rows = [ b_lhs; i_lhs; o_lhs ] in
       (* LHS is a single shape, so wrap it in a singleton list for the shapes parameter *)
       let invalid_from_rhs =
-        compute_block_invalid_vars ~this_side_rows:(List.concat rhs_shapes) ~other_side_shapes:[ lhs_rows ]
+        compute_block_invalid_vars ~this_side_rows:(List.concat rhs_shapes)
+          ~other_side_shapes:[ lhs_rows ]
       in
       let invalid_from_lhs =
         compute_block_invalid_vars ~this_side_rows:lhs_rows ~other_side_shapes:rhs_shapes
@@ -1806,8 +1807,8 @@ let%debug4_sexp derive_projections (update_step : update_step) : unit =
   (* We will not use the old inferred padding so that we can derive precisely the padding
      contributed by this step. *)
   let _debug_update_step : update_step = update_step in
-  let (proj_axis_env, invalid_vars, ineqs) :
-      proj_axis_env * Row.dim_var_set * Row.constraint_ list =
+  let (proj_axis_env, invalid_vars, ineqs) : proj_axis_env * Row.dim_var_set * Row.constraint_ list
+      =
     get_inequalities ~for_projections:true update_step
   in
   (* We need to solve the equations/inequalities one last time because of fresh row variables
@@ -1883,12 +1884,10 @@ let%debug4_sexp derive_projections (update_step : update_step) : unit =
       (module Idx.Symbol)
       (Row.product_dim_iterators proj_env |> List.map ~f:(fun (p, d, s) -> (s, (p, d))))
   in
-  (* Build connected components from Concat indices.
-     Symbols that appear together in a Concat must be iterated together.
-     We use union-find to group symbols into connected components.
-     Include both product dimensions and Concat dimensions.
-     Note: Concat can appear either as Row.Concat dim or as a regular Dim whose
-     proj_id maps to Idx.Concat. *)
+  (* Build connected components from Concat indices. Symbols that appear together in a Concat must
+     be iterated together. We use union-find to group symbols into connected components. Include
+     both product dimensions and Concat dimensions. Note: Concat can appear either as Row.Concat dim
+     or as a regular Dim whose proj_id maps to Idx.Concat. *)
   let product_indices : Idx.axis_index list =
     List.filter_map all_dims ~f:(fun dim ->
         match dim with
@@ -1913,12 +1912,11 @@ let%debug4_sexp derive_projections (update_step : update_step) : unit =
   in
   let unique_by_iterator =
     let seen =
-      Set.of_list
-        (module Idx.Symbol)
-        (List.map unique_by_iterator ~f:(fun (_, _, s) -> s))
+      Set.of_list (module Idx.Symbol) (List.map unique_by_iterator ~f:(fun (_, _, s) -> s))
     in
     let missing_symbols =
-      concat_groups |> List.concat |> Utils.unique_keep_first ~equal:Idx.equal_symbol
+      concat_groups |> List.concat
+      |> Utils.unique_keep_first ~equal:Idx.equal_symbol
       |> List.filter ~f:(fun s -> not (Set.mem seen s))
     in
     let missing_entries =
@@ -1927,13 +1925,11 @@ let%debug4_sexp derive_projections (update_step : update_step) : unit =
     in
     unique_by_iterator @ missing_entries
   in
-  (* Union-find to group symbols that appear in the same Concat.
-     Symbols within the same Concat must be in the same iteration group so that
-     they are iterated SEQUENTIALLY (via unflat_lines), not NESTED.
-     For (a, b) ++^ "a; b => a^b", i2 and i3 should be in the same group:
-     - First iterate i2 (RHS[0] active)
-     - Then iterate i3 (RHS[1] active)
-     This is achieved by making them part of the same product_iterators entry. *)
+  (* Union-find to group symbols that appear in the same Concat. Symbols within the same Concat must
+     be in the same iteration group so that they are iterated SEQUENTIALLY (via unflat_lines), not
+     NESTED. For (a, b) ++^ "a; b => a^b", i2 and i3 should be in the same group: - First iterate i2
+     (RHS[0] active) - Then iterate i3 (RHS[1] active) This is achieved by making them part of the
+     same product_iterators entry. *)
   let symbol_classes : (Idx.symbol, Idx.symbol) Hashtbl.t = Hashtbl.create (module Idx.Symbol) in
   let find_repr sym =
     let rec loop s =
@@ -1953,9 +1949,7 @@ let%debug4_sexp derive_projections (update_step : update_step) : unit =
   in
   (* Union all symbols within each Concat group to make them iterate sequentially *)
   List.iter concat_groups ~f:(fun syms ->
-      match syms with
-      | [] -> ()
-      | first :: rest -> List.iter rest ~f:(fun s -> union first s));
+      match syms with [] -> () | first :: rest -> List.iter rest ~f:(fun s -> union first s));
   (* Group unique_by_iterator entries by their representative symbol *)
   let components : (Idx.symbol, (Row.proj_id * int * Idx.symbol) list) Hashtbl.t =
     Hashtbl.create (module Idx.Symbol)
@@ -2376,7 +2370,8 @@ let shape_spec_to_dims_bio labels =
         let dims =
           List.map labels ~f:(fun label ->
               Row.Var
-                (Hashtbl.find_or_add dim_var_env label ~default:(fun () -> Row.get_var ~name:label ())))
+                (Hashtbl.find_or_add dim_var_env label ~default:(fun () ->
+                     Row.get_var ~name:label ())))
         in
         Row.Concat dims
   in
File "arrayjit/lib/low_level.ml", line 1, characters 0-0:
diff --git a/_build/default/arrayjit/lib/low_level.ml b/_build/default/arrayjit/lib/.formatted/low_level.ml
index 7bb5852..5359d1f 100644
--- a/_build/default/arrayjit/lib/low_level.ml
+++ b/_build/default/arrayjit/lib/.formatted/low_level.ml
@@ -269,7 +269,8 @@ let visit_llc traced_store ~merge_node_id reverse_node_map ~max_visits llc =
       | Indexing.Concat _syms ->
           (* Concat should be eliminated during lowering before we get here *)
           invalid_arg
-            "BUG: Concat index encountered during virtualization - should have been eliminated during lowering")
+            "BUG: Concat index encountered during virtualization - should have been eliminated \
+             during lowering")
   in
   let rec loop_proc ~first_visit env llc =
     let loop = loop_proc ~first_visit env in
@@ -308,9 +309,9 @@ let visit_llc traced_store ~merge_node_id reverse_node_map ~max_visits llc =
           traced.is_accessing <- traced.is_accessing || is_accessing_comp traced_store llsc;
           traced.is_complex <- traced.is_complex || is_complex_comp traced_store llsc);
         Hash_set.add traced.assignments (lookup env idcs);
-        (* Track which tensor uses which symbol. When multiple tensors share a symbol
-           (e.g., in Block/concat lowering), mark both as complex to disable virtualization.
-           See TODO(#134): this prevents multiple virtual arrays from sharing for loops. *)
+        (* Track which tensor uses which symbol. When multiple tensors share a symbol (e.g., in
+           Block/concat lowering), mark both as complex to disable virtualization. See TODO(#134):
+           this prevents multiple virtual arrays from sharing for loops. *)
         let track_symbol s =
           match Hashtbl.find reverse_node_map s with
           | None -> Hashtbl.set reverse_node_map ~key:s ~data:tn
File "tensor/row.ml", line 1, characters 0-0:
diff --git a/_build/default/tensor/row.ml b/_build/default/tensor/.formatted/row.ml
index 898e33e..1534f31 100644
--- a/_build/default/tensor/row.ml
+++ b/_build/default/tensor/.formatted/row.ml
@@ -2424,9 +2424,11 @@ let%track5_sexp solve_dim_ineq ~(stage : stage) origin ~(cur : dim) ~(subr : dim
       (* Element-wise unification of concatenated dimensions *)
       let eqs = List.map2_exn dims1 dims2 ~f:(fun d1 d2 -> Dim_eq { d1; d2; origin }) in
       (eqs, env)
-  | _, Concat dims when List.count dims ~f:(function Var v -> Set.mem env.invalid_vars v | _ -> false) >= List.length dims - 1 ->
-      (* Concat in subr position with all-but-one (or all) components being invalid vars:
-         preserve inequality so the solver can infer the variables *)
+  | _, Concat dims
+    when List.count dims ~f:(function Var v -> Set.mem env.invalid_vars v | _ -> false)
+         >= List.length dims - 1 ->
+      (* Concat in subr position with all-but-one (or all) components being invalid vars: preserve
+         inequality so the solver can infer the variables *)
       ([ Dim_ineq { cur; subr; from_ = Sexp.List []; origin } ], env)
   | Concat _, _ | _, Concat _ ->
       (* Defer to dimension equality for concat with non-concat *)
@@ -2941,13 +2943,13 @@ let%debug5_sexp rec close_dim_terminal ~(stage : stage) ~is_param origin env (di
       (* The input dimension itself cannot be dim-1, and the over dimension doesn't become
          transitively terminal. *)
       []
-  | Concat dims ->
-      (* For concatenation, filter out dimension-0 components and if one remains, close it.
-         TODO: Consider guessing invalid_vars components to 0 at stage 6, but wait until needed. *)
+  | Concat dims -> (
+      (* For concatenation, filter out dimension-0 components and if one remains, close it. TODO:
+         Consider guessing invalid_vars components to 0 at stage 6, but wait until needed. *)
       let non_zero_dims = List.filter dims ~f:(function Dim { d = 0; _ } -> false | _ -> true) in
-      (match non_zero_dims with
-       | [ single ] -> close_dim_terminal ~stage ~is_param origin env single
-       | _ -> [])
+      match non_zero_dims with
+      | [ single ] -> close_dim_terminal ~stage ~is_param origin env single
+      | _ -> [])
 
 let last_dim_is dims p = match List.last dims with Some (Dim { d; _ }) -> p d | _ -> false
 
@@ -3214,8 +3216,7 @@ let%track5_sexp close_row_terminal ~(stage : stage) ~is_param origin env
 
 let%debug5_sexp eliminate_dim_entry stage origin env v ~lub constr =
   let guess_dim () =
-    if Set.mem env.invalid_vars v then get_dim ~d:0 ~proj_id:56 ()
-    else get_dim ~d:1 ~proj_id:59 ()
+    if Set.mem env.invalid_vars v then get_dim ~d:0 ~proj_id:56 () else get_dim ~d:1 ~proj_id:59 ()
   in
   match (lub, constr) with
   | Some (Dim { d; _ } as lub), At_least_dim d2 when d2 > d ->
@@ -3232,8 +3233,7 @@ let%debug5_sexp eliminate_dim_entry stage origin env v ~lub constr =
       Some (Dim_eq { d1 = Var v; d2 = lub; origin })
   | None, At_least_dim d when is_stage7 stage ->
       Some (Dim_eq { d1 = Var v; d2 = get_dim ~d ~proj_id:58 (); origin })
-  | None, _ when is_stage7 stage ->
-      Some (Dim_eq { d1 = Var v; d2 = guess_dim (); origin })
+  | None, _ when is_stage7 stage -> Some (Dim_eq { d1 = Var v; d2 = guess_dim (); origin })
   | _ -> None
 
 let%track5_sexp process_shape_row ~(stage : stage) origin env ({ dims; bcast; prov } as r : row) :
@@ -3245,12 +3245,12 @@ let%track5_sexp process_shape_row ~(stage : stage) origin env ({ dims; bcast; pr
     | Affine { over; conv = Some { kernel; _ }; _ } ->
         finalize_upper_lower_bound over @ finalize_upper_lower_bound kernel
     | Concat dims -> List.concat_map dims ~f:finalize_upper_lower_bound
-    | Var v ->
+    | Var v -> (
         let guess_dim () =
           if Set.mem env.invalid_vars v then get_dim ~d:0 ~proj_id:61 ()
           else get_dim ~d:1 ~proj_id:62 ()
         in
-        (match find_dim env.dim_env v with
+        match find_dim env.dim_env v with
         | Some (Bounds_dim { is_in_param = true; _ }) when final ->
             raise
             @@ Shape_error
@@ -3993,8 +3993,10 @@ let%debug4_sexp solve_proj_equations (eqs : proj_equation list)
   let verify_when_solved2 = ref [] in
   let p_dims = ref [] in
   let iterated_vars = ref [] in
-  let p_concat_targets = ref [] in (* (target_pid, component proj_dims) for deferred Concat handling *)
-  let p_concat_components = ref @@ Set.empty (module Proj_id) in (* proj_ids that are Concat components *)
+  let p_concat_targets = ref [] in
+  (* (target_pid, component proj_dims) for deferred Concat handling *)
+  let p_concat_components = ref @@ Set.empty (module Proj_id) in
+  (* proj_ids that are Concat components *)
   let proj_classes = ref @@ Map.empty (module Proj_id) in
   let rec loop (eq : proj_equation) : unit =
     match eq with
@@ -4019,8 +4021,8 @@ let%debug4_sexp solve_proj_equations (eqs : proj_equation list)
         | None -> c.target_id <- Some p);
         (* We will substitute variables in conv_input later *)
         p_conv_input := (p, conv_input) :: !p_conv_input
-    | Proj_eq (Solved idx, (Conv_input _ | Concat _ as conv_input))
-    | Proj_eq ((Conv_input _  | Concat _ as conv_input), Solved idx) ->
+    | Proj_eq (Solved idx, ((Conv_input _ | Concat _) as conv_input))
+    | Proj_eq (((Conv_input _ | Concat _) as conv_input), Solved idx) ->
         verify_when_solved1 := (idx, conv_input) :: !verify_when_solved1
     | Proj_eq
         ( (Conv_input { stride = stride1; over = over1; _ } as conv_input1),
@@ -4029,7 +4031,7 @@ let%debug4_sexp solve_proj_equations (eqs : proj_equation list)
         loop (Proj_eq (over1, over2));
         if equal_proj conv_input1 conv_input2 then ()
         else verify_when_solved2 := (conv_input1, conv_input2) :: !verify_when_solved2
-    | Proj_eq ((Conv_input _ as conv_input1), (Conv_input _ | Concat _ as conv_input2))
+    | Proj_eq ((Conv_input _ as conv_input1), ((Conv_input _ | Concat _) as conv_input2))
     | Proj_eq ((Concat _ as conv_input1), (Conv_input _ as conv_input2)) ->
         (* Conv_input vs Conv_input/Concat - defer verification *)
         if equal_proj conv_input1 conv_input2 then ()
@@ -4110,7 +4112,7 @@ let%debug4_sexp solve_proj_equations (eqs : proj_equation list)
       (module Proj_id)
       (Set.to_list !p_concat_components
       |> List.map ~f:(fun p ->
-             fst @@ Utils.union_find ~equal:Proj_id.equal !proj_classes ~key:p ~rank:0))
+          fst @@ Utils.union_find ~equal:Proj_id.equal !proj_classes ~key:p ~rank:0))
   in
   List.iter !p_solved ~f:(fun (p, idx) ->
       let repr, _ = Utils.union_find ~equal:Proj_id.equal !proj_classes ~key:p ~rank:0 in
@@ -4150,8 +4152,7 @@ let%debug4_sexp solve_proj_equations (eqs : proj_equation list)
                      [] )));
   List.iter concat_dims ~f:(fun (p, d) ->
       let repr, _ = Utils.union_find ~equal:Proj_id.equal !proj_classes ~key:p ~rank:0 in
-      if not @@ Map.mem !product_dim repr then
-        product_dim := Map.set !product_dim ~key:repr ~data:d);
+      if not @@ Map.mem !product_dim repr then product_dim := Map.set !product_dim ~key:repr ~data:d);
   (* Create fresh iterators for product dimensions, EXCEPT for those that will get their index from
      Conv_input (they will be processed later). *)
   Map.iteri !product_dim ~f:(fun ~key:p ~data:_ ->
@@ -4232,9 +4233,7 @@ let%debug4_sexp solve_proj_equations (eqs : proj_equation list)
       in
       let syms =
         List.filter_map proj_dims ~f:(fun (pid, { d; _ }) ->
-            let repr, _ =
-              Utils.union_find ~equal:Proj_id.equal !proj_classes ~key:pid ~rank:0
-            in
+            let repr, _ = Utils.union_find ~equal:Proj_id.equal !proj_classes ~key:pid ~rank:0 in
             match Map.find !projs repr with
             | Some (Idx.Iterator s) -> Some s
             | Some (Idx.Fixed_idx 0) when d = 0 -> None (* d=0 is invalid dimension, skip *)
@@ -4246,9 +4245,7 @@ let%debug4_sexp solve_proj_equations (eqs : proj_equation list)
                          "Concat component projection %{pid#Proj_id} (d=%{d#Int}) has no iterator"],
                        [] ))
       in
-      let expected_idx =
-        if List.is_empty syms then Idx.Fixed_idx 0 else Idx.Concat syms
-      in
+      let expected_idx = if List.is_empty syms then Idx.Fixed_idx 0 else Idx.Concat syms in
       match Map.find !projs target_repr with
       | None -> projs := Map.set !projs ~key:target_repr ~data:expected_idx
       | Some existing_idx ->
@@ -4312,6 +4309,6 @@ let proj_to_iterator_exn proj_env p =
 let product_dim_iterators proj_env =
   Map.to_alist proj_env.product_dim
   |> List.filter_map ~f:(fun (p, d) ->
-         match Map.find proj_env.proj_to_index p with
-         | Some (Idx.Iterator s) -> Some (p, d, s)
-         | _ -> None)
+      match Map.find proj_env.proj_to_index p with
+      | Some (Idx.Iterator s) -> Some (p, d, s)
+      | _ -> None)
dune build @fmt failed
"/usr/bin/env" "bash" "-c" "opam exec -- dune build @fmt --ignore-promoted-rules || (echo "dune build @fmt failed"; exit 2)" failed with exit status 2
2026-01-20 15:54.14: Job failed: Failed: Build failed