Problem
scripts/lint-assembly-warnings.ps1 enforces one strict-warning policy: exactly one -warn:5 in each csc.rsp, no analyzer arguments, and a WarningsAsErrors.ruleset with one IncludeAll Action="Error" and no weakening rules. Its response-file scan only recognizes the positive warning-level token, so the switches that undo the policy pass unnoticed.
Reproduction (repository at 9cd77e1, verified 2026-10-02)
mkdir -p /tmp/awfix/Editor
cp Editor/WallstopStudios.DataVisualizer.Editor.asmdef /tmp/awfix/Editor/
cp Editor/WarningsAsErrors.ruleset /tmp/awfix/Editor/
printf -- '-warn:5\n-nowarn:1701,CS0162\n' > /tmp/awfix/Editor/csc.rsp
pwsh -NoProfile -File scripts/lint-assembly-warnings.ps1 -Root /tmp/awfix
Actual: [assembly-warnings] OK: all 1 assembly definition(s) use maximum compiler warnings and warnings as errors without repository-local analyzer payloads, exit 0.
Expected: exit 1 naming the response file. The same fixture with -warnaserror- instead of -nowarn: also reports OK.
Evidence for the cause: the scan filters with ^(?:-|/)(?:warn|w)(?::|$) (scripts/lint-assembly-warnings.ps1:57). -nowarn:... starts with -n and -warnaserror- with -warnaserror, so neither token matches, the count of recognized arguments stays 1, and the disabling switch is never inspected.
Impact
Acceptance criteria
scripts/lint-assembly-warnings.ps1 fails, naming the response file, when a csc.rsp contains -nowarn: / -nowarn, /nowarn, or any -warnaserror / /warnaserror form that disables or weakens warnings-as-errors.
- It fails when a suppression switch is hidden from the scan, for example behind an rsp comment or a differently spelled alias the scanner does not recognize, rather than relying on a prefix list.
- Self-tests in
scripts/tests/test-assembly-warnings.ps1 cover each rejecting case as a data-driven row, and the existing clean case still passes.
npm run lint:llm:full green on ubuntu and Windows; the four committed assemblies still pass.
Notes
Found while repairing the #131 review finding, which was the same class of defect in a different guard: a machine-readable config construct the reader does not understand is silently ignored, so the check passes while the real configuration disagrees. PR #131 fixes its own guard and refuses glob constructs it cannot match instead of guessing.
Problem
scripts/lint-assembly-warnings.ps1enforces one strict-warning policy: exactly one-warn:5in eachcsc.rsp, no analyzer arguments, and aWarningsAsErrors.rulesetwith oneIncludeAll Action="Error"and no weakening rules. Its response-file scan only recognizes the positive warning-level token, so the switches that undo the policy pass unnoticed.Reproduction (repository at
9cd77e1, verified 2026-10-02)Actual:
[assembly-warnings] OK: all 1 assembly definition(s) use maximum compiler warnings and warnings as errors without repository-local analyzer payloads, exit 0.Expected: exit 1 naming the response file. The same fixture with
-warnaserror-instead of-nowarn:also reports OK.Evidence for the cause: the scan filters with
^(?:-|/)(?:warn|w)(?::|$)(scripts/lint-assembly-warnings.ps1:57).-nowarn:...starts with-nand-warnaserror-with-warnaserror, so neither token matches, the count of recognized arguments stays 1, and the disabling switch is never inspected.Impact
-warn:5drift in chore: The CSharpier gate cannot pass on a non-Windows checkout (CRLF vs LF) #129, so the policy it claims to enforce can be turned off without any signal.Acceptance criteria
scripts/lint-assembly-warnings.ps1fails, naming the response file, when acsc.rspcontains-nowarn:/-nowarn,/nowarn, or any-warnaserror//warnaserrorform that disables or weakens warnings-as-errors.scripts/tests/test-assembly-warnings.ps1cover each rejecting case as a data-driven row, and the existing clean case still passes.npm run lint:llm:fullgreen on ubuntu and Windows; the four committed assemblies still pass.Notes
Found while repairing the #131 review finding, which was the same class of defect in a different guard: a machine-readable config construct the reader does not understand is silently ignored, so the check passes while the real configuration disagrees. PR #131 fixes its own guard and refuses glob constructs it cannot match instead of guessing.