Skip to content

v0.4.1 (2026-07-07)

v0.4.1 is a focused follow-up to v0.4.0, landing on the first prod rollout of that release. Most of the change is in the catalog tables — the run log and models tables gain full column control and hold their alignment when scrolled or resized — alongside the operational fixes that surfaced once v0.4.0’s larger asset-generation cases and clean-checkout site build ran for real, and the azure-prod image pins that put v0.4.0 into production.

This remains pre-1.0 software, built first for the people working on the project.

The catalog tables are fully column-configurable

Section titled “The catalog tables are fully column-configurable”

The descriptor-driven run-log and models tables introduced in v0.4.0 gain complete control over which columns render. Every data column is now optional, so the header column picker lists them all with their shown/hidden state and can hide any column, not just reveal the default-hidden extras — only the caret gutter stays fixed, and the last remaining visible column locks so the table can’t be emptied.

The run tables also add an optional test-case version column (reads subject.testCaseVersion), hidden by default and opt-in through the picker, so the home and runs tables can surface a run’s exact case version without changing their resting layout.

Resizing freezes the whole table on the first drag

Section titled “Resizing freezes the whole table on the first drag”

Previously a resize drag pinned only the grabbed column and left the rest flexing on their fr defaults, so the untouched columns absorbed the drag and boundaries shifted on both sides of the one being resized. A drag now snapshots every column’s current rendered width when it begins — pinning the flexible tracks to fixed pixels — so from the first drag onward the table is fully pinned and only the grabbed boundary moves. An untouched table still renders on its flexible template, and a handle click that doesn’t move commits nothing.

Table rows stay styled and aligned across the full scrolled width

Section titled “Table rows stay styled and aligned across the full scrolled width”

The run log and models tables scroll horizontally when their columns (especially once resized wider) exceed the panel, and several seams showed once they did:

  • Row styling stopped at the panel edge. Each row is a CSS-grid box that sized only to the panel’s visible width, so the grid tracks spilled past it while the row’s background, top border, and hover wash stopped short — leaving an unstyled strip beside the cells that scrolled on past. Each row now grows to its columns’ full width with width: fit-content (still collapsing to the panel at rest), the per-scope min-width is floored at max(100%, …) so rows always at least fill the panel, and mobile card rows stay full-width.
  • The header drifted out of alignment with its rows. A flexible column’s track takes its minimum from its content; body cells opt out with min-width: 0 so they truncate, but the header cells did not, so their label set a larger track minimum and the header row resolved wider than the data rows once the columns overflowed. The header cells now carry the same min-width: 0, keeping the two the same intrinsic width from first paint.
  • The column-picker gutter is reserved on every row. Only the header reserved right-side padding for the floating picker trigger, making it the widest row and driving the scroll width while the narrower data rows fell short. The picker gutter moves from the header onto the base row, so every row reserves it and they all share one width.

In-progress runs show their version and category

Section titled “In-progress runs show their version and category”

The run tables dashed the version and category cells for in-progress runs even though neither value depends on the run result — both are known from the run’s launch identity and the catalog. Category (the case’s test type) is now resolved by slug in the column’s active renderer, like the test-name cell. Version is fixed at enqueue but was dropped between launch and the active-run listing; a test_case_version column is lifted onto the job table (new migration) as with the other identity columns, carried on JobSummary / ActiveJobOut / Notification, threaded through the regenerated TS contract, and read off the run.

The New Run dropdown rendered cases in the catalog’s slug order while labeling each option with its display name, so e.g. “Carom” appeared where “pong” sits instead of alongside the other ‘C’ cases. The options now sort by resolved display name to match what’s shown.

Section titled “The gallery build resolves the runtime packages on a clean checkout”

The Cloudflare Pages build ran build -w run-record && build -w site, but ui (typechecked through its source by the site) now imports @test-cabinet/voxel-runtime and @test-cabinet/particle-runtime, whose types publish only from their gitignored dist/. On a clean checkout nothing built them, so tsc -b failed to resolve the modules (TS2307) and the deploy errored — leaving published runs stuck off the live gallery. A new root build:site script builds run-record, voxel-runtime, particle-runtime, then the site in dependency order, and the documented CF build command points at it so the ordered list lives in version control.

Heavy dual-contouring cases no longer OOM locally

Section titled “Heavy dual-contouring cases no longer OOM locally”

The base 4Gi run-pod memory limit OOM-killed heavy dual-contouring cases — DC samples at a 0.5 cell, so the double-size variant of a DC case (e.g. aegis-dc-anim at 240×220×300) is a ~129M-node field, ~1.5 GB per part for the field arrays plus the DC vertex grid, before the extracted mesh, the Mesa/llvmpipe preview renderer, and the agent process share the same pod. The kill surfaced as an infrastructure failure. TCAB_K8S_RUN_MEMORY_LIMIT is raised to 8Gi in the local overlay only (prod and staging unchanged); the request stays at the base 1Gi, so scheduling is unaffected — this only lifts the OOM ceiling.

The prod overlay’s service and run-container image pins roll from 3e7b41d (services) / c461b06 (run containers) to ba19bd69 — the v0.4.0 build, and the newest sha both build-service-images and build-containers published (the two commits after it on the release line touch only the changelog and release.yml, so no images exist at those shas). The run-container images (TCAB_CONTAINER_TAG) land on the same sha as the services this time because v0.4.0 reworked the asset-generation crates, so build-containers ran and published multi-arch (amd64 + arm64) at ba19bd69; they remain decoupled in general. The two env-value image refs the kustomize images: transformer can’t reach (TCAB_DRIVER_IMAGE and TCAB_PUBLISHER_IMAGE) are bumped alongside. See rolling prod service images.