{"since":"2026-10-30T08:59:17Z","until":"2026-10-31T08:59:17Z","view":"all","by":"date","matched":113,"offset":0,"returned":50,"by_meaning":false,"items":[{"id":"github:scrollprize/villa#2266","source":"github","kind":"pr","title":"ScrollPrize/villa #2266: zarr_tasks: write the per-level scale OME-NGFF 0.4 requires","url":"https://github.com/ScrollPrize/villa/pull/2266","date":"2026-10-30T21:39:10Z","summary":"**In one sentence:** Pyramids written by the `zarr_tasks` threshold, transpose, scale and recompress tasks now carry the per-level scale that OME-NGFF 0.4 requires, so they pass OME-NGFF 0.4 validation like the scroll volumes they are made from. **One real example:** Starting with a 128³ crop of Scroll 1A (`54keV_7.91um_Scroll1A.zarr`, level 2, origin z,y,x = 1797, 986, 1012), I ran `python -m vesuvius.image_proc.run.zarr_tasks crop.zarr/0 out.zarr --task threshold -t 100 --num-levels 3`, and the output failed OME-NGFF 0.4 validation; with this PR it passes and the pixel data is unchanged. **Before:** `multiscales.datasets` entries contain only `path`. `ome_zarr_models.v04.Image.from_zarr` rejects the group with a `ValidationError`. The source scroll volume itself passes, so the task turns a valid OME-Zarr into an invalid one. **After this PR:** each level `i` gets `coordinateTransformat","keyword":50,"topics":["Scroll work","Compression and storage"],"matched":["zarr","volume","volumes"],"parts":[["ScrollPrize/villa pull request",30],["Compression and storage (strong): zarr",14],["context: volume, volumes",6]],"state":"merged","who":"rwe6445","created":"2026-10-23T10:49:49Z","activity":{"what":"closed","who":"bruniss","date":"2026-10-30T21:39:10Z","text":"","url":"https://github.com/ScrollPrize/villa/pull/2266","also":["merged"]},"code":["https://github.com/rwe6445/villa/blob/pr-evidence/pr-evidence/pr_h_codespace_result.png?raw=true","https://github.com/rwe6445/villa/blob/pr-evidence/pr-evidence/pr_h_codespac"],"semantic":8,"sim":0.708,"near":"Compression and storage","rule":50,"score":94,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2197","source":"github","kind":"pr","title":"ScrollPrize/villa #2197: ink_detection: read mask surfaces once in default patch finding","url":"https://github.com/ScrollPrize/villa/pull/2197","date":"2026-10-30T21:33:47Z","summary":"**In one sentence:** default patch finding (`find_segment_patches` in `vesuvius/src/vesuvius/ink_detection/data/patch_finding_default.py`) returns the same patches about 9 to 12 times faster on a real training set, because it reads each mask surface once instead of once per candidate, and with about 0.8 GB less peak memory on the segment measured alone. Fixes #2195 **One real example:** Starting with 44 training segments of three scrolls (supervision, validation and inklabels masks as zarr, chunks 28x128x128), I ran `find_segment_patches` from main and from this PR on every segment at 17x256x256 and 17x384x384 with patch_overlap 0.25, and compared the patch lists corner by corner: identical on 44 of 44 segments at both sizes (388,818 and 184,644 patches), and the summed time went from 2309.3 s to 260.1 s at 256 (8.9x) and from 2169.5 s to 174.4 s at 384 (12.4x). **Before:** for every can","keyword":50,"topics":["Scroll work","Compression and storage"],"matched":["zarr"],"parts":[["ScrollPrize/villa pull request",30],["Compression and storage (strong): zarr",14],["context: zarr",6]],"state":"merged","who":"evilaliv3","created":"2026-10-21T14:46:23Z","activity":{"what":"closed","who":"bruniss","date":"2026-10-30T21:33:47Z","text":"","url":"https://github.com/ScrollPrize/villa/pull/2197","also":["merged"]},"semantic":7,"sim":0.707,"near":"Ink and imaging","rule":50,"score":94,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2146","source":"github","kind":"pr","title":"ScrollPrize/villa #2146: ink_detection: share the physical sampling key for aligned w028 and native w044","url":"https://github.com/ScrollPrize/villa/pull/2146","date":"2026-10-30T21:19:22Z","summary":"**In one sentence:** Give aligned `pherc0139-w028` and native `w044` one physical sampling budget, as required by the publisher's source table. **One real example:** The archived real-data reproduction used the same bounded pool of 116 production-discovered patches (four from each of 29 ink_9um representations). The publisher [lists both labels](https://huggingface.co/buckets/scrollprize/datasets/tree/ink_9um) under `PHerc0139/segments/20260115000000-w044_2026011522`, in different CT scans. **Before:** The shipped configs assign separate physical keys (`0139:w028` and `0139:w044`), so the shared source receives two budgets. **After this PR:** Both use `0139:w044`. The two representations and their CT frames remain distinct. Only two config values change; the sampler is unchanged. | Archived measurement | Before | Corrected | |---|---:|---:| | PHerc. 0139 physical budget groups | 10 | 9 |","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"merged","who":"RhudeJJJJ","created":"2026-10-18T21:22:31Z","code":["https://huggingface.co/buckets/scrollprize/datasets/tree/ink_9um","https://github.com/RhudeJJJJ/vesuvius-source-bound-sampling/tree/b255e84db9045d3f9acd231f373492de13e4a1ee"],"semantic":15,"sim":0.715,"near":"Ink and imaging","rule":30,"score":94,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2123","source":"github","kind":"pr","title":"ScrollPrize/villa #2123: normalgridtools / vc_gen_umbilicus: optional --uncrush for crushed scrolls","url":"https://github.com/ScrollPrize/villa/pull/2123","date":"2026-10-30T21:17:35Z","summary":"**Why I made this:** I've made these automatic umbilici, which are scroll axes for First Letters scrolls that don't have one yet, since the spiral fit requires an axis and only a couple of the eligible scrolls have one that's hand-made. I kept seeing VC3D's estimate far off from the actual center on crushed scrolls, with the windings being squashed into ellipses. Instead, we stretch each slice back towards round before we estimate, use the sheet normals so the round scrolls are left alone, and it's off by default. When I checked it against hand-made axes on real scrolls, the uncrushed axis fit just as well as the hand-made one, and at the same time today's estimate did way worse. **In one sentence:** `vc_gen_umbilicus --uncrush 1.5` gives crushed scrolls an automatic umbilicus about as good as a hand-made one, and leaves round scrolls as they are. **One real example:** Starting with the ","keyword":38,"topics":["Scroll work","Sheets and surfaces"],"matched":["sheet"],"parts":[["ScrollPrize/villa pull request",30],["Sheets and surfaces (weak): sheet",8]],"state":"merged","who":"EconLearn","created":"2026-10-16T16:35:50Z","semantic":0,"sim":0.691,"near":"Scroll work","rule":38,"score":94,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2142","source":"github","kind":"pr","title":"ScrollPrize/villa #2142: ink_detection: warn when a requested layer window is silently discarded","url":"https://github.com/ScrollPrize/villa/pull/2142","date":"2026-10-30T21:10:16Z","summary":"**In one sentence:** If you pass `--layer-start`/`--layer-end` to flat ink inference and the window does not survive clamping, you now get a warning instead of a silent run that is byte-identical to using no window at all. **One real example:** Starting with my own published render of PHerc0813 z4704_w080 (9.362 um, 31 layers, `rodriguescarson/eligible-scroll-atlas-renders`), I ran `infer` twice with the `hybrid_3d2d-seed43/step-060000` checkpoint — once with no layer window and once with `--layer-start 40 --layer-end 50` on a volume that only has 31 layers — and the two predictions came out with the same SHA256. **Before:** The second run logs `Selected source layer indices=[7 ... 23]`, writes a prediction, and exits 0. Nothing says the requested window was thrown away. ``` $ infer crop1024.zarr step-060000.pth A_default.tif --overlap 0.5 --blend-mode hann INFO Selected source layer ind","keyword":66,"topics":["Scroll work","Ink and imaging","Compression and storage"],"matched":["ink","zarr","volume"],"parts":[["ScrollPrize/villa pull request",30],["Ink and imaging (strong): ink",16],["Compression and storage (strong): zarr",14],["context: volume, zarr",6]],"state":"merged","who":"rodriguescarson","created":"2026-10-18T19:23:21Z","semantic":0,"sim":0.663,"near":"Ink and imaging","rule":66,"score":94,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2129","source":"github","kind":"pr","title":"ScrollPrize/villa #2129: Fix the segment example in Volume's failure hint (add scroll_id)","url":"https://github.com/ScrollPrize/villa/pull/2129","date":"2026-10-30T20:59:50Z","summary":"**In one sentence:** When `Volume` fails to load, the example it prints for opening a segment now actually works, so a new user isn't sent from one error straight into a second. **One real example:** Starting with segment 20230827161847 from Scroll 1, I followed the \"Example Usage\" text that `Volume` prints on failure, and it produced `ValueError: Could not determine energy/resolution for scroll None`. **Before:** The printed hint was `Volume(type=\"segment\", segment_id=20230827161847)`, which raises the ValueError above. **After this PR:** The hint reads `Volume(type=\"segment\", segment_id=20230827161847, scroll_id=1)`, which loads the segment. **Proof:** ``` $ python -c \"from vesuvius import Volume; Volume(type='segment', segment_id=20230827161847)\" ValueError: Could not determine energy/resolution for scroll None. Please provide them explicitly. ... Example Usage: segment = Volume(type=","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"merged","who":"Wittmoon","created":"2026-10-17T17:32:17Z","semantic":0,"sim":0.657,"near":"Scroll work","rule":30,"score":93,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2084","source":"github","kind":"pr","title":"ScrollPrize/villa #2084: VC3D AppImage: open remote data on Fedora / RHEL / Rocky / AlmaLinux (use the host's CA bundle)","url":"https://github.com/ScrollPrize/villa/pull/2084","date":"2026-10-30T21:01:39Z","summary":"**In one sentence:** The Linux AppImage can stream scroll data (Open Data Catalog, remote volumes, normal grids, segments) on Fedora, RHEL, Rocky, AlmaLinux and openSUSE machines, not only on Debian/Ubuntu. **One real example:** Starting with PHerc0343P segment `20250905172054-1_b2` and its 8.64 µm volume on the open-data bucket, I ran `vc_render_tifxyz --remote-url …` from the AppImage on an AlmaLinux 9.6 cluster node, and it rendered all 31 layers of the segment instead of failing on the first request. **Before:** every HTTPS request from the AppImage fails on these systems, so no open data can be opened: ``` # AlmaLinux 9.6; VC3D-fb8c2c4-2026-10-06-linux-x86_64.AppImage extracted, run via its AppRun $ squashfs-root/AppRun vc_render_tifxyz -s seg --remote-url https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0343P/volumes/20250521134555-8.640um-1.2m-116keV-masked.zar","keyword":50,"topics":["Scroll work","Compression and storage"],"matched":["zarr","volume","volumes"],"parts":[["ScrollPrize/villa pull request",30],["Compression and storage (strong): zarr",14],["context: volume, volumes",6]],"state":"merged","who":"protonjls","created":"2026-10-13T23:52:39Z","semantic":0,"sim":0.659,"near":"Compression and storage","rule":50,"score":91,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2244","source":"github","kind":"pr","title":"ScrollPrize/villa #2244: zarr_tasks merge: create output levels through create_level_dataset so merge runs under zarr 3 (fixes #2240)","url":"https://github.com/ScrollPrize/villa/pull/2244","date":"2026-10-30T21:34:28Z","summary":"## Problem `vesuvius.zarr_tasks --task merge` cannot run under zarr 3. `MergeTask.prepare` and `MergeTask._generate_pyramid_levels` call `Group.create_dataset`, which zarr 3 removed, and `vesuvius/pyproject.toml` allows `zarr>=2.18.7,<4`, so a fresh install that resolves zarr 3 fails before writing level 0: ``` AttributeError: 'Group' object has no attribute 'create_dataset' ``` Reproduced on this branch's parent with zarr 3.2.1 by running the task end to end on two 8x8x8 inputs: the crash is at `merge.py:296`, as #2240 reports. The same run passes with zarr 2.18.7. ## Change Both call sites now go through `create_level_dataset` in `zarr_tasks/utils.py`, the helper the scale, threshold, transpose and recompress tasks already use. It works on zarr 2 and zarr 3 and writes the zarr v2 group itself, so `prepare` empties the output directory first, which is what `zarr.open(..., mode=\"w\")` did","keyword":50,"topics":["Scroll work","Compression and storage"],"matched":["zarr"],"parts":[["ScrollPrize/villa pull request",30],["Compression and storage (strong): zarr",14],["context: zarr",6]],"state":"merged","who":"stantheman0128","created":"2026-10-22T19:01:51Z","activity":{"what":"closed","who":"bruniss","date":"2026-10-30T21:34:28Z","text":"","url":"https://github.com/ScrollPrize/villa/pull/2244","also":["merged"]},"semantic":0,"sim":0.652,"near":"Compression and storage","rule":50,"score":89,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2199","source":"github","kind":"pr","title":"ScrollPrize/villa #2199: Recompress: pass the source level, not the OME-Zarr group root, to workers","url":"https://github.com/ScrollPrize/villa/pull/2199","date":"2026-10-30T21:31:43Z","summary":"**In one sentence:** Recompressing an OME-Zarr folder into a new output now copies the real data, instead of writing a valid-looking output full of zeros when `--skip-corrupt` is on. **One real example:** I copied level 5 of the public PHerc1203 volume (`s3://vesuvius-challenge-open-data/PHerc1203/volumes/20250820131727-9.362um-1.2m-113keV-masked.zarr/5`, 594 x 214 x 214 uint8, 42 MB, with its `.zattrs`) into a local OME-Zarr folder and ran `python -m vesuvius.image_proc.run.zarr_tasks PHerc1203_l5.zarr out.zarr --task recompress --skip-corrupt -n 2 --num-levels 3`. **Before:** The run finished with \"Recompression complete\" and listed all 20 chunks as corrupted and filled with zeros. The output level 0 had 0 nonzero voxels. The source has 7,434,944. Without `--skip-corrupt` every worker fails instead. **After this PR:** The output level 0 has 7,434,944 nonzero voxels and the same sha256 ","keyword":50,"topics":["Scroll work","Compression and storage"],"matched":["zarr","volume","volumes"],"parts":[["ScrollPrize/villa pull request",30],["Compression and storage (strong): zarr",14],["context: volume, volumes",6]],"state":"merged","who":"Rano200","created":"2026-10-21T14:57:47Z","activity":{"what":"closed","who":"bruniss","date":"2026-10-30T21:31:43Z","text":"","url":"https://github.com/ScrollPrize/villa/pull/2199","also":["merged"]},"semantic":0,"sim":0.694,"near":"Compression and storage","rule":50,"score":89,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2108","source":"github","kind":"pr","title":"ScrollPrize/villa #2108: tifxyz writer: overwrite=True keeps the other files in the segment directory","url":"https://github.com/ScrollPrize/villa/pull/2108","date":"2026-10-30T20:36:53Z","summary":"**In one sentence:** `write_tifxyz(path, surface, overwrite=True)` now replaces the surface files and keeps every other file in the segment directory, as `QuadSurface::saveWithUuid` does, instead of deleting the directory and putting back only `x/y/z.tif`, `meta.json` and `mask.tif`. **One real example:** Starting with a copy of PHercParis4 segment 20231007101619 (the 45.532 µm tifxyz) with an ink label next to it, I rewrote the surface in place with `s = read_tifxyz(seg); write_tifxyz(seg, s, overwrite=True)`. The label was the published 2.4 µm ink prediction for this segment, resized to the surface's full resolution and saved as `20231007101619_ink.png`. On main the call returns normally and the label is gone: `list_labels()` goes from 1 label to 0. With this PR the label is still there, byte-identical, and the surface files are rewritten as before. **Before:** `TifxyzWriter.write` wri","keyword":46,"topics":["Scroll work","Ink and imaging"],"matched":["ink"],"parts":[["ScrollPrize/villa pull request",30],["Ink and imaging (strong): ink",16]],"state":"merged","who":"CVasilopoulos","created":"2026-10-15T08:32:04Z","semantic":0,"sim":0.599,"near":"Compression and storage","rule":46,"score":86,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2067","source":"github","kind":"pr","title":"ScrollPrize/villa #2067: Resampled tifxyz grids: don't keep vertices interpolated from a missing vertex (merge_concat_runs)","url":"https://github.com/ScrollPrize/villa/pull/2067","date":"2026-10-30T20:47:15Z","summary":"**Rebased on main `e1aa625a6` (2026-10-29):** #2358 removed `volume-cartographer/scripts/repair_tifxyz_spacing.py` as an unused script, so this PR now changes only `merge_concat_runs.resample_to` and adds its test. The real-data run below was made on `bcdf9bf53`, while the repair script (same masking code) still existed; the part that still applies is the `resample_to` line (5 -> 0), because `resample_to` and `invalid_mask` are unchanged on current main apart from a docstring. Re-run on the rebased branch: `tests/test_merge_resample_mask.py` 1 failed, 1 passed on main and 2 passed here; `tests/test_merge_concat_runs.py` 4 passed on both. **In one sentence:** resampling a tifxyz grid in `merge_concat_runs.py` or `scripts/repair_tifxyz_spacing.py` no longer writes vertices as valid when they were interpolated from a missing (-1) vertex. Those vertices land hundreds to thousands of voxels a","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"merged","who":"CVasilopoulos","created":"2026-10-13T08:44:10Z","semantic":0,"sim":0.671,"near":"Compression and storage","rule":30,"score":84,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2254","source":"github","kind":"pr","title":"ScrollPrize/villa #2254: fix(ink-inference): release buffers after raw-empty patches","url":"https://github.com/ScrollPrize/villa/pull/2254","date":"2026-10-30T21:38:46Z","summary":"**In one sentence:** Flat ink inference can release completed blend buffers when overlapping patches have empty raw input. **One real example:** A `28 x 384 x 384` crop from our PHerc0211 render, using the published `ink_9um` seed42 step-075000 checkpoint, schedules 17 patches and skips three with empty raw input. **Before:** Two probability/weight buffer pairs (256 KiB) remain until the final flush in each depth direction because skipped patches never complete their scheduled contributions. **After this PR:** No buffers remain before the final flush on this crop. Empty patches complete their bookkeeping without allocating arrays or adding blend weights. **Proof:** The [trained-checkpoint comparison](https://github.com/bnleft/first-light-pherc0211/blob/ab91ab3b76c62c9012722a77b4982417ff2bffa3/contrib/october-flat-inference-buffer-fix/TRAINED_CHECKPOINT_CURRENT.json) produces byte-identic","keyword":46,"topics":["Scroll work","Ink and imaging"],"matched":["ink"],"parts":[["ScrollPrize/villa pull request",30],["Ink and imaging (strong): ink",16]],"state":"merged","who":"bnleft","created":"2026-10-23T01:47:36Z","activity":{"what":"closed","who":"bruniss","date":"2026-10-30T21:38:46Z","text":"","url":"https://github.com/ScrollPrize/villa/pull/2254","also":["merged"]},"code":["https://github.com/bnleft/first-light-pherc0211/blob/ab91ab3b76c62c9012722a77b4982417ff2bffa3/contrib/october-flat-inference-buffer-fix/TRAINED_CHECKPOINT_CURRENT.json","https://github.com/bnleft/first-light-pherc0211/blob/ab91ab3b76c62c9012722a77b4982417ff2bffa3/contrib/october-flat-inference-buffer-fix/CURRENT_UPSTREAM_VALIDATION.md"],"semantic":0,"sim":0.655,"near":"Sheets and surfaces","rule":46,"score":82,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2156","source":"github","kind":"pr","title":"ScrollPrize/villa #2156: zarr_tasks recompress --inplace: keep the source array on a trailing slash or a failed copy","url":"https://github.com/ScrollPrize/villa/pull/2156","date":"2026-10-30T21:30:30Z","summary":"**In one sentence:** `vesuvius.zarr_tasks --task recompress --inplace` copies every chunk into ` _tmp`, deletes the source chunk and finally swaps the copy in, and two paths destroyed the source: a trailing slash on the input path (`vol.zarr/`, as shell tab-completion writes it) put the temp array *inside* the source, so replacing the source deleted both and nothing was left; and an error raised part-way through the copy (shown here with a truncated chunk and no `--skip-corrupt`) deleted the temp array, which by then held every chunk already removed from the source. This PR normalises the input path and, on failure, writes the moved chunks back into the source before the temp array is removed. **One real example:** level 4 of the public PHerc0500P2 volume (`PHerc0500P2/volumes/20250820143440-9.362um-1.2m-113keV-masked.zarr/4`, 442 × 263 × 263 uint8, 128³ chunks, nested `/` keys, stored u","keyword":50,"topics":["Scroll work","Compression and storage"],"matched":["zarr","volume","volumes"],"parts":[["ScrollPrize/villa pull request",30],["Compression and storage (strong): zarr",14],["context: volume, volumes",6]],"state":"merged","who":"tencur","created":"2026-10-19T18:21:52Z","activity":{"what":"closed","who":"bruniss","date":"2026-10-30T21:30:30Z","text":"","url":"https://github.com/ScrollPrize/villa/pull/2156"},"semantic":7,"sim":0.707,"near":"Compression and storage","rule":50,"score":81,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2141","source":"github","kind":"pr","title":"ScrollPrize/villa #2141: spiral-fitting: read SQLite track stores without losing WAL commits","url":"https://github.com/ScrollPrize/villa/pull/2141","date":"2026-10-30T21:04:45Z","summary":"SQLite track stores now use the read-only SQLite reader on every supported Python version. Complete, checkpointed stores can open from read-only dataset directories without creating sidecars, while existing WAL commits remain visible. Motivation: Villa's spiral-fitting reader encounters this with published PHercParis4 track stores. Their SQLite headers specify WAL mode: ```sh curl -s -r 0-99 https://dl.ash2txt.org/datasets/spiral_datasets/PHercParis4/tracks/m7_ds2_z3000_18000_surf.dbm \\ | python3 -c \"import sys; h = sys.stdin.buffer.read(); print(h[:16], h[18], h[19])\" # b'SQLite format 3\\x00' 2 2 ``` SQLite detection precedes native DBM dispatch, addressing [the maintainer review](https://github.com/ScrollPrize/villa/pull/2141#issuecomment-6324404963). The reader adds `immutable=1` only when no WAL exists; otherwise it retains normal read-only locking and WAL access. Other DBM formats k","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"merged","who":"jonmarrs","created":"2026-10-18T18:27:10Z","code":["https://github.com/ScrollPrize/villa/pull/2141#issuecomment-6324404963"],"semantic":0,"sim":0.647,"near":"Compression and storage","rule":30,"score":79,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2148","source":"github","kind":"pr","title":"ScrollPrize/villa #2148: volume-cartographer: use @loader_path rpaths for Python bindings on macOS","url":"https://github.com/ScrollPrize/villa/pull/2148","date":"2026-10-30T21:45:46Z","summary":"_Requested by **Shiwei** · [project thread](https://claude.ai/code/project/chan_011KpMWe2yCaxzYKBXh1kBcA?thread=cmsg_011KpMWe2yCaxzYKBXh1kBcABiVuHyApcz2JSE4g7hJwwQ)_ **In one sentence:** On macOS, `import vc` now works after `uv sync` in `vesuvius/`, without hand-patching the installed libraries. **One real example:** Starting with a fresh `uv sync --extra models --extra tests` in `vesuvius/` on macOS 15.7 (Apple M3 Pro, Homebrew LLVM 23), I ran `uv run python -c \"import vc\"`, and it printed `import vc OK` instead of failing to load `libvc_core.dylib`. **Before:** `import vc` failed with: ``` ImportError: dlopen(.../site-packages/vc/volume.cpython-314-darwin.so, 0x0002): Library not loaded: @rpath/libvc_core.dylib Reason: tried: '$ORIGIN:$ORIGIN/../libvc_core.dylib' (no such file) ``` The library was installed right next to the module. macOS doesn't understand Linux's `$ORIGIN`, so it lo","keyword":44,"topics":["Scroll work","Fibers and tracing"],"matched":["fiber","volume"],"parts":[["ScrollPrize/villa pull request",30],["Fibers and tracing (weak): fiber",8],["context: volume",6]],"state":"merged","who":"aprilschen","created":"2026-10-18T21:40:58Z","activity":{"what":"closed","who":"bruniss","date":"2026-10-30T21:45:46Z","text":"","url":"https://github.com/ScrollPrize/villa/pull/2148","also":["merged"]},"semantic":0,"sim":0.655,"near":"Scroll work","rule":44,"score":77,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2063","source":"github","kind":"pr","title":"ScrollPrize/villa #2063: vc_grow_seg_from_seed: opt-in seed_anchor_xyz keeps a vertex fixed at the seed","url":"https://github.com/ScrollPrize/villa/pull/2063","date":"2026-10-30T20:57:22Z","summary":"**In one sentence:** With the new opt-in parameter `seed_anchor_xyz` set to the explicit seed, `vc_grow_seg_from_seed` keeps one vertex fixed at that seed in every solve while it grows, so a trace started on one winding can't drift onto another winding at the start (#2059). **One real example:** Starting with PHerc0139 scan `20250728140407` (9.362 µm) and its published surface prediction, I grew 60 generations from `-s 4201 3186 4602`, a seed 1.1 voxels from the published winding w031, once on `main` and once with this PR and `\"seed_anchor_xyz\": [4201, 3186, 4602]`. With this PR the trace starts on w031 and most of it stays there: 80 % of its scored vertices are within 4 voxels of w031, and 13 % reached w032 in one corner. On `main`, none of its vertices are on w031 and half are on w033. **Before:** On `main` nothing holds the four starting vertices: any local or global solve that reache","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"merged","who":"ChaseHendrick","created":"2026-10-12T20:39:46Z","semantic":0,"sim":0.638,"near":"Sheets and surfaces","rule":30,"score":76,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z","who_name":"Chase Hendrick"},{"id":"github:scrollprize/villa#2130","source":"github","kind":"pr","title":"ScrollPrize/villa #2130: README: make the entrypoint table match the commands that are actually installed","url":"https://github.com/ScrollPrize/villa/pull/2130","date":"2026-10-30T20:59:40Z","summary":"**In one sentence:** The `vesuvius` README now lists only commands that exist after installing the package, with the right module paths, so people stop looking for tools that aren't there. **One real example:** Starting from a fresh install of the `vesuvius` package, I tried `vesuvius.render_obj` from the README table, and it produced `no such file or directory: .venv/bin/vesuvius.render_obj`. **Before:** The table listed three commands that aren't installed (`vesuvius.render_obj`, `vesuvius.flatten_obj`, `vesuvius.proofreader`), gave old module paths for three others, and left out four that are installed (`accept_terms`, `blend_and_finalize`, `find_patches`, `zarr_tasks`). **After this PR:** Every command in the table is in `[project.scripts]` and every installed command is in the table. The proofreading steps point to `segmentation/vc_proofreader/main.py --config ...`, where the proofr","keyword":44,"topics":["Scroll work","Sheets and surfaces"],"matched":["flatten","voxel"],"parts":[["ScrollPrize/villa pull request",30],["Sheets and surfaces (weak): flatten",8],["context: voxel",6]],"state":"merged","who":"Wittmoon","created":"2026-10-17T17:32:19Z","semantic":0,"sim":0.68,"near":"Scroll work","rule":44,"score":73,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2138","source":"github","kind":"pr","title":"ScrollPrize/villa #2138: copy: default bbox overlap to 0.5 to reduce block-edge seams (#2040)","url":"https://github.com/ScrollPrize/villa/pull/2138","date":"2026-10-30T21:11:59Z","summary":"## Summary - Change the Copy CLI `--bbox-overlap` default from `0.0` to `0.5` to reduce inference crop boundary seams observed in #2040. - Retain explicit `--bbox-overlap 0.0` for faster legacy behavior; document the quality/runtime tradeoff in CLI help. - Add focused regression coverage that extracts and **executes the actual production `parse_args` function**, without importing unrelated GPU/native dependencies. It covers the default, explicit overrides, and invalid values including NaN/Infinity. - Harden bbox overlap range validation to reject non-finite values that the previous ` = 1` comparisons allowed (e.g., NaN). ## Evidence Issue #2040 reports jumps ≥75 µm across block boundaries in 27.2% of matched pairs with overlap 0.0 versus 0.9% with overlap 0.5 for one PHerc0841 strip. **These measurements are from the issue reporter, not independently reproduced by this PR.** ## Independe","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"merged","who":"malzevvladimir73","created":"2026-10-18T10:59:49Z","code":["https://github.com/ScrollPrize/villa/issues/2040#issuecomment-6155074620","https://github.com/ScrollPrize/villa/issues/2040#issuecomment-6163320158"],"semantic":0,"sim":0.645,"near":"Speed and scale","rule":30,"score":72,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2124","source":"github","kind":"pr","title":"ScrollPrize/villa #2124: fix(tracer): invalidate normal caches when the selected grid changes","url":"https://github.com/ScrollPrize/villa/pull/2124","date":"2026-10-30T21:42:43Z","summary":"**In one sentence:** Prevent normal-guided surface optimization from reusing path and snapping data from a different normal grid. **One real example:** While validating resume-local refinement with `vc_grow_seg_from_seed` on PHerc0343 grids, trial points selected new slices while their projected 2D endpoints stayed within the cache radius. The persistent cost reused paths from the previous slice. **Before:** An instrumented local solve recorded 595 of 987 source transitions with stale-origin results corrected by the patch in replay at the recorded states. The largest residual discrepancy was 0.356326563827401. **After this PR:** A fixed-live solve on the same input and settings passed every selected-source cache check. All 44,712 recorded cost calls matched fixed replay within residual `1e-12` and Jacobian `1e-10` tolerances. The runs take different trajectories. The 595 witnesses and ze","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"merged","who":"filacocta","created":"2026-10-16T18:34:01Z","activity":{"what":"closed","who":"bruniss","date":"2026-10-30T21:42:42Z","text":"","url":"https://github.com/ScrollPrize/villa/pull/2124","also":["merged"]},"code":["https://github.com/filacocta/villa/blob/9d777128988c9d7ad642edfbeb20e6eefb2711a1/volume-cartographer/docs/normal-constraint-cache.md"],"semantic":0,"sim":0.635,"near":"Sheets and surfaces","rule":30,"score":71,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2387","source":"github","kind":"pr","title":"ScrollPrize/villa #2387: vc_reader: verify HTTPS against the Windows certificate store","url":"https://github.com/ScrollPrize/villa/pull/2387","date":"2026-10-30T23:23:56Z","summary":"**In one sentence:** On Windows, VC3D can load the Open Data Catalog and create projects from it again. **One real example:** An annotator on the Windows build (`VC3D-8f5f0d7-2026-10-30-win64.exe`) opened File > Open Data Catalog… to create a PHerc0139 project, and the status bar showed: `Using cached catalog. Live refresh failed: GET https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/metadata.json failed after 1 attempts: Problem with the SSL CA cert (path? access rights?)` **Before:** Every HTTPS request made through vc_reader's `HttpClient` fails on end-user Windows machines. The MSYS2 libcurl uses OpenSSL and looks for its CA bundle under `/ucrt64/...`, which only exists on the build machine. **After this PR:** On Windows, `HttpClient` uses the Windows certificate store (`CURLSSLOPT_NATIVE_CA`), the same as `utils/src/http_fetch.cpp` already does. macOS and Linux are unc","keyword":38,"topics":["Scroll work","Fibers and tracing"],"matched":["fiber"],"parts":[["ScrollPrize/villa pull request",30],["Fibers and tracing (weak): fiber",8]],"state":"merged","who":"skyward7187","created":"2026-10-30T23:08:11Z","activity":{"what":"branch deleted","who":"skyward7187","date":"2026-10-30T23:23:56Z","text":"","url":"https://github.com/ScrollPrize/villa/pull/2387","also":["closed","merged"]},"semantic":0,"sim":0.601,"near":"Scroll work","rule":38,"score":70,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2133","source":"github","kind":"pr","title":"ScrollPrize/villa #2133: vc_grow_seg_from_seed: let a resumed trace grow past cells skipped at x/y/z limits (#2104)","url":"https://github.com/ScrollPrize/villa/pull/2133","date":"2026-10-30T21:44:04Z","summary":"**In one sentence:** A saved surface resumed with x/y/z limits now keeps growing on the sides that still have room, instead of stopping as soon as the cells inside its grid are used up. **One real example:** Starting with a 480-vertex PHerc0139 surface traced inside the 1024×1024×512 box from #2104, I resumed it with the same limits, and it grew to 2,607 vertices (0.858 cm²) instead of stopping at 642 vertices (0.208 cm²). **Before:** `vc_grow_seg_from_seed --resume` with x/y/z limits filled the holes inside the imported grid and then stopped at generation 14: cells skipped at a limit stay `STATE_PROCESSING`, and the hole-filling branch never offers cells outside `used_area`, so the outer edge was never tried. **After this PR:** each resumed generation also offers the outward neighbours of the grid edge. The trace stops only when no untried cell next to the surface is left (generation 59","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"merged","who":"alexeygoncharov","created":"2026-10-17T22:45:01Z","activity":{"what":"closed","who":"bruniss","date":"2026-10-30T21:44:03Z","text":"","url":"https://github.com/ScrollPrize/villa/pull/2133","also":["merged"]},"semantic":0,"sim":0.632,"near":"Fibers and tracing","rule":30,"score":70,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2134","source":"github","kind":"pr","title":"ScrollPrize/villa #2134: vc_grow_seg_from_seed: stop at the work-grid edge instead of aborting with \"point too close to problem border!\"","url":"https://github.com/ScrollPrize/villa/pull/2134","date":"2026-10-30T21:23:21Z","summary":"**In one sentence:** `vc_grow_seg_from_seed` no longer aborts when a trace grows to the edge of its work grid: growth stops two cells from the edge, the log says so once, and the surface is saved. Before, the run died with `point too close to problem border!` and nothing was written. **One real example:** Two runs. (a) Resuming a 30 × 30 crop of a PHerc0211 surface I traced (20 vx step, `\"generations\": 0`, the m7 surface prediction from the open-data bucket). (b) The public seed of #2104 on PHerc0139 (`-s 3770 3698 4608`, `\"generations\": 0`). `vc_grow_seg_from_seed` built from main (1db9cd9) and from this branch in the CI image `ghcr.io/scrollprize/vc3d-deps/linux:sha-0c371b1d…` (clang, QuickBuild -O2), `VC_GROWPATCH_RNG_SEED=1`, `thread_limit` 1. **Before:** (a) stops at generation 25 with `ERROR: vc_grow_seg_from_seed: segment growth failed: point too close to problem border!` (exit st","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"merged","who":"vincentl065","created":"2026-10-18T01:11:40Z","semantic":0,"sim":0.602,"near":"Fibers and tracing","rule":30,"score":70,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2259","source":"github","kind":"pr","title":"ScrollPrize/villa #2259: docs: run AppImage CLI tools on headless Linux through AppRun","url":"https://github.com/ScrollPrize/villa/pull/2259","date":"2026-10-30T21:37:35Z","summary":"**In one sentence:** Linux users can launch the release's CLI tools on a headless server using the required host libraries and bundled loader. **One real example:** On Debian 13 x86_64, the current release `VC3D-e2254eb-2026-10-22-linux-x86_64.AppImage` was extracted with `--appimage-extract`. With no display configured, calling its `usr/bin/vc_render_tifxyz --help` directly segfaulted; calling `AppRun vc_render_tifxyz --help` printed help and exited 0. **Before:** The main installation page says all dependencies are bundled. The packaging notes list the host libraries, but give no reusable extracted CLI command or explanation that direct binary invocation bypasses the bundled loader. #2153 reports both obstacles while rendering scroll data. **After this PR:** The installation page states the host-library requirement. The packaging notes give a Debian/Ubuntu runtime package command, extr","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"merged","who":"jonmarrs","created":"2026-10-23T04:14:14Z","activity":{"what":"closed","who":"bruniss","date":"2026-10-30T21:37:35Z","text":"","url":"https://github.com/ScrollPrize/villa/pull/2259","also":["merged"]},"semantic":0,"sim":0.621,"near":"Compression and storage","rule":30,"score":69,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:ahggggg/first-letters-clean-sheets","source":"github","kind":"repo","title":"Ahggggg/first-letters-clean-sheets","url":"https://github.com/Ahggggg/first-letters-clean-sheets","date":"2026-10-30T20:20:37Z","summary":"173 self-traced clean single-sheet patches (355 cm²) on 13 First Letters-eligible Herculaneum scrolls, with CT cross-section QA, an on-sheet score for public surfaces, and a laptop tracing recipe","keyword":82,"topics":["Scroll work","Sheets and surfaces","Fibers and tracing"],"matched":["herculaneum","sheet","tracing","ct"],"parts":[["new GitHub repository",15],["scroll terms: herculaneum",45],["Sheets and surfaces (weak): sheet",8],["Fibers and tracing (weak): tracing",8],["context: ct",6]],"who":"Ahggggg","created":"2026-10-20T01:21:40Z","new_repo":true,"stars":0,"forks":0,"license":"MIT","language":"Python","semantic":42,"sim":0.742,"near":"Scroll work","rule":82,"score":69,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2115","source":"github","kind":"pr","title":"ScrollPrize/villa #2115: lasagna: add a rocm PyTorch backend to bootstrap_venv.py so AMD GPUs are used","url":"https://github.com/ScrollPrize/villa/pull/2115","date":"2026-10-30T20:49:15Z","summary":"Team: Sebastien Chicoineau (@slchicoineau-creator) and Chris Thomas (@Baz248) **In one sentence:** On a machine with an AMD GPU, `scripts/bootstrap_venv.py` now installs the ROCm build of PyTorch, so lasagna runs on the GPU instead of falling back to CPU with no warning that the AMD GPU goes unused. **One real example:** On a Linux PC with an AMD Radeon AI PRO R9700 (ROCm 7.2.2, no `nvidia-smi`), my teammate ran `python3 scripts/bootstrap_venv.py --venv .venv`. It picked `rocm`, installed `torch 2.11.0+rocm7.2`, and its GPU smoke test passed. `predict3d` on a 256³ crop of the public PHerc0841 9.366 µm volume then ran on the GPU (`devices=cuda:0`, `torch.version.hip` 7.2; the GPU was about 98 % busy in `rocm-smi` during the run) and finished all 125 tiles. **Before:** the bootstrap only looks for `nvidia-smi`. With no `nvidia-smi` it installs CPU PyTorch, and the AMD GPU is never used: ``","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"merged","who":"slchicoineau-creator","created":"2026-10-16T03:15:02Z","semantic":0,"sim":0.532,"near":"Scroll work","rule":30,"score":67,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:antaloaalonso/mac-first-letters","source":"github","kind":"repo","title":"antaloaalonso/mac-first-letters","url":"https://github.com/antaloaalonso/mac-first-letters","date":"2026-10-31T05:50:46Z","summary":"Search Herculaneum scrolls for First Letters on a Mac or free on Kaggle: one-command spiral fit to ink, held-out benchmark, coverage atlas","keyword":76,"topics":["Scroll work","Ink and imaging"],"matched":["herculaneum","ink"],"parts":[["new GitHub repository",15],["scroll terms: herculaneum",45],["Ink and imaging (strong): ink",16]],"who":"antaloaalonso","created":"2026-10-31T05:48:46Z","new_repo":true,"stars":0,"forks":0,"license":"MIT","language":"Python","semantic":18,"sim":0.718,"near":"Scroll work","rule":76,"score":66,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T08:46:48Z"},{"id":"github:scrollprize/villa#2206","source":"github","kind":"pr","title":"ScrollPrize/villa #2206: ink_detection: labels made with create_label_zarrs are now seen by flat training on 21- and 28-slice volumes","url":"https://github.com/ScrollPrize/villa/pull/2206","date":"2026-10-31T01:18:49Z","summary":"**In one sentence:** after the labelling loop in `docs/ink_detection.md` (edit the label images, run `create_label_zarrs`, retrain), flat training on the 9 µm 21- and 28-slice surface volumes still found every patch but got no supervision from the new labels; with this PR it trains on them. **One real example:** Starting with PHerc0139 segment `w035` (28-slice 9 µm surface volume, published `ink_9um` labels) and the shipped recipe `aligned21_hybrid_3d2d.json`, I saved the labels as TIFF, converted them back with `create_label_zarrs` as the docs describe, and built the training dataset: on main none of the 312 sampled patches had a single supervised pixel. **Before:** (main `efddd7770`; the same on `a329895e`) ``` 1. published label stores label store shape (28, 5820, 5240); training patches found: 1247 of 312 sampled patches, 312 carry any supervised pixel; supervised pixels 3454843, ink","keyword":52,"topics":["Scroll work","Ink and imaging"],"matched":["ink","volume","volumes"],"parts":[["ScrollPrize/villa pull request",30],["Ink and imaging (strong): ink",16],["context: volume, volumes",6]],"state":"open","who":"tencur","created":"2026-10-21T17:53:21Z","activity":{"what":"review requested","who":"tencur","date":"2026-10-31T01:18:42Z","text":"Copilot","url":"https://github.com/ScrollPrize/villa/pull/2206","also":["force-pushed"]},"semantic":0,"sim":0.684,"near":"Sheets and surfaces","rule":52,"score":66,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T07:25:07Z"},{"id":"github:canadaapollo6/vesuvius-spiral-chains","source":"github","kind":"repo","title":"CanadaApollo6/vesuvius-spiral-chains","url":"https://github.com/CanadaApollo6/vesuvius-spiral-chains","date":"2026-10-30T20:01:31Z","summary":"Automatic relative-winding chains for the ScrollPrize/villa spiral fitter, with pre-registered evaluations","keyword":65,"topics":["Scroll work","Sheets and surfaces"],"matched":["vesuvius","scrollprize"],"parts":[["new GitHub repository",15],["scroll terms: vesuvius, scrollprize",50]],"who":"CanadaApollo6","created":"2026-10-28T20:15:12Z","new_repo":true,"stars":0,"forks":0,"license":"Apache-2.0","language":"Python","semantic":89,"sim":0.789,"near":"Sheets and surfaces","topics_by_meaning":["Sheets and surfaces"],"rule":78,"score":66,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2073","source":"github","kind":"pr","title":"ScrollPrize/villa #2073: sheet tracer: write area_cm2 at the traced volume's voxel size","url":"https://github.com/ScrollPrize/villa/pull/2073","date":"2026-10-30T22:43:40Z","summary":"**In one sentence:** traces on a volume that is not 9.6 um get the right `area_cm2` in meta.json, from `--voxel-size` or the volume's meta.json. **One real example:** Starting with a local window of PHerc1447 (volume 20250521151220, 8.64 um) and scrollprize/sheet_tracer_7pt_gap60, I traced both ways from one row of an existing surface, 40 steps requested each way; the tracer kept 1 step up and 4 down (6 rows by 265 columns). meta.json declared 0.017155 cm2 for 18614.59 vx2 at 9.6 um. At 8.64 um the same surface is 0.013896 cm2: the value the fix computes for this surface (area_vx2 × 8.64² / 1e8); the unit test checks the code path. **Before:** `area_cm2` = area_vx2 × 9.6² / 1e8 for any `--volume` (the checkpoint's `data.voxel_size_um`; config.py:25: `voxel_size_um: float = 9.6 # level-0 voxel size of the volume (s1_ds2: 9.6 um), for area_cm2 in written tifxyz`), 23.5 per cent too large a","keyword":44,"topics":["Scroll work","Sheets and surfaces"],"matched":["sheet","volume","voxel"],"parts":[["ScrollPrize/villa pull request",30],["Sheets and surfaces (weak): sheet",8],["context: volume, voxel",6]],"state":"open","who":"evilaliv3","created":"2026-10-13T14:35:07Z","activity":{"what":"marked ready for review","who":"evilaliv3","date":"2026-10-30T22:43:40Z","text":"","url":"https://github.com/ScrollPrize/villa/pull/2073"},"semantic":0,"sim":0.681,"near":"Scroll work","rule":44,"score":64,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2370","source":"github","kind":"issue","title":"ScrollPrize/villa #2370: ink/ bucket: HF65 canvases do not line up with the tifxyz beside them (Paris4 by up to 286 px, 1667 w018 by one stored cell)","url":"https://github.com/ScrollPrize/villa/issues/2370","date":"2026-10-30T22:28:38Z","summary":"**In one sentence:** On the four segments I measured, HF65 canvas pixel (y, x) shows the CT at tifxyz cell (y + dy, x + dx) with dy and dx well away from zero, while `full_3d` training pairs label pixel (y, x) with tifxyz cell (y, x). **I was trying to:** answer the first question in #2346 (how the HF65 XYZ maps correspond to CT voxels) by measuring it. **Using:** `scrollprize/datasets` `ink/phercparis4/w00_20231016151002`, `w01_20230702185753_r15`, `w05_4424` and `ink/1667/w018_20240304144031_2um` (slice 32 of the HF65 zarr and the tifxyz in each folder); CT `PHercParis4/volumes/20260411134726-2.400um-0.2m-78keV-masked.zarr` and `PHerc1667/volumes/20251217075048-2.399um-0.2m-78keV-masked.zarr` from the open data bucket at level 2; villa main 7154682 for the index convention (`tifxyz/types.py:153-154`) and the `full_3d` read (`ink_detection/data/dataset.py:431`). **What happened:** I sam","keyword":58,"topics":["Scroll work","Ink and imaging","Compression and storage"],"matched":["ink","zarr","volume","volumes"],"parts":[["ScrollPrize/villa issue",22],["Ink and imaging (strong): ink",16],["Compression and storage (strong): zarr",14],["context: volume, volumes",6]],"state":"open","comments":3,"who":"stantheman0128","created":"2026-10-30T09:37:26Z","activity":{"what":"comment","who":"stantheman0128","date":"2026-10-30T22:28:38Z","text":"Some follow-up, starting with prior art I should have found before opening this. tifxyz_label_transfer already handles a constant canvas offset. vesuvius/src/vesuvius/tifxyz_label_transfer (added in #1943 on 2026-10-01) notes that annotations drawn on published renders \"do not always sit pixel-for-pixel on the TIFXYZ canvas\". Its QA workflow measures the offset from CT and applies it through --label-canvas-offset DY DX, with pherc0139-w039 as the example, and docs/theory.md uses the same sign as this issue. So the 0139 shift was known. What this issue adds is the training side: the...","url":"https://github.com/ScrollPrize/villa/issues/2370#issuecomment-6534839877"},"semantic":0,"sim":0.687,"near":"Scroll work","rule":58,"score":64,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2167","source":"github","kind":"issue","title":"ScrollPrize/villa #2167: PHerc0139: w036 lies inside w034 across part of the sector missing from w035","url":"https://github.com/ScrollPrize/villa/issues/2167","date":"2026-10-31T02:42:04Z","summary":"**In one sentence:** In the published PHerc0139 meshes on scan `20260102150214`, w035 covers only part of a turn, and where it is missing, w036 lies inside w034 on 42% of the rays crossing both once, so the winding numbers do not give a reliable local order there. **I was trying to:** Use the published segments as a reference for winding counts and spiral fitting, and identify which parts should be left out before treating the winding numbers as labels. **Using:** The public PHerc0139 tifxyz meshes and umbilicus, checked with [`kit stackcheck` at `1243518`](https://github.com/ChaseHendrick/Scrolls/blob/1243518dae102dd334ff1d7a63995f323c1095e4/kit/stackcheck.py). On 18 October I had both runs from the [published measurement note](https://github.com/ChaseHendrick/Scrolls/blob/1243518dae102dd334ff1d7a63995f323c1095e4/docs/logs/2026-10-14-pherc0139-segment-defects.md) rerun from fresh public","keyword":44,"topics":["Scroll work","Sheets and surfaces"],"matched":["winding number","voxel"],"parts":[["ScrollPrize/villa issue",22],["Sheets and surfaces (strong): winding number",16],["context: voxel",6]],"state":"open","comments":4,"who":"ChaseHendrick","created":"2026-10-20T12:01:10Z","activity":{"what":"comment","who":"Wittmoon","date":"2026-10-31T02:42:04Z","text":"Thanks both. Stan, your 1.129 µm reads and my count tell the same story at the E places and both unwrap heights — encouraging, since they come from different scans, different code, and different rules. G2 is the least clear-cut on both sides. Mine is a radial run count on the 2.4 µm scan at 4.8 µm (level 1), with the counting rule written down before I read any gap window: https://github.com/Wittmoon/vesuvius-label-topology-audit/blob/main/validation/pherc0139_2167_run_count.md | Place | 1.129 µm (yours) | 2.4 µm run count (mine; share of crossings with two meshes in one run) | | --- | --- |...","url":"https://github.com/ScrollPrize/villa/issues/2167#issuecomment-6537933181"},"code":["https://github.com/ChaseHendrick/Scrolls/blob/1243518dae102dd334ff1d7a63995f323c1095e4/kit/stackcheck.py","https://github.com/ChaseHendrick/Scrolls/blob/1243518dae102dd334ff1d7a63995f323c1095e4/docs/logs/2026-10-14-pherc0139-segment-defects.md"],"semantic":0,"sim":0.695,"near":"Sheets and surfaces","rule":44,"score":63,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T08:46:48Z","who_name":"Chase Hendrick"},{"id":"github:scrollprize/villa#2381","source":"github","kind":"pr","title":"ScrollPrize/villa #2381: ink_detection: suggest where to label next, from where the predictions are least sure","url":"https://github.com/ScrollPrize/villa/pull/2381","date":"2026-10-30T22:49:22Z","summary":"**In one sentence:** point it at a segment's `preds` folder and it marks the 20 tiles where the predictions are least sure, so you know where to look first when you extend the labels. In two tests against the organizers' next label round, the pick tested on each scroll held 3.8 and 1.8 times the average tile's share of the predictions' mistakes. **One real example:** Starting with the three ink predictions in the public `preds` folder of PHerc0841 `auto_grown_20260220144552896` (16,763 x 18,712 px), I ran `python -m vesuvius.ink_detection.preprocessing.suggest_label_tiles .../preds --output-dir out` with the defaults. In 150 seconds on 4 CPU cores (7.5 GB peak) it wrote `label_suggestions.png` with 20 of the 76,212 eligible 64 px tiles marked, `random_tiles.png` with 20 random ones to compare against, and `suggestions.json`. The shuffle check came out `targeted` (top tiles' mean score 0.","keyword":46,"topics":["Scroll work","Ink and imaging"],"matched":["ink"],"parts":[["ScrollPrize/villa pull request",30],["Ink and imaging (strong): ink",16]],"state":"open","who":"ChaseHendrick","created":"2026-10-30T21:04:23Z","activity":{"what":"review requested","who":"ChaseHendrick","date":"2026-10-30T22:49:22Z","text":"bruniss","url":"https://github.com/ScrollPrize/villa/pull/2381","also":["marked ready for review"],"who_name":"Chase Hendrick"},"semantic":0,"sim":0.672,"near":"Scroll work","rule":46,"score":63,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z","who_name":"Chase Hendrick"},{"id":"github:scrollprize/villa#2161","source":"github","kind":"pr","title":"ScrollPrize/villa #2161: ChunkCache: keep one copy of each remote chunk in a Zarr mirror cache","url":"https://github.com/ScrollPrize/villa/pull/2161","date":"2026-10-30T21:29:08Z","summary":"**In one sentence:** A remote volume's chunk cache now holds each chunk once instead of twice, so rendering or browsing remote data takes half the disk: 238 MiB instead of 476 MiB for a 1024×1024 crop of PHerc0139 w029. **One real example:** I rendered a 1024×1024 crop of the PHerc0139 w029 surface with `vc_render_tifxyz --volume https://vesuvius-challenge-open-data.s3.us-east-1.amazonaws.com/PHerc0139/volumes/20250728140407-9.362um-1.2m-113keV-masked.zarr`. The cold and prefetch runs started from an empty `remote_cache_dir`; the warm run reused the cold run's cache. Base: `23876bef6` plus the macOS 27 preset fix (#2159), since main does not build here; then this branch on top. **Before:** - After the render, the cache held 252 files and 476 MiB for the 119 chunks the surface touches. - Every chunk was there twice, byte-identical: `0/35/21/30`, written by `writeMirrorObject`, and `level_","keyword":50,"topics":["Scroll work","Compression and storage"],"matched":["zarr","volume","volumes"],"parts":[["ScrollPrize/villa pull request",30],["Compression and storage (strong): zarr",14],["context: volume, volumes",6]],"state":"closed","who":"nerln","created":"2026-10-20T01:23:32Z","activity":{"what":"comment","who":"bruniss","date":"2026-10-30T21:29:08Z","text":"chunkcache will be retired in a few days in a separate pr","url":"https://github.com/ScrollPrize/villa/pull/2161#issuecomment-6533848344"},"semantic":69,"sim":0.769,"near":"Compression and storage","rule":60,"score":63,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2243","source":"github","kind":"issue","title":"ScrollPrize/villa #2243: Surfaces regridded by vc_transform_geom sit a fraction of a cell off, so labels moved between scan resolutions land about 7.4 px off","url":"https://github.com/ScrollPrize/villa/issues/2243","date":"2026-10-31T08:38:52Z","summary":"**In one sentence:** when a segment is carried to a volume of another voxel size, the regrid in `transformSurfacePoints` places new node j at source parameter (j + 0.5) / k - 0.5 instead of j / k, so ink labels drawn or predicted on a render of the new mesh and resized onto the render of the original mesh land g = 10 (1 - 1/k) px off on both axes (20 px per node), 7.43 px for 9.362 um to 2.399 um. **I was trying to:** rebuild the released Reader v2 ink labels with their recipe: the ink map rendered on a segment's 2.399 um mesh, resized by area onto the canvas of the same segment's 9.362 um surface volume, thresholded there. **Using:** villa main 5f380c396c79c92a02a0e4664e57363351497163, `volume-cartographer` built with CMake (Release, VC_TESTING=ON), Ubuntu, GCC, and its `vc_transform_geom -i -o out -a transform.json --invert` on PHerc0139 w025. The published meshes and `transform.json` ","keyword":52,"topics":["Scroll work","Sheets and surfaces","Ink and imaging"],"matched":["mesh","ink","volume","voxel"],"parts":[["ScrollPrize/villa issue",22],["Sheets and surfaces (weak): mesh",8],["Ink and imaging (strong): ink",16],["context: volume, voxel",6]],"state":"open","comments":2,"who":"evilaliv3","created":"2026-10-22T18:59:51Z","activity":{"what":"comment","who":"evilaliv3","date":"2026-10-31T08:38:51Z","text":"This issue, addressed in #2358, could probably be closed, since the refactoring of that pull request removed the code path that carried the offset. The grid-node offset reported here (node j placed at (j+0.5)/k-0.5 instead of j/k, about 7.4 px on the PHerc0139 w025 example) reproduces up to 5f380c39, the build it was measured on. Two commits by @bruniss inside #2358, both of 27 October, changed this: 9ddd16d23 (\"apps, core: remove 16 unused CLIs\") removes vc_transform_geom together with TransformSurface and ScaleTifxyz, and c73ccbbc9 (\"apps, core, libs: remove vc_tifxyz...","url":"https://github.com/ScrollPrize/villa/issues/2243#issuecomment-6541244201"},"semantic":18,"sim":0.718,"near":"Sheets and surfaces","rule":52,"score":62,"learned":"full","band":"high","first_seen":"2026-10-31T08:46:48Z","last_seen":"2026-10-31T08:46:48Z"},{"id":"github:scrollprize/villa#2147","source":"github","kind":"pr","title":"ScrollPrize/villa #2147: Add vesuvius.label_topology_audit: dataset-level topology audit for surface labels","url":"https://github.com/ScrollPrize/villa/pull/2147","date":"2026-10-31T02:48:13Z","summary":"**In one sentence:** This makes reviewing surface labels faster: instead of opening every crop by hand, you get a ranked list of the ones that need attention, a way to check each one in the CT, and a check that a fix actually helped. **One real example:** I ran it on the 892 Kaggle surface-label crops. The topology audit flagged 152 with holes. When I checked 33 of those holes in the CT, 19 were not mistakes: they were real gaps between two sheets, and the current fill script (`fix_holes.py`) welds 8 of them shut. A second queue, built from the Kaggle 3rd-place surface model disagreeing with the label, ranks different crops: 39 of its top 50 have no hole finding, and in a blind check of the ten highest-ranked ones, 8 of the 8 tiles I could score were papyrus the label misses. **Before:** You open crops one at a time and fill holes with `fix_holes.py`, which fills every hole, including th","keyword":46,"topics":["Scroll work","Sheets and surfaces"],"matched":["sheet","topolog","ct"],"parts":[["ScrollPrize/villa pull request",30],["Sheets and surfaces (weak): sheet, topolog",10],["context: ct",6]],"state":"open","who":"Wittmoon","created":"2026-10-18T21:27:54Z","labels":["keep-open"],"semantic":7,"sim":0.707,"near":"Sheets and surfaces","rule":46,"score":62,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T08:46:48Z"},{"id":"github:stantheman0128/vesuvius-hf65-alignment","source":"github","kind":"repo","title":"stantheman0128/vesuvius-hf65-alignment","url":"https://github.com/stantheman0128/vesuvius-hf65-alignment","date":"2026-10-30T22:27:26Z","summary":"Measured offsets between HF65 ink canvases and the tifxyz beside them in the ScrollPrize ink/ bucket","keyword":88,"topics":["Scroll work","Ink and imaging","Registration"],"matched":["vesuvius","scrollprize","ink","alignment"],"parts":[["new GitHub repository",15],["scroll terms: vesuvius, scrollprize",50],["Ink and imaging (strong): ink",16],["Registration (weak): alignment",7]],"who":"stantheman0128","created":"2026-10-30T09:36:44Z","new_repo":true,"stars":0,"forks":0,"license":"MIT","language":"Python","semantic":0,"sim":0.691,"near":"Scroll work","rule":88,"score":62,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2385","source":"github","kind":"pr","title":"ScrollPrize/villa #2385: ink inference: --tta-shift blends several tile-grid positions (removes the grid-position lottery)","url":"https://github.com/ScrollPrize/villa/pull/2385","date":"2026-10-30T22:11:47Z","summary":"**In one sentence:** `--tta-shift 0 4 8 12` runs the flat ink inference with the 128 px tile grid at several offsets and blends them, so the result no longer depends on where the grid happens to fall. On 6 labelled segments it never made AUC worse and removed the bad draws (0.774 → 0.886 on one of them). **One real example:** The public `ink_9um` checkpoint `hybrid_3d2d-seed42/step-075000.pth` on the PHerc0139 w016 validation region (the #1946 setup: level 2 of the public 2.399 µm surface volume → 21 planes, window [2,19), `--overlap 0.5 --blend-mode hann`), scored against the published ink labels inside the validation mask. **Before:** AUC **0.774**. The same model with the same input, but with the tile grid moved by 8 px (cropping 8 px off the top/left), gives 0.854: the flat models are not shift-invariant, so a single run is a draw on the grid position. seed43 on the same region gives","keyword":52,"topics":["Scroll work","Ink and imaging"],"matched":["ink","volume"],"parts":[["ScrollPrize/villa pull request",30],["Ink and imaging (strong): ink",16],["context: volume",6]],"state":"closed","who":"vincentl065","created":"2026-10-30T21:48:56Z","activity":{"what":"comment","who":"vincentl065","date":"2026-10-30T22:11:46Z","text":"Closing this myself. I ran the comparison I should have run first: --overlap 0.75 (already there) on the same 6 segments and both seeds. | mean AUC gain over the default run | seed42 | seed43 | |---|---|---| | --tta-shift 0 4 8 12 | +0.031 | +0.007 | | --overlap 0.75 | +0.018 | +0.008 | The shift is still better on the worst draw (w016 seed42: 0.886 vs 0.851), but --overlap 0.75 gets most of the way there for a similar cost, without a new flag. Not worth the extra option in infer.py. If someone hits the grid lottery, --overlap 0.75 is the cheap fix.","url":"https://github.com/ScrollPrize/villa/pull/2385#issuecomment-6534585385","also":["closed"]},"semantic":0,"sim":0.691,"near":"Speed and scale","rule":52,"score":62,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2384","source":"github","kind":"pr","title":"ScrollPrize/villa #2384: extract_surface_tracks: give the skeletonizer the dust threshold in downsampled voxels (sheet pieces the dust filter kept lost their tracks)","url":"https://github.com/ScrollPrize/villa/pull/2384","date":"2026-10-30T21:39:14Z","summary":"**In one sentence:** `extract_surface_tracks.py` documents `dust_threshold` (400) in full-resolution voxels and its dust filter converts it for the 4× downsampled labels (400 // 4³ = 6), but `skeletonize_kwargs()` passes the raw 400 to Kimimaro/Brook, which count the downsampled voxels they are given, so every sheet piece in a slab smaller than 400 downsampled voxels (25,600 full-resolution voxels) that the dust filter kept is dropped again by the skeletonizer and gets no tracks; this passes the same converted cutoff. **One real example:** the CPU backend (Kimimaro) with the shipped settings (downsample 4, `dust_threshold` 400, ribbons 4 thick every 16, vertical slabs 4 thick every 64, `interjoint` paths) on the published PHerc0500P2 surface prediction (volume `20250820143440`, model m7, L0, th0.2; a 128 × 256 × 256 crop at z 3456, y/x 2048), with `z_min`/`z_max` set to the crop. **Befor","keyword":52,"topics":["Scroll work","Sheets and surfaces","Fibers and tracing"],"matched":["sheet","skeleton","volume","voxel"],"parts":[["ScrollPrize/villa pull request",30],["Sheets and surfaces (weak): sheet",8],["Fibers and tracing (weak): skeleton",8],["context: volume, voxel",6]],"state":"open","who":"tencur","created":"2026-10-30T21:36:37Z","semantic":0,"sim":0.694,"near":"Sheets and surfaces","rule":52,"score":62,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2195","source":"github","kind":"issue","title":"ScrollPrize/villa #2195: Default patch finding takes over two minutes on a large segment","url":"https://github.com/ScrollPrize/villa/issues/2195","date":"2026-10-30T21:33:49Z","summary":"**In one sentence:** `find_segment_patches` (default patch finding, `vesuvius/src/vesuvius/ink_detection/data/patch_finding_default.py`) spends minutes on a large segment re-reading the same mask chunks and sorting every support pixel before training can start. **I was trying to:** train an ink model on 44 training segments of three scrolls, first on 17x256x256 and then on 17x384x384 patches, with patch_overlap 0.25. **Using:** main bc36e2d9d5404a338ab981dcff012f0ee8b39682, `find_segment_patches(segment, open_volume)` called once per segment in a single process, numpy 2.4.6 and zarr 3.2.1 as `vesuvius/uv.lock` pins them, on CPU. The masks (supervision, validation, inklabels) are zarr arrays with chunks 28x128x128. **What happened:** on one large PHerc0139 segment (20250223000000-w059, masks 28x7220x10020, the 11th largest of the 44 by plane size), one call took 157.4 s at 17x256x256 and ","keyword":58,"topics":["Scroll work","Ink and imaging","Compression and storage"],"matched":["ink","zarr"],"parts":[["ScrollPrize/villa issue",22],["Ink and imaging (strong): ink",16],["Compression and storage (strong): zarr",14],["context: zarr",6]],"state":"closed","comments":0,"who":"evilaliv3","created":"2026-10-21T14:31:02Z","activity":{"what":"closed","who":"bruniss","date":"2026-10-30T21:33:50Z","text":"","url":"https://github.com/ScrollPrize/villa/issues/2195"},"semantic":0,"sim":0.7,"near":"Scroll work","rule":58,"score":62,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2151","source":"github","kind":"pr","title":"ScrollPrize/villa #2151: vc_tifxyz -s: write the right scale for a resampled surface (renders came out 4x too big or small per axis)","url":"https://github.com/ScrollPrize/villa/pull/2151","date":"2026-10-30T21:15:14Z","summary":"**In one sentence:** After `vc_tifxyz -s` resamples a surface, its `meta.json` scale now matches the new grid, so the resampled surface renders at the same size as the original. **One real example:** I started from PHerc1447 segment `auto_grown_20250703034159599` (scale 0.05, 20 vx spacing) and ran `vc_tifxyz -s 2`. Rendering it with `vc_render_tifxyz --scale 1 -g 0` on the open PHerc1447 8.64 µm volume gave a 5460×3700 image, the same size as rendering the original segment. **Before:** `QuadSurface::resample` divided the scale by the factor, but scale is grid cells per voxel, so it should be multiplied. - After `-s 2` the grid really has 10 vx spacing, but `meta.json` said 0.025 (40 vx). - The render came out 21840×14800: 4× per axis and 16× the pixels, so a crop at the same position lands on empty space. - `-s 0.5` went the other way: the render was 1370×930. **After this PR:** `-s 2` ","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"closed","who":"boredspaceape","created":"2026-10-19T02:58:40Z","activity":{"what":"comment","who":"bruniss","date":"2026-10-30T21:15:14Z","text":"tool is removed","url":"https://github.com/ScrollPrize/villa/pull/2151#issuecomment-6533611903"},"semantic":0,"sim":0.661,"near":"Sheets and surfaces","rule":30,"score":62,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2149","source":"github","kind":"pr","title":"ScrollPrize/villa #2149: Add `vesuvius.ome_zarr_qa`: offline OME-Zarr pyramid/metadata integrity checker (+75 tests)","url":"https://github.com/ScrollPrize/villa/pull/2149","date":"2026-10-30T21:14:03Z","summary":"### What A new CPU-only, network-free QA tool, `vesuvius.ome_zarr_qa`, that validates a *built* OME-Zarr multiscale pyramid. It reads only metadata (`.zarray`/`.zattrs`/`zarr.json`, sibling `meta.json`/`metadata.json`) plus bounded chunk-file listings and targeted existence checks. It never loads pixel data, so it is cheap enough to run in CI on every produced volume. ### Why The issue tracker has a recurring family of pyramid/metadata-integrity bugs that make volumes silently wrong or unopenable in VC3D. This tool turns \"someone noticed by hand, weeks later\" into a one-command, CI-gateable check. Checks and the reported classes they target (each is reproduced at unit scale in the tests): - `pyramid_level_shapes`: a downsampled spatial axis that is not `ceil(n / 2**L)`, e.g. one voxel short on an odd axis from banker's rounding (#2135). Channel/time axes must keep their size. - `ome_scal","keyword":50,"topics":["Scroll work","Compression and storage"],"matched":["zarr","volume","volumes"],"parts":[["ScrollPrize/villa pull request",30],["Compression and storage (strong): zarr",14],["context: volume, volumes",6]],"state":"closed","who":"seankim-business","created":"2026-10-19T01:20:05Z","semantic":53,"sim":0.753,"near":"Compression and storage","rule":52,"score":62,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2101","source":"github","kind":"pr","title":"ScrollPrize/villa #2101: ink_detection: preserve singleton spatial axes in masks and labels","url":"https://github.com/ScrollPrize/villa/pull/2101","date":"2026-10-30T20:42:28Z","summary":"## Change Preserve length-one Y/X axes when loading grayscale masks and label images. Only singleton non-spatial TIFF axes are removed using TIFF axes metadata; existing first-channel and top-left crop/pad semantics remain. ## Real example and evidence Single-row, single-column and single-pixel crops from the real PHerc0139 w035 smoke mask previously failed as non-2D. Label conversion failed on the corresponding prediction-derived crops. With this change, both consumers retain the spatial shape and exact pixel content. The label smoke inputs are derived from the w035 prediction TIFF, not trusted ink annotations. This verifies conversion and alignment, not ink-detection quality. Existing human motivation and before/after terminal screenshots are in [the author comment](https://github.com/ScrollPrize/villa/pull/2101#issuecomment-6177525623): original baseline 3/10 checks passed; patched br","keyword":53,"topics":["Scroll work","Ink and imaging","Registration"],"matched":["ink","alignment"],"parts":[["ScrollPrize/villa pull request",30],["Ink and imaging (strong): ink",16],["Registration (weak): alignment",7]],"state":"closed","who":"oleg494","created":"2026-10-14T18:11:44Z","code":["https://github.com/ScrollPrize/villa/pull/2101#issuecomment-6177525623"],"semantic":0,"sim":0.666,"near":"Sheets and surfaces","rule":53,"score":62,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2093","source":"github","kind":"pr","title":"ScrollPrize/villa #2093: data: listing-only check for coarse pyramid chunks missing under finer data","url":"https://github.com/ScrollPrize/villa/pull/2093","date":"2026-10-30T20:35:21Z","summary":"**What:** a small module + CLI that checks every adjacent level pair of an OME-Zarr pyramid and reports coarse chunks that have no object although the next finer level has data under them. zarr returns `fill_value` for those chunks, so viewers, loaders and annotators see blank papyrus while the data exists one level down. - `vesuvius/src/vesuvius/data/pyramid_occupancy.py`: `check_pyramid(store_url, anon=...)` and `expected_coarse_occupancy(...)`. It reuses `zarr_chunk_index.build_chunk_occupancy` (with `use_cache=False`) for the listing, so it adds **no new dependencies** and **downloads no chunk data**. It reads only `.zattrs`, `.zarray` and object listings. Scale factors come from the multiscales `scale` transforms, or from the level shapes if those are missing. Different chunk sizes per level and partial edge chunks are handled. - `vesuvius/src/vesuvius/scripts/check_pyramid_occupanc","keyword":50,"topics":["Scroll work","Compression and storage"],"matched":["zarr"],"parts":[["ScrollPrize/villa pull request",30],["Compression and storage (strong): zarr",14],["context: zarr",6]],"state":"closed","who":"sfc0324","created":"2026-10-14T14:44:00Z","semantic":17,"sim":0.717,"near":"Compression and storage","rule":50,"score":62,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2300","source":"github","kind":"pr","title":"ScrollPrize/villa #2300: vc_reader on macOS: concurrent first opens of a disk cache, float32 CPU sheet normals on arm64, and the temp dir symlink","url":"https://github.com/ScrollPrize/villa/pull/2300","date":"2026-10-31T00:17:29Z","summary":"**In one sentence:** three vc_reader fixes for macOS: new disk caches opened by several processes at once no longer fail with \"database is locked\", the CPU sheet normals keep float32 rounding on arm64, and an uncached remote image no longer fails under the macOS temporary directory symlink. **One real example:** villa main a23ec7c3 on an M1 Max (macOS 26.6.2, Apple clang 21, Python 3.11, torch 2.14.1). Main builds on macOS now (the `std::atomic ` fetcher that libc++ cannot compile left with #2358, so that part of this PR is gone), and `pytest tests` gives 11 failed, 208 passed, 62 skipped. **Before:** three of those failures, and one more case, are macOS problems: - `test_unrelated_downloads_overlap_with_a_shared_cache` fails in 12 of 20 runs with \"database is locked\". When several processes open a new disk cache together, `PRAGMA journal_mode=WAL` returns SQLITE_BUSY without calling the","keyword":45,"topics":["Scroll work","Sheets and surfaces","Registration"],"matched":["sheet","alignment"],"parts":[["ScrollPrize/villa pull request",30],["Sheets and surfaces (weak): sheet",8],["Registration (weak): alignment",7]],"state":"open","who":"AndreasHad04","created":"2026-10-25T12:39:59Z","activity":{"what":"review requested","who":"AndreasHad04","date":"2026-10-31T00:17:29Z","text":"bruniss","url":"https://github.com/ScrollPrize/villa/pull/2300","also":["marked ready for review","renamed"]},"semantic":0,"sim":0.636,"near":"Scroll work","rule":45,"score":61,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:23:53Z"},{"id":"github:scrollprize/villa#2126","source":"github","kind":"pr","title":"ScrollPrize/villa #2126: ink_detection: validate on whole held-out datasets","url":"https://github.com/ScrollPrize/villa/pull/2126","date":"2026-10-31T00:09:14Z","summary":"The default validation windows come from each training segment's `_validation_mask`. Training supervision already drops those voxels, so labels never mix, but the image crops overlap: on the PHerc0139 w016 crop used in #1927, 233 of 282 validation crops share voxels with a training crop. That score measures interpolation inside segments the model trains on; in #1867 it did not rank the ink_9um checkpoints for an unseen scroll. This adds an opt-in `\"split\": \"validation\"` key on a `datasets` entry: - every window the dataset would have trained on is scored on its supervision mask (its own `_validation_mask` windows too), and none of it is trained on; - in-segment validation windows of training datasets are dropped, so validation reads only held-out data; - training patches of training datasets are unchanged and in the same order; - before the first step the trainer refuses the split unless","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"open","who":"AndreasHad04","created":"2026-10-17T17:05:02Z","activity":{"what":"review requested","who":"AndreasHad04","date":"2026-10-31T00:09:15Z","text":"bruniss","url":"https://github.com/ScrollPrize/villa/pull/2126","also":["marked ready for review"]},"semantic":0,"sim":0.659,"near":"Scroll work","rule":30,"score":61,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:23:53Z"},{"id":"github:scrollprize/villa#2122","source":"github","kind":"pr","title":"ScrollPrize/villa #2122: ChunkedPlaneSampler: round uint8 trilinear samples to nearest","url":"https://github.com/ScrollPrize/villa/pull/2122","date":"2026-10-30T22:44:08Z","summary":"**In one sentence:** trilinear samples from `ChunkedPlaneSampler` (VC3D's chunked viewer and the Python `Volume.sample_coords` / `Volume.sample_planes`) now round to the nearest grey level instead of truncating, the same change as #2120 makes in `Slicing.cpp`. **One real example:** I sampled 9 oblique planes of 300 x 300 points (810,000 points, every coordinate fractional) from a 41 x 256 x 256 uint8 block of a PHerc0139 render (segment 20260206000001-w047, the same surface as in #2119), once with main and once with this PR, through both entry points. The difference (this PR minus main) is 0 or 1 on every point: 405,078 of 810,000 changed (share 0.500096), mean +0.500096. Against the trilinear value computed in float64 from the same block and coordinates, main is on average 0.500012 below it and this PR 0.000084 above it; this PR equals the float64 value rounded to nearest on 0.999994 of","keyword":43,"topics":["Scroll work","Compression and storage"],"matched":["chunked","volume"],"parts":[["ScrollPrize/villa pull request",30],["Compression and storage (weak): chunked",7],["context: volume",6]],"state":"draft","who":"evilaliv3","created":"2026-10-16T15:59:38Z","activity":{"what":"comment","who":"evilaliv3","date":"2026-10-30T22:44:08Z","text":"@bruniss: Converting to draft while the rounding fix discussed in #2120 lands in the maintainers' PR; I will rebase or close this one depending on whether that PR covers ChunkedPlaneSampler too.","url":"https://github.com/ScrollPrize/villa/pull/2122#issuecomment-6535071765","also":["converted to draft"]},"semantic":0,"sim":0.688,"near":"Sheets and surfaces","rule":43,"score":61,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2382","source":"github","kind":"pr","title":"ScrollPrize/villa #2382: ink inference: --mask-path no longer crashes on a pyramid that floors odd sizes","url":"https://github.com/ScrollPrize/villa/pull/2382","date":"2026-10-30T21:32:34Z","summary":"**In one sentence:** `--mask-path` works on surface volumes whose pyramid was written with floor rounding; before, the run stopped before the first tile with a broadcast error. **One real example:** Reader v2 (`reader-v2-step040000.pth`) on a 30-layer PHerc0841 surface render from my own pipeline (30 × 2201 × 4793, pyramid levels 1–5 written with floor rounding: 1100 × 2396, 550 × 1198, 275 × 599), with a 2201 × 4793 mask (`--mask-path`, 1.5 % foreground), `--overlap 0.5`, CPU, Windows 11, Python 3.12, main at ded54c6. **Before:** `ValueError: operands could not be broadcast together with shapes (275,599) (276,600)` in `build_lowres_block_mask`, exit 1, no prediction written. The occupancy scan reads level 3 (floored: 275 × 599), while the user mask is any-pooled by 8 with padding, so it is ceil-sized (276 × 600). **After this PR:** The pooled mask is cropped (or padded with `False`) to ","keyword":66,"topics":["Scroll work","Ink and imaging","Compression and storage"],"matched":["ink","zarr","volume","volumes"],"parts":[["ScrollPrize/villa pull request",30],["Ink and imaging (strong): ink",16],["Compression and storage (strong): zarr",14],["context: volume, volumes",6]],"state":"open","who":"vincentl065","created":"2026-10-30T21:32:27Z","semantic":0,"sim":0.642,"near":"Scroll work","rule":66,"score":61,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#1333","source":"github","kind":"issue","title":"ScrollPrize/villa #1333: The usage example Volume prints on failure does not work: type='segment' needs scroll_id","url":"https://github.com/ScrollPrize/villa/issues/1333","date":"2026-10-30T20:59:52Z","summary":"When `Volume` fails to initialise it prints a short usage block to help the caller (`volume.py:368-371`): ``` Example Usage: volume = Volume(type=\"scroll\", scroll_id=1) segment = Volume(type=\"segment\", segment_id=20230827161847) zarr_vol = Volume(type=\"zarr\", path=\"/path/to/my/data.zarr\") ``` The second line does not work as written: ```python >>> Volume(type=\"segment\", segment_id=20230827161847) ValueError: Could not determine energy/resolution for scroll None. Please provide them explicitly. ``` Adding `scroll_id` is enough — energy and resolution are then resolved on their own: | call | result | |---|---| | `Volume(type=\"segment\", segment_id=20230827161847)` | ValueError | | `Volume(type=\"segment\", segment_id=20230827161847, scroll_id=1)` | **works**, shape (65, 9163, 5048) | | … also passing `energy=54, resolution=7.91` | works | Small thing, but the timing is unfortunate: this text ","keyword":42,"topics":["Scroll work","Compression and storage"],"matched":["zarr","volume"],"parts":[["ScrollPrize/villa issue",22],["Compression and storage (strong): zarr",14],["context: volume, zarr",6]],"state":"closed","comments":1,"who":"aistae","created":"2026-08-05T05:37:58Z","semantic":0,"sim":0.668,"near":"Compression and storage","rule":42,"score":61,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:scrollprize/villa#2111","source":"github","kind":"pr","title":"ScrollPrize/villa #2111: spiral-fitting README: PHerc0826 example uses ACW and the catalog properties (fixes #2105)","url":"https://github.com/ScrollPrize/villa/pull/2111","date":"2026-10-30T20:37:44Z","summary":"The PHerc0826 `spiral-scroll.json` example said `\"CW\"`. Its catalog volume 20250821151701 has `z_direction_is_top_to_bottom: true` and `left_handed_coordinates: false`, which the README rule turns into ACW. With those two properties added as the README asks, `parse_scroll_spec` rejects the example. Without them it is accepted as CW with no warning. Change: the example now carries both catalog properties and `\"spiral_outward_sense\": \"ACW\"`. README only. Scope: this makes the example agree with the catalog. It does not confirm the catalog entry against the scan; see the discussion below. Evidence: catalog values read from the live open-data `metadata.json` (fetched 2026-10-15, Last-Modified 12 Oct 2026). AI-assisted: an AI agent wrote the change.","keyword":30,"topics":["Scroll work"],"matched":[],"parts":[["ScrollPrize/villa pull request",30]],"state":"closed","who":"scrollashlab","created":"2026-10-16T00:07:58Z","semantic":0,"sim":0.646,"near":"Sheets and surfaces","rule":30,"score":61,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"},{"id":"github:praysimanjuntak/windcon","source":"github","kind":"repo","title":"praysimanjuntak/windcon","url":"https://github.com/praysimanjuntak/windcon","date":"2026-10-30T14:46:15Z","summary":"Automatic winding constraints (drawn paths and relative windings) for the Vesuvius Challenge spiral fit","keyword":60,"topics":["Scroll work","Sheets and surfaces"],"matched":["vesuvius"],"parts":[["new GitHub repository",15],["scroll terms: vesuvius",45]],"who":"praysimanjuntak","created":"2026-10-29T14:01:12Z","new_repo":true,"stars":0,"forks":0,"license":"MIT","language":"Python","semantic":95,"sim":0.795,"near":"Sheets and surfaces","topics_by_meaning":["Sheets and surfaces"],"rule":79,"score":61,"learned":"full","band":"high","first_seen":"2026-10-31T06:03:27Z","last_seen":"2026-10-31T06:03:27Z"}]}