fix(windows): Invoke-Checked rejected the empty argument list every no-arg test uses (#512) - #583
Conversation
…o-arg test uses (#512) `windows-msvc-cpu` has failed on every pull request, ~21 minutes in, with zero compile diagnostics: Cannot bind argument to parameter 'Arguments' because it is an empty array. `Invoke-Checked` declared `Arguments` as `[Parameter(Mandatory)][string[]]`. PowerShell's `Mandatory` validation treats an empty collection as "not supplied", so every call that runs a test executable taking no arguments died at parameter binding before the process was ever started. There are six such production call sites, not four -- the two forced-CPU-tier invocations (`VT_CPU_MATMUL_TIER=portable` / `avx2`) are on the same path and would have failed next. The fix is `[AllowEmptyCollection()]` alongside `Mandatory`, not a `= @()` default. The existing intent is that a caller must state its argument list; `AllowEmptyCollection` keeps the omission an error while permitting an explicitly empty list, whereas a default would silently accept a call that forgot the parameter entirely. The contract step ran green all along because the suite never executed an empty-argument invocation, which is why a 21-minute build step caught what a seconds-long contract step should have. `Invoke-CheckedContractTests` closes that: it injects a recording runner -- mirroring the `DumpbinRunner` and unsupported-tier-probe seams already in this file -- and asserts the empty and non-empty argument lists are forwarded verbatim and that a nonzero status still throws on both. `Invoke-Checked` gains the matching optional `-Runner` seam. RED-first, run under pwsh 7.6.4: the new contract test fails with the exact CI message above before `[AllowEmptyCollection()]` is applied, and passes after. Five mutations of the claimed guarantees are each caught by their intended assertion (drop `AllowEmptyCollection`; swallow the argument list; never throw on nonzero; forward the wrong program; truncate the arguments), and the real `& $Program @Arguments` path -- not just the fake runner -- was exercised against `/bin/true`, `/bin/echo a b`, and `/bin/false`. The pre-existing unsupported-tier contract assertion is untouched and proven still non-vacuous: making the probe send an empty, a wrong, or a two-element argument list each still trips "did not receive one exact filter argument". That empty-args mutation also shows the fake-runner scriptblock parameters need no `AllowEmptyCollection` of their own -- being non-mandatory, they bind `@()` and fail on the assertion rather than on binding. This is a distinct defect from #514, the POSIX `setenv`/`unsetenv` C3861 error that fails `windows-msvc-vulkan`; that one is fixed on its own branch and `windows-msvc-vulkan` stays red here until it lands. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
CI result — read from the completed job, not predicted#512 is closed.
The contract step passing on the real Windows runner is the direct proof: the Baseline subtraction
The empty-array message is gone. The script ran past all six empty-argument
What #512 was masking — filed as #584
That is a defect in the test binary, not in this PowerShell change — this PR This PR is still the correct and complete fix for #512: it converts a failure |
Brings in #583, which repairs the Invoke-Checked empty-argument defect that was red on every open PR including this one, plus the Nemotron and intake records. No overlap with this branch, which touches the DSpark spec, the benchmark record, STATUS, BENCHMARKS and two standalone harnesses. Worth noting for this row specifically: BENCH-ASSERT-CLOCK-STATE (51ec6be) records that the SM clock moves 12.8% between boots. That is the same class of effect this branch records as "absolute numbers move up to 5% between sessions for the same binary", and it independently reinforces why only WITHIN-session, interleaved ratios are quotable here. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
Closes #512.
windows-msvc-cpufailed on every PR with:Invoke-Checked's$Argumentsis[Parameter(Mandatory)]and six call sites pass@()— PowerShell treats an empty collection as "not supplied".Fix
[AllowEmptyCollection()]alongsideMandatory, not a= @()default. The intent is that a caller must state its argument list, so omission should stay an error while an explicitly empty list is permitted. A fresh review proved both halves rather than accepting the argument: omission still raisesmissing mandatory parameters: Arguments, while the rejected= @()form silently accepts it.Also adds
Invoke-CheckedContractTests. The pre-existing contract suite passed green today — which proves it never exercised an empty-argument call, or it would have caught this. A 21-minute Windows build step was catching what a seconds-long local step should have.pwshruns this path on Linux, so it does now.Success criterion — narrow, and NOT "the job is green"
Closing #512 unmasked a hard crash.
test_openai_api_server.exedies with-1073740791=0xC0000409(STATUS_STACK_BUFFER_OVERRUN) before doctest prints anything — zeroStatus:lines, zeroassertions:lines, just the version banner. That binary had never once executed on Windows, so the crash was latent for as long as #512 was. Filed as #584.What this PR claims, verified from completed jobs:
windows-msvc-cpuempty arraySo: the empty-array error is gone and the script now runs past all six sites on both real Windows runners.
windows-msvc-cpucannot go green until #584 lands, andwindows-msvc-vulkanstays red on #514.🤖 Generated with Claude Code