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.
Features
Section titled “Features”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-scopemin-widthis floored atmax(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: 0so 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 samemin-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 picker sorts by display name
Section titled “The New Run picker sorts by display name”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.
The gallery build resolves the runtime packages on a clean checkout
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.
Deployment
Section titled “Deployment”azure-prod is pinned to v0.4.0
Section titled “azure-prod is pinned to v0.4.0”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.