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

@ -178,14 +178,26 @@ external systems.
## Post-audit stabilization update — 2026-08-18
R1 has been implemented and fully gated in the current uncommitted working
tree. The launcher child is detached under the supervisor gate and stopped,
R1 has been implemented, fully gated, and preserved at `0a934cf5` on
`codex/release-stabilization`. The launcher child is detached under the supervisor gate and stopped,
unsubscribed, and disposed outside it; a deterministic captured-callback race
test fails against the old mechanism and passes against the fix. Launcher.Core
passes 339/339, and two fresh serialized complete Release runs each finish
inside a 900-second hard bound with 14,748 passes / 77 skips / 0 failures.
This resolves F-009 technically but does not change the baseline audit's
historical count until the coherent R1 checkpoint is reviewed and committed.
The public-release decision remains no-go because F-001, F-002, F-014, and the
remaining high-priority release-governance findings are untouched.
historical count; the checkpoint is committed but not yet merged to `main`.
The subsequent R2 gate checkpoint pins SDK feature band `10.0.300`, adds a
repository-owned bounded Release command and Windows CI workflow that discover
and run all 12 test assemblies, captures TRX/log/environment/hash evidence, and
collects mini dumps before an outer process-tree timeout. Its local evidence
run reports 14,748 executed and passed / 77 skipped / 0 failed in 107.337
seconds. Three additional default-parallel solution runs pass without the
previous Avalonia compositor cleanup failure after shown test windows were
closed on their owning session.
This resolves F-014 technically on the campaign branch and partially addresses
F-010/F-019. The public-release decision remains no-go because F-001, F-002,
the 26 clean-build warnings, unpinned package graph, and the remaining
high-priority release-governance/test-truth findings are untouched.

View file

@ -214,8 +214,8 @@ did not find an actionable exception beyond the documented classes.
test that proves both exit-callback and disposal orders converge. Audit the
ordinary `SystemChildProcess` wrapper for the same inversion.
**Post-baseline resolution checkpoint (2026-08-18, uncommitted):** the working
tree now performs the ownership transfer and all child operations outside
**Post-baseline resolution checkpoint (2026-08-18, `0a934cf5`):** the campaign
branch now performs the ownership transfer and all child operations outside
`_gate`; `OnProcessExited` obtains its optional exit code without holding that
gate. A barrier-controlled regression captures the exit delegate before
unsubscription and makes child disposal wait for that callback. It times out in
@ -223,9 +223,8 @@ five seconds with the old lock shape, passes in milliseconds with the fix, and
passed 25/25 fresh-process repetitions. Launcher.Core passes 339/339. Two
fresh serialized complete-solution runs each finished under a 900-second hard
bound with 14,748 passes / 77 skips / 0 failures in 1:28.822 and 1:30.241.
F-009 remains a baseline finding until the coherent R1 checkpoint is reviewed
and committed; the current working-tree mechanism and required gates are
resolved.
F-009 remains in this historical baseline, but its mechanism and required gates
are resolved in a durable campaign-branch commit that is not yet merged.
## F-010 — Published build/test baseline materially overstates the portable gate
@ -250,6 +249,13 @@ resolved.
Fail on unexpected skips and duplicate discovery IDs; do not hand-edit test
totals into multiple living documents.
**Post-baseline gate checkpoint (2026-08-18, commit pending):** the new
repository gate emits per-assembly TRX plus a JSON summary that distinguishes
14,748 executed/passed cases from 77 reported skips and retains the known
duplicate-discovery warning in the process log. This makes the complete
portable count reproducible, but F-010 remains open until R3 classifies false
passes/skips/diagnostics and the stale public headline claims are replaced.
## F-011 — Mandatory WorldBuilder inventory is an obsolete OpenGL design guide
- **Severity:** P1 high
@ -341,6 +347,18 @@ resolved.
split environment-dependent gates explicitly. Give every job a hang timeout
and collect dumps; make the portable complete gate required before release.
**Post-baseline resolution checkpoint (2026-08-18, commit pending):**
`.github/workflows/release-gate.yml` now runs the repository-owned Release gate
on Windows for pull requests, `main` pushes, and manual dispatch. The script
auto-discovers and verifies all 12 solution test projects, runs each once in a
fresh bounded process, arms VSTest mini-dump collection before the outer
process-tree watchdog, and uploads commands, logs, TRX, environment metadata,
aggregate counts, and hashes even on failure. The exact local workflow command
passed 14,748 executed / 77 skipped / 0 failed in 107.337 seconds; an isolated
watchdog probe returned 124 at 2.107 seconds and left no child. F-014 is
technically resolved on the campaign branch, pending commit/review and actual
GitHub execution after publication.
## F-015 — Headline pass totals include hundreds of unexecuted test contracts
- **Severity:** P1 high
@ -471,6 +489,13 @@ resolved.
that proves a clean checkout. Keep tool-only exceptions explicit rather than
allowing per-project drift.
**Post-baseline partial checkpoint (2026-08-18, commit pending):** `global.json`
pins SDK feature band `10.0.300` with `latestPatch` roll-forward, and all five
CI setup sites now consume that file. `docs/release-gate.md` documents the one
complete command and its evidence. F-019 remains open: common compiler/package
settings are still duplicated, there are no package lock files or locked
restore, and the unsupported tool-project decisions have not been made.
## F-020 — The issue ledger is an unbounded mixed tracker, research log, and archive
- **Severity:** P1 high

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.