- build-linux and build-linux-split each probe the other's configure line with build_fingerprint.py on their own runner (disaggregation branches only); when it matches, build-linux-split skips its compile and the split consumers take build-linux's runtime and library
- the consumers red when build-linux-split skipped but build-linux's guard did not agree, or when the link ratchet, now also run in build-linux, did not pass; a difference falls back to the old two builds, and dev is unchanged apart from the consumers also waiting for build-linux
- the transport resolution check moves after 'Split lanes' and proves the IPC defaults from each passed entry's client log (split_log_paths.py ipc-config, canned tests); with both proven, Transport A/B and the non-strict split unit run are skipped as repeats
- the test job carries REQUIRE_GPU and libegl-mesa0 on the three branches; skip census: arm-monolith, arm-inproc and unit-split become optional rows
- scripts/ci/configure_build.sh holds build-linux's (primary) and build-linux-split's (split) configure lines, flag for flag as before
- scripts/ci/build_fingerprint.py compares two configured trees (cache, compile commands, link statements, CTest files, toolchain) with the build path normalised and the benchmarks left out; its guard configures a probe through the script and never counts thin evidence as equal
- pipe-gates runs its self-test; no job uses the guard yet
- Strict split lane: drop the kMGPipeP5eRunAheadReady grep and its red-by-design pre-flip arm; the constant is true, so the arm never ran
- Dual-block census lane: drop the "green with rows outstanding" rule, inert while dualblock-expected-fatals.txt is empty; the empty-census rule and expect-fatal stay
- delete scripts/ci/tcp_log_forwarding_control.py, which nothing calls
- integration-verify: drop control B, whose pair the in-lane PoisonOmitted entries already pin with a stricter check; the arming grep becomes junit_tally --require-entry-passed on the six VerifyArming, VerifyCorrupted and PoisonOmitted entries (a skip fails)
- integration-verify-split: drop the server-side-read rerun and control B; the same check covers the eight VerifySplit control entries, which assert those properties in-test
- controls A and A2 stay: nothing in-lane covers the FATAL=1 abort half or the capability field
- retrace-verify: the corrupted-snapshot control must go red with its own Fatal{PipeVerifyDiffer, "GetRenderStateParameters@"; test_run_trace_case.py proves the check on canned output
- MG_IntegrationTest/CMakeLists.txt: the comments on the VerifySplit control entries say how CI now checks them
- PoisonOmissionScenario.cpp: WithoutOmissionCompletes is described as the ambient half of the pair, and its failure note no longer names a CI step
- 'Split lanes' keeps its first ctest's exit code beside split-baseline.xml; the controls step tallies that JUnit (DirectGLES.Split. entries) with the same refusals instead of re-running 802 entries, on every branch
- the rerun stays as the fallback when the lane step never ran, the case where the baseline was the only run of those entries
- smoke cases: reuse, fallback, a red exit code under a green JUnit, and a JUnit with no DirectGLES.Split. entry
- skip census: retire lane junit-integration-split/isplit (nothing borrows it; split-baseline covers the names)
- retrace-split loses its two negative controls, which re-ran every leg (~68 runner-min per run), and its dependency on the monolith-control artifact; the in-test evidence check from the previous commit replaces them
- build-linux-monolith-control keeps its zero-MG_Remote proof and its upload; on the disaggregation branches the new retrace-shipped job replays OpenRA on both backends through that library (elsewhere the retrace job's library has that shape), so the shipped shape is still replayed on every branch
- delete retrace_transport_control.sh, retrace_drop_draw_control.sh, their smoke cases and stub modes, and the uncalled redcheck_control_smoke_test.sh
- control-runtime/build-push-control leaves the eleven metadata loops; remove-artifact-clutter waits for retrace-shipped
- run_trace_case.cmake writes output/split-evidence.txt only after its transport assertions pass
- MGTRACE_WIRE_EVIDENCE (a harness name) turns on the library's counters and requires DrawVbo records on the wire and draws on the server role
- retrace-split's OpenRA legs ask for wire evidence; every split leg, and every inproc retrace row, checks its evidence file with retrace_split_evidence.py
- test_run_trace_case.py runs the real script on canned logs: each assertion goes red on its bad log, and pipe-gates runs it
- the first ubuntu-26.04 unit run failed 41 log-reading cases: 239 raw cores from intentional aborts filled /tmp, and the library's log writes then failed silently
- setup-test-runner pipes cores through a zstd handler that keeps honouring each process's RLIMIT_CORE; steps keep their ulimit -c and lose their own core_pattern lines
- the unit job prints free disk space and the core count after its run
- ubuntu-latest moves to 26.04 job by job from 2026-10-19 to 11-19; a build on one image and its tests on the other would fail on glibc, so all 32 jobs move together now, pinned
- the ccache keys say ubuntu26: the 24.04 compiler's objects would not hit anyway
- the unit and integration lanes set MOBILEGL_DISABLE_SHADER_PREWARM=1: every entry is its own process and none compiles enough to repay ~100 ms of table building
- the retrace legs and the benchmark keep the prewarm; they replay or measure real application startup
- locally the unit suite took 71 s with it set against 101 s without, all 3114 entries passing both ways
- the four runtime tarballs (0.5-0.8 GB each) took 65-100 s to pack with single-threaded gzip, two of them on the critical path, and every consumer spent about 16 s unpacking
- unit, integration and integration-verify ctest run at -j nproc; the same labels already run at -j in the split lanes, with the same names and results
- build-linux, -split and -verify also publish the library (and the server image) alone; the retrace legs load nothing else, yet downloaded and unpacked the 0.5-0.8 GB test runtime
- build-retrace no longer waits for build-linux: it fetched the runtime only to test -f a path configure does not read
- every branch saves its own rolling ccache entry, deleting only its own old one (--ref); only dev saved, and dev has not run since the key rename, so every build was cold
- !cancelled() replaces job-level always() on the retrace, summary and skip-census jobs: a superseded run kept starting its pending legs and held the next run in the concurrency group for up to 154 minutes
- retrace and retrace-split run 8 legs at a time, not 4; the cap dates from per-leg LFS checkouts
- apt requests time out after 30 s and retry 3 times; install steps time out at 15 minutes, not 45
- the APK trace case matrix no longer waits for the build, which it does not read
- retrace-split prepares its metadata once, after the split library is unpacked