ci: add bounded complete release gate

This commit is contained in:
Erik 2026-08-18 09:09:38 +02:00
parent 0a934cf578
commit 2ac054864d
11 changed files with 772 additions and 102 deletions

View file

@ -120,7 +120,7 @@ callback. The test needs a deterministic race harness after the production
fix; the current timing-dependent version alternates between passing in 48 s
and hanging indefinitely.
**Post-baseline resolution checkpoint (2026-08-18, uncommitted):**
**Post-baseline resolution checkpoint (2026-08-18, `0a934cf5`):**
`DisposeAllowsAnAlreadyCapturedExitCallbackToComplete` is now the deterministic
race harness. Explicit barriers make the fake child capture the exit delegate,
release it from inside disposal, and wait for the callback to return. The old
@ -401,3 +401,28 @@ regression contracts with T-011's output apparatus. When a test graduates into
a stable contract, organize it under the owning component/behavior and retain
the issue ID in a trait or comment; keep investigation programs in a separate,
non-default diagnostic project.
### T-017 — Shown Avalonia test windows escaped their owning UI session
Four `MainWindowViewTests` called `window.Show()` but never closed the window.
One default-parallel solution run then failed during Avalonia headless cleanup:
the runner/compositor touched an object from a thread other than the one that
owned it, even though the Launcher project passed alone. The tests now close
shown windows and pump dispatcher cleanup in `finally` on the owning Avalonia
session. No product code, suite serialization, or retry was added. The focused
class passes 13/13, and three fresh default-parallel complete-solution runs pass
all 12 assemblies in 56.719, 56.321, and 58.506 seconds.
### T-018 — A live stderr assertion could disable the producer it observed
`ReadFileEventuallyContainingAsync` used `File.ReadAllTextAsync` while the
ProcessStartInfo stderr callbacks were still draining. Its read handle did not
share writes. If the final callback overlapped that short read, the capture
sink saw a sharing violation, deliberately latched into its no-throw state, and
the test waited five seconds for a line it had itself caused to be dropped. The
first complete repository-gate run exposed exactly that two-of-three-lines
failure. The helper now opens a live reader with
`FileShare.ReadWrite | FileShare.Delete`, matching the production status
tailer; the expected lines and timeout are unchanged. The test subsequently
passed 25/25 fresh-process runs and Launcher.Core passed 339/339 in the final
gate.