Changelog archive — 2026-10-01 through 2026-10-07#
Entries moved out of the root CHANGELOG.md on 2026-10-17 so the live file stays
readable (its own rule: archive past ~700 lines, never delete). Newest-first, running
back to where changelog-archive-2026-09-30.md picks up. One mechanical edit, no
rewording: relative links are re-based on this directory.
2026-10-07 — IREE: every Linux target tree settles before its GIL build; the compiler twin proved on both lanes (CON81, CON79 1)#
Every Linux IREE target tree configures twice before it builds (
_iree_configure_settled, native and cross; owner approval 2026-10-07). IREE addsruntime/, whoseiree::baselinks${IREE_LIBBACKTRACE_TARGET}, beforebuild_tools/third_party/libbacktracecaches it (v3.12.0 lines 1199/1236, v3.11.0 1149/1186), so only a second configure putsIREE_HAVE_LIBBACKTRACE=1on the compile lines that seeiree::base(1187 of 6700 on the amd64 compiler tree). The twin’s reconfigure used to be that second configure and recompiled them all. An aarch64 cross configure moves 377 of 474 lines the same way, so the cross target trees settle too; the host stage configures once.The GIL wheels’ bytes do not change (correcting CON81’s premise): release builds run
IREE_STATUS_MODE2, which compiles the stack-trace path out. The settled build’s 28 native files are byte-identical to:latest’s.Linux, proved in
:latestamd64 throughbuild-app-wheelhouse.shwith the full in-tree LLVM, cold,-j16, on IREE v3.11.0 (the published image’s ENVIREE_VERSIONwon over the tree’s v3.12.0 pin in that local run): configure 55 s (17 s of it the settle), build 2334 s; twin pass 25 s, 58 objects, all Python bindings (an unsettled tree changed 1272 compile lines).proveloaded 14 compiler modules and the runtime module with the GIL off; in a 3.14t venv MLIR parsed in-process, a VMFB compiled and ran onlocal-taskfrom 8 threads, and the twins’iree-compile/iree-run-moduleran.libIREECompiler.soand the ten runtime tools are byte-identical between the GIL wheels and the twins. Tests:test-iree-wheelhouse-stages.sh66 -> 76, 3 mutations.Windows, proved in
:winamd64on IREE v3.12.0 (2b05c5db),Build-IreeFromSource.ps1unchanged, compiler and in-tree LLVM: both clang-cl fixes held on the full tree; GIL pass 8696 edges in 23 min at-j20; twin pass 94 s, 137 edges (80 reach Python; 56 follow the VM ISA genrule, which re-runs for the venv’s Python and relinksIREECompiler.dlland the tools, differing only in the COFFTimeDateStamp).proveloaded all 13 compiler modules and the runtime module with the GIL off;compile_strpluslocal-taskran in eight threads at once.
2026-10-07 — Lock file maintenance in the preset; sqlite3.wasm 3.7.0; pandoc 3.12; PR merge refs on Windows#
Every lockfile moves to the newest release its manifest allows (owner rule 2026-10-07).
default.jsonsetslockFileMaintenance(enabled, schedule “at any time”). Before it, WebDavClient’s uv.lock sat 41 packages behind, DocumANTation’s 19 and OmniAccelerANT’s pubspec.lock 17, while every manager reported them up to date.Under
--platform=localRenovate builds the update and never reports it (44.140.0:dryRun=lookupskips the branch phase, the report’sbranchesstays empty), sorenovate-local.shcarries it:renovate_planner.py lockmaintreads the resolved config, the report lists each maintained lock once with its command, and--applyruns Renovate’s own command per lock (uv lock –upgrade, cargo update, pub upgrade, poetry, pdm, npm, pnpm) through the existing pre-flight, copies, undo, read-back and collateral guard; yarn is NOT CARRIED (exit 2). Tests:test-renovate-lockmaint.sh(M1-M10), 4 mutations; docs/dependency-updates.md#lock-file-maintenance. End to end with real Renovate over DocumANTation:--applymoved 19 packages, the same lock a hand-runuv lock --upgradewrote.The preset reads pubspec
environment: flutter:floors with npm versioning, moved from OmniAccelerANT’s config.SQLITE3_WASM_VERSION3.3.1 -> 3.7.0 (SHA256 by full download = GitHub’s asset digest), with OmniAccelerANT’s sqlite3 package; jotrockenmitlocken (locks 3.6.0) must follow.pandoc 3.11 -> 3.12 (
PANDOC_SHA256_AMD64/ARM64at GitHub’s digests;pandoc --versionran from the measured bytes), with DocumANTation’s Dockerfile ARGs (gitlink 7c89684 -> ce1498b, which also carries its lock maintenance, the ruff 0.16.10 pin and its lint fixes).clone-into-short-pathfetches a pull request’s merge commit. A clone lacksrefs/pull/<n>/merge, so every PR’s Windows container jobs diedfatal: unable to read treein “Prepare Windows container host” (OmniAccelerANT #45, which looked like a go_router failure). It now fetches the ref by SHA when the clone lacks it, as actions/checkout does.DocumANTation is declared in
.github/consumers.json, so workflow-lint grades it.
2026-10-07 — riscv64: the cross wheel link takes the sysroot’s libc#
fix(riscv64):
ci_packaging.sh’s cross mode puts-L<sysroot>/lib/riscv64-linux-gnu -L<sysroot>/usr/lib/riscv64-linux-gnufirst inLDSHAREDand drops the-Wl,-m,elf64lriscvpin. setuptools appends the host interpreter’s LIBDIR,-lcthen found the hostlibc.so, and itsOUTPUT_FORMAT(elf64-x86-64)made lld refuse every riscv64 object (OrchestrANT runs 37196119524, 37329297990; its riscv64 packaging had failed since 2026-10-04). Reproduced and fixed in:latestwith the riscv64 sysroot: the wheel builds (64 compiled modules), and a compiled module imports under QEMU and returns bit-identical floats to the pure-Python source.
2026-10-07 — Windows arm64: cp314t twins of the chain wheels on the cross lane (CON79 item 2)#
The arm64 cross lane builds the
win_arm64twins:winamd64builds:onnxruntime,av,apache-tvm-ffiandiree-base-runtime(no compiler on this lane), inC:\runtime\wheels-cp314t. The host’s x64 3.14t runs each build; the target tree’spython314t.lib(CON74) is what each module links.New-FreeThreadedBuildPythonlinksGet-TargetBuildPython -FreeThreadedand pins the cross venv’sEXT_SUFFIXto.cp314t-win_arm64.pyd;Invoke-PythonWheelBuild -FreeThreadedadds--plat-name.PyAV links with
build_ext -L <target libs>(setuptools’ hostlibs\came first and failedLNK2001 __imp_PyModuleDef_Init). ORT re-applies its cross MLAS flags after the twin’s re-configure, IREE its ukernel flags (Update-IreeCrossNinjaFile).New-TvmFfiCrossWheelassembles both tvm-ffi wheels;apache-tvm’s cross wheel ispy3-none-win_arm64now, as upstream builds it.media-tvm builds the free-threaded target tree too, and that tree stages
python3t.lib: IREE’s FindPython requiresDevelopment.SABIModule.
Static gates on the build host, the proof on the device. A cross twin is stored after its tags, a new import gate (
Get-FreeThreadedWheelImportFinding, on amd64 too) and its PE machine. At the merge,Write-BundleManifest.ps1refuses a cross store that does not mirror the GIL store, andTest-TargetArch.ps1 -ImportWalkmachine-checks every wheel’s members and fails acp3XYtmodule that imports a GIL runtime.Test-Arm64Bundle.ps1proves each twin in apython3.14t -m venvwith thefree-threaded-wheel.pythatExport-Arm64Bundle.ps1now ships beside it.Proved in
:winarm64(an x64 3.14t and the ARM64 trees from this checkout): twin passes 107 s PyAV, 72 s tvm-ffi, 90 s ORT (DLLs byte-identical to the GIL wheel’s), 36 s IREE runtime; every member0xAA64, every module importingpython314t.dll; manifest check and arch gate (1275 inspected, 0 violations) green. Onlywindows-11-armcan load the twins (CON79).
2026-10-07 — Pins: Renovate’s hub report (Vulkan SDK 1.4.363.0, flatpak 26.08, llama.cpp b11476, Node 26.11.0, …)#
Owner rule (2026-10-07): every update Renovate reports is taken, majors and runtime branches included.
Vulkan SDK 1.4.357.0 → 1.4.363.0 (LunarG’s latest on linux, windows and warm alike).
VULKAN_SDK_SHA256,VULKAN_RT_WINDOWS_ZIP_SHA256andVULKAN_RT_WINDOWS_ARM64_ZIP_SHA256re-measured by full download, each equal to LunarG’ssdk/sha/digest; every Dockerfile ARG and install-deps’ default follow. The SDK’s slang carries PR #12305, so the riscv64 slang patch, its_vulkan_patch_componentarm and itsDockerfile.sdkCOPY are retired.spec_vulkannow refreshes the warm/ ARM64 loader zip too.Flatpak runtime 24.08 → 26.08. Since 25.08 the GL sibling branch is
<ver>-extraand the codecs ridecodecs-extra//<ver>-extra(FFmpeg, x264, x265, libde265); the openh264 ref andFLATPAK_OPENH264_VERSIONare gone (2.6.0 was never on flathub, so the old install had been failing with only a warning).packaging-deps.shinstalled 7/7 refs in:latest; Platform//26.08 carries glibc 2.44, and a minimal flatpak-builder build ran on it.llama.cpp b11472 → b11476 with the whole
LLAMA_CPP_*set (commit, source archive, CPU and Vulkan zips at GitHub’s digests). Node 26.9.0 → 26.11.0, x265 4.1 → 4.2 (Build-FfmpegCodecs.ps1now refuses any OLD CMake policy; 4.2 dropped the two it patched), vvdec v3.2.1, binaryen version_133, Chrome for Testing 155.0.8059.39, Renovate 44.144.1 (engines.node still^24.11.0), upload-artifact v7.0.2 / download-artifact v8.0.2. Every SHA256 by full download, checked against a second source; Node, pandoc, wasm-opt, Chrome for Testing and the SDK tools ran from the measured bytes in:latest.Held: protobuf 36.2 (slaved to LiteRT-LM 0.18.0’s v36.1, still its newest release).
2026-10-07 — One cp314t twin table for both lanes; Linux 3.14t venvs take the chain ORT twin (CON79 4, 1c)#
The twin verdicts live in one file both lanes read,
linux/scripts/03-media/free-threaded-twins.txt(dist|verdict|PIN=value|evidence,#comments). Linux’sft_wheel_tableand Windows’Get-FreeThreadedTwinTableboth parse it, so their verdicts cannot drift. They had:torchvision(none) was only on Windows,libcamera(gil) only on Linux, and four evidence texts were worded apart. The file holds the union, 12 rows, with the fuller evidence.Linux mounts it per file beside
free-threaded-wheels.shin the six RUNs that build or store a twin. Windows mounts it atC:\bkmnt\free-threaded-twins.txtin the three twin RUNs ofDockerfile.media-builder, and the final stage’s one COPY bakes it intoC:\temp\scripts, where Test-Container section 20 reads it. No other RUN re-keys on it.A missing table stops a run instead of reading as unclassified, on both lanes and in the smoke.
Tests: both lanes keep their pin re-check, and each asserts its parse equals the file row for row and that neither reader holds a row literal. 7 mutations; the Pester guards were proved by hand (7 edits, all bite).
A
cp3XYtvenv inside:latesttakes the chain ORT twin (CON79 1c).Dockerfile.torchnames/opt/wheels-cp314tinPYTHON_WHEELS_CP314T, Windows’ variable, after the store’s late COPY.uv_reconcile_chain_ortreads it for acp3XYtvenv and proves the venv against the twin store, taking only the twins of the flavoursORT_CHAIN_WHEEL_DIRholds (a GPU image’s twin store carries two ORT flavours). Without the variable the leg is refused on the ABI as before, and the FT-STORE gate wants it on every arch.Proved in the published
:latestamd64 with a 3.14.8t built bybuild_python.sh: a 3.14t venv holding PyPI’s cp314t onnxruntime 1.30.0, refused by the previouspython_uv.sh, was reconciled ontoonnxruntime_dnnl-1.30.0-cp314-cp314t(census PASS, GIL off). The twins were pure-Python stand-ins; a real cp314t ORT twin needs the GIL ORT build tree. A GIL venv with the variable set still took the image’s real chain wheels. Tests:test-uv-chain-ort.sh,test-free-threaded-store.sh; 5 mutations.
2026-10-07 — Windows: the media fan-in merges site-packages in place (CON80)#
import Cythonfailed in:winamd64and:winarm64(2026-10-04):Cython\shadow.py, while its RECORD namesShadow.py. A Windows container layer that replaces a file a lower layer holds stores the new name lowercased, and BuildKit’sCOPYreplaces every file it overwrites. The fan-in COPYed media-core’s and then media-tvm’s site-packages; both carry Cython, numpy, pip, setuptools, wheel and packaging, so the second COPY lowercased all 451 of their RECORD entries. NTFS opens either spelling, CPython’s import does not, and Cython is the one with CamelCase modules (docs/windows-build-invariants.md, docs/failure-modes.md).The two COPYs are one
RUN: both branch trees bind-mounted, merged byMerge-SitePackageTree(WindowsSitePackages.Common.psm1) with robocopy, which overwrites in place. It refuses a distribution at two versions and any RECORD entry spelled otherwise on disk afterwards.Both branches install
cython==PY_CYTHON_VERSION, forwarded as a build-arg tomedia-core-built-ffmpegandmedia-tvm-env.Smoke section 2 imports
Cython.Shadowat the pin and checks every base-interpreter RECORD against the disk, case-sensitively; section floor 6 -> 8.Proved by a replay of the fan-in on the local stage images: 451 mismatches and the ModuleNotFoundError before, 0 over 31 distributions and a working import after (9.9 s). Tests:
SitePackages.Merge.Tests.ps1(10).
2026-10-07 — Linux: proved cp314t twins of the media wheels whose code declares free-threading#
Every wheel the media stage builds natively for a package whose own code declares free-threading also ships as a proved
cp314ttwin, in/opt/wheels-cp314t(owner request 2026-10-07). The GIL wheels are built as before. One table decides,ft_wheel_tablein03-media/free-threaded-wheels.sh, each row read at aversions.envpin that a test re-checks; it holds the same verdicts as Windows’Get-FreeThreadedTwinTable.Each build reruns in its warm tree on a 3.14t venv pinned to the GIL build venv’s executors;
ft_soabi_gateandfree-threaded-wheel.py proverun before a twin is stored, andfree-threaded-store.shproves the store again after the repair.verify-wheels.shis ABI-exact on both stores, the ORT twin has its ownort-provenance-cp314t.sha256, and a native build fails on a missing or stray twin or an unclassified wheel. Cross builds build no twin (CON79).:latestships the store; the runtime smoke’s FT-STORE gate proves each twin onpython3.14tand wants exactly/opt/venv’s twin families on a native arch.
free-threaded-wheel.pycounts a bare.soas a module only when it exportsPyInit_<name>, so ORT’slibonnxruntime_providers_shared.sono longer fails the proof.Proved in
:latestamd64: ORT CPU, PyAV, tvm-ffi and the IREE runtime twins, twin passes 97 s / 28 s / 29 s / 130 s cold (11-40 s warm for ORT); in a 3.14t venv numpy, onnxruntime, av, tvm_ffi and iree.runtime import with the GIL off. Tests:test-free-threaded-wheels.sh,test-free-threaded-store.sh, 33 mutations.
2026-10-07 — Windows: cp314t twins of the chain wheels that declare free-threading#
Owner request 2026-10-07: every chain wheel twice,
cp314tonly where the code declares it. Checked in upstream source at the pinned tags: onnxruntime (py::mod_gil_not_used()), PyAV (freethreading_compatible), apache-tvm-ffi (# cython: freethreading_compatible = True) and IREE runtime and compiler (nanobindFREE_THREADED) get a twin; apache-tvm (a py3 wheel) and torchvision carry no CPython module; onnxruntime-genai, LiteRT, pyhailort, libcamera and cv2 declare nothing and stay GIL-only. The verdicts live inGet-FreeThreadedTwinTablewith the pin each was read at, and a pin bump fails a test until the evidence is re-read.:winamd64builds them beside the unchanged cp314 ones, inC:\runtime\wheels-cp314t(PYTHON_WHEELS_CP314T). Each twin is built in a uv venv onC:\python-freethreadedwith the GIL pass’s tool versions, tag-checked (cp3XY-cp3XYt,win_amd64, every.pyd), installed alone into a fresh venv and proved withfree-threaded-wheel.py provebefore it is stored.Save-PythonWheelrefuses a cp3XYt wheel in the GIL store, nothing installs intoC:\python-freethreaded, and smoke section 20 checks the store’s exact set.ORT re-configures the GIL build tree for the venv’s Python and rebuilds only
onnxruntime_pybind11_state; the twin’s DLLs must be byte-identical to the GIL wheel’s, and the ORT census takes both wheels as chain references (Get-OrtChainWheel -Abi). A 3.14t venv’s chain-ORT reconcile reads the twin store.IREE forces abi3 off (upstream only knows a
cpython-NNtSOABI), clears nanobind’s cached GIL suffix, and drops the GIL pass’s leftover_runtime.pydbefore the twin packs.Measured in
:winamd64: ORT twin pass 60 s, PyAV 43 s, tvm-ffi 34 s, IREE runtime 20 s; each proved with the GIL off. A module without the declaration was refused. The clang-built 3.14t reportswin-amd64, so no platform-tag shim is needed.
Invoke-CmakeConfigure -Settle. CMake 4.4’s Ninja generator writes\paths on a tree’s first configure and/after, so every re-configure recompiled all 1474 ORT edges; the GIL pass now configures twice when a twin follows.IREE v3.12.0 on clang-cl. Its VM ISA genrules ran a bare
python3, which no Windows image has; they runPython3_EXECUTABLE. Its profile statistics sink needs__udivti3, so every IREE link getsclang_rt.builtins-<arch>.lib. Both broke the pinned build regardless of the twin.
2026-10-07 — ROCm 10.1 (TheRock therock-10.1), MIGraphX 2.18.0 and llama.cpp b11472 (CON73)#
Owner decision: TheRock 10.1, MIGraphX 2.18.0 and the newest llama.cpp, all three. Renovate has reported TheRock 10.1 since its annotation reads
versioning=loose; the bump was made by hand, since every pin carries a paired value.MIGRAPHX_VERSIONis shared by both lanes.Linux (
:latest-rocm).ROCM_VERSION=10.1,MIGRAPHX_VERSION=2.18.0. The list resolves to 262 packages at10.1.0-3plusamdrocm10-migraphx{,-dev}2.18.0-1(298 with ASAN, all 10.1).PYTORCH_ROCM_INDEXstaysrocm7.14:rocm7.14.1,7.15,7.16,8.0,10,10.0and10.1answer 403.MIGraphX left
/opt/rocm/lib. 10.1 installs it under/opt/rocm/extras-10/; the first 10.1 install stopped atmigraphx.hpp not found.setup-rocm-repo.shwriteslibmigraphx_c’s directory intorocm.conf, findsmigraphx.hppanywhere under/opt/rocmand fails unlessldconfig -plistslibmigraphx_c;30-build-native-amd.shhands ORT MIGraphX’s own prefix as--migraphx_home(ORT’sfind_package(migraphx PATHS /opt/rocm)missesextras-10) and drops the dead2.14.0default;publish_rocm_ld_pathpublishes the same directory and no longer publishescore-asan-*.Proved in
:latest: the real 10.1 install (7.0 GB, 21.7 GB on disk) and the ASAN branch pass the script and its release check, and the script built ORT v1.30.0 with the MIGraphX EP, whose provider loads GPU-less.test-rocm-packages.sh22 → 36 assertions, 10 mutations.
Windows (
:winamd64-rocm).ROCM_WINDOWS_RELEASE10.0.0 → 10.1.0: the gfx120X-all tarball (2,244,477,973 B) and therocmsdist,rocm-sdk-core,rocm-sdk-librariesand the gfx1201/gfx1200 device wheels, every SHA256 self-measured by full download. 10.1.0 names hiprtchiprtc0716.dll; every check derives the name.MIGraphX 2.18.0 is the head of
release/rocm-rel-10.1(95672916; norocm-10.1tag yet). It carries upstream 5a80dc91ba, so001-mlir-off-stubs.patchis gone. It built to the end in 58 min in a:winamd64container (prefuse_ops.cppalone about 50 min on one core), and the ORT AMDGPU EP built against it.llama.cpp b11460 → b11472, with
ggml-hip.dllbuilt here. Upstream still ships onlywin-rocm-10.0zips.Build-LlamaCppHipFromSource.ps1builds upstream’swindows-rocmrecipe from the tag’s source archive with TheRock’s AMD clang for gfx1200/gfx1201, with nothing that downloads at build time (3 min 27 s cold).Install-LlamaCpp.ps1 -Backend hipputs it beside the tag’swin-cpu-x64zip (llama-server/llama-cliand the CPU backends, SHA-pinned asLLAMA_CPP_CPU_SHA256), as upstream’s own ROCm zip merges them: a full source build would fetch the server’s web UI and BoringSSL unpinned. No ROCm DLL sits beside it; the directory is 178 MB, down from about 1.24 GB. The Vulkan build stays upstream’s zip at the same tag.rocm-checks\LlamaCpp.ps1checks that no ROCm DLL sits beside llama-server, walks ggml-hip’s imports into ROCm’s bin and runsllama-cli --list-devices.WindowsMigraphx.CommongainsInvoke-RocmClangConfigureandAssert-RocmBuiltPe. TheRock 10.1’s clang compiles HIP against MSVC 14.51 without thehip-msvc-cmathoverlay, which stays until an image build proves it can go (CON78).
What only the published images prove is BACKLOG CON78.
2026-10-07 — The arm64 bundle carries a free-threaded CPython too (CON74, half 1)#
:winarm64’sC:\runtimegainspython-freethreadedbeside the GIL target interpreter. Media-core’sBuild-TargetCpython.ps1builds the target checkout twice with the image’s VS 2026 ClangCL toolset (Invoke-CpythonPcbuild -Platform ARM64, then-FreeThreaded, both with/p:PreferredToolArchitecture=x64) and stages each tree right after its own build.One staging function,
Install-CpythonTargetTree, is the old block: the PE-machine gate, the host-arch CRT replacement, thevcruntime140_1drop, headers,Lib, an emptysite-packages, the CRT beside the exe and the ensurepip check. On the same build output the GIL tree andC:\runtime\binare byte-identical to the old code’s.The free-threaded tree holds
python3.14t.exeandlibs\python314t.lib, nopython.exe, no DLL-directory shim, andvenvlaunchert.exe/venvwlaunchert.exeinLib\venv\scripts\nt: without themuv venvrefuses a tree with nopython.exeto copy.media-tvm passes
-SkipFreeThreaded, since the merge takes only media-core’s trees.BUNDLE-ENVsetsKATA_PYTHON_FREETHREADEDand appends the tree last toPATH.
The merge gate’s import walk threw on the second of two same-named wheels. Both trees ship ensurepip’s
pip-26.2.1wheel;Test-TargetArch.ps1now extracts each into its own directory.Test-Arm64Bundle.ps1runspython3.14t.exe -Iin a bundle that has it and fails unless the GIL is off,Py_GIL_DISABLEDis 1 andsys.versionsaysARM64. The steps a bundle may lack shareInvoke-ShippedBundleStep.Measured in
:winamd64on a fresh v3.14.8 checkout (32 CPUs): ARM64 GIL build 65-96 s, free-threaded 67-79 s. The free-threaded tree has 2793 files and 82.5 MB, and all 61 of its PE files are0xAA64. The merge gate over both trees inspected 131 binaries and walked 157, with 0 unresolved. The same function on an x64 free-threaded build gave a tree that uv took withUV_PYTHON_DOWNLOADS=never, and its venv ran with the GIL off. Onlywindows-11-armcan run the ARM64 tree. A media-stage change::winarm64rebuilds from media-core on.
2026-10-07 — A proved free-threaded wheel beside the GIL one#
A project that declares free-threading ships a
cp314twheel too (owner request 2026-10-07: two wheels, the free-threaded one only where the project supports it).ci_packaging.shandInvoke-CiPackaging.ps1readpyproject.toml’s officialProgramming Language :: Python :: Free Threadingclassifier (any level) through the sharedfree-threaded-wheel.py.The
CYTHONIZE=Truebuild runs again on the image’s 3.14t, found byuv python findand never downloaded, and must leave onecp314twheel (auditwheel-repaired on Linux).A fresh 3.14t venv installs the shipped wheel and loads every compiled module; the step fails when the GIL is back on, naming the first module that turned it on.
The sdist and the pure wheel are built once. Undeclared projects build what they built before, plus one log line.
PYTHON_FREE_THREADED_WHEEL=auto|on|off(Windows also-FreeThreadedWheel) overrides; the riscv64 and Windows arm64 cross lanes skip it with a reason (CON75). New moduleWindowsPythonWheel.Common.psm1.A consumer moves its hub pin only once its images resolve
3.14t(:latestamd64/arm64,:winamd64): a declared project’s packaging step fails without one, by design.
The Linux GIL build asks uv for
3.14+gil, as Windows does:uv buildignores the venv.free-threaded-wheelinput (CON77):python-ci-linux.ymlandpython-ci-windows.ymlpassauto/on/offto the drivers asPYTHON_FREE_THREADED_WHEEL, so a caller can switch the wheel off without dropping its classifier.auditwheel runs on Linux at last. It is PATH’s, else the binary packaging venv’s; PATH never had one, so every Cython wheel shipped as
linux_<arch>under a log line calling it pure.python-app-bundle.shpicks the wheel by its runtime’s ABI, likeSelect-PythonAppWheel.Proved on OrchestrANT (64 compiled modules, manylinux2014/manylinux_2_17 and win_amd64) and WebDavClient (3 modules) in
:latestand:winamd64, with a uv-fetched 3.14.7t standing in for the images’ own until they ship it. Tests:test-python-free-threaded-wheel.sh,PythonWheel.FreeThreaded.Tests.ps1, 14 mutations.
2026-10-07 — The free-threaded CPython is built from source, on every arch (CON66)#
Owner decision:
3.14.8tcomes from the toolchain stage, not uv’s python-build-standalone download.build_python.shbuildsPYTHON_VARIANTS(gil,freethreaded) in turn from the one SHA256-verified tarball, and/usr/local/bin/python3.14tstays the contract path.The GIL build is unchanged. Against the old script, its staged cross trees list the same 9600 paths at the same sizes, and every file but
libpython(its build date) is byte-identical.The twin is
--disable-gil --without-static-libpythonin/opt/python-freethreaded: PGO and LTO natively, LTO alone per cross arch. Its rpath goes in throughLDFLAGS_NODIST, so acp314twheel built against it inherits none.Each arch’s tree is staged at
/opt/python-cross-ft/<arch>/opt/python-freethreaded. The build arch’s is hardlinks and is staged in native mode too, soDockerfile.packagetakes the target arch’s with one COPY (runtime-artifacts.manifest,ALLOWED_RELOCATIONS).A cross tree is a
make altinstall(bytecode,python3.14t-config) and keeps_ctypes, which the GIL cross trees build without._python_dynload_auditmakes_ssl,_hashlib,_sqlite3,zlib,_bz2,_lzmaand_ctypesfatal there.install_free_threaded_pythonlinks and checks the COPY’d tree and refuses a missing one; nothing downloads.
Gates.
smoke-toolchain.shruns the twin and checks every staged arch.The
free-threaded-pythonrow also wantssysconfig’s prefix/opt/python-freethreadedand the stdlib imports, so a python-build-standalone tree fails it.The tree-arch gate scans
/opt/python-freethreaded.New suite
test-build-python-variants.sh; eight new mutations.
Measured in
:lateston 32 cores. The image’s flags (cross amd64/arm64/riscv64) took 624 s: 6.5 min native (4.7 of them the PGO profile run) and under 2 min per cross arch. Shipped trees: 138 MB amd64, 120 MB arm64, 233 MB riscv64.Each tree, installed by the new package-stage code, reports
3.14.8 Falseand passes the row; arm64 and riscv64 ran under QEMU.uv 0.12.17 finds it for
3.14tand not for3.14+gil.
2026-10-07 — The Windows image builds its free-threaded CPython from source#
:winamd64carriesPYTHON_VERSIONtwice, both source-built with the image’s VS 2026 / MSVC 14.51 and the ClangCL toolset (owner request 2026-10-07). Until now every Windows3.14tleg had uv download a python-build-standalone interpreter.Build-ToolchainAll.ps1builds the GIL tree as before, then the same checkout withPCbuild\build.bat --disable-gilinto its own trees (PCbuild\freethreaded,PCbuild\obj\freethreaded).CPython’s own
PC\layout --include-freethreaded --include-dev --include-venv --include-stableinstalls it intoC:\python-freethreaded(PYTHON_FREETHREADED_BIN, 36 MB). It sits last onPATH, has nopython.exeand starts with an emptysite-packages.uv resolves
3.14ttoC:\python-freethreaded\python3.14t.exewithUV_PYTHON_DOWNLOADS=never.3.14,3.14+giland a barepythonstay onC:\temp\cpython\PCbuild\amd64\python.exe. Measured in:winamd64on a fresh v3.14.8 checkout: GIL build 120-207 s, free-threaded 104-124 s (32 CPUs).uv build --python 3.14tbuilt acp314-cp314t-win_amd64wheel.The stage stops unless both interpreters report the pin, the
AMD64marker and their GIL state (Assert-CpythonInterpreter). Smoke section 2 checks the free-threaded one and uv’s resolution again.Select-CpythonImportLibowns the import-library pick:python314.libfor GIL callers,python314t.libwith-FreeThreaded.Get-SourceBuildPython -FreeThreadedis new.A toolchain-stage change: every stage after it rebuilds once. The arm64 bundle has no free-threaded interpreter yet (BACKLOG CON74).
2026-10-07 — :latest-rocm installs one ROCm tree again: every package name carries ROCM_VERSION#
The bug.
setup-rocm-repo.shinstalled versionless metapackages (amdrocm-core-dev,-runtime-dev,-blas-dev,-dnn-dev,-hipblas-common-dev,-fft-dev,-rccl-dev,-sparse-dev,-solver-dev). AMD’sstablesuite is rolling and gained ROCm 10.1 on 2026-09-30, so each one resolved to10.1.0-3whileversions.envpinsROCM_VERSION=10.0.amdrocm-migraphx2.17.0+rocm10.0.0 still pulls the 10.0 libraries, so the image carried two trees:apt-get install -sselected 262 packages of 10.1 and 73 of 10.0.The fix.
rocm_packagesbuilds the list fromROCM_VERSIONandMIGRAPHX_VERSION.The nine libraries are
amdrocm-<name>-dev10.0.MIGraphX is pinned through apt:
amdrocm-migraphx{,-dev}=<ver>+rocm10.0.*for 10.0, andamdrocm10-migraphx{,-dev}=<ver>-*from 10.1, where AMD renamed it.The ASAN package stays
amdrocm-asan${ROCM_VERSION}.An unknown release, or a
ROCM_VERSIONthat is notX.Y, fails before the first download.Dockerfile.amdnow passesMIGRAPHX_VERSIONto the script.
New hard gate. After the last install, any installed
amdrocm*package whose name carries a release other thanROCM_VERSIONfails the build and is listed.Proof.
apt-get install -sagainst the live repo in:latest, through the script’s own repo setup.The 10.0 list selects 251 packages: 249 named
…10.0and the two MIGraphX ones at2.17.0+rocm10.0.0.With ASAN it selects 281, again all 10.0.
A real install of
amdrocm-hipblas-common-dev10.0passes the check, and adding its 10.1 twin fails it.
Tests. New
test-rocm-packages.sh(22 assertions) and 13rocm-stack.*mutations, all biting. The family is declared ingate-proofs.allow.Docs.
linux-accelerator-images.md§ The ROCm release is in every package name; row 3 of the ROCm sweep table (assert the installed versions) is done.
2026-10-07 — Renovate names the pins it skips, and eight skipped pins are readable again#
Eight annotated pins were invisible to every report. The custom manager reads
versions.envandtool-pins.envwithsemverunless an annotation names a scheme. A value semver cannot parse is skipped asinvalid-value, and a skipped dependency is never behind. SoROCM_VERSION=10.0hid TheRock 10.1 (released 2026-10-05) from the 2026-10-07 bumps. The other seven wereVULKAN_VERSION,ABSEIL_VERSION,NASM_WINDOWS_VERSION,PANDOC_VERSION,PY_PATCHELF_VERSION,PY_PACKAGING_VERSIONandBINARYEN_VERSION, as the new list showed over the unfixed tree. Each annotation now namesloose,pep440or aregex:.UBUNTU_VERSIONwas read, and now namesubuntuso only an LTS counts as stable.Newly visible: binaryen 133, Vulkan SDK 1.4.363.0, pandoc 3.12 and TheRock 10.1.
Five independent pins had no annotation at all, and four of them hid a release: x265 4.2 (bitbucket-tags), the freedesktop runtime 25.08/26.08 for the flatpak (gitlab-tags), Chrome for Testing 155.0.8059.39 (a new
custom.chrome-for-testingdatasource, Stable channel), plus HailoRT and TAPPAS (current at 5.4.0). The pins still left unannotated, and why, are in docs/dependency-updates.md.A value pin no longer moves to npm’s integrity hash. npm reports
newDigest(the tarball’ssha512-…) on every update, and the planner preferred it overnewValue, so the report showed Renovate 44.142.1 assha512-prNFz. An apply would have written that intoRENOVATE_VERSION, had the approval rule not refused it. Only a digest pin moves by digest.renovate-local.shends its report with a NOT CHECKED list. It names every dependency Renovate skipped or failed to look up, with the reason and the file. By-design skips (path dependencies,disabled,unspecified-version, …) are counted on one line. The planner’s newskippedmode reads them, andtest-renovate-local.shcovers both kinds.test-renovate-annotations.shparses every annotated value with its scheme, so a value Renovate would skip fails before any run. It catches the oldROCM_VERSIONline.Renovate keeps updating itself:
RENOVATE_VERSIONandRENOVATE_NODE_VERSIONare annotated like every other pin (docs/dependency-updates.md § A skipped pin is not up to date).
2026-10-07 — The Renovate bumps of 2026-10-07: every patch and feature release (CON72)#
Owner choice: bump everything Renovate reported that is a patch or feature release. The report was
custom.regexplus the default managers over the hub. Every pin was moved by hand with its paired SHA256, commit or source change. Each SHA256 comes from a full download and was checked against a second source: GitHub’s asset digest, the publisher’s sums file, python.org, NVIDIA’s redist manifest,releases_linux.jsonor the PyTorch index.Toolchain. LLVM 23.1.3 on both lanes (
LLVM_COMMIT0d261d1c), Rust 1.99.0, CPython 3.14.8, CMake 4.4.4, uv 0.12.23 (and its installer pin).Both AArch64 size patches still apply to 23.1.3, and the patched file passes
Build-LlvmFromSource.ps1’s assertions.uv 0.12.23 offers
3.14.8tfor linux x86_64/aarch64/riscv64 and windows x64/arm64 (CON66).The CPython clang patch is gone. 3.14.8’s
PC/pyconfig.hnames clang by major.minor.patch itself;Build-ToolchainAll.ps1still refuses asys.versionwithoutAMD64.Consumers that gate rustc’s stamp (OmniAccelerANT
check-rust-toolchain.sh) follow once they move their hub pin after the image is published.
Media. TVM v0.27.0, IREE v3.12.0, onnxruntime-genai v0.17.0, LiteRT-LM 0.18.0, PyAV 19.0.1, OpenVINO 2026.4.1, ComputeLibrary v53.3.1, libpng 1.6.59, AMF headers v1.5.3.
TVM_COMMITis now the v0.27.0 tag’s commit, and must never be emptied. apache/tvm also has a branchv0.27.0, andclone --branchtakes the branch.GenAI is 0.17.0, not Renovate’s 0.17.1, which is on PyPI but has no GitHub tag. Its
D3D12Core.dllnow comes from a NuGet restore into__nuget; the Windows sidecar filter matches it.protoc is 36.1 and Python protobuf 7.36.1, not Renovate’s 36.2. Both stay slaved to LiteRT-LM 0.18.0’s
LITERTLM_PROTOBUF_TAG, whichbump_versions.pycan now read.LiteRT-LM 0.18’s GPU DLLs import
webgpu_dawn.dll. The rocm lane stages and pins that file instead oflibwebgpu_dawn.dll.
Apps. torch 2.14.1 and torchvision 0.29.1 (with the rocm source commits and the win-arm64 wheel), llama.cpp b11460, Ollama 0.40.0, Flutter 3.47.6, cuDNN 9.27.0.42.
llama.cpp b11461 had a tag and no release yet; b11460 is the newest build with both zips.
Tools. ruff 0.16.10, syft v1.54.1, Renovate 44.140.0, meson 1.12.1, scikit-build-core 1.1.1, setuptools-scm 10.3.4, cargo-tarpaulin 0.37.5, Git for Windows 2.56.0, lavapipe 26.2.4, the
ubuntu:26.04digest,docker/dockerfile1.27.1.APISIX 3.19.0 for the llm-stack gateway: the gateway e2e passed 79 of 79 on it (and on 3.18.0 before), so
geniex_hook.luais proven on 3.19.0.
Consumers follow before the next chain. OrchestrANT pins ruff 0.16.10, torch 2.14.1 and torchvision 0.29.1, and onnxruntime-genai(-cuda) 0.17.0; the hub’s consumer-pins gate is red in its lint lane until it does. Its
uv.lockalso needs iree-base-compiler 3.12.0, because a 3.12 runtime does not load a 3.11 VMFB.What only a chain can prove is BACKLOG CON72.
2026-10-07 — git-sync-branches.sh moves third-party submodules by default#
Owner decision: the newest commits everywhere, not just in the family’s repos. Every submodule now goes to the tip of its
branch =. A library held at a release declares that release branch, as AccelerANTgine does for FUZZTEST.--owned-onlyreplaces--alland keeps the earlier behaviour: submodules under another owner stay at their recorded commit.
2026-10-07 — git-sync-branches.sh: every checkout on its branch tip#
New entry point
linux/scripts/git-sync-branches.sh. It checks out the superproject’s default branch and, recursively, each submodule’sbranch =(or its remote’s default), fast-forward only. OmniAccelerANT needed it after a pull left its submodules detached.Only the superproject owner’s submodules move. Third-party ones stay at their recorded commit unless
--allis passed. Dirty trees are skipped, and a diverged branch fails the run.It commits no gitlink, so it is not the forbidden bare
git submodule update --remote. It lists what drifted from the recorded commits.test-git-sync-branches.shruns it against bare-repo fixtures under two owners.
2026-10-07 — DeepStream is in every amd64 nvidia build (CON42)#
Owner decision: DeepStream ships with every
:latest-nvidiabuild, at full size. TensorRT 10’s builder resources for every GPU generation stay (2.6 GB), so the RTX 2080’s sm_75 keeps working.stage-defs.shnow defaultsENABLE_DEEPSTREAM=truefor an nvidia chain on an amd64 build platform, the way it defaultsENABLE_TENSORRT=false. Until now every run had to ask.ENABLE_DEEPSTREAM=falseopts a run out.An arm64 (Jetson) nvidia build gets no default, because
deepstream.shrefuses arm64 (phase 7).A default or rocm chain still refuses the flag.
test-gpu-variant.shcovers the default, the opt-out, arm64 and rocm. Two new mutations bite.
2026-10-07 — The Windows clang-format check can gate#
Invoke-ClangFormatCheckonly ever reported. BeschleunigerBallett swept its sources to zero deviations with clang-format 23.1.1 (d59d210f) and re-counted them in its ownBuild-Windows.ps1to fail the build.Two switches, the default unchanged:
-FailOnDeviationthrows on any deviating file, and on a missing clang-format instead of skipping.-ExpectedVersionrefuses a clang-format of another release (CON71).
The report no longer names BB’s backlog entry.
WindowsFormatting.ClangFormatCheck.Tests.ps1covers both switches and the default.
2026-10-07 — A consumer’s CMake sccache goes through the guarded launcher#
Cache.cmakehanded CMake the baresccache. When its server died, every compile of the job failed (BeschleunigerBallett run 37509585546,Connection refused), and BB patched around it in its ownProjectOptions.cmake(05c7a338).myproject_enable_cachenow sets the hub’ssccache-launcher.shoff Windows, which retries once and then compiles directly. ccache and Windows keep their binary.test-cmake-cache-launcher.shcovers sccache, ccache and no cache, and the new mutationsccache.cmake-guarded-launcherbites. BB’s override becomes a no-op once its hub pin includes this.
2026-10-06 — Every LLVM tool is the pinned release (CON71, in source)#
Owner decision: no LLVM tool may come from another version, clang-format included. It reverses CON15, which kept
clang-formatandllvm-configat LLVM 21.Linux, measured on the published
:latest: 86 unversioned/usr/binLLVM names were Ubuntu’s LLVM 21, among themclang-format,/usr/bin/clang-tidy,clang-clandllvm-config.The package stage diverts every one of them.
wire_pinned_llvm_toolspoints each name the pinned LLVM has into/usr/local/llvm-target/binand moves the rest offPATH. The-NNnames stay LLVM 21 for explicit callers.The toolchain stage builds lldb and installs the LLVM utilities, so
lldb,FileCheck,yaml2objandllvm-tblgenare 23.1.1 too. This rebuilds LLVM on all three arches.The compiler smoke grades 26 tools against
LLVM_RELEASE, no longer against clang’s own version, and fails any distro LLVM left under an unversioned name.Windows: IREE’s
clang,llvm-linkandFileCheckand the MSVCllvm-symbolizer(all 23.0.0git) came first onPATH.The entrypoint now puts
C:\llvm-patched\binfirst.The patched LLVM installs its utilities, so
FileCheckcomes from it.Test-Toolchain.ps1andTest-Container.ps1check every LLVM tool against the pin.
Proven before the chain:
The wiring on a throwaway
:latest: 86 names moved, a reinstall kept them, clang++ still links.An LLVM 23.1.1 configure with the new flags installs all 13 missing names.
The new entrypoint on
:winamd64: 20 of 21 tools pass, and only IREE’sFileCheckwaits for the rebuild.Seven new mutations, all caught.
2026-10-06 — The chain wheels are proven once in every :latest child (CON52 closed)#
The fix shipped with the
:latestof 2026-10-03. Its three children come from one chain run (20261002-211215-63e1803b, hub b4d5fdd5), which carries 9ff5e2a3:reconcile_local_wheelsis the one install point, andassert_chain_wheels_installedfails the torch stage, underset -Eeuo pipefail, when a staged wheel is not the venv’s.Read back from the published venvs on 2026-10-06. In amd64 and arm64 (under QEMU), every chain wheel is installed from its
/opt/wheelsfile:ai-edge-litert,onnxruntime-genai,iree-base-runtime,av,libcamera, TVM and the arch’s ORT. torch and torchvision come from the lock. The riscv64 child was published from the same run.
2026-10-06 — riscv64 consumer lanes are in place; Flutter is a new row (CON48 closed)#
The hub half and three consumers have been green since 2026-10-01:
setup-riscv64-cross,container-ci-riscv64.yml,lib/riscv64-cross.shand the CMake toolchain, used by OxidANT, AccelerANTgine and BeschleunigerBallett. The Vulkan-variable override went 2026-10-06.OmniAccelerANT’s lane needs a riscv64 Flutter engine, which upstream does not publish (flutter/flutter#99963). That is CON70, blocked on an owner decision.
2026-10-06 — Every test runs on every arch lane (CON50 closed)#
The owner goal of 2026-10-01 is met in all six consumers. The last open parts closed this week:
OmniAccelerANT’s release APK runs on the emulator in CI (83f4596).
OrchestrANT’s
benchmarks/testsjoinedtestpathsand runs on every lane (7e0d47c, green on 80a587f).WebDavClient’s client has real unit tests (a9ef2cf).
What is left belongs to CON64: BeschleunigerBallett’s Windows arm64 GPU suites validate once a published
:winarm64carries the validation layer. The row moved there.
2026-10-06 — The published :latest-rocm passes the three media checks (CON51 closes)#
What was open. The rocm chain of 2026-10-02 (hub b4d5fdd5) republished
:latest-rocm, amd64 manifestbdfcb731…. Nobody had read its runtime smoke verdicts for the 2026-10-01 media fixes.Measured instead, on the published image. Pulled on 2026-10-06, created 2026-10-02 20:50. The three checks ran as
smoke-runtime-image.shruns them:check_no_libunwind_closure: none of 1487 shared objects under/optand/usr/localneedslibunwind.so.8;check_lavapipe_subgroup:LP_NATIVE_VECTOR_WIDTH=256, and lavapipe reportssubgroupSize 8(CON44);_gst_check_blacklist: the GStreamer registry blacklists nothing, and gst-validate’s SSIM override writes 3 frames (CON47).
Every variant now has GStreamer and libcamera without libunwind except
:latest-nvidia, which gets them from the chain run CON42 waits on.
2026-10-06 — A consumer’s pytest stack ships in the :winarm64 wheel store (CON67)#
OrchestrANT’s arm64 lane fetched its test runner from PyPI, unpinned, at cross-build time: pytest and six plugins for win_arm64.
The merge stage stages them now.
versions.envpins 31 cp314 wheels by URL and SHA256 (PYTEST_WINDOWS_ARM64_*). They are pytest 9.1.1, pytest-cov 7.1.0, pytest-benchmark 5.2.3, pytest-html 4.2.0, pytest-md 0.2.0, pytest-md-report 0.8.0 and requests 2.34.2, with their closure.Copy-Arm64TorchWheels.ps1stages them beside the torch stack and checks the three native ones’ target arch. Every SHA256 equals PyPI’s.Test-Arm64Bundle.ps1proves them on the device: an offline install into the bundle’s interpreter, then an import, in a bundle that carries them.
2026-10-06 — The free-threaded Python ships in :latest (CON66)#
Every
3.14tleg downloaded its interpreter. OrchestrANT’s and WebDavClient’s free-threaded legs had uv fetch a3.14.Nt, its patch unpinned, on every run.The package stage installs it now, on all three arches.
install_free_threaded_pythonrunsuv python install <PYTHON_VERSION>tinto/opt/python-freethreaded, outside uv’s store, and links/usr/local/bin/python3.14t. uv checks the download against the SHA256 its pinned release embeds. The stage stops unless the interpreter reportsPYTHON_VERSIONwith the GIL off.The smoke gate checks it in a
free-threaded-pythoncontract row, with no exemption.Proven in a
:latestcontainer:uv venv --python 3.14tused it withUV_PYTHON_DOWNLOADS=never, and a plain3.14request still took the GIL build.
2026-10-06 — cargo-audit, cargo-deny and cargo-tarpaulin ship in :latest (CON65)#
Every OxidANT run built them from crates.io.
cargo_security_checks.shandcargo_coverage.shrancargo installfor all three on every run; no image carried them.The package stage installs them now, on amd64 and arm64.
install_cargo_qa_toolsdownloads each upstream release binary and verifies it against a newCARGO_*_LINUX_{X86_64,AARCH64}_SHA256pin; cargo-audit’s aarch64 build is a glibc one. A missing pin or a failed download stops the stage. riscv64 ships none: no upstream binary, and its lanes cross-build on amd64.The smoke gate checks them. A
cargo-qa-toolsconsumer-contract row compares each binary’s reported version with its pin, exempt on riscv64 and re-checked by its own fact.The scripts skip a tool the image already has.
cargo_install_pinnedin_cargo_wrapper.shbuilds one only when the pinned version is not onPATH. A plaincargo installwould fail on a binary cargo did not install, so consumers need this hub commit before the image publishes.Renovate no longer auto-applies their bumps: each version now moves with two SHA pins.
docs/image-decisions.mdrecords why CON20’s “stay lane-installed” no longer holds.
2026-10-06 — The WebRTC loopback no longer fails a run whose frames arrived (CON68 closes)#
What the failures were. Classified across 25 loopbacks under load, every failure looked the same:
the consumer reached EOS after 2.15 s, the same as the passing runs, so its 60 frames at 30/s had arrived;
its only error was webrtcsrc’s own signaller in teardown,
send failed because receiver is gonefromimp.rs:1736;gst-launch then exited 1.
How often. 1 run in 30 idle and 5 in 25 under load. The race is upstream, in gst-plugins-rs, not in the image’s WebRTC.
Two fixes were measured first and dropped.
Waiting for the producer’s registration did not help: it is listed 28 ms after the port listens.
One retry still failed 3 times in 30 under load.
Get-GstLoopbackTeardownErrorpasses a consumer that exits 1 only when all of these hold:it reached EOS;
its frames flowed for at least
Frames/30s;every element error is
webrtcsrc0’s, and the signaller’s is that teardown message.
The smoke test prints such a pass as a
[WARN], so the rate stays visible.Tests. Five harness tests, built from a real failing run’s logs, cover the pass and the four ways it must still fail. 25 loopbacks under load had no failures, and 6 of them passed with the error named.
2026-10-06 — The Vulkan validation layer in C:\runtime\vulkan-layers (CON64)#
arm64 had no layer to stage. The image’s Vulkan SDK 1.4.357.0 ships
VkLayer_khronos_validationas x64 only (Bin-ARM64lacks it), and LunarG’s ARM64 SDK installer is an ARM64 executable the amd64 container cannot run. BeschleunigerBallett’s Windows arm64 GPU suites therefore ran unvalidated.The merge stage now stages it on both arches.
Build-VulkanValidationLayers.ps1copies the SDK’s layer on amd64 and, on arm64, builds Khronos Vulkan-ValidationLayers atvulkan-sdk-<VULKAN_VERSION>with the dependency commits itsknown_good.jsonpins.Build.VulkanValidationLayers.Tests.ps1covers the dependency plan and the manifest check.The device gate loads it.
Test-Arm64Bundle.ps1forces the layer into avulkaninfoinstance when the bundle carries it; an older bundle is named and not counted, so the floor stays 12 until:winarm64is republished. The bundle README says how to register it.
2026-10-06 — WiX’s firewall extension ships in :winamd64’s final stage#
Consumers’ MSIs can declare
fw:FirewallExceptionnow.windows/Dockerfilerunswix extension add --global WixToolset.Firewall.wixext/$WIX_FIREWALL_EXT_VERSION.The pin is new in
versions.env(7.0.0).Renovate’s WiX 7 lock and
bump_versions.py’s same-major rule cover it, like the UI extension.
It lands in the final stage, not in base beside the UI extension. A change to base rebuilds the whole chain; the final stage rebuilds in minutes, as it did for the Vulkan loader (CON25).
Build-Buildkit.ps1passes the pin with the final stage’s other args.The smoke gate asserts it in section 4 (
WiX firewall extension).A process-isolated container has no Windows Firewall.
MpsSvcandBFEare disabled in the image, so an exception installs there only withIgnoreFailure='yes'. OmniAccelerANT’s cat cam MSI carries one, LAN-only and bound to its exe, and its install test passed 14 of 14 in the image with it.Published the same day as
sha256:ea8c3c6e, withBuild-Buildkit.ps1 -Stages final -PushRef …. Only the final stage was rebuilt, and the push took 5 s. The first attempt’s smoke gate stopped on one WebRTC loopback failure, filed as CON68. The retry’s gate had no failures.
2026-10-06 — :winamd64 republished: WebRTC works, Rust is pinned, ripgrep ships (CON60 closes)#
What the image is. A local BuildKit chain from hub f4c0e2be, on a host whose Stevedore had first been repaired (Phase R: the patched runhcs shim, buildkitd’s step-log env and
--config, containerd’s teardown variable). It was pushed withBuild-Buildkit.ps1 -PushRef ghcr.io/kataglyphis/kataglyphis_beschleuniger:winamd64: manifestsha256:5dbc0291, replacing 2026-10-04’ssha256:65c0dc1f. OmniAccelerANT’s Windows lane passed all 26 steps on it before the push finished.What its smoke gate passed: 229 assertions, 1 skipped.
The WebRTC loopback (
webrtcsink -> webrtcsrcdecoding 60 frames over DTLS-SRTP).The lavapipe checks.
Rust at RUST_VERSIONandflutter_rust_bridge_codegen at FLUTTER_RUST_BRIDGE_VERSION.
In its GStreamer:
all 13 contract plugins;
rswebrtcandrsrtp;libffi type exports OK;the DTLS fix 17d22abe89.
CON60 closes: a published
:winamd64passes the Rust-pin asserts.CON56 is half done: the image answers
ripgrep 15.2.0, but the published Linux:latestdoes not yet.OmniAccelerANT’s cat cam builds and installs on this image. Its MSI passed 13 of 13 install checks in it, including a
webrtcsrcviewer decoding 60 frames.
2026-10-06 — Invoke-ClangTidyFixStep’s parallel default is bounded by memory#
The core count alone ran out of memory. BeschleunigerBallett’s Windows x64 lane, with the module skip lifted, ran four clang-tidy processes on a 4-vCPU, 16 GB runner, and
App.cppdied withLLVM ERROR: out of memory(run 37466488394).Measured per file, peak working set in the
:winamd64container: module TUs up to 10.4 GB (VulkanRenderer.cpp), 9.6 (App.cpp), 7.1 (DeferredRasterizer.cpp). The non-module TUs stay at 0.2-1.4 GB, apart from one at 5.3.-ThrottleLimit0 (the default) now means the core count capped at one process per 6 GB of RAM: two on a 16 GB runner, ten on a 61 GB, 32-core host. An explicit value still wins.
2026-10-06 — Invoke-ClangTidyFixStep tidies in parallel, and module TUs on request#
One process per file,
-ThrottleLimitat a time (default: the core count). Each file’s output is logged whole and in file order, and the step names every file that failed, not just the first.-Fixstays serial: two files’ fixes can rewrite the same header.Module TUs are tidyable. The image’s clang-tidy reads the build’s BMIs (CON10), so a consumer passing
-ModuleImportPattern '(?!)'tidies itsimporting TUs too; the default still skips them. Measured 2026-10-06 in BeschleunigerBallett’s clang-cl Debug container build: its 32 module TUs all exit 0 (797 s one at a time), and the step over all 43SrcTUs takes 112 s on 32 cores.WindowsClang.Common.Tests.ps1covers both paths with a fake clang-tidy.
2026-10-06 — riscv64_cross_env stops overriding the Vulkan variables (CON48)#
The image no longer needs it. The entrypoint used to leave
VULKAN_SDKandVK_ADD_LAYER_PATHon/opt/vulkan/<version>/x86_64, which a riscv64 process under QEMU cannot use, soriscv64_cross_envre-pointed both at/opt/vulkan/active.Checked in the
:latestof 2026-10-03, amd64. After the entrypoint,VULKAN_SDK,VK_ADD_LAYER_PATH,PATH,LD_LIBRARY_PATHandPKG_CONFIG_PATHall name/opt/vulkan/active. The twoexports are gone. On an older image the riscv64 lane fails asdocs/riscv64-cross-test-lanes.mddescribes.
2026-10-06 — the Windows merge stage’s lavapipe step reads the version it logs#
Install-Lavapipe.ps1threw on its own log line. cc1846c2 moved the pins into$pinValues, andWrite-Host "Downloading the Vulkan loader ${vulkanVersion}: …"kept the old local, which strict mode turns into “The variable ‘$vulkanVersion’ cannot be retrieved because it has not been set”.The first chain to reach the step, a local
:winamd64rebuild on 2026-10-06, stopped there.That was after the media merge’s GStreamer had passed every WebRTC check.
Three other strings printed the hashtable.
"lavapipe $pinValues.MesaVersion"expands$pinValuesand keeps.MesaVersionliterally, so the log readSystem.Collections.Hashtable.MesaVersion. All four now use$(…).A regression test.
Lavapipe.Install.Tests.ps1parses the script and fails when it reads a variable that is neither a parameter, assigned, a loop variable nor automatic. It fails on the old script, namingvulkanVersion.
2026-10-06 — Install-NewHost.ps1 redeploys a shim an update replaced#
The record no longer stands in for the patch.
Invoke-StepShimskipped wheneverC:\ProgramData\kataglyphis\shim-patch.jsonexisted. A Stevedore/containerd update overwrites the shim and leaves that file, so a host repaired with Install-NewHost stayed on the stock shim, the oneAssert-ShimPatchrefuses. The skip now needs the live shim’s SHA256 to equal the record’s (Test-RecordedShimLive). A mismatch is logged and redeployed.Seen on 2026-10-06. Stevedore’s 2026-09-21 update had wiped four things on this host:
the patched shim, replaced by the stock one at 25 975 296 B;
buildkitd’s step-log environment;
buildkitd’s
--config;containerd’s teardown variable.
Tests:
NewHost.ShimRecord.Tests.ps1, 4 cases: a match, a shim the update replaced, a lowercase hash, and a missing, unreadable or hash-less record.
2026-10-06 — package_archive.sh builds the deb, AppImage and flatpak it always claimed#
One release binary, four formats.
06-packaging/package_archive.shwrote the tar and stopped:create_deb()went on 2026-08-08, and--flatpak-manifest,--desktop-fileand--appdata-filewere checked and never read. Two docs pages still listed “tar/deb/AppImage/Flatpak”. It now stages the binary as a bundle and hands it to the bundle packagers the Flutter lanes use, by--package-types.app-packaging.shtakes the bundle from its caller. Seven knobs carry it:APP_PACKAGING_BUNDLE_DIR,_VERSION,_DESKTOP_FILE,_ICON_FILE,_OUT_DIR,_DEB_DEPENDSand_APP_ID. Each keeps the Flutter default when unset.The project’s desktop entry is used with
Exec/Iconset per format (app_packaging_adapt_desktop_file).An icon goes in the hicolor directory of its real size, read from the PNG header (
app_packaging_icon_size); a non-PNG falls back to the old512x512.The flatpak copies
lib/anddata/only when they exist.
Errors where it used to be silent: an unknown package type stops the run before anything is built;
--flatpak-manifestand--appdata-filesay they were removed (the manifest is generated); the three bundle formats need--arch. Their two env rows leftlint-env-knobs.allow.Proof:
test-package-archive.sh(stubbed packagers, plus one real deb through the real library) and ninepackaging.*mutations. In:latest, OxidANT’s release CLI gave all four, and each ran: the deb’s binary, the AppImage, and the flatpak viaflatpak run --command=oxidantwith its desktop entry and 128×128 icon exported. OmniAccelerANT’s Flutter packages are unchanged: its icon is a real 512×512.
2026-10-06 — a crashed staged test names its exit code#
Invoke-StagedTests.ps1: a binary that dies before its summary used to stop the run with “no libtest ‘test result:’ line” and nothing else. OxidANT’s arm64 WARP crash (run 36889467167) left onlyrunning 39 tests. The error now carries the exit code with its NTSTATUS name, e.g.exit -1073741819 (0xC0000005 STATUS_ACCESS_VIOLATION). It adds the faulting module, offset and exception code when Windows Error Reporting logged an event 1000 for that binary since it started. That is best effort, and read from the event’s data, not its message, which is localized. Each binary’s-> passed …line names its exit code the same way. One new case inStagedTests.Tests.ps1proves both halves.CON50’s OmniAccelerANT row: Chrome is closed (814da16, both Dart suites in Chrome since 2026-10-05). The APK on an emulator is what stays open.
2026-10-06 — Windows-host follow-ups: the mutation gate skips too; the suites pass in the image#
verify_mutations.pyon a Git Bash host:A test that exits 77 is a
skip, reported with itsSKIPline. It used to read as a vacuous bite, so a Windows pre-push went red for the host, not the code.A survivor is a
skiptoo, neverSURVIVED, when its suite skipped or waived a case on this host: the case that would catch it may never have run. The commit hook showed the need; fourmutations.*entries survived there in_posix_hostcases.The closing line then counts the skips.
On Linux nothing changes: exit 77 is a vacuous bite, and nothing is waived.
test-mutation-gate.shproves both sides by running the gate as itself and withsys.platformset tomsys. Four mutations cover it.
run-tests.shlists its skips before the verdict, so a red Git Bash run still says what it never ran.Eight suites failed inside
:lateston a green tree. Each test assumed a bare CI runner. They pass in the image now:compiler-cache-launcher,media-jobs,vulkan-host-sdk-pruneandpython-ci-packaging-armrun copies of their scripts. The copies now point/opt/scriptsat a path that does not exist; the image’s real copy used to win over the fixture.compiler-cachedrops every directory holding ansccachefromPATHfor its “absent” fixture.cuda-runtime-payloadunsetsPYTORCH_ROCM_INDEX, which the image exports.smoke-arch-parityruns its stubbed pythons with-S. The image’s venv has onnxruntime, and its site-packages start-up imports collided with the stubs.verify-runtime-paths.shwas vacuous whereverenvsubstwas missing, the image included. Both lists it compares came out empty, so it passed having checked nothing. A bash_envsubstnow does the same expansion (${NAME}and$NAME, exported variables only, byte-identical on every form tried). A test with a brokenenvsubstfirst onPATHholds it, andruntime-paths.needs-no-envsubstproves that test can fail.
New-PythonAppPackage.ps1finds wix throughResolve-WixExe($env:WIX, thenPATH) instead of a barewix.
2026-10-05 — WebRTC works on Windows: libffi, DTLS and the Rust plugins#
libffi exported zeroed type descriptors on both Windows lanes. Its meson port declares the twelve
ffi_type_*as baredllexporttentative definitions, which clang-cl’s-fno-commonturned into six strong definitions each;/FORCE:MULTIPLEhid the 60 duplicate-symbol errors and lld-link keptprep_cif.c.obj’s zeros. Every GObject signal with arguments then skipped its C handler, sowebrtcbinnever answeredcreate-offer.-fcommonjoins the C arguments (and the cross lane’s native file),/FORCE:MULTIPLEis gone, andAssert-LibffiTypeExport(WindowsMeson.Common.psm1) reads the shippedffi-7.dllbefore the plugin gate.DTLS with OpenSSL 4.
Build-GstreamerFromSource.ps1carries upstream GStreamer 17d22abe89 (an empty BIO read signals retry, not EOF) untilGSTREAMER_VERSIONmoves past 1.29.2, and fails when the hunk neither applies nor is upstream. The OpenSSL DLLs gstdtls imports are staged into<prefix>\binon amd64 too.gst-plugins-rs
rswebrtcandrsrtpare built in a new phase8b, as on Linux:gstreamer-$GSTREAMER_VERSION, plaincargo build --release --locked(Get-GstRustCargoPlan),--target aarch64-pc-windows-msvcon the cross lane. gstreamer-rs is fetched from its GitHub mirror through a cargo source replacement (Get-GstRustSourceMirrorConfig,--config): gitlab.freedesktop.org served it at 10-15 KiB/s, and a run stopped after 20 minutes was still cloning.The plugin contract has thirteen entries (CON28):
dtls,srtp,sctp,rtpmanager,openh264,rswebrtc,rsrtpjoined, on both lanes. The gate finds each DLL by its exact name, and smoke section 11 ends with a WebRTC loopback (Invoke-GstWebRtcLoopback, 60 decoded frames over DTLS-SRTP).Smoke floors move by the eight new assertions: section 11 to 20, the driver’s defaults to 178 (CPU) and 198 (GPU), inside
Smoke.FloorCalibration.Tests.ps1’s bounds.meson is pinned to
PY_MESON_VERSION.pip install mesonfloated to 1.12.1 under build-subproject patches written against 1.12.0.Docs:
windows-builds.md(§ libffi’s type exports, § DTLS with OpenSSL 4, § gst-plugins-rs on Windows),windows-cross-builds.md,failure-modes.md,image-decisions.md(CON28),windows-build-invariants.md,windows-host-setup.md,overview.md, the licence list.Tests:
SourceBuild.GstreamerWebRtc.Tests.ps1(20 cases, synthetic PEs for the libffi guard) and the contract suite at thirteen entries.code-dupes.allowfollows the measurement: 15 new idiom pairs, 20 budgets lowered, 2 stale rows gone.Measured on amd64 in a
:winamd64container: no lld-link diagnostic in the whole build,ffi_callreturns 42 where the old DLL’sffi_prep_ciffailed, all thirteen plugins load, and the loopback decodes 60 frames in 2.1 s. arm64 is unproven (CON63).
2026-10-05 — an MSI function and the helper list; CON55 closes#
Invoke-MsiPackageinWindowsMsix.Commonbuilds one MSI from a project’s own.wxswithwix build. Every moving value is a preprocessor variable:Version,ExeSource,LicenseRtf,ProductName,Manufacturer, plusPayloadFiles=1with a generated fragment. It names a missing input before it runs anything, and fails when wix reports success without writing the file. Two helpers come with it:Resolve-WixExelooks at-OverridePath, then$env:WIX, thenPATH.New-WixPayloadFragmentwrites one component per file, inPayloadFilesunderAPPLICATIONFOLDER, with aSubdirectoryonly where one is given.
Invoke-MsixPackageandInvoke-MsiPackageshare one private runner,Invoke-PackagerTool: clear the output, run the tool, fail when no file appears.Resolve-WixExereads$env:WIXand hands the rest toResolve-WindowsSdkToolPath.New-PythonAppPackage.ps1renames its script-localInvoke-MsiPackagetoInvoke-MsiAppPackage, besideInvoke-MsixAppPackage, so it no longer shadows the module function of the same name.Proof: eight Pester cases in
WindowsMsix.Common.Tests.ps1. A real WiX 7 build in:winamd64of OxidANT’smain.wxsgave a 172 KB MSI.msiexec /aunpacked it witha&b.dllbeside the exe and a plugin underlib\gstreamer-1.0\.“Reach for these before writing a helper”, in
adopting-in-a-new-project.md§ 8: the table of hub functions each consumer once rewrote, moved from OxidANT’sAGENTS.md. All 22 were checked against their modules’ exports. One row was wrong:ConvertTo-XmlEscapedTextis internal, and the exported name isConvertTo-XmlSafeText.docs/INDEX.mdpoints at the list, and § 7 says when to callInvoke-MsiPackage.OxidANT turns both into deletions and moves its pin, which closes CON55.
2026-10-05 — the script suites skip on a Windows host, loudly (CON61)#
t_skip_unless <what> <cmd…>: a suite that needs what Git Bash lacks exits 77 there withSKIP [suite] this host lacks <what>.run-tests.shlists it as skipped and leaves it out of the suite count. On Linux the same line fails the suite, and so does a stray exit 77, so CI cannot shrink without a red line.t_needs <what> <cmd…>sits right after at_case: on Git Bash it waives that one case’s failures, andt_summaryprints how many it waived. 24 suites use it, so the cases the host can run still run.Probes:
t_posix_symlinks,t_posix_modes,t_posix_python,t_is_elf.Guards: 39 suites failed on a Git Bash host on a green tree. Eleven skip whole, through five guards:
jq:test-agentic-loop.shandtest-prune-safe.sh. The latter skipped by hand before, and then failed for running zero assertions.Real symlinks: the seven
test-renovate-*, throughrenovate-fixtures.sh.A POSIX venv:
test-chain-wheels-installed.sh.shellcheck:test-shellcheck-warnings.sh.
Fixed instead of skipped:
verify_package_names.pyandverify_stdout_returns.pyprintedlinux\scripts\…on Windows. The first also never matched its CPython table there.test-shared-config-sync.shcounts its CRs; Git Bash’s grep strips them first.test-harness-guards.shprobes the harness file, not/etc/passwd.
On Git Bash,
run-tests.shdefaultsPYTHONUTF8=1. Without it, Windows’ python wrote its code page into the pipe, and every em dash a suite compared turned to�.Proof:
test-host-skips.sh(26 assertions) and eight mutations (gate-fixture.*,script-tests.skip-only-on-git-bash).
2026-10-05 — host-tool pins leave the image’s build inputs (CON59)#
01-core/tool-pins.envnow holds the 30 pins no image build reads: shellcheck, gitleaks, hadolint, actionlint, mold, binaryen, ruff, syft, Renovate’s Node and CLI.Dockerfile.basebind-mountsversions.env, so any edit to it re-keyed the compiler image, and a hadolint bump cost as much as a GCC bump. A bump here rebuilds nothing.Readers:
lint-shell,lint-secrets,lint-dockerfiles,lint-workflows,lint-python,lib/wasm-opt.sh,lib/linker-select.shandWindowsWasmOpt.Commonnow readtool-pins.env.scan-image-sbom.shreads both files: the image tag stays inversions.env.renovate-local.shparsestool-pins.env; it used tosourceversions.env.
Bookkeeping reads both files:
Renovate’s two package rules and both custom managers.
bump_versions.py, which writes each key back to the file that holds it.sync_versions.py’s pin table, which the consumer-pins check uses.The env-knob gate counts
tool-pins.envas an owner.
Tests:
test-renovate-annotations.shreads both files and asserts that every custom manager matches both;test-env-knobs.shgains atool-pins.envowner case; eight suites read or fake their pin in the new file. Six mutations re-pointed, one added.
2026-10-05 — Windows Rust pinned; five of OxidANT’s waiting rows land (CON60, CON55)#
Windows Rust is pinned to
RUST_VERSION(owner decision).Install-RustToolchain.ps1mirrorschannel-rust-<RUST_VERSION>.tomlinstead ofchannel-rust-stable.toml, and bakesflutter_rust_bridge_codegenatFLUTTER_RUST_BRIDGE_VERSIONinstead of the newest release.Dockerfile.basedeclares bothARGs above the Rust layer, andTest-Container.ps1asserts the values rather than a well-formed version. Ran in a throwaway:winamd64container:1.98.1-x86_64-pc-windows-msvc, codegen 2.13.0._cargo_wrapper.shadds thesafe.directoryguard (CARGO_SAFE_DIRECTORY, default/workspace, empty opts out, never added twice). Everycargo_*.shdriver now sources the wrapper, so release, doc, coverage, security and fmt/clippy also get the CARGO_HOME and toolchain guards.test-cargo-wrapper.sh: 12 assertions, three mutations.Get-ANTfrastructurePinmoves toWindowsScripts.Shared.psm1, with a-VersionsEnvPathfor tests, andwindows/scripts/rust/Build-Windows.ps1is deleted (owner decision: no consumer; OxidANT owns its Windows Rust build).The MSIX trust steps (
Rootas well asTrustedPeople,0x800B0109,Get-AppxLog) move intowindows/scripts/certificates/README.md.docs/adopting-in-a-new-project.md§ 8 namesscripts/windows/container/.
2026-10-05 — the push gate counts from develop; lint tools install in one rename#
pre-push grades the mutations a push actually adds. git hands the hook each pushed ref’s remote tip, which becomes
verify_mutations.py --changed --base <tip>.origin/mainstays the fallback for a new remote ref or an unfetched tip. Counting fromorigin/main, which lagsdevelopby hundreds of entries, ran every hub push for 25 minutes and more, and ended it in--no-verify.download_verified_install(01-core/downloads.sh) downloads, verifies and unpacks in a stage beside the destination, then moves the binary into place in one rename. shellcheck, gitleaks, hadolint and actionlint use it. They used to write straight into the shared cache, where a parallel mutation job could run half a gitleaks: a clean scan failed in hub CI run 37329252097.gitleaks runs on a Windows host.
lint-secrets.shchose its asset byuname -malone, so Git Bash fetched the Linux binary and every consumer’s lint gates died withExec format error. AGITLEAKS_WINDOWS_X64_SHA256pin (GitHub’s digest, matching the release checksums) and an OS check now installgitleaks.exe.The image adds
aarch64-linux-androidto the pinned Rust toolchain (install-rust.sh), andsmoke-toolchain.shchecks it (CON58). OmniAccelerANT’s Cargokit builds with that toolchain now, and its Android lane was adding the target on every run.Backlog: CON59 (tool pins out of the base closure), CON60 (Windows Rust pin, the owner’s call), CON61 (host-only suite skips), CON62 (WSL containers, blocked upstream).
Tests: three new cases in
test-prepush-hook.sh, one intest-mutation-gate.sh, andtest-download-verified-install.sh(15 assertions). Seven mutations, each caught.
2026-10-05 — an opt-in linker: KATAGLYPHIS_LINKER=lld|mold#
lib/linker-select.sh:linker_select_envappends-fuse-ld=<x>toLDFLAGS(plus clang’s LLVMgold.so for mold) and links the host Rust target through$CCwith the same linker. Unset changes nothing.cmake_build_prepare_envand the cargo test/bench/debug wrappers call it.Fails, never falls back: 2 on an unknown value, 1 on a set
RUSTFLAGS, a failing probe link or an unobtainable mold. mold comes from PATH, else the pinned, SHA-checked 3.0.0 release (MOLD_LINUX_*inversions.env, noforward).Measured first: lld matches or beats mold on every family build, and mold 2.x cannot link AccelerANTgine. The table and the reasons are in
docs/shared-script-libraries.md§ linker-select.sh. CON57 holds baking mold into the image.test-linker-select.sh: 22 assertions, and nine mutations that each red it.WSL 3’s
wslcwas evaluated beside it, against Rancher Desktop. It has faster bind mounts and a fixed credential pull. It has no--privileged,--platformor--device, so no lane moves (docs/rancher-desktop-linux-containers.md§ WSL containers).
2026-10-05 — ripgrep is the family’s search tool#
Owner rule: search with
rg, notgrep -rorfindstr, in every repo of the family (AGENTS.md§ Searching the tree: ripgrep (rg)); the consumer template links it.The images get it with their next chain (CON56):
ripgrepinsetup-package-image.shwithrgin its presence check,main/ripgrepamong the floating scoop tools.
2026-10-05 — Windows CodeQL results honour the config’s paths-ignore#
database analyzeappliedpaths-ignoreto traced C++ not at all: OmniAccelerANT’s first complete scan reported 39 of its 63 cpp results, all four high-severity ones among them, from the ignoredthird_party/AccelerANTgine/third_party.Invoke-BuildCodeQLnow drops results under the config’spaths-ignorefrom each SARIF after the analysis and logs the count (Remove-SarifIgnoredResult). On that scan’s SARIF it drops exactly those 39.CodeQL’s path semantics: a plain path covers its subtree,
*one segment,**any depth. No unfiltered copy is kept, since an uploader that globs*.sarifwould send both.CodeQL.SarifFilter.Tests.ps1: four tests; a prefix match without the/, a lost**and a filter that is not written back each red one.
2026-10-05 — the Dart gate can test in Chrome#
flutter_checks.sh --test-platform chromerunsflutter test --platform chromewhere the image setsCHROME_EXECUTABLE, and the VM where it does not (riscv64), so a lane never passes on zero tests. The default staysvm; an unknown platform is refused.test-flutter-checks-platform.shdrives the gate with stubflutter/dartover a tracked fixture: four cases, and dropping either branch reds one of them.OmniAccelerANT’s web lane is the first caller (
docs/consumer-image-contract.md§ Browser tests run in Chrome for Testing).
2026-10-05 — a CodeQL-traced Windows build runs without sccache#
Invoke-BuildCodeQL’sdatabase createhung for hours at near-zero CPU. The image’s sccache server never exits (SCCACHE_IDLE_TIMEOUT=0), and one started under the CodeQL tracer keeps its client’s output pipe, so the Rust extractor’scargo metadatawaited forever. Killing the server freed one call, and the next started a new server and blocked again (OmniAccelerANT).Disable-SccacheForTraceclearsRUSTC_WRAPPER,CC_WRAPPER,CXX_WRAPPERand both CMake launcher variables and setsKATAGLYPHIS_NO_SCCACHE=1beforedatabase create.Initialize-BuildCacheEnvironmentleaves the launchers off under the marker, andGet-SccacheStatsTextreturns nothing, since asking for stats starts a server. A cache hit would also have hidden the compile from the extractor.CodeQL.SccacheOff.Tests.ps1, four tests; removing each guard reds its own test.Proven on OmniAccelerANT’s scoped scan on the 2026-10-04
:winamd64: from a cold tree,database createand both analyses finished in 27 min (63 cpp and 10 rust results), with no sccache process left.docs/failure-modes.md§ CodeQLdatabase createhangs for hours at near-zero CPU.
2026-10-04 — the riscv64 cross wheel builds through pip, not uv#
ci_packaging.sh’s cross mode no longer exports_PYTHON_HOST_PLATFORM: uv reads it while inspecting the interpreter and refusesUnknown operating system: linux_riscv64at bothuv venvanduv build, which killed OrchestrANT’s packaging step one second in. The target tag travels asPYTHON_HOST_PLATFORM_TARGETand is set only on the wheel’spython -m pip wheelcommand; the sdist stays onuv build --sdist.The arm suite pins both halves: the wheel commands carry the tag, uv’s environment never does.
2026-10-04 — lavapipe ships in the Windows image and the arm64 bundle#
Install-Lavapipe.ps1stages Mesa’s lavapipe (mmozeiko/build-mesa, SHA256-pinned; the only arm64 Windows build) and LunarG’s Runtime Components loader for the target arch intoC:\runtime\lavapipe, registers the ICD in HKLM on amd64 (the loader ignoresVK_DRIVER_FILESin an elevated process) and verifies the PE machines.The media merge stage runs it before the bundle manifest, so
BUNDLE-ENV/READMEname the ICD andLP_NATIVE_VECTOR_WIDTH=256(Mesa 26.2’s BVH sort needs 8-lane subgroups, CON44); the image smoke runsvulkaninfo --summaryand fails without llvmpipe, andTest-Arm64Bundle.ps1gains the device step (floor 11 to 12).:winamd64was republished on 2026-10-04 (digest65c0dc1f): the smoke’svulkaninfo --summarylists the llvmpipe device and the lavapipe step passes; the:winarm64bundle is published and its device gate passed 12/12 on the Snapdragon X.
2026-10-04 — a root directory survives the tar-pipe exclude#
Invoke-ContainerBuildgains-InboundItems(default.): the top-level entries to stream.--excludematches at every depth, so a pattern naming a root directory (build) also droppedthird_party/ANTinfrastructure/windows/scripts/build, and no pattern form anchors; a caller omits the root directory from the item list instead.The module’s contract suite pins the parameter and its forwarding; the performance page records the matching rule.
2026-10-03 — the riscv64 wheel is cross-built on the native row#
ci_packaging.shgains cross mode (PACKAGING_CROSS_TARGET=riscv64): the wheel is built on the amd64 row under the five setuptools knobs (CC/LDSHARED= the riscv64 cross wrapper,CFLAGSwith the staged target Python’s include dir,SETUPTOOLS_EXT_SUFFIX,_PYTHON_HOST_PLATFORM), and the app-package skip now follows the target, not the host’suname -m.python-ci-linux.yml’s riscv64 row builds the sysroot (sysroot: true) and runs the packaging step onlinux/amd64with it mounted; the test step stays on the emulated riscv64 image. The emulated compile hung four hours on one Cython unit (run 37127505865) and could not fit the 360-minute job.
2026-10-03 — a cross lane gates the arm64 bundle on a device per push#
container-ci-windows.ymlgainsbundle-artifact-name: the build job packs the image’s own runtime bundle (windows/scripts/build/Export-Arm64Bundle.ps1, ~290 MB zipped) besideTest-Arm64Bundle.ps1, and awindows-11-armjob extracts the zip and runs the gate. The bundle’s device half was a manual run until now; the floor stays the gate’s own default, so a device that ran nothing cannot look green.The bundle travels as
C:\runtime(~0.63 GB, 9k files), not the 15 GB image: the export runs in the same container the build already pulled.
2026-10-03 — the clang-cl ASan runtime follows the target arch#
cmake/Sanitizers.cmakepicks the ASan link dir and lib names fromCMAKE_SYSTEM_PROCESSOR: MSVC keeps x64 inlib/x64with-x86_64libs and arm64 inlib/arm64with-aarch64, so an arm64 cross build links Microsoft’s runtime instead of LLVM’s, whose aarch64 runtime the image does not carry. Native x64 configures unchanged.Copy-Arm64VsRuntime.ps1gains-Flat: stage beside a staged test tree’s exes instead of itsbin\, which an arm64 ASan suite needs on the runner.
2026-10-03 — the arm64 bundle carries the VS runtimes its payloads link#
Copy-Arm64VsRuntime.ps1(wasCopy-Arm64AsanRuntime.ps1) also stages the aarch64vcomp140.dllfrom the VS redist: the cp313 torch stack’storch_cpu.dllimports the MSVC OpenMP runtime, and the arch gate wants a CRT inside the bundle on a cross lane.Test-TargetArch.ps1countspython313.dllas an external: the cp313 wheels target a device-provided 3.13 interpreter, which the bundle does not ship.The device gate checks both runtimes; a suite case pins the allowance.
2026-10-03 — compound extras markers stop reaching pip in the arm64 bundle#
Copy-TargetPythonDeps.ps1dropped only extras whose marker began right after the;; setuptools declares them compounded ((python_version < '3.14') and extra == 'test-full'), so the first arm64 rebuild with the torch stack sent marker’d requirements topip download, where cmd.exe stripped their double quotes and pip rejected the marker. The filter now looks anywhere in the marker, and surviving markers go out single-quoted.
2026-10-03 — the emulated riscv64 packaging leg stops syncing all extras#
ci_packaging.shhonours the lane’sSYNC_EXTRASinput (mapped toUV_SYNC_EXTRAS), and the riscv64 row’s test and packaging steps shareUV_CACHE_DIR=/workspace/.uv-cache. Without both, the first OrchestrANT packaging run resolved 306 packages (all extras, opencv-python and torchvision from git among them) and was killed at the 300-minute budget.The riscv64 row’s ceiling moves 300 -> 360: it covers a cold cache, where the packaging leg re-pays the test leg’s measured 151-minute source builds beside its 169-minute test leg.
2026-10-03 — the Ansible fleet-update lane goes live#
The cat cam joined as the third Pi:
tabblscatcam(Raspberry Pi 5, Debian 13) — found via mDNS, bootstrapped viasetup-fleet-host.sh tabblscatcam(values from gitignored host_vars, like every host). Its FIRST run was real: apt updates applied, a pending bootloader EEPROM update staged, and the inline reboot+wait flashed it —BOOTLOADER: up to dateafter, second run idempotent. This closes the discovery question: the fleet is three Pis (pi-1, pi-2, tabblscatcam), one SpacemiT SBC and one Windows host.ping.ymllearned a second play: the builtin ping cannot run on Windows, so the lane proof splitsfleet(ping) fromwindows(win_ping) — summy-server had been failing the lane proof since it joined.The microcontroller updates are now REAL, gated, and in the Sunday run (owner directive):
update_tasmota.ymlflashes the stock plugs ONLY when the official release version differs from the installed one — the comparison is OURS, because the nativeUpgrade 1was probed live and re-flashes even at the same version; after a flash it waits for the reboot and asserts MQTT health.update-bitshake.ymljoined the weekly run behind the same kind of version gate (it flashes only when the manifest differs, with the magic-byte check and the post-flash health gate). The nerdctl toolchain stays REPORT-ONLY by design — it is build infrastructure and its upgrade is deliberately confirmed by hand. A real bug found while proving this: the nested playbook calls ran fromplaybooks/where noansible.cfglives — the inventory never resolved, every nested lane silently matched zero hosts and exited 0. The Sunday run had been green while doing nothing for the Tasmota, bitShake and Windows lanes. Fixed (run fromlinux/ansible/) and proven by fresh execution: the winget log carries the run’s timestamp.summy-server (Windows 11 ARM Pro) joined the fleet: managed over OpenSSH with
ansible_shell_type: powershell— WinRM stays closed. Three one-time traps, all encoded inscripts/setup-openssh-ansible.ps1(run once via SSH): the deploy key must go intoC:\ProgramData\ssh\administrators_authorized_keysfor an administrator account (userauthorized_keysis ignored), the ACL must be set with SIDs not account names (a German-locale Windows does not resolveAdministrators), and OpenSSH’sDefaultShellmust be PowerShell (the cmd default breaks ansible module result deserialization — symptom:No start of json char found).update-windows.ymlinstalls PSWindowsUpdate from the gallery, applies all updates with-AcceptAll -IgnoreReboot, reports what remains (Defender signature updates are perpetual — new definitions release daily), and reboots inline only when the registry says pending. Wired into the weekly run viamanage_windows_updates; a failing Windows lane is surfaced without failing the Pi lane. Also fixed in the same pass: both nested playbooks (tasmota report, windows update) had doubledplaybooks/playbooks/paths — the tasmota one was silently masked byfailed_when: false.The stock Tasmota ESP8266 plugs joined the report lane (
report-tasmota.yml, wired into the weekly run via thereport_tasmotahost_vars flag): version against the official release plus an MQTT-health assertion. That assertion exists because one plug (.128, a NOUS A1T) was found with NO broker configured — registered in HA but silently dead. Root cause + fix: itsMqttHostwas empty; set via one HTTP command, live-verified by watching itstele/…/SENSORmessages arrive on the broker. All three plugs sit on the current official release (15.6.0, 2026-08-25) and on the ungated public OTA channel — unlike the bitShake device, they can self-update, and the flash stays deliberate either way.The bitShake update is now a playbook (
update-bitshake.yml, on-demand — deliberately never scheduled): manifest fetch with the browser-gate header bypass, firmware download + magic-byte validation (the manifest sha256 is stale), upload through the device’s own forms, a version-wait with timeout, SMR app install with retry (a first refusal after a flash is transient), and a final loud gate on firmware version, meter data and MQTT. Proven idempotent against the live, already-updated device (ok=10 changed=0, plan “firmware current, SMR app installed”). The manual procedure and the traps it encodes stay owned by the Home Assistant README.playbooks/update.yml(apt safe-upgrade + autoremove per Pi, reboot only when required) runs Sundays 04:30 Berlin via a user systemd timer (systemd/, installed byplaybooks/schedule.yml, armed 2026-10-03). Proven with a real run on pi-1:ok=14 failed=0— fully current.The host’s nerdctl-full bundle was upgraded 2.3.5 → 2.4.1 (containerd v2.4.1, buildkit v0.33.1) via
install-nerdctl-full.sh --include-rootful: checksum-verified download, both containerd lanes stopped and restarted together, rollback backup in~/.cache/nerdctl-full-backup. The install warnings (“stale v0.31.2”, “user buildkit.service won’t start”) were both an orphaned pre-upgrade daemon holding the user socket — this host has no user buildkit unit (rootless containerd for HA + rootful buildkit is its topology); reaped, all services verified on the new binaries.Beyond apt, per gitignored
host_varsflags (pi-1 carries all three): the HA/glances containers update weekly (compose pull+--force-recreate— REQUIRED under nerdctl, which keeps a running container on its old image), a report-only nerdctl drift check (the upgrade stays deliberate behindNERDCTL_INSTALL_CONFIRM=1), and the ansible venv upgrades itself LAST so a broken release cannot take down the run that installs it.Bootloader EEPROM is now covered too (Pi 4/5; pi-2 is pre-Pi4 with no EEPROM): the playbook queries
rpi-eeprom-update(exit 1 = update available — wording pinned from the tool source, not guessed), stages it with-aand makes it a reboot trigger. Without this, a bootloader-only apt update could sit unflashed indefinitely: the boot-timerpi-eeprom-update.servicestages at reboot, but nothing guarantees a reboot happens. Branch logic mutation-tested (fires on rc 1, silent on rc 0 and missing register); both Pis ran green with the lane in place. The container-recreate tasks now carry an honest note: they reportchangedevery run because--force-recreate(required under nerdctl) bounces the stack by design.Two traps are encoded in the playbook rather than left for the next session: the control node reboots LAST and DELAYED (
shutdown -r +2— an inline reboot kills the running playbook mid-report, so inventory order is load-bearing, pi-1 last); and kernel staleness is compared within the running kernel’s FLAVOR — this host runsv8-16k+whilev8-rt+sorts last in/lib/modules, so a naive comparison would reboot-loop the Pi every Sunday. Debian carries no/var/run/reboot-requiredmarker by default; the marker check stays for Ubuntu-family hosts.The second fleet Pi is discovered and staged (old-gen Pi MAC, Debian 13): deploy key generated,
known_hostspinned, inventory slotpi-2. Its address and login live in gitignoredhost_vars/— no LAN topology in the repo. It awaits the owner’s one-timessh-copy-id(done 2026-10-03, both Pis then ran the update playbook green).serial: 1in the update playbook: never two Pis down at once — pi-1 carries Home Assistant.
2026-10-02 — Ansible lands on pi-1, via pip on the host#
Installed per the official installation guide: the
ansiblecommunity package 14.4.0 (core 2.21.4) into~/venvs/ansible(Python 3.13.5) — the venv + pip path the docs prescribe, which is also the only one Ubuntu 26.04’s PEP 668 externally-managed Python permits. Proven with the ping playbook:pi-1answers over the local connection. Playbooks, inventory,ansible.cfgandssh_configlive inlinux/ansible/, whose README documents the install, the upgrade path and the host facts.The first draft ran Ansible in a container next to Home Assistant; dropped by owner directive. Two findings worth keeping from that attempt: the official EE images (
ghcr.io/ansible-community/community-ee-*) are amd64-only, so they were never an option on this aarch64 Pi; andnerdctl compose runhardcodes--tty, which dies with “provided file is not a console” outside an interactive shell.
2026-10-03 - the arm64 bundle gets its device gate, and passes it#
New
windows/scripts/build/Test-Arm64Bundle.ps1: runs the shipped bundle’s tools and Python on an arm64 device (HailoRT, a GStreamer pipeline, IREE, the offline wheel install, the ORT providers, cv2), every step exit-code-checked, with a passing floor so a device that ran nothing cannot look green.Smoke.Arm64Bundle.Tests.ps1pins the floor logic.First device run 2026-10-03 on a Snapdragon X against the published
:winarm64: nine of nine steps pass - HailoRT-CLI 5.4.0, GStreamer 1.29.2, Python 3.14.7 with numpy 2.5.3, onnxruntime 1.30.0 (DirectML + CPU) and cv2 5.0.0. CON30’s “loads only” no longer holds.The arm64 CUDA payload gains nvrtc and cupti (13.4.92, SHA-pinned from the redist) for consumers that compile kernels at run time or profile; nvtx is header-only on windows-arm64. Forwarded in Build-Buildkit.ps1, ARGs in Dockerfile.nvidia, and the staging script asserts both.
The arm64 bundle ships Microsoft’s aarch64 ASan runtime (clang_rt.asan_dynamic-aarch64.dll
the dbg twin) from VS 2026’s toolset: staged in the merge stage, machine-checked by the arch gate, asserted by Test-Arm64Bundle.ps1 on the device. The smoke probe still skips on the x64 host, now for the real reason - it must execute an aarch64 exe.
The arm64 bundle’s wheel store gains the cp313 win-arm64 torch stack (torch 2.14.0+cpu, torchvision 0.29.1a0+cpu, pillow, MarkupSafe and the pure-python first-touch deps), SHA-pinned from pytorch.org/PyPI. Upstream builds no cp314 win-arm64 wheel (stable, test and nightly checked), so the bundle’s own 3.14 interpreter cannot install them - they serve a device that brings its own cp313 interpreter.
2026-10-02 - the Python lane grows a riscv64 row: the riscv64 image under QEMU#
python-ci-linux.ymltakesarches: riscv64: the row registers QEMU’s binfmt handler (setup-riscv64-crosswithsysroot: false), runs the riscv64 image under QEMU on an amd64 runner, and tests only - static analysis, packaging and the docs build stayx64’s. The row carries its own 300-minute budget - the first packaging run hit the original 180 and was cancelled mid-way through the wheel build.New input
test-extras, backed byci_tests.sh’sSYNC_EXTRAS: every leg syncs only those extras. A riscv64 leg needs it because the full extra set builds wheels from source under emulation.Artifacts are named per arch (
test-reports-<arch>,packages-linux-<arch>-...), so the riscv64 row cannot collide withx64’s uploads.Follow-up (owner request same day): packaging on the row is opt-in through
package-emulated. A Cythonized app’s wheel is arch-specific - without it the riscv64 wheel existed for no arch but this one. The wheels build under QEMU with the row; the app packages of apackaging/app.jsonapp stay amd64-arm64 (ci_packaging.shwarns there: the image’s AppImage tooling has no riscv64 build). Consumer: OrchestrANT’slinux-riscv64.yml, renamedLinux riscv64 · build + test.
2026-10-02 - CON34: the HIP/ overlay installs with TheRock, and MIGraphX drops its copy#
Dockerfile.rocmnow installswindows/scripts/hip/with TheRock: the headers intoC:\runtime\opt\hip-msvc-cmath, both*.cfgbeside TheRock’sclang.exe- instead of the end ofDockerfile.rocm-llama. The move re-keys the rocm chain, which the next rebuild pays anyway.MIGraphX no longer passes its own
-isystemoverlay:Write-HipMsvcCmathOverlay,Get-MigraphxCmakeArgs -HipMathOverlayand the parity test are gone. The next rocm build proves MIGraphX compiles with the configs active (never measured before).
2026-10-02 - CON31’s :winamd64-rocm record: the redistribution question is closed#
The Redistribution section of
docs/windows-rocm.mdstill said the public push “is an owner decision to take before:winamd64-rocmis pushed” - stale since the tag was published on 2026-09-28. The record now states the decision and keepsLicenseRef-Proprietary-EULAfor the runtime indocs/deps/deps.json(the id describes the licence, not the permission).
2026-10-02 - clang-tidy skips the files the build never compiled#
Invoke-ClangTidyFixStepnow reads the compile database and tidies only the files it names. An option-gated subdirectory (KATAGLYPHIS_BUILD_KOMPUTE_PLAYGROUND=OFFin BeschleunigerBallett) is not compiled, so its files have no compile command; tidy ran them with defaults and failed the step on the first include ('kompute/Algorithm.hpp' file not found, run 36979869674). Skipped files are named in the build log.Regression:
windows/scripts/tests/WindowsClang.Common.Tests.ps1.
2026-10-01 - The torch stage installs the chain wheels once, and proves them (CON52)#
The detour is gone. The 2026-10-01 chain installed
ai-edge-litertandonnxruntime-genaifrom/opt/wheelsbeforeuv sync, which removed them again (an exact sync drops what--no-install-packageexcludes), andreconcile_local_wheelsinstalled them a second time.build_uv_sync_argsandrun_uv_sync_with_fallbacknow install nothing, andcollect_locked_local_wheelsis gone:reconcile_local_wheelsis the one install point.assert_chain_wheels_installedruns after the torch pins and fails the stage (CHAIN-WHEEL FAIL) unless every staged wheel is the venv’s distribution of its name, by uv’sdirect_url.json. Exempt: TVM, source-bound OpenCV, riscv64 IREE.OrchestrANT’s lock stays on PyPI. Routing a package to
/opt/wheelsmakesuv lockfail off the image (Failed to read --find-links directory), and no marker tells the image apart. Doc:docs/linux-cross-builds.md§ The chain wheels and the app’s lock; failure modeCHAIN-WHEEL FAIL.Suite
test-chain-wheels-installed.sh; sixwheels.chain-*mutations.
2026-10-01 - The entrypoint leaves the Vulkan variables on /opt/vulkan/active (CON48)#
Measured in the published
:latestchildren: the entrypoint sources LunarG’ssetup-env.sh, which resolvesVULKAN_SDKto/opt/vulkan/<version>/<uname -m>and puts that dir intoVK_ADD_LAYER_PATH,PATH,LD_LIBRARY_PATH,PKG_CONFIG_PATHandCMAKE_PREFIX_PATH(x86_64on amd64,aarch64on arm64). The image ENV alone (--entrypoint bash) keeps/opt/vulkan/active; the login shell sources nothing. A riscv64 process under QEMU in the amd64 image re-roots/opt/vulkan/activeinto its sysroot, but not thex86_64dir, which is whyriscv64_cross_envhad to override two of them.vulkan_env_prefer_active_link(01-core/vulkan-env.sh) rewrites every component under the link’s target back to<root>/active, without duplicating an entry the image ENV already has.vulkan_env_source, the entrypoint, and a newvulkan_env_source_script(now used bylib/cmake-build.shandlib/ctest-run.shfor--vulkan-setup-script) call it. Natively nothing changes: the link resolves to the same dir. Checked by mounting the new files over the published amd64 and arm64 children:vkarch=neutral, the loader findsVkLayer_khronos_validation.jsonthrough the link,glslcruns.The boot smoke no longer requires
VULKAN_SDKresolved past the link. It proves the entrypoint sourcedsetup-env.shthroughVK_ADD_LAYER_PATH(vkadd=yes), and fails any of the six variables with a/opt/vulkan/<version>/component (vkarch=). The published children printvkarch=VULKAN_SDK,VK_ADD_LAYER_PATH,PATH,LD_LIBRARY_PATH,PKG_CONFIG_PATH,CMAKE_PREFIX_PATH,, so the next chain cannot ship the old shape.Suite
test-vulkan-env-active-link.sh, probe cases intest-runtime-image-gates.sh, nine mutations (vulkan.env-*,lib.*-vulkan-script-on-link,boot.vulkan-*). Docs:failure-modes.md. Ships with the next chain;riscv64_cross_envkeeps its override until consumers run on it.
2026-10-01 - The layer-cache keep value means layer cache; surplus cache-mount records (CON53)#
--keep-storagebounds the whole store, cache mounts included (BuildKit v0.33.0cache/manager.gosums every unshared record before the type filter applies). Against 196 GB of cache mounts,PRUNE_KEEP_GB=100 prune-safe.shtherefore deleted every idle layer record (0.17 GB left)._disk_guard_regular_keep_mb(01-core/disk-guard.sh) adds the unprunable records’ size frombuildctl du --format '{{json .}}';prune-safe.shand the chain’s DISK1 fallback both pass that, soPRUNE_KEEP_GBandCROSS_BUILDKIT_KEEP_GBare GB of layers.Surplus cache-mount records: with
sharing=sharedBuildKit creates a second record for a cache id when the one it would reuse is locked mid-release, then keeps reusing the lowest record id. Six ids held 52 GB of surplus on this host.prune-safe.shlists them, andPRUNE_DUP_CACHEMOUNTS=1removes them; it refuses while a build holds a record. It now reads the store as JSON (exact bytes; it needsjq) and rejects a non-numericPRUNE_KEEP_GB.Suite
test-prune-safe.sh, atest-disk-guard.shcase, sevenprune-safe/disk-guardmutations (mutation-family:prune-safedeclared).
2026-10-01 - A browser and an Android emulator in :latest (CON50 items 3 and 4)#
Chrome for Testing on amd64 and arm64. Google’s Stable build and its chromedriver, a SHA256 per zip in
versions.env, installed by06-packaging/install-chrome-for-testing.shas the package stage’s last RUN.CHROME_EXECUTABLE=/usr/local/bin/chrome, a wrapper adding--no-sandbox --no-zygote --disable-dev-shm-usage; empty on riscv64, which has no build. +0.45 GB per arch.The Android emulator and
system-images;android-35;google_apis;x86_64on amd64, from Google’s zips by06-packaging/install-android-emulator.sh.android-avd.sh create|start|stopin/usr/local/binboots it headless on/dev/kvm. +4.66 GB on amd64. API 30’s ARM translator SIGILLs on OmniAccelerANT’s APK; API 35’s runs it.Proven on a throwaway image FROM the published
:latest(sha256:1a913b84…), not on a rebuilt chain: headless Chrome as uid 1001 on amd64, and on arm64 under QEMU; OmniAccelerANT’s tests in Chrome (37 pass, two files needdart:io); the emulator booted in 25 s with KVM and ran the arm64-v8a release APK. Ships with the next:latestrebuild.Gates. The consumer contract gains the
chromeandandroid-emulatorrows (exempt on riscv64, and on arm64 and riscv64).download_verified_cached(01-core/downloads.sh) re-verifies a cache-mount copy before every reuse.bump_versions.pyrefreshes the CfT pins and holds the emulator’s.Tests:
test-chrome-and-emulator.sh(new),test-runtime-image-gates.sh(+8 cases), 11chrome-emulator.*mutations.
2026-10-01 - A runner-native pytest job on windows-11-arm (CON50 item 6)#
python-ci-windows.ymlgainsarm64-tests(default false), witharm64-python-versions,arm64-extras,free-threaded-extrasandtest-paths. The job checks the caller out and runs the newwindows/scripts/python/Invoke-PythonTestLegs.ps1from its ANTfrastructure pin, with no container. Each leg has its own venv throughNew-UvProjectEnvironment, so a3.14leg after a3.14tleg still gets the GIL build. Every leg gates. The error names each leg that failed and the step: venv, sync or pytest. Page:docs/python-ci.md§ Windows arm64: the runner-native test job.versions.env:UV_WINDOWS_ARM64_SHA256(noforward) pins uv’suv-aarch64-pc-windows-msvc.zip, matching the release’s own.sha256.bump_versions.py’sspec_uvrefreshes it with the Linux pins.Invoke-StagedTests.ps1reads a-qpytest summary. pytest drops the=frame around the counts line under-q, so7 passed, 1 skipped in 0.42sis now read as well.test-reusable-windows-lane.shholds the job’s contract: off by default, gated on the input, and inputs passed through env. Three newwindows-lanemutations prove it bites.windows-lane.powershell-lint-defaults-offnow names its own input, because a baredefault: falsematched twice.PythonApp.Cross.Tests.ps1removes its fakeuvagain.Remove-Item function:global:uvignores the scope prefix, so the fake outlived its suite and answered every later suite’suv(the full run failedPythonTestLegs.Tests.ps1on it). It now usesRemove-Item -Path Function:\uv.Suite
PythonTestLegs.Tests.ps1. Hand mutations bite: nocontinueafter a failed sync, no SHA check, a free-threaded leg ignoring its extras, and a bare--python. A real run on an x64 host against WebDavClient, with legs3.14t 3.14, gave the 3.14 leg a GIL 3.14.7: 10 passed.
2026-10-01 - riscv64 consumer lanes: cross-build on amd64, test under QEMU (CON48)#
Owner decision: a consumer’s riscv64 lane builds on the amd64 runner and runs only the tests under QEMU user-mode. A fully emulated build is 20-30x slower and would pass the 6 h job limit for the C++ repos. Page:
docs/riscv64-cross-test-lanes.md.setup-riscv64-cross(action) registerstonistiigi/binfmt:qemu-v10.2.3(pinned by digest) with theFflag and exports the image’s riscv64 child into a sysroot withlinux/scripts/02-toolchain/riscv64-sysroot.sh(allowlist, absolute links made relative, the index taken from the pulled amd64 image’sRepoDigests).lib/riscv64-cross.sh(riscv64_cross_env): the distro clang (the image’s clang 23 is X86-only), triple-named wrappers over the sysroot and its GCC 16.2.0 libstdc++, the cc-rs/Cargo/pkg-config variables,QEMU_CPU=rva23u64(rv64andrva22u64SIGILL in the image’s RVV glibc), and arch-neutralVULKAN_SDK/VK_ADD_LAYER_PATH.cmake/toolchains/riscv64-linux-gnu.cmakeis the CMake side.container-ci-riscv64.yml(reusable) wraps host prep, the action, the compiler cache and one container step. Consumers: OxidANT, AccelerANTgine, BeschleunigerBallett; OmniAccelerANT waits for Flutter in the riscv64 image.Suite
test-riscv64-cross.sh, seven mutations in theriscv64-crossfamily.
2026-10-01 - Python lanes run the whole suite, 3.14t can gate, and arm64 runs pytest (CON50)#
ci_tests.shpasses pytest no path of its own. It used to hard-codetests/unit, so pytest never read the consumer’stestpaths. WebDavClient’s six WebDAV client tests and every consumer’stests/integrationran on no lane, on any arch.PYTEST_PATHS(inputtest-paths) still narrows it on request.A free-threaded leg can be real. With
free-threaded-extras(FREE_THREADED_SYNC_EXTRAS), a*tleg syncs only the core and those extras, and gates. Without it the leg stays experimental, and a failed venv, sync or test run now prints a::warning::annotation instead of passing silently. On 2026-10-013.14tran 0 tests on every lane of OrchestrANT and WebDavClient, with every job green.container-ci-windows.ymltakes a test tree with no binaries. Settest-arch-gate-min-inspected: 0for a Python suite that the product’s own interpreter runs: any PE file in the tree must still be arm64, but none is required and no import walk runs.Invoke-StagedTests.ps1gains thepytestkind, read from pytest’s final summary line.Tests:
test-python-ci-defaults.sh(+5 cases), three newpython.ci-tests-*mutations, andStagedTests.Tests.ps1(pytest).BACKLOG CON50 holds the cross-consumer audit and the owner’s decisions.
2026-10-01 - :winarm64 rebuilt without NVIDIA; the arm64 lanes run tests#
:winarm64is published again, at hub 59a4bca3. The image of 2026-09-22 predated the variant split and carried CUDA, cuDNN and TensorRT (GPU_TYPE=nvidia). By owner decision that stack belongs in:winarm64-nvidia, as on amd64.The rebuild drops the NVIDIA stack. It is the default variant, so the sdk slot is an alias of base. Its config has no
CUDA_PATH,TENSORRT_ROOTorGPU_TYPE.The rebuild also brings WiX 7 and the CPython version-string fix. The toolchain stage stops on a
sys.versionwithoutAMD64, so a venv reportswin-amd64again.It took 2 h 46 min. That includes a full base and toolchain rebuild, since WiX 7 changed the base. The smoke and publish gates passed.
The effect, in OrchestrANT’s arm64 lane:
zip 902 → 204 MB, MSI 793 → 167 MB, MSIX 924 → 207 MB;
166 PE files under the arch gate;
--self-testpasses onwindows-11-armfor the bundle and the unzipped package.
CON43’s consumer half is done. AccelerANTgine, OxidANT, BeschleunigerBallett and OmniAccelerANT run their tests on
windows-11-arm, and each lane is now “Windows arm64 · cross build + test”.
2026-10-01 - Invoke-InLinuxContainerBuild hands bash LF-only lines#
What went wrong. A caller builds its container command in a here-string, and a here-string keeps its file’s line endings. OmniAccelerANT’s
Invoke-Renovate.ps1is checked out with CRLF, so bash receivedset -e<CR>and stopped at once:set: -: invalid option.The fix.
WindowsBuildSweep.Common’sInvoke-InLinuxContainerBuildturns CRLF into LF beforebash -c. Pester:WindowsBuildSweep.Common.Tests.ps1.
2026-10-01 - Python app bundles and their packages for Windows arm64#
Invoke-CiPackaging.ps1 -TargetArch arm64builds a consumer’s app for arm64 in:winarm64. Empty takes the image’sWINDOWS_TARGET_ARCH, so x64 runs as before. It builds only the pure wheel: no Cython step, which compiles for the host, and no host venv sync. The bundle and its zip, MSI and MSIX go todist\windows-arm64.New-PythonAppBundle.ps1 -TargetArch arm64:New-PythonAppCrossRuntimelays out the image’s target CPython withPC\layout --arch arm64.Install-PythonAppCrossPackageinstalls the lock withuv pip install --target --python-platform aarch64-pc-windows-msvc.The chain cv2 comes from the target CPython, and the launchers are compiled for aarch64.
The self-test is deferred:
Test-PythonAppSelfTest.ps1, now standalone, goes next to the bundle for thewindows-11-armjob.bundle.jsonrecordsarchandpython.
New-PythonAppPackage.ps1reads the arch frombundle.json. It names the packageswindows-<x64|arm64>and passes it towix build -archand to the AppxManifest’sProcessorArchitecture. An arm64 bundle is packed and signed, never started. The newGet-WindowsPackageArchis the one place that spells the arch the x64/arm64 way.Proven in
:winarm64with OrchestrANT 0.0.29: the arch gate passed over 191 PE files, G6 passed, and all three packages were built and the MSIX signed. They are three times the x64 size (zip 902 MB), because the image’s arm64 OpenCV is a CUDA build. That gap, and the image’s host CPython that predates the version-string fix, are BACKLOG CON49.Pester:
PythonApp.Cross.Tests.ps1, plus arm64 cases in the wheel, MSIX and target-arch suites.
2026-10-01 - A staged test can report its own skip; OrchestrANT’s permissions census is at 0#
Invoke-StagedTests.ps1reads an optionalskip_patternpertests.jsonentry. A wgpu test without an adapter printsSKIP: no GPU adapterand returns, which cargo counts as passed. Each line matching the pattern moves one test from passed to skipped, so a windows-11-arm runner with no GPU no longer reports those tests as passed. OxidANT’s renderer entry already names it. Pester:StagedTests.Tests.ps1.workflow-conventions.allowdropsCENSUS | OrchestrANT | permissions | 2. OrchestrANT’s lane files now setpermissions: contents: readat the top, so the count is 0 and the row has nothing left to freeze.
2026-10-01 - Renovate reads and bumps CMake dependencies (CON46, hub part)#
The shared preset (
default.json) gains two regexcustomManagersover everyCMakeLists.txtand*.cmake. Every consumer inherits them throughextends.GIT_REPOSITORY <GitHub URL>thenGIT_TAG <tag>, and a tag archive (.../archive/refs/tags/<tag>.zip|.tar.gz), both asgithub-tags.A
# renovate: datasource=… depName=…line directly aboveGIT_TAG <v>,set(<NAME> <v>or a quoted"<v>".Only a dotted value is a version:
master,main, a SHA,${VAR}and a commit archive are skipped. The forms exclude each other, because Renovate’s regex manager does not de-duplicate rows.Measured with Renovate 44.82.0 and RE2 on AccelerANTgine’s and BeschleunigerBallett’s real files: each pin once, every floating ref skipped.
--strictvalidation passes.
renovate-local.sh --applyrewrites those pins. The locator runs the preset’s ownmatchStrings; the audit reads the file with a new CMake tokenizer (linux/scripts/renovate_cmake.py) and refuses a tag archive behindURL_HASH/URL_MD5and a match inside a comment.renovate_locator.syntax()picks the reader per file, so oneregexreport can carryversions.envand CMake.Docs:
docs/dependency-updates.md§ CMake dependencies. Test:linux/scripts/tests/test-renovate-cmake.sh; ninerenovate-cmake.*mutations.Left for the consumers (BACKLOG CON46): pin corrosion, move googletest to a tag archive, drop the two repo-level CMake managers, then the fleet report run.
2026-10-01 - WiX 7 (OSMF EULA accepted) and arm64 tests on windows-11-arm (CON43, hub part)#
WiX 4.0.6 → 7.0.0, with the owner’s acceptance of the wix7 OSMF EULA (2026-10-01). WiX 4 left community support on 2025-02-05.
Install-ScoopTools.ps1runswix eula accept wix7after the install. Without it, every build stops withWIX7015, measured. It refuses any other major, since a new EULA is a new licence decision. Renovate’s guard moves from<5to<8.Measured in
:winamd64with WiX 7.0.0:OxidANT’s
wix/main.wxs(UI extension, payload fragment) builds, installs and uninstalls.A CPack
WIXpackage (CPACK_WIX_VERSION 4mode) builds.OrchestrANT’s Python app MSI builds, installs, starts, is on
PATHand uninstalls.
The images carry WiX 7 from their next build. Until then they keep 4.0.6, whose sources are the same.
container-ci-windows.ymlcarries tests to the arm64 runner.New inputs
test-artifact-dirandtest-command. The staged tests get the product’s arch gate, so an amd64 test cannot pass by emulation.The run job demands one
TESTS: passed=<n> failed=<n> skipped=<n>line, and fails without it, on a failure, or with nothing passed.windows/scripts/build/Invoke-StagedTests.ps1prints that line from googletest, libtest and exit-code results. It is self-contained, because the runner has no checkout.Docs:
docs/windows-cross-builds.md§ Consumer cross lanes. Test:windows/scripts/tests/StagedTests.Tests.ps1.The consumers follow one at a time (CON43).
2026-10-01 - Windows uv venvs install a missing version before asking for its GIL build#
Fixed a regression from 88e27ab9. A version the host lacked stopped the venv:
New-UvProjectEnvironmentasks forX.Y+gil, and uv downloads nothing for that request.OmniAccelerANT’s CMake format gate, which wants 3.12, failed with
No interpreter found for Python 3.12+gilon its first run with hub 709d09f3.The function now runs
uv python install X.Yfirst whenuv python findcomes back empty, as Linux’suv_ensure_python_availabledoes.Measured in
:winamd64: 3.12 is installed and its venv is GIL. 3.14 keeps the image’sC:\temp\cpython.Test:
windows/scripts/tests/Uv.PythonRequest.Tests.ps1.
Invoke-CiPackaging.ps1reads the binaries venv’s base interpreter from itspyvenv.cfg, after that venv exists, instead of askinguv python findbefore it. TheLIBfix then holds for a version the venv step had to install.
2026-10-01 - Python app packages: MSIX, Linux aarch64, and one chain ORT per Windows bundle#
MSIX.
New-PythonAppPackage.ps1builds it by default, next to the zip and MSI.New-PythonAppAppxManifestgives each script a full-trust console app with its own execution alias, so the CLIs reachPATHas the MSI’s PATH entry does. Onlygui_scriptis listed in Start.makeappxpacks the bundle in place through a mapping file.The signature is a test certificate for
CN=<publisher>, made in memory byNew-PythonAppSigningCertificate, so no store is touched. Its.cerships beside the MSIX.Proven in
:winamd64: the unpacked package starts, and inside the containersigntool verify /papasses once the.ceris trusted; the root is removed again. makeappx refusesdesktop4:Subsystem="console"withoutSupportsMultipleInstances(80080204).Test:
windows/scripts/tests/PythonApp.Msix.Tests.ps1.
Linux aarch64 builds the bundle and its packages.
ci_packaging.shno longer skips non-x86_64.Proven under QEMU with the arm64
:latest: closure, G6 and self-test pass, and the tar.gz (232 MB) and deb (190 MB) each start once.That image’s chain ORT wheel is
onnxruntime_webgpu. The AppImage needs a real arm64 host (qemu-usercannot loadappimagetool), which CI’s arm64 lane is.
One chain ORT per Windows bundle.
Copy-ChainOpenCvPackage -SharedDirectorysearches the bundle’s ownonnxruntime\capifirst and names it in cv2’sconfig.py, instead of copying a secondonnxruntime.dllandDirectML.dllintocv2\bin.Proven in
:winamd64:import cv2succeeds beforeonnxruntimeis imported, and G6 and the import walk pass.The bundle went from 561 to 550 MB.
2026-10-01 - lavapipe gets 8-lane subgroups, the SSIM validate plugin stops blacklisting itself, libunwind is gone from the media closure#
For the :latest rebuild the owner approved on 2026-10-01. None of it is in a published image yet.
ENV LP_NATIVE_VECTOR_WIDTH=256in the package image, every arch (CON44). Mesa 26.0.8’s lavapipe sorts its BVH with 8-lane subgroups; llvmpipe gives 4 on arm64 and riscv64 (measured withvulkaninfoin the published:latest), and the scatter SEGVs. The runtime smoke’scheck_lavapipe_subgroupfails a variable other than 256 or asubgroupSizeother than 8. BeschleunigerBallett can drop its own export once it runs on the new image.The SSIM validate plugin no longer blacklists itself (CON47). It was no loader error:
plugin_initreturned FALSE outside gst-validate, and the core registry scansgstreamer-1.0/validate/too. Patch007returns TRUE there, as the gapplication plugin does; proven by building gst-devtools 1.29.2 with the hub’s patcher (blacklist 1 → 0, the override still writes its frames under gst-validate). The plugin-health check now FAILS on any undocumented blacklisted plugin, andcheck_gst_validate_ssimruns the override on amd64.The libcamera half of the libunwind fix is measured, and the owner chose “everywhere”.
build-libcamera.shbuilt with and without-Dlibunwind=disabled: without itlibcamera-baseNEEDslibunwind.so.8and a C host that loads it first segfaults on an exception throughstd::call_once; with it the exception is caught. A readelf sweep over all three published arches found no other user under/optor/usr/local, only distroXvfband gperftools outside it.check_no_libunwind_closurenow fails a shipped file that needs it.Tests:
test-lavapipe-vector-width.sh,test-gst-validate-ssim.sh,test-no-libunwind.sh(extended); 18 mutation entries.
2026-10-01 - Windows Python lanes: static analysis runs at all, and wheels are built for the GIL#
OrchestrANT’s first Windows run on 5cfc5259 failed in three places, and the hub owned two of them.
Invoke-CiStaticAnalysis.ps1failed all six gates withCannot bind argument to parameter 'Context' because it is null. Each gate’s script block went throughGetNewClosure(), and inside a closure’s dynamic module$script:BuildContextis$null. This was in place since 2026-09-12; earlier failures in the same lane had hidden it. The context is now bound to a local before the closure.uv buildbuilt the Windows wheel free-threaded (cp314-cp314t). It finds its own interpreter and ignores the venv’s+gilone, soInvoke-CiPackaging.ps1passes it--python X.Y+giltoo. Seedocs/python-ci.md§ Free-threaded and GIL legs in one container.The GIL build then could not link (
LNK1104: python314.lib). The image’s CPython is an in-tree build, and its import library sits besidepython.exe, where setuptools never looks. The binaries step puts that directory onLIB. Proven in:winamd64: OrchestrANT buildsorchestrant-0.0.28-cp314-cp314-win_amd64.whl.The bundle builder picks the wheel by the runtime’s ABI. It used the first
win_amd64wheel, so the GIL runtime tried to install thatcp314twheel.Select-PythonAppWheeltakescp314orabi3, and falls back to the pure wheel only when there is no binary at all. A binary for another ABI alone is an error. Test:windows/scripts/tests/PythonApp.Wheel.Tests.ps1.
2026-10-01 - DeepStream’s GPU gate passes; four defects it found are fixed (CON42)#
The GPU gate passed on the build host’s RTX 2080 (sm_75, driver 595.58.03, CDI through rootless nerdctl), in a throwaway container FROM the published
:latestamd64 child plus the variant’s CUDA 13.4.2: TensorRT 10.16 builds the sample engine for sm_75; NVDEC decodes; decode →nvstreammux→nvinfer→nvtracker→nvmultistreamtiler→nvdsosd(GPU mode) runs with detections and tracker ids in the metadata, as root and as uid 1001;nvstreamdemuxandnvurisrcbinrun; NVIDIA’s CUDA 13.2 kernels run on 13.4. Pass/fail only: the licence forbids publishing benchmark results.TensorRT builder resources are linked by file name. An engine build
dlopen()slibnvinfer_builder_resource_sm75.so.10.16.1by name, whichld.so.cachenever holds;deepstream.shlinks them into/usr/lib/<triplet>/and the gates check the links.NVDEC works through the distro
libv4l2, with NVIDIA’slibcuvidv4l2_plugin.solinked into its plugin dir bystage-runtime(and gated); no SONAME hijack.The image selects the new
nvstreammux(USE_NEW_NVSTREAMMUX=yeswith DeepStream, empty otherwise). NVIDIA’s prebuilt legacy mux readsGstMapInfo.dataafter unmap, which GStreamer ≥ 1.28 clears; it failed every buffer with no message.GStreamer core and libcamera build without libunwind, in every variant.
libunwind.so.8ahead oflibgcc_sturned an exception throughstd::call_onceinto a segfault (docs/failure-modes.md); it took the TensorRT error above down with it. Backtraces fall back to glibc’sbacktrace().Host setup: a GPU container on an x86 desktop with rootless nerdctl (
linux-host-setup.md§ B2c): the Secure Boot key, the CDI spec in~/.config/cdipluscdi_spec_dirs, and regenerating it after every driver update.Still open for CON42: the owner-approved nvidia chain run with
ENABLE_DEEPSTREAM=true.
2026-10-01 - Python app bundles become tar.gz, deb, AppImage, zip and MSI, each started once#
Packagers.
linux/scripts/06-packaging/python-app-package.sh(tar.gz, deb, AppImage) andwindows/scripts/python/New-PythonAppPackage.ps1(zip, MSI) wrap a finished bundle. They then start each package throughpython-app-selftest.py/Invoke-PythonAppSelfTest -Root, which also requires ONNX Runtime to load from inside it. The deb is installed withdpkg -i, started and removed when root. The MSI is installed, started, checked on the systemPATHand removed, but only inside an elevated Windows container: on any other machine it is proven by an administrative unpack, so a developer’s run changes nothing.The lanes build them. When a consumer has
packaging/app.json,ci_packaging.shandInvoke-CiPackaging.ps1build the bundle intobuild/app-bundleand the packages intodist/packages, which the lanes’dist/artifact already uploads. Linux does this on x86_64 only, until an aarch64 bundle is proven.The deb’s
Dependsis measured. It islibc6at the newestGLIBC_any bundled ELF asks for, plus thedpkg -Sowners of every library left to the host. A waived soname (unresolved_allowed, now inbundle.json) is skipped, and an unowned one fails. For OrchestrANT it islibc6 (>= 2.43)and six X/GL/GLib packages, so the Linux packages need Ubuntu 26.04 or newer, and the flatpak 24.08 runtime does not fit. Only the chain ORT (2 of 142 ELF files) asks for 2.43; the next newest is 2.38.Nothing writes into an installed package. The builders compile all bytecode, and the launchers pass
-B. Before this, the first start as admin or root left__pycache__that the removal did not delete.MSI: WiX 4.0.6 has no harvesting, so
New-PythonAppWxswrites the tree out. It installs per machine, keys a major upgrade onmsi_upgrade_code, adds a Start menu shortcut and the systemPATHentry, and refuses paths past MAX_PATH. Windows’tar.exehas no-s, so the zip names its top folder by renaming the bundle while it zips.Tests:
linux/scripts/tests/test-python-app-selftest.sh,windows/scripts/tests/PythonApp.Msi.Tests.ps1.
2026-10-01 - Python apps ship as relocatable bundles; Windows venvs get the image’s OpenCV#
Bundle builders. A Python consumer can now turn its app into one folder: its own CPython, the locked wheels, the chain ORT, its data and one launcher per console script.
windows/scripts/python/New-PythonAppBundle.ps1(moduleWindowsPythonApp.Common, C launcher inwindows/scripts/python/app-launcher/) andlinux/scripts/06-packaging/python-app-bundle.sh(+python-app-closure.sh) both read the consumer’spackaging/app.json. The gates are the import walk, G6 and the app’s own self-test. Proven on OrchestrANT: Windows 561 MB, Linux 666 MB, each run again after being moved. Seedocs/python-app-bundles.md.Test-TargetArch.ps1 -Standalone. On a native lane the import walk only reports, because the image’sPATHsupplies what is missing. A bundle has no image behind it, so-Standalonemakes the walk fatal there, as it is on a cross lane. It caught the gap below by name, where the self-test had only saidDLL load failed.Windows: OpenCV comes from the image, in bundles and in CI venvs. PyPI’s
cv2.pydimports Media Foundation, which Server Core and Windows N lack. Copying the image’s cv2 package was not enough: itsconfig.pynames only OpenCV’sbin, while the image’s basesitecustomize.pyregisters the other DLL homes. A venv or a bundle never runs that file, soimport cv2failed in both. The PE walk showed five FFmpeg DLLs as the gap.Copy-ChainOpenCvPackagewalks the.pyd’s closure over the config dirs,ONNX_ROOT\binand everyC:\runtimedir onPATH. The bundle copies the closure (56 DLLs) intocv2\bin; a CI venv (-ReferenceImage) names the three image dirs instead.Sync-UvProjectDependenciesnow ends withSync-UvChainOpenCv. Measured in:winamd64: the CI venv imports cv2 5.0.0 with FFmpeg and DirectShow.Get-PeImportClosureis split out ofCopy-PeImportClosurefor that walk.
Windows venvs ask uv for the GIL build.
New-UvProjectEnvironmentpassesGet-UvPythonRequest’sX.Y+gil, the twin of Linux’suv_python_request. A plain3.14took a free-threaded download in OrchestrANT’s Windows CI.
2026-10-01 - DeepStream may be published: the owner’s licence decision (CON42)#
The owner allowed publishing NVIDIA’s DeepStream runtime in
:latest-nvidia. The stage graph no longer refuses a pushing chain withENABLE_DEEPSTREAM=true; its test now asserts the chain is accepted, and the gate’s mutation entry is gone with the gate.The image ships the runtime
.sofiles, not the static archives. The licence supplement makes “the runtime files ending with “.so”” distributable; the package stage’sdeepstream.sh stage-runtimedeleteslibnvdsgst_multistream_legacy.aandlibnvds_service_maker_utils.a, which only a build links.LicenseAgreement.pdfships.Still open for CON42: a GPU run (the host’s driver is blocked by Secure Boot: the DKMS key is not enrolled) and an owner-approved nvidia variant chain run.
CON47:
libgstvalidatessim.sofails to load in the published:latest, found by the spike; tracked to be measured and fixed.
2026-10-01 - DeepStream for the nvidia variant (CON42): spike measured, source in, off by default#
The spike (phases 1–3), without a chain. In throwaway containers FROM the published
:latestamd64 child plus the variant’s CUDA 13.4.2: NVIDIA’s DeepStream 9.1 runtime.debunpacked, and its Apache-2.0 plugins and libraries built against/opt/gstreamer1.29.2 (not Ubuntu 24.04’s 1.24).nvinfer,nvstreammux,nvvideoconvert,nvtracker,nvdsosd,nvv4l2decoder,nvmultistreamtiler,nvstreamdemuxandnvurisrcbinregister without a GPU. No GStreamer or GLib symbol is missing, and no CUDA symbol against 13.4.2 (the runtime targets 13.2).TensorRT 10 beside 11. NVIDIA’s tracker and infer utilities link
libnvinfer.so.10, and thenvdsinfersource does not compile against 11.3 (56 errors, APIs removed in 11). The image carries TensorRT 10.16.1.11 privately. Measured: with TensorRT 11 in a process’s global scope, a library linked against.10binds to 11’s unversioned symbols.Upstream fixes the build needs here. GCC 16 (missing transitive
<cstdint>/<algorithm>, a new-Werror), each Makefile keeping its own compiler (one compiles C withCXX:=gcc), an$ORIGINRUNPATH for thenvds_rest_serverdependencies, and helper libraries moved out ofgst-plugins/: the registry scandlclose()d them and the next plugin segfaulted ing_quark_from_static_string.Proven with the hub script, not only the spike.
deepstream.sh buildpasses its gates in a fresh container (48 components, 2m58s warm with sccache), andstage-runtimepasses on a clean:latestwith only the runtime packages, as root and as the runtime user. The gates caught three real faults on the way there, each fixed: the otel libraries without a RUNPATH, NVIDIA’slibnvdsgst_sparse4d.sowhose RUNPATH namesdeepstream-9.0, and agrep -qwhose SIGPIPE underpipefailclassedlibgstnvvideo4linux2.soas a helper library.In the source, off by default.
linux/scripts/05-frameworks/deepstream.shanddeepstream-verify.sh, a gateddeepstreamstage inDockerfile.media, the package’sstage-runtime/assert-absentRUN,check_deepstreamin the runtime smoke,DEEPSTREAM_*pins with SHA256s,test-deepstream.sh, new cases intest-gpu-variant.sh, and 19 mutation entries.ENABLE_DEEPSTREAM=trueis refused outside the nvidia variant, and a DeepStream chain refuses to push until the owner decides whether NVIDIA’s licence allows publishing it (the facts:docs/linux-accelerator-images.md§ Licence: the owner decision).cuDNN pin fix (found on the way). The nvidia variant never installed its
CUDNN_VERSION:libcudnn9-dev-cuda-13=9.26.0.51*depends on the exactlibcudnn9-headers-cuda-13, apt took the newest headers, the pinned tier failed, and the unpinned tier installed 9.27.0.42.install-cuda-stack.shnow pins the headers package in the same call.Cache cost.
versions.envis in the base closure, so this commit re-keys every chain from base on its next build, as any pin bump does.Not done. No GPU run (this host’s NVIDIA driver is not loaded) and no variant chain run:
BACKLOG.mdCON42.