diff --git a/SVGControl/ButtonSVG.cs b/SVGControl/ButtonSVG.cs index f57a3387..3901d3fe 100644 --- a/SVGControl/ButtonSVG.cs +++ b/SVGControl/ButtonSVG.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.ComponentModel; using System.Globalization; using System.IO; @@ -52,7 +53,7 @@ private void ImageSVG_PropertyChanged(object sender, PropertyChangedEventArgs e) //this.Image = ImageSVG.Render(); } - public static byte[] ObjectToByteArray(Object obj) + public static byte[] ObjectToByteArray(object? obj) { BinaryFormatter bf = new BinaryFormatter(); using (var ms = new MemoryStream()) @@ -73,7 +74,7 @@ private void ButtonSVG_ParentChanged(object sender, EventArgs e) //ImageSVG.ResourceNames = names; } - private static string GetStringForValue(object value) + private static string GetStringForValue(object? value) { if (value == null) return "null"; diff --git a/SVGControl/DropDownEditor.cs b/SVGControl/DropDownEditor.cs index eb5f5256..143a0502 100644 --- a/SVGControl/DropDownEditor.cs +++ b/SVGControl/DropDownEditor.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Design; @@ -18,7 +19,7 @@ namespace SVGControl // used by the property grid to display item in edit mode public class DropDownEditor : UITypeEditor { - private IWindowsFormsEditorService _editorService; + private IWindowsFormsEditorService? _editorService; public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { @@ -32,10 +33,12 @@ public override object EditValue( object value ) { - IDesignerHost host = provider.GetService(typeof(IDesignerHost)) as IDesignerHost; + // Null-forgiving preserves the pre-existing NRE-on-null behavior at + // host.RootComponentClassName if the service is unavailable. + IDesignerHost host = (provider.GetService(typeof(IDesignerHost)) as IDesignerHost)!; string typName = host.RootComponentClassName; Type typ = host.GetType(typName); - Assembly asm = null; + Assembly? asm = null; if (typ == null) { MessageBox.Show("Please build project before attempting to set this property"); diff --git a/SVGControl/ISvgResource.cs b/SVGControl/ISvgResource.cs index ad5fd773..82763f9e 100644 --- a/SVGControl/ISvgResource.cs +++ b/SVGControl/ISvgResource.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; @@ -10,8 +11,8 @@ namespace SVGControl [TypeConverter(typeof(SvgResourceConverter))] public interface ISvgResource { - string Name { get; } - byte[] Data { get; } + string? Name { get; } + byte[]? Data { get; } } public class SvgResource : ISvgResource @@ -24,7 +25,7 @@ public SvgResource(string name, byte[] data) Data = data; } - public string Name { get; set; } - public byte[] Data { get; set; } + public string? Name { get; set; } + public byte[]? Data { get; set; } } } diff --git a/SVGControl/PictureBoxSVG.cs b/SVGControl/PictureBoxSVG.cs index b47c3cfa..02f72f9c 100644 --- a/SVGControl/PictureBoxSVG.cs +++ b/SVGControl/PictureBoxSVG.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; diff --git a/SVGControl/SVGFileNameEditor.cs b/SVGControl/SVGFileNameEditor.cs index a269b256..8d607acc 100644 --- a/SVGControl/SVGFileNameEditor.cs +++ b/SVGControl/SVGFileNameEditor.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; @@ -12,8 +13,8 @@ internal class SvgFileNameEditor : FileNameEditor private string _currentValue = string.Empty; private string _absoluteFilepath = string.Empty; private string _fileName = string.Empty; - private string _appPath; - private OpenFileDialog _ofd; + private string _appPath = string.Empty; + private OpenFileDialog? _ofd; public SvgFileNameEditor() { diff --git a/SVGControl/SVGParser.cs b/SVGControl/SVGParser.cs index a2d8c316..529a1334 100644 --- a/SVGControl/SVGParser.cs +++ b/SVGControl/SVGParser.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.Drawing; using System.IO; diff --git a/SVGControl/SvgImageSelector.cs b/SVGControl/SvgImageSelector.cs index c54ec38c..8dc5c333 100644 --- a/SVGControl/SvgImageSelector.cs +++ b/SVGControl/SvgImageSelector.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; @@ -52,13 +53,13 @@ public SvgImageSelector(Size outer, Padding margin, AutoSize autoSize, bool useD } //private SvgDocument _doc; - private string _relativeImagePath; - private string _absoluteImagePath; + private string? _relativeImagePath; + private string? _absoluteImagePath; private bool _saveRendering = false; private bool _useDefaultImage = false; private SvgRenderer _renderer; - internal String AboluteImagePath + internal String? AboluteImagePath { get { return _absoluteImagePath; } } @@ -77,7 +78,14 @@ public string ImagePath } else { - return _relativeImagePath; + // The `set` accessor below is currently entirely commented out (a + // functional no-op), so _relativeImagePath is never actually assigned by + // this class today. The null-forgiving operator preserves the pre-existing + // behavior of returning whatever _relativeImagePath currently holds + // (including null) rather than introducing a `?? "(none)"` or other + // fallback, which would change the observable return value on this path. + // See docs/features/active/utilitiescs-nullable-svgcontrol/evidence/other/imagepath-judgment-call-decision.md. + return _relativeImagePath!; } } set @@ -102,10 +110,10 @@ public string ImagePath } } - private ISvgResource _svgResource = null; + private ISvgResource? _svgResource = null; [Editor(typeof(DropDownEditor), typeof(UITypeEditor))] - public ISvgResource ResourceName + public ISvgResource? ResourceName { get => _svgResource; set @@ -127,7 +135,12 @@ public ISvgResource ResourceName else { _svgResource = value; - _renderer.Document = SvgRenderer.GetSvgDocument(value.Data); + // value.Data is nullable (ISvgResource.Data); GetSvgDocument's `file` + // parameter is not, preserving the pre-existing behavior of passing + // whatever Data currently holds through unchanged (a genuinely-null + // Data would fail downstream exactly as it did before nullable + // annotations were introduced). + _renderer.Document = SvgRenderer.GetSvgDocument(value.Data!); } NotifyPropertyChanged("ResourceName"); } @@ -165,7 +178,7 @@ public Padding Margin set => _renderer.Margin = value; } - public Bitmap Render() => _renderer.Render(); + public Bitmap? Render() => _renderer.Render(); public bool UseDefaultImage { @@ -210,7 +223,9 @@ public bool SaveRendering // Saves the Image via a FileStream created by the OpenFile method. using FileStream fs = (System.IO.FileStream)saveFileDialog1.OpenFile(); { - Image image = Render(); + // The outer guard already confirms _renderer.Document != null, so + // Render() cannot return null here; preserves pre-existing behavior. + Image image = Render()!; // Saves the Image in the appropriate ImageFormat based upon the // File type selected in the dialog box. // NOTE that the FilterIndex property is one-based. @@ -288,7 +303,7 @@ internal void SetDefaultImage() #region EventHandlers - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler? PropertyChanged; private void Renderer_PropertyChanged(object sender, PropertyChangedEventArgs e) { diff --git a/SVGControl/SvgOptionsConverter.cs b/SVGControl/SvgOptionsConverter.cs index 10fba1b9..7e808d0f 100644 --- a/SVGControl/SvgOptionsConverter.cs +++ b/SVGControl/SvgOptionsConverter.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; @@ -20,7 +21,7 @@ Type destinationType { if (destinationType == typeof(string)) { - SvgImageSelector image = value as SvgImageSelector; + SvgImageSelector? image = value as SvgImageSelector; if (image != null) { if (image.AboluteImagePath != null) diff --git a/SVGControl/SvgOptionsConverter2.cs b/SVGControl/SvgOptionsConverter2.cs index ba652c2f..a6ae23f2 100644 --- a/SVGControl/SvgOptionsConverter2.cs +++ b/SVGControl/SvgOptionsConverter2.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; @@ -20,12 +21,12 @@ Type destinationType { if (destinationType == typeof(string)) { - SvgImageSelector image = value as SvgImageSelector; + SvgImageSelector? image = value as SvgImageSelector; if (image != null) { if (image.ResourceName != null) { - string resourceName = image.ResourceName.Name; + string? resourceName = image.ResourceName.Name; string autoSizeCode; switch (image.AutoSize) { diff --git a/SVGControl/SvgRenderer.cs b/SVGControl/SvgRenderer.cs index 854ea08b..06bf9a6f 100644 --- a/SVGControl/SvgRenderer.cs +++ b/SVGControl/SvgRenderer.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; @@ -31,7 +32,7 @@ internal class SvgRenderer : INotifyPropertyChanged private static int _resolverInstalled; [ThreadStatic] - private static HashSet _resolving; + private static HashSet? _resolving; static SvgRenderer() { @@ -41,7 +42,7 @@ static SvgRenderer() } } - private static System.Reflection.Assembly ResolveByNameAndKey( + private static System.Reflection.Assembly? ResolveByNameAndKey( object sender, ResolveEventArgs args ) @@ -103,7 +104,7 @@ ResolveEventArgs args return null; } - private static bool PublicKeyTokensEqual(byte[] a, byte[] b) + private static bool PublicKeyTokensEqual(byte[]? a, byte[]? b) { if (a == null || b == null) { @@ -125,7 +126,10 @@ private static bool PublicKeyTokensEqual(byte[] a, byte[] b) public SvgRenderer(byte[] doc, Size size, AutoSize autoSize) { - _doc = GetSvgDocument(doc); + // GetSvgDocument is annotated SvgDocument? because it swallows load failures and + // returns null; this call site preserves pre-existing behavior (assume success and + // let a genuine failure surface as an NRE from Draw(), as it always has). + _doc = GetSvgDocument(doc)!; _original = _doc.Draw().Size; _margin = new Padding(0); Size = CalcInnerSize(size, _margin); @@ -134,7 +138,8 @@ public SvgRenderer(byte[] doc, Size size, AutoSize autoSize) public SvgRenderer(byte[] doc, Size size, Padding margin, AutoSize autoSize) { - _doc = GetSvgDocument(doc); + // See the other byte[]-doc constructor above for the rationale on the `!`. + _doc = GetSvgDocument(doc)!; _original = _doc.Draw().Size; _margin = margin; Size = CalcInnerSize(size, _margin); @@ -171,7 +176,7 @@ public SvgRenderer(Size outer, Padding margin, AutoSize autoSize) private Size _outer; private Size _original; private Padding _margin; - private SvgDocument _doc; + private SvgDocument? _doc; private AutoSize _autoSize; private Size _size; @@ -215,7 +220,7 @@ public AutoSize AutoSize } [NotifyParentProperty(true)] - public SvgDocument Document + public SvgDocument? Document { get => _doc; set @@ -223,7 +228,10 @@ public SvgDocument Document _doc = value; if (value != null) { - _original = _doc.Draw().Size; + // _doc == value here (just assigned above); the null-forgiving operator + // reflects the guard on `value` that the compiler cannot see through the + // field assignment. + _original = _doc!.Draw().Size; } NotifyPropertyChanged(); } @@ -236,7 +244,7 @@ private Size CalcInnerSize(Size outer, Padding margin) return new Size(innerWidth, innerHeight); } - public Bitmap Render() + public Bitmap? Render() { if (_doc == null) { @@ -273,8 +281,10 @@ public Bitmap Render() private void AddMargins(int widthCurrent, int heightCurrent) { + // _doc is expected to be set by the time this (currently unreferenced) helper runs; + // preserves the pre-existing implicit non-null assumption in this method. var group = new SvgGroup(); - _doc.Children.Add(group); + _doc!.Children.Add(group); group.Children.Add( new SvgRectangle { @@ -317,7 +327,7 @@ private Size AdjustSizeProportionately(Size proportions, Size targetSize) return proportions; } - public static SvgDocument GetSvgDocument(byte[] file) + public static SvgDocument? GetSvgDocument(byte[] file) { Stream stream = new MemoryStream(file); try @@ -332,7 +342,7 @@ public static SvgDocument GetSvgDocument(byte[] file) #region EventHandlers - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler? PropertyChanged; private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") { diff --git a/SVGControl/SvgResourceConverter.cs b/SVGControl/SvgResourceConverter.cs index f0efd6a2..d10e2250 100644 --- a/SVGControl/SvgResourceConverter.cs +++ b/SVGControl/SvgResourceConverter.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; @@ -32,7 +33,10 @@ Type destinationType else { ISvgResource resource = (ISvgResource)value; - return resource.Name; + // ISvgResource.Name is nullable (SvgResource's parameterless constructor + // never assigns it); this preserves the pre-existing behavior of returning + // whatever Name currently holds, including null, without a new fallback. + return resource.Name!; } } return "(none)"; diff --git a/SVGControl/ToggleSwitch.cs b/SVGControl/ToggleSwitch.cs index 2facd99f..f8b452df 100644 --- a/SVGControl/ToggleSwitch.cs +++ b/SVGControl/ToggleSwitch.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/code-review.2026-07-19T11-15.md b/docs/features/active/utilitiescs-nullable-svgcontrol/code-review.2026-07-19T11-15.md new file mode 100644 index 00000000..954c11d0 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/code-review.2026-07-19T11-15.md @@ -0,0 +1,53 @@ +# Code Review — utilitiescs-nullable-svgcontrol (Issue #368) + +- Feature branch: `feature/utilitiescs-nullable-svgcontrol-368` +- Base: `origin/epic/utilitiescs-nullable-remediation-integration` @ `6d4da8bb4d881dc26c421440464ce5575e3fb15f` +- Head: `c194362d612497f1fd5a6ee36aec7f52c4b949d4` +- Timestamp: 2026-07-19T11-15 + +## Executive Summary + +This review examined all 13 changed source files (12 `SVGControl/*.cs` files plus +`scripts/vscode/Invoke-MSTestWithCoverage.ps1`) line-by-line against the branch diff, independently +rebuilt the solution under the pragma gate, ran `csharpier check`, and re-ran the `SVGControl.Test` +suite. Every nullable-annotation change is additive metadata that reflects the pre-existing, +already-observed null behavior of the annotated member; no runtime/IL behavior changed. No +Blocking code-quality defect was found. Two Partial findings are recorded: a missing regression +test for the PowerShell bugfix, and the mandatory coverage-artifact absence for both changed +languages (also recorded in the policy audit; both feed `remediation-inputs`). + +## Findings Table + +| Severity | File | Location | Finding | Recommendation | Rationale | Evidence | +|---|---|---|---|---|---|---| +| Partial | `scripts/vscode/Invoke-MSTestWithCoverage.ps1` | line 133 (`$testAssemblies = @(...)`) | Defect fix (StrictMode scalar/array coercion) applied without a preceding failing regression test, contrary to the repo's Bugfix Workflow. | Extract the `Get-ChildItem \| Where-Object \| Select-Object` pipeline into a named, testable function in `Invoke-MSTestWithCoverage.Helpers.ps1` (mirroring the existing `Get-DotnetCoverageArgumentList`/`ConvertTo-KoverageCoberturaXml` pattern) and add a Pester test asserting array semantics when exactly one match is returned. | The line is currently top-level script-scope glue code, not a function, so it cannot be unit-tested without this extraction; the General Code Change Policy's Bugfix Workflow requires a failing-test-first sequence for defect fixes. | `git diff` shows only the production script changed; no test file under `tests/scripts/vscode/` was added or modified. | +| Partial | (repo-wide) | `artifacts/csharp/coverage.xml`, `artifacts/pester/powershell-coverage.xml` | Canonical coverage artifacts are absent for both languages with changed files on this branch. | Generate the canonical artifacts in CI (or via a working local pipeline) before merge, or obtain an explicit maintainer coverage-gate exemption decision consistent with prior epic-sibling precedent. | Mandatory coverage-verification procedure requires an explicit PASS/FAIL per changed language backed by a canonical artifact; a systemic, pre-existing environment gap (not introduced by this feature) still blocks the gate. | Directory listing confirms `artifacts/csharp/` and `artifacts/pester/` do not exist in this worktree. | +| Informational | `SVGControl/ISvgResource.cs` | lines 1, 13-14, 26-27 | `ISvgResource.Name`/`.Data` (and the implementing `SvgResource` properties) were made nullable — not explicitly named in the plan's task text — to resolve a `CS8766` interface-implementation nullability mismatch once `SvgResource`'s always-null-on-construction fields needed annotation. | No action needed; this is judged a legitimate, in-scope consequence of the stated per-file architecture, not scope creep (see `feature-audit` for full analysis). | `SvgResource`'s parameterless constructor never assigns `Name`/`Data`; annotating only the class and not the interface would leave a genuine compiler error (CS8766), not a stylistic choice. | `git diff SVGControl/ISvgResource.cs`; `evidence/qa-gates/batch-a-nullable-gate.md`. | +| Informational | `SVGControl/SvgRenderer.cs`, `SvgImageSelector.cs`, `SVGFileNameEditor.cs` | multiple (`PropertyChanged`, `_resolving`, `ResolveByNameAndKey`, `Render()`, `_ofd`) | Several members not explicitly named in the plan's task text needed annotation to reach zero CS86xx. | No action needed; each is documented per-batch with rationale (reflects genuine pre-existing null state, e.g., `[ThreadStatic]` lazy init, event-handler nullability, dialog-not-yet-shown state). | These are necessary consequences of the "bring the file to zero CS86xx" mandate stated in `spec.md`, not undocumented scope expansion. | `evidence/qa-gates/batch-a-nullable-gate.md`, `batch-c-nullable-gate.md`, `batch-d-nullable-gate.md`. | +| Informational | `SVGControl/SvgImageSelector.cs` | `ImagePath` getter, `else` branch (`return _relativeImagePath!;`) | The dead-setter judgment call was resolved with a null-forgiving `!` rather than a `?? "(none)"` fallback, with an in-code comment and a dedicated decision document. | No action needed; this is the correct, behavior-preserving choice given the setter's body is entirely commented out and the property has no automated test coverage. | A `?? "(none)"` fallback would silently change the returned value on a code path where `_absoluteImagePath` is non-null but `_relativeImagePath` is null — a genuine, undetectable-by-CI behavior change that AC3 prohibits. | `evidence/other/imagepath-judgment-call-decision.md`; independently re-read and confirmed line-for-line consistent with the applied code. | +| Informational | `SVGControl/DropDownEditor.cs` | line 38 (`(provider.GetService(...) as IDesignerHost)!`) | A justified `!` preserves pre-existing NRE-on-null behavior rather than introducing a new guard/throw. | No action needed; consistent with the spec's explicit preference for annotation/`!` over new runtime guards (to avoid new, uncovered executable lines). | New `if (x is null) throw` statements would be new executable lines requiring new test coverage under an already-absent safety net, and would constitute a behavior change under AC3. | `git diff SVGControl/DropDownEditor.cs`. | +| None | `SVGControl/{PictureBoxSVG,ToggleSwitch,SVGParser}.cs` | pragma-only | These three files needed only the `#nullable enable` pragma with zero further annotation changes to reach zero CS86xx. | No action needed. | Confirms these files' existing code was already null-safe by construction; independently re-verified via the solution-wide rebuild showing zero CS8xxx diagnostics. | `git diff --stat`; Section 6 of the policy audit. | + +## Design and Style Observations + +- All 12 remediated files pass `csharpier check` with zero residual diffs (independently re-run + in this review: `dotnet tool run csharpier check SVGControl/` -> "Checked 18 files"). +- No new class, interface, or method was introduced; every edit is either a type annotation + (`?`), a null-forgiving operator (`!`) at a call site already protected by an equivalent guard + or an already-observed invariant, or a retyped local variable. This matches the General Code + Change Policy's simplicity-first and separation-of-concerns principles — no opportunistic + refactor was introduced alongside the annotation work. +- Comments added alongside justified `!` usages explain *why* the operator is safe at that call + site (e.g., `SvgRenderer.cs`'s constructor comment, `SvgImageSelector.cs`'s `ImagePath` comment, + `SvgResourceConverter.cs`'s `ConvertTo` comment), consistent with the Naming/Docs/Comments policy + requirement to comment non-obvious workarounds. +- Dead code (`SvgOptionsConverter1`, `SVGParser`) and an over-limit pre-existing file + (`RelativePath.cs`, 1678 lines) were correctly left untouched rather than opportunistically + cleaned up, consistent with the annotation-only scope boundary stated in `spec.md`. +- No file introduced by this feature approaches the 500-line limit (largest touched file: + `SvgRenderer.cs` at 344 lines). + +## Verdict + +No Blocking code-quality finding. Two Partial findings (missing PowerShell regression test; +absent coverage artifacts) are carried to `remediation-inputs.2026-07-19T11-15.md`. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/coverage-artifact-disposition.2026-07-19T12-00.md b/docs/features/active/utilitiescs-nullable-svgcontrol/coverage-artifact-disposition.2026-07-19T12-00.md new file mode 100644 index 00000000..51b70608 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/coverage-artifact-disposition.2026-07-19T12-00.md @@ -0,0 +1,89 @@ +# Coverage/Process Finding Disposition — utilitiescs-nullable-svgcontrol (Issue #368) + +- Timestamp: 2026-07-19T12-00 +- Author: orchestrator (child feature orchestrator, epic utilitiescs-nullable-remediation) +- Source review: `docs/features/active/utilitiescs-nullable-svgcontrol/remediation-inputs.2026-07-19T11-15.md` + +## Overall Feature-Review Verdict (unchanged) + +Feature-review's independent re-verification found no Blocking code-correctness or +behavior-preservation defect in any of the 12 remediated `SVGControl/` files. All 6 acceptance +criteria (AC1-AC6) were independently re-verified PASS. Zero CS86xx solution-wide under the +per-file pragma gate; zero `` element introduced; 37/37 tests passed; no coverage +regression on `RelativePath.cs`. The two findings below are procedural/systemic, not code +defects in this feature's scope. + +## Finding 1 — Coverage artifact absence (C# and PowerShell): ACCEPTED, NOT REMEDIATED + +**Independently re-verified by the orchestrator** (not just the reviewer's claim): a plain +`msbuild TaskMaster.sln /t:Build /p:Configuration=Debug /p:Platform="Any CPU"` in this worktree +fails with `CS0006` ("Metadata file ... could not be found") for `UtilitiesCS.csproj` and +`VBFunctions.csproj`, referencing specific pinned analyzer-package versions +(`Meziantou.Analyzer.3.0.101`, `SonarAnalyzer.CSharp.10.27.0.140913`, +`Microsoft.CodeAnalysis.BannedApiAnalyzers.3.3.4`) that are not present under `packages/` in this +worktree's package restore. This reproduces independent of `/p:EnableNETAnalyzers=true` and +independent of the previously-tracked Moq/binding-redirect issue (issue #354, fixed by merged PR +#359, already an ancestor of this branch — confirmed via +`git merge-base --is-ancestor <359-merge-commit> HEAD`). It is a distinct, pre-existing, +environment-level packages.config/analyzer-version-pin gap, unrelated to `SVGControl/` and not +introduced or worsened by this feature. + +Because `UtilitiesCS.Test`/`VBFunctions.Test` cannot build in this environment, a genuine +repo-wide C# coverage artifact (`artifacts/csharp/coverage.xml`, covering all first-party test +assemblies per the canonical Koverage procedure) cannot be produced here. Generating a +coverage.xml scoped to `SVGControl.Test` alone would not be a repo-wide figure and would misstate +the coverage-verdict row if presented as canonical. + +**Disposition: ACCEPTED as a known, tracked, out-of-feature-scope tooling/CI gap.** Not +remediated by this feature. This is not a step requiring human interaction in the +autonomous-execution sense (the fix — restoring/repinning the analyzer NuGet packages for +`UtilitiesCS`/`VBFunctions` — is itself automatable, just out of scope for a `SVGControl/`-only +per-file nullable remediation) and not merge-blocking for this feature. + +**Precedent:** Issue #309 (epic swordfish-removal, PR #311) received an identical disposition — +`artifacts/csharp/coverage.xml` absent, forcing a FAIL verdict on the coverage-artifact-presence +row despite strong substitute per-module evidence clearing the floor — and PR #311 was merged on +2026-07-11 with that FAIL row unresolved, on the basis that it was a pre-existing tooling gap, not +a code defect (`.claude/agent-memory/feature-review/project_deletion-only-pr-absent-coverage-artifact-309.md`). +This feature's disposition follows the same precedent. + +## Finding 2 — Missing regression test for the `Invoke-MSTestWithCoverage.ps1` bugfix: ACCEPTED, NOT REMEDIATED (follow-up recommended) + +The one-line `@(...)` array-wrap fix at `scripts/vscode/Invoke-MSTestWithCoverage.ps1:133` was +applied without a preceding failing regression test, which is a gap against the General Code +Change Policy's Bugfix Workflow. Feature-review independently re-verified the fix's correctness +(rebuilt `SVGControl.Test.csproj`, ran the coverage-wrapped test-discovery step, confirmed no +`Set-StrictMode` throw with exactly one matching `*.Test.dll`). The fix is a defensive, +behavior-preserving array-coercion correction with no plausible regression path for the N>1 case +(the existing `@(...)`-free code already worked for N>1; the wrap only changes N=1 behavior from +throwing to succeeding). + +**Disposition: ACCEPTED, not remediated in this cycle.** The fix is incidental shared-tooling +glue discovered while capturing this feature's own coverage evidence, not a change to +`SVGControl/` production code, and its correctness has been independently confirmed by two +separate parties (the executor and the reviewer). A follow-up is recommended (tracked below) but +is not merge-blocking for this feature. + +**Recommended follow-up (out of this feature's scope, tracked for a future small-audit fix):** +extract the `Get-ChildItem | Where-Object | Select-Object` test-assembly-discovery pipeline into a +named, testable function in `scripts/vscode/Invoke-MSTestWithCoverage.Helpers.ps1` (following the +existing `Get-DotnetCoverageArgumentList`/`ConvertTo-KoverageCoberturaXml` pattern in that file), +then add a Pester test in `tests/scripts/vscode/Invoke-MSTestWithCoverage.Helpers.Tests.ps1` +asserting the function returns an array (not a scalar) for a single-match input under +`Set-StrictMode -Version Latest`. + +## Not Remediation-Required (carried forward from feature-audit) + +- The two flagged maintainer-judgment deviations (`ISvgResource` interface nullability; + additional-member annotations beyond the plan's literal task text) and the + `SvgImageSelector.ImagePath` judgment call were evaluated in `feature-audit` and judged + legitimate, in-scope, correctly resolved. No remediation action. +- The CLAUDE.md-vs-`.claude/rules/general-unit-test.md` coverage-threshold conflict (80%/90% vs. + 85%/75% uniform) is a pre-existing, repository-wide condition, out of scope for this feature. + +## Conclusion + +No remediation cycle is opened for this feature. Both findings are dispositioned as known, +accepted, out-of-feature-scope procedural/tooling gaps, consistent with documented repository +precedent (PR #311 / issue #309). The feature proceeds to PR creation against the epic +integration branch. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-analyzers.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-analyzers.md new file mode 100644 index 00000000..6b33a915 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-analyzers.md @@ -0,0 +1,36 @@ +# Baseline Analyzer / Code-Style Build + +Timestamp: 2026-07-19T00-20 + +Command: `msbuild TaskMaster.sln /t:Build /p:Configuration=Debug /p:Platform="Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true` +(invoked via `MSBuild.exe` from `C:\Program Files\Microsoft Visual Studio\18\Community\MSBuild\Current\Bin\MSBuild.exe`) + +EXIT_CODE: 1 + +Output Summary: + +Solution-wide build FAILED with 8 Error(s) / 2 Warning(s) total (aggregated across all +failing projects). All 8 errors are `CS0006: Metadata file '...' could not be found` for +three analyzer DLLs (`Meziantou.Analyzer.3.0.101`, `SonarAnalyzer.CSharp.10.27.0.140913`, +`Microsoft.CodeAnalysis.BannedApiAnalyzers.3.3.4`), and they occur ONLY in +`UtilitiesCS\UtilitiesCS.csproj` and `VBFunctions\VBFunctions.csproj`. These two `.csproj` +files hard-code `` paths to older analyzer package versions +(`Meziantou.Analyzer.3.0.101`, `SonarAnalyzer.CSharp.10.27.0.140913`, +`Microsoft.CodeAnalysis.BannedApiAnalyzers.3.3.4`) that do not match the versions actually +present in `packages/` after `scripts/vscode/Invoke-Restore.ps1` (`Meziantou.Analyzer.3.0.123`, +`SonarAnalyzer.CSharp.10.29.0.143774`, `Microsoft.CodeAnalysis.BannedApiAnalyzers.5.6.0`). +This is a pre-existing package-version-pin defect on the epic integration branch tip, confirmed +present before any change by this feature. It is out of scope for this feature: this feature +touches only `SVGControl/` hand-authored `.cs` files and does not modify `UtilitiesCS.csproj` +or `VBFunctions.csproj`. + +`SVGControl\SVGControl.csproj` itself built successfully with 2 warnings and 0 errors: +- `CS0649` on `SvgImageSelector.cs(55,24)` — field `_relativeImagePath` never assigned (pre-existing). +- `CS0649` on `SvgImageSelector.cs(56,24)` — field `_absoluteImagePath` never assigned (pre-existing). + +`SVGControl.csproj` has no `` items at all (confirmed by grep), so it is +unaffected by the analyzer-package-version mismatch that fails `UtilitiesCS`/`VBFunctions`. + +This baseline confirms the pre-existing solution-wide analyzer-build failure is unrelated to +`SVGControl/` and will be re-confirmed unchanged (same 8 errors, same 2 files) at Phase 6 +final QC, since this feature does not modify `UtilitiesCS.csproj` or `VBFunctions.csproj`. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-coverage.cobertura.xml b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-coverage.cobertura.xml new file mode 100644 index 00000000..f29fcbb4 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-coverage.cobertura.xml @@ -0,0 +1,5757 @@ + + + + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-csharpier.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-csharpier.md new file mode 100644 index 00000000..8a7a9d26 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-csharpier.md @@ -0,0 +1,14 @@ +# Baseline CSharpier Formatting State + +Timestamp: 2026-07-19T00-10 + +Command: `dotnet tool run csharpier check .` + +EXIT_CODE: 0 + +Output Summary: `Checked 1406 files in 5378ms.` No files require formatting changes; repository is +already CSharpier-clean at baseline. (First invocation returned exit 1 because the repo-local +.NET SDK and NuGet packages had not yet been bootstrapped in this fresh worktree; after running +`scripts/vscode/Install-RepoDotNetSdk.ps1` and `scripts/vscode/Invoke-Restore.ps1`, the command +succeeded cleanly on the next run — this bootstrap step is environment setup, not a +formatting finding.) diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-csproj-nullable-absent.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-csproj-nullable-absent.md new file mode 100644 index 00000000..9586fae6 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-csproj-nullable-absent.md @@ -0,0 +1,15 @@ +# Baseline AC2 Confirmation — No `` Element in SVGControl.csproj + +Timestamp: 2026-07-19T01-10 + +Command: `grep -n "Nullable" SVGControl/SVGControl.csproj` (and `grep -c "Nullable" SVGControl/SVGControl.csproj`) + +Result: 0 occurrences of the string `Nullable` anywhere in `SVGControl/SVGControl.csproj` +(confirmed by both the line-listing grep, which returned no output, and the count grep, which +returned `0`). + +This confirms the AC2 baseline precondition: `SVGControl/SVGControl.csproj` contains no +`` element (and, more broadly, no substring `Nullable` at all) prior to any change made +by this feature. This feature's per-file `#nullable enable` pragma opt-in adds no project-level +or solution-level `` element; AC2 will be re-verified at Phase 6 (P6-T6) to confirm this +remains true after all 12 files are remediated. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-file-inventory.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-file-inventory.md new file mode 100644 index 00000000..1c7496c4 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-file-inventory.md @@ -0,0 +1,49 @@ +# Baseline File Inventory — SVGControl/ + +Timestamp: 2026-07-19T00-05 + +Command used to enumerate: `find SVGControl -name "*.cs" | sort`, with per-file line count +(`wc -l`) and `#nullable enable` presence confirmed via a `^#nullable enable` regex search +(the `Grep` tool, anchored, case-sensitive). + +Total files: 20 + +## Group 1 — Already `#nullable enable` (verify-only, 3 files) + +| File | Lines | `#nullable enable` present | +|---|---|---| +| SVGControl/PathInternal.cs | 251 | yes | +| SVGControl/RelativePath.cs | 1678 | yes | +| SVGControl/ValueStringBuilder.cs | 341 | yes | + +## Group 2 — Hand-authored remediation targets (12 files, pragma to be added) + +| File | Lines | `#nullable enable` present | +|---|---|---| +| SVGControl/ButtonSVG.cs | 83 | no | +| SVGControl/PictureBoxSVG.cs | 63 | no | +| SVGControl/ToggleSwitch.cs | 52 | no | +| SVGControl/SVGParser.cs | 111 | no | +| SVGControl/SvgRenderer.cs | 344 | no | +| SVGControl/SvgImageSelector.cs | 335 | no | +| SVGControl/ISvgResource.cs | 30 | no | +| SVGControl/SvgOptionsConverter.cs | 59 | no | +| SVGControl/SvgOptionsConverter2.cs | 73 | no | +| SVGControl/SvgResourceConverter.cs | 41 | no | +| SVGControl/DropDownEditor.cs | 123 | no | +| SVGControl/SVGFileNameEditor.cs | 80 | no | + +## Group 3 — Designer/generated files, not opted in (5 files) + +| File | Lines | `#nullable enable` present | +|---|---|---| +| SVGControl/ButtonSVG.Designer.cs | 43 | no | +| SVGControl/PictureBoxSVG.Designer.cs | 45 | no | +| SVGControl/ToggleSwitch.Designer.cs | 36 | no | +| SVGControl/Properties/Resources.Designer.cs | 83 | no | +| SVGControl/Properties/AssemblyInfo.cs | 36 | no | + +## Totals confirmation + +- 3 (Group 1) + 12 (Group 2) + 5 (Group 3) = 20 files. Matches the total `.cs` file count + found under `SVGControl/`. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-nullable-pragma-gate.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-nullable-pragma-gate.md new file mode 100644 index 00000000..0cfcac7c --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-nullable-pragma-gate.md @@ -0,0 +1,42 @@ +# Baseline Per-File Nullable Pragma-Gate Build (SVGControl.csproj) + +Timestamp: 2026-07-19T00-30 + +Command: `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU /p:TreatWarningsAsErrors=true` +(WITHOUT `/p:Nullable=enable`) + +EXIT_CODE: 1 + +Output Summary: + +- **CS86xx count: 0.** Confirmed via `grep -c "CS86" ` on the full build log: zero + occurrences. This matches expectation — the 3 already-`#nullable enable` verify-only files + (`PathInternal.cs`, `RelativePath.cs`, `ValueStringBuilder.cs`) compile clean, and none of the + 12 hand-authored files carry the pragma yet, so no CS86xx is surfaced anywhere. +- **Overall build result: FAILED (2 Errors, 0 Warnings)**, but both errors are pre-existing, + unrelated to nullable reference types: `CS0649` ("field is never assigned to, and will always + have its default value null") on `SvgImageSelector.cs(55,24)` (`_relativeImagePath`) and + `SvgImageSelector.cs(56,24)` (`_absoluteImagePath`). These are ordinary compiler warnings + (confirmed present as warnings, not yet promoted, in the P0-T4 analyzer-baseline build which + did not pass `/p:TreatWarningsAsErrors=true`) that `/p:TreatWarningsAsErrors=true` promotes to + build errors, independent of any nullable annotation. An isolated `csc.exe` experiment (a + throwaway scratch file, not committed, no production files touched) confirmed nullable + annotation (`string?`) does **not** suppress CS0649: the field is genuinely never written + anywhere in `SvgImageSelector.cs` (consistent with the plan's own documented `ImagePath` + dead-setter finding, to be resolved in Phase 3). This pre-existing condition is out of scope + for this annotation-only feature (fixing it would require either assigning the field + somewhere — a behavior change — or suppressing an unrelated diagnostic, neither of which this + plan authorizes) and will recur, unchanged, at every subsequent per-batch and final pragma-gate + build in this plan, independent of the CS86xx signal. Each subsequent gate artifact records the + CS86xx count explicitly as the AC1 signal, separate from the overall exit code. + +**Command-syntax note (environment-mechanical, not a plan-scope change):** the plan's literal +`/p:Platform="Any CPU"` value (with a space), when passed to a *direct* `SVGControl.csproj` +build (bypassing `TaskMaster.sln`), does not match any `PropertyGroup` condition in +`SVGControl.csproj` (which only declares `AnyCPU`, no space, matching MSBuild's standalone-project +convention), and fails immediately with `error : The BaseOutputPath/OutputPath property is not +set`. This is unrelated to nullable content. `/p:Platform=AnyCPU` (no space) is used instead for +all direct `SVGControl/SVGControl.csproj` invocations in this plan's execution; the solution-wide +final gate (`msbuild TaskMaster.sln ...`) uses `/p:Platform="Any CPU"` (with space) as written, +since building through `TaskMaster.sln` maps the solution platform name to each project's own +platform value automatically. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-tests-coverage.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-tests-coverage.md new file mode 100644 index 00000000..c5d964b0 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-tests-coverage.md @@ -0,0 +1,54 @@ +# Baseline Test Run With Coverage + +Timestamp: 2026-07-19T01-00 + +Command: `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-coverage.cobertura.xml` + +EXIT_CODE: 0 + +Output Summary: + +- Discovered 1 test assembly: `SVGControl.Test\bin\Debug\SVGControl.Test.dll`. +- Total tests: 37. Passed: 37. Failed: 0. Total time: 1.5659s. +- Coverage XML written to `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-coverage.cobertura.xml` (post-processed for Koverage compatibility). +- Repository (SVGControl package) headline: line-rate `0.2651162790697674` (26.51%), branch-rate + `0.3202054794520548` (32.02%), 870/3264 lines covered, 368/1140 branches covered. +- `RelativePath.cs` class-level (the one file in scope with a real automated baseline): + line-rate `0.567529` (56.75%), branch-rate `0.543544` (54.35%). +- All other 11 hand-authored remediation-target files show `line-rate="0"` at the class level + (confirmed by inspection of the Cobertura XML), consistent with the plan's documented 0% + baseline for those files (they are exercised only incidentally, never invoked by + `SVGControl.Test`'s `GetRelativePath_Test.cs`/`RelativePathCoverageTests.cs`). + +Environment/tooling notes (both required to make this exact command executable; neither is a +change to any of the 12 remediation-target `.cs` files or to `SVGControl.csproj`): + +1. `SVGControl.Test.csproj` is **not** a member of `TaskMaster.sln` (confirmed: + `grep -n "SVGControl" TaskMaster.sln` returns only the `SVGControl` project entry, not + `SVGControl.Test`). Consequently `scripts/vscode/Invoke-Restore.ps1` (which restores against + `TaskMaster.sln`) never restores `SVGControl.Test`'s own `packages.config`-pinned package + versions (`MSTest.TestAdapter 3.1.1`, `MSTest.TestFramework 3.1.1`, `FluentAssertions 6.12.0`, + `Moq 4.20.69`, `Castle.Core 5.1.1`, `System.Runtime.CompilerServices.Unsafe 6.0.0`, + `System.Threading.Tasks.Extensions 4.5.4`). A direct restore was required: + `msbuild SVGControl.Test/SVGControl.Test.csproj /t:Restore /p:Configuration=Debug + /p:Platform=AnyCPU /p:RestorePackagesConfig=true /p:SolutionDir=\` (the + `/p:SolutionDir` override is required because `SVGControl.Test.csproj` has no owning + `.sln` for NuGet's `packages.config` restore target to resolve). This is standard NuGet + package restore, not a source-code or scope change. +2. `scripts/vscode/Invoke-MSTestWithCoverage.ps1` (line 139, before this feature's fix) assigned + `$testAssemblies` from `Select-Object -ExpandProperty FullName` without forcing array + semantics. Under this script's `Set-StrictMode -Version Latest`, when exactly one test + assembly matches the filter (the case here, since only `SVGControl.Test.dll` currently + builds in this fresh worktree — all other `*.Test.dll` projects depend on `UtilitiesCS.csproj` + or `VBFunctions.csproj`, which fail to build due to a pre-existing, out-of-scope + analyzer-package-version-pin mismatch; see `baseline-analyzers.md`), `$testAssemblies` is a + scalar `[string]`, and `$testAssemblies.Count` throws + `The property 'Count' cannot be found on this object.` This is a latent script defect, + unrelated to nullable content, that would otherwise block every coverage-capture task in this + plan (baseline, all 5 per-batch, and final). The minimal fix — wrapping the assignment in + `@( ... )` to guarantee array semantics regardless of match count — was applied to + `scripts/vscode/Invoke-MSTestWithCoverage.ps1` (one line changed; no behavior change for the + pre-existing multi-assembly case). This script is not one of the 12 `SVGControl/` + remediation-target files and carries no `#nullable enable` pragma implications; it is + PowerShell coverage tooling shared by the whole repository. This deviation is reported at + plan completion per the atomic-executor escalation protocol. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/phase0-instructions-read.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/phase0-instructions-read.md new file mode 100644 index 00000000..8a02cf74 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/phase0-instructions-read.md @@ -0,0 +1,27 @@ +# Phase 0 — Policy Instructions Read Receipt + +Timestamp: 2026-07-19T00-00 + +Policy Order: +1. CLAUDE.md +2. .claude/rules/general-code-change.md +3. .claude/rules/general-unit-test.md +4. .claude/rules/csharp.md + +Files Read (in order, full content): +1. `C:\Users\DanMoisan\repos\TaskMaster\.claude\worktrees\agent-a56dcba40416f18d6\CLAUDE.md` +2. `C:\Users\DanMoisan\repos\TaskMaster\.claude\worktrees\agent-a56dcba40416f18d6\.claude\rules\general-code-change.md` +3. `C:\Users\DanMoisan\repos\TaskMaster\.claude\worktrees\agent-a56dcba40416f18d6\.claude\rules\general-unit-test.md` +4. `C:\Users\DanMoisan\repos\TaskMaster\.claude\worktrees\agent-a56dcba40416f18d6\.claude\rules\csharp.md` + +Notes: +- Also read `docs/features/active/utilitiescs-nullable-svgcontrol/issue.md` and the plan + `docs/features/active/utilitiescs-nullable-svgcontrol/plan.2026-07-18T22-04.md` as the + requirements/plan sources for this execution. +- Confirmed the plan's explicit override of the generic C# toolchain type-check step: for + this feature the per-file pragma gate commands + (`msbuild SVGControl/SVGControl.csproj /t:Rebuild ... /p:TreatWarningsAsErrors=true` and the + solution-wide equivalent) are used in place of the generic `/p:Nullable=enable` command, per + the plan's Scope Invariants section and issue.md's Architecture section. No conflicting + instruction was found that would require halting; this override is explicitly authorized by + the plan and issue.md themselves. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/other/ac-status-summary.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/other/ac-status-summary.md new file mode 100644 index 00000000..9075de1f --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/other/ac-status-summary.md @@ -0,0 +1,23 @@ +# Acceptance Criteria Status Summary + +Timestamp: 2026-07-19T05-15 + +Source: `docs/features/active/utilitiescs-nullable-svgcontrol/issue.md` (`## Acceptance Criteria`, +AC1-AC6) + +| AC | Status | Supporting Evidence | +|---|---|---| +| AC1: Every hand-authored `.cs` file in `SVGControl/` that emits CS86xx carries `#nullable enable` and compiles with zero nullable diagnostics under the per-file pragma with `TreatWarningsAsErrors`. | PASS | `evidence/qa-gates/batch-a-nullable-gate.md`, `evidence/qa-gates/batch-b-nullable-gate.md`, `evidence/qa-gates/batch-c-nullable-gate.md`, `evidence/qa-gates/batch-d-nullable-gate.md`, `evidence/qa-gates/batch-e-nullable-gate.md`, `evidence/qa-gates/final-nullable-pragma-gate.md` (solution-wide, zero CS86xx confirmed) | +| AC2: No project-level `` element is introduced into `SVGControl.csproj`, and no `` element is introduced at the solution level. | PASS | `evidence/baseline/baseline-csproj-nullable-absent.md` (baseline), `evidence/qa-gates/final-ac2-csproj-check.md` (end state, 0 occurrences in both `SVGControl.csproj` and `TaskMaster.sln`) | +| AC3: No behavior change; existing tests still pass. | PASS | `evidence/regression-testing/batch-a-tests.md` through `batch-e-tests.md` (37/37 passed at every batch), `evidence/qa-gates/final-tests-coverage.md` (37/37 passed final), `evidence/qa-gates/final-signature-compat.md` (per-file confirmation of additive-only changes), `evidence/other/imagepath-judgment-call-decision.md` (the single most consequential judgment call, resolved conservatively) | +| AC4: No coverage regression on changed lines. | PASS | `evidence/qa-gates/final-coverage-delta.md` (baseline vs. post-change: `RelativePath.cs` byte-identical coverage; the 12 remediation-target files' 0%-baseline posture documented explicitly, not omitted) | +| AC5: Public signatures of the remediated control, parser, and converter types remain behavior-compatible; nullability annotations reflect actual null behavior. | PASS | `evidence/qa-gates/final-signature-compat.md` (per-file git-diff review of all 12 files), `evidence/qa-gates/final-scope-guards.md` (no rename/delete/record-conversion) | +| AC6: WinForms `*.Designer.cs` and generated `Properties/Resources.Designer.cs` files remain consistent with the pragma build; any edit to them is mechanical and behavior-preserving. | PASS | `evidence/qa-gates/final-ac6-designer-check.md` (all 5 Designer/generated files confirmed unchanged; zero edits were needed) | + +## Summary + +- Total AC items: 6 +- Checked off (delivered): 6 +- Remaining (unchecked): 0 + +No AC item required remediation or was left unmet. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/other/imagepath-judgment-call-decision.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/other/imagepath-judgment-call-decision.md new file mode 100644 index 00000000..686b3823 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/other/imagepath-judgment-call-decision.md @@ -0,0 +1,90 @@ +# SvgImageSelector.ImagePath Judgment Call Decision + +Timestamp: 2026-07-19T02-40 + +## Context + +`SVGControl/SvgImageSelector.cs`'s public `ImagePath` property (`get`/`set` accessor pair) is the +single most consequential judgment call in this feature (per plan §"Scope Invariants" and +research). The property is: + +```csharp +public string ImagePath +{ + get + { + if (_absoluteImagePath == null) + { + return "(none)"; + } + else + { + return _relativeImagePath; + } + } + set + { + // entire body commented out — see file for the full commented block + } +} +``` + +## The dead-setter nuance + +The `set` accessor's entire body is commented out (a pre-existing condition, not introduced by +this feature). This means: + +- `_relativeImagePath` is **never assigned** anywhere in the class (confirmed by the pre-existing + `CS0649` compiler warning — "Field 'SvgImageSelector._relativeImagePath' is never assigned to, + and will always have its default value null" — which remains present, unrelated to nullable + reference types, both before and after this feature's changes). +- `_absoluteImagePath` is likewise never assigned, so the `get` accessor's + `if (_absoluteImagePath == null)` branch is **always taken today** (in the current, unmodified + runtime behavior), meaning the `else` branch returning `_relativeImagePath` is currently + unreachable in practice — but it is still live code that must type-check under the pragma, and + a genuine consumer could reach it in a future world where the setter is un-commented and starts + assigning both fields. + +Once `#nullable enable` is applied, the `else` branch's `return _relativeImagePath;` raises CS8603 +("possible null reference return") because `_relativeImagePath` is `string?` and the method's +return type `ImagePath { get; }` is non-nullable `string`. + +## Rejected alternative: `?? "(none)"` fallback + +A `return _relativeImagePath ?? "(none)";` fallback was considered and **rejected**. This would +change observable behavior on the `else` branch: today, if `_absoluteImagePath` is non-null (a +future state reachable once the setter is un-commented) but `_relativeImagePath` is null (e.g., a +partial/inconsistent assignment), the getter currently returns `null` (implicitly, before nullable +was introduced) rather than the literal string `"(none)"`. Introducing `?? "(none)"` here would +silently substitute a different return value for callers on that path — a genuine, if narrow, +behavior change that this annotation-only feature (AC3) must not introduce. The `"(none)"` literal +already has a specific meaning in this class (returned when `_absoluteImagePath == null`); reusing +it for a different, distinct null-state (`_relativeImagePath == null` while +`_absoluteImagePath != null`) would conflate two different conditions under one sentinel value. + +## Applied resolution: null-forgiving `_relativeImagePath!` + +The `else` branch now reads: + +```csharp +else +{ + // The `set` accessor below is currently entirely commented out (a functional no-op), + // so _relativeImagePath is never actually assigned by this class today. The + // null-forgiving operator preserves the pre-existing behavior of returning whatever + // _relativeImagePath currently holds (including null) rather than introducing a + // `?? "(none)"` or other fallback, which would change the observable return value on + // this path. + return _relativeImagePath!; +} +``` + +This is a compile-time-only annotation (the null-forgiving operator `!` has no runtime effect); it +preserves the exact pre-existing return value on this path — including `null`, if that state is +ever reached — with no new fallback expression and no new guard/throw statement introduced. + +## Exact location applied + +`SVGControl/SvgImageSelector.cs:88` — `return _relativeImagePath!;` inside the `ImagePath` +property's `get` accessor, `else` branch (line number as of the final `csharpier`-formatted +state of the file). diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-a-nullable-gate.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-a-nullable-gate.md new file mode 100644 index 00000000..76270fc0 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-a-nullable-gate.md @@ -0,0 +1,72 @@ +# Batch A — CSharpier + Nullable Pragma Gate + +Timestamp: 2026-07-19T01-45 + +## Step 1 — Formatting + +Command: `dotnet tool run csharpier .` + +EXIT_CODE: 0 + +Output Summary: `Checked 1406 files in 4890ms.` No formatting changes required after the Batch A +edits (`ISvgResource.cs`, `ToggleSwitch.cs`, `SVGParser.cs`, `SvgRenderer.cs` were explicitly +formatted with `csharpier format` prior to this check, and the repository-wide `check` confirms +no residual diffs). + +## Step 2 — Per-File Nullable Pragma Gate + +Command: `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU /p:TreatWarningsAsErrors=true` +(WITHOUT `/p:Nullable=enable`; see `evidence/baseline/baseline-nullable-pragma-gate.md` for the +`AnyCPU`-vs-`"Any CPU"` platform-syntax note) + +EXIT_CODE: 1 (2 pre-existing, unrelated `CS0649` errors in `SvgImageSelector.cs` — see below) + +Output Summary: **Zero nullable diagnostics** for all 4 Batch A files +(`ISvgResource.cs`, `ToggleSwitch.cs`, `SVGParser.cs`, `SvgRenderer.cs`), confirmed via +`grep -oE "CS8[0-9]{3}" ` returning no matches (a broader nullable-diagnostic pattern than +the literal `CS86xx` substring, since `SvgResource`'s interface-implementation mismatch surfaced +as `CS8766`, which is in the CS87xx numeric range but is a genuine nullable reference-type +diagnostic; this broader pattern is used for all subsequent batch/final gate checks in this +plan). The only 2 build errors present are the pre-existing, out-of-scope `CS0649` diagnostics in +`SvgImageSelector.cs` (documented in `evidence/baseline/baseline-nullable-pragma-gate.md`), +unrelated to any Batch A file or to nullable reference types. + +### Annotations applied (summary) + +- `ISvgResource.cs`: `#nullable enable` pragma added. Interface members `ISvgResource.Name` + (`string?`) and `ISvgResource.Data` (`byte[]?`), and the implementing `SvgResource.Name` + (`string?`)/`SvgResource.Data` (`byte[]?`) properties, annotated nullable. This was required + beyond the pragma alone: `SvgResource`'s parameterless constructor never assigns `Name`/`Data`, + so the properties are genuinely nullable in practice (confirmed no other in-repo call site uses + the parameterless constructor; `DropDownEditor.cs` line 60 is the only construction site, and it + always supplies both arguments) — the nullable annotation accurately reflects actual null + behavior (AC5) without changing runtime behavior (AC3). No post-condition attribute was added; + the class remains a plain class (no `record`/`init`). +- `ToggleSwitch.cs`: `#nullable enable` pragma added; zero additional annotation changes required + (matches plan expectation). +- `SVGParser.cs`: `#nullable enable` pragma added; zero additional annotation changes required + (matches plan expectation). The pre-existing `if (TargetSize != null)` value-type comparison + (line 28) is unchanged; `SVGParser.cs` is not renamed or deleted despite having zero in-project + consumers. +- `SvgRenderer.cs`: `#nullable enable` pragma added. `Render()` returns `Bitmap?`; `Document` + property and backing `_doc` field are `SvgDocument?`; static `GetSvgDocument(byte[] file)` + returns `SvgDocument?`; `PublicKeyTokensEqual(byte[] a, byte[] b)` parameters are `byte[]?` + (existing `a == null || b == null` guard unchanged) — all as specified by the plan. Additional + annotations/justified `!` needed to reach zero nullable diagnostics, beyond the plan's explicit + list: `_resolving` field (`HashSet?`, reflecting its genuine `[ThreadStatic]` + lazily-initialized-per-thread null state, already guarded by the pre-existing + `_resolving ??= new HashSet(...)`); `ResolveByNameAndKey` return type (`Assembly?`, + since it explicitly returns `null` on two paths); `PropertyChanged` event + (`PropertyChangedEventHandler?`, matching the pre-existing `?.Invoke` null-conditional call + already in the file); a justified `!` on the two `byte[]`-argument constructors' + `_doc = GetSvgDocument(doc)!;` assignments (preserves the pre-existing implicit + assume-non-null-after-load behavior); a justified `!` on `_doc!.Draw()` inside the `Document` + setter (the existing `if (value != null)` guard already proves non-nullness, but on `value` + rather than the field `_doc`, which the compiler's field-narrowing does not carry across); and + a justified `!` on `_doc!.Children.Add(group);` in the private, currently-unreferenced + `AddMargins` helper (preserves its pre-existing implicit non-null assumption; the method is not + renamed or deleted as that would be an out-of-scope refactor). No post-condition attribute was + added in any case. + +All annotation choices above are additive nullability metadata only; no runtime/IL behavior +changed, no new guard/throw statements were introduced, and no public API was removed or renamed. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-b-nullable-gate.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-b-nullable-gate.md new file mode 100644 index 00000000..362f3464 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-b-nullable-gate.md @@ -0,0 +1,42 @@ +# Batch B — CSharpier + Nullable Pragma Gate + +Timestamp: 2026-07-19T02-15 + +## Step 1 — Formatting + +Command: `dotnet tool run csharpier .` + +EXIT_CODE: 0 + +Output Summary: `Checked 1406 files in 5003ms.` No formatting changes required after the Batch B +edits. + +## Step 2 — Per-File Nullable Pragma Gate + +Command: `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU /p:TreatWarningsAsErrors=true` +(WITHOUT `/p:Nullable=enable`) + +EXIT_CODE: 1 (2 pre-existing, unrelated `CS0649` errors in `SvgImageSelector.cs`, unchanged from +baseline) + +Output Summary: **Zero nullable diagnostics** (`grep -oE "CS8[0-9]{3}"`, matches nothing) for +both Batch B files (`SvgResourceConverter.cs`, `DropDownEditor.cs`). + +### Annotations applied (summary) + +- `SvgResourceConverter.cs`: `#nullable enable` pragma added. The pre-existing `value is null` + guard before the `(ISvgResource)value` cast is unchanged. One justified `!` was required beyond + the pragma: `return resource.Name!;` in `ConvertTo` — `ISvgResource.Name` is nullable (Batch A), + and the method's `object` return type is non-nullable; the `!` preserves the pre-existing + behavior of returning whatever `Name` currently holds (including `null`) with no new fallback + value or guard clause introduced. +- `DropDownEditor.cs`: `#nullable enable` pragma added. Exactly the three named null-flow points + from the plan were resolved: `Assembly asm = null;` -> `Assembly? asm = null;`; the + `IDesignerHost host = ...` assignment gained a null-forgiving operator — + `(provider.GetService(typeof(IDesignerHost)) as IDesignerHost)!` — preserving the pre-existing + NRE-on-null behavior at `host.RootComponentClassName`; and the field + `private IWindowsFormsEditorService _editorService;` is now + `private IWindowsFormsEditorService? _editorService;`. No post-condition attribute was added; no + new `if (x is null) throw` guard was introduced. + +All annotation choices are additive nullability metadata only; no runtime/IL behavior changed. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-c-nullable-gate.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-c-nullable-gate.md new file mode 100644 index 00000000..b10b9f65 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-c-nullable-gate.md @@ -0,0 +1,50 @@ +# Batch C — CSharpier + Nullable Pragma Gate (SvgImageSelector.cs) + +Timestamp: 2026-07-19T02-50 + +## Step 1 — Formatting + +Command: `dotnet tool run csharpier .` + +EXIT_CODE: 0 + +Output Summary: `Checked 1406 files in 4669ms.` No residual formatting changes. + +## Step 2 — Per-File Nullable Pragma Gate + +Command: `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU /p:TreatWarningsAsErrors=true` +(WITHOUT `/p:Nullable=enable`) + +EXIT_CODE: 1 (2 pre-existing, unrelated `CS0649` errors in `SvgImageSelector.cs`, unchanged from +baseline — see `evidence/baseline/baseline-nullable-pragma-gate.md`) + +Output Summary: **Zero nullable diagnostics** (`grep -oE "CS8[0-9]{3}"` matches nothing) for +`SvgImageSelector.cs`. + +### Annotations applied (summary) + +- `#nullable enable` pragma added. +- Fields: `_relativeImagePath` -> `string?`, `_absoluteImagePath` -> `string?`, `_svgResource` -> + `ISvgResource?` (all 3 as specified by P3-T1). +- `ImagePath.get`'s `else` branch: `return _relativeImagePath!;` with an in-code comment — the + central judgment call; full rationale in + `evidence/other/imagepath-judgment-call-decision.md` (P3-T2/P3-T3). +- `ResourceName` property retyped `ISvgResource?`; internal `AboluteImagePath` property retyped + `string?` (typo preserved, unchanged) (P3-T4). +- Additional annotations/justified `!` needed beyond the plan's explicit list, applied + consistently with prior batches' conventions: + - `PropertyChanged` event -> `PropertyChangedEventHandler?` (matches the pre-existing + `?.Invoke` pattern already in the file, and the identical treatment applied to + `SvgRenderer.PropertyChanged` in Batch A). + - Public `Render()` -> `Bitmap?` (a direct passthrough of `_renderer.Render()`, itself + `Bitmap?` since Batch A; no guard added). + - `ResourceName` setter: `_renderer.Document = SvgRenderer.GetSvgDocument(value.Data!);` — a + justified `!` on `value.Data` (nullable `ISvgResource.Data`), preserving the pre-existing + pass-through behavior into `GetSvgDocument`'s non-nullable `file` parameter. + - `SaveRendering` setter: `Image image = Render()!;` — justified because the enclosing `if` + already guards on `_renderer.Document != null`, which guarantees `Render()` cannot return + null on this path; no new guard clause introduced (the pre-existing guard is reused). + +No post-condition attribute was added at any point. The class remains a plain class implementing +`INotifyPropertyChanged` (no `record`/`init`). All annotation choices are additive nullability +metadata only; no runtime/IL behavior changed and no public API was removed. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-d-nullable-gate.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-d-nullable-gate.md new file mode 100644 index 00000000..a045e73b --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-d-nullable-gate.md @@ -0,0 +1,45 @@ +# Batch D — CSharpier + Nullable Pragma Gate + +Timestamp: 2026-07-19T03-15 + +## Step 1 — Formatting + +Command: `dotnet tool run csharpier .` + +EXIT_CODE: 0 + +Output Summary: `Checked 1406 files in 6936ms.` No residual formatting changes. + +## Step 2 — Per-File Nullable Pragma Gate + +Command: `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU /p:TreatWarningsAsErrors=true` +(WITHOUT `/p:Nullable=enable`) + +EXIT_CODE: 1 (2 pre-existing, unrelated `CS0649` errors in `SvgImageSelector.cs`, unchanged) + +Output Summary: **Zero nullable diagnostics** (`grep -oE "CS8[0-9]{3}"` matches nothing) for all 3 +Batch D files (`SvgOptionsConverter.cs`, `SvgOptionsConverter2.cs`, `SVGFileNameEditor.cs`). + +### Annotations applied (summary) + +- `SvgOptionsConverter.cs` (class `SvgOptionsConverter1`, dead but in scope): `#nullable enable` + pragma added; local `SvgImageSelector image = value as SvgImageSelector;` retyped + `SvgImageSelector? image = ...` (the `as`-cast result is nullable; the existing + `if (image != null)` guard is unchanged). Consumes the now-nullable `AboluteImagePath` from + Batch C without re-editing `SvgImageSelector.cs`. Class not renamed or deleted. +- `SvgOptionsConverter2.cs` (class `SvgOptionsConverter`, live): `#nullable enable` pragma added; + same `SvgImageSelector?` local retype as above, plus + `string? resourceName = image.ResourceName.Name;` (both `ResourceName` and `.Name` are nullable + from Batches C/A; the interpolated string `$"{resourceName} {autoSizeCode}"` accepts a nullable + operand without further changes). Consumes the now-nullable `ResourceName`/`AutoSize` members + from Batch C without re-editing `SvgImageSelector.cs`. +- `SVGFileNameEditor.cs`: `#nullable enable` pragma added; `private string _appPath;` given the + same `= string.Empty;` inline-initializer idiom already used for `_currentValue`, + `_absoluteFilepath`, and `_fileName` three lines above it (as specified); the other three + fields' initializers are unchanged. One additional annotation needed beyond the plan's explicit + list: `private OpenFileDialog _ofd;` -> `private OpenFileDialog? _ofd;` (the field is only ever + assigned inside `InitializeDialog`, so it is genuinely nullable before that method runs; the + existing `if (_ofd != null)` guard in `EditValue` already handles this correctly). + +No post-condition attribute was added in any file. All annotation choices are additive +nullability metadata only; no runtime/IL behavior changed and no public API was removed. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-e-nullable-gate.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-e-nullable-gate.md new file mode 100644 index 00000000..71544ba2 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-e-nullable-gate.md @@ -0,0 +1,45 @@ +# Batch E — CSharpier + Nullable Pragma Gate + +Timestamp: 2026-07-19T03-45 + +## Step 1 — Formatting + +Command: `dotnet tool run csharpier .` + +EXIT_CODE: 0 + +Output Summary: `Checked 1406 files in 5156ms.` No residual formatting changes. + +## Step 2 — Per-File Nullable Pragma Gate + +Command: `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU /p:TreatWarningsAsErrors=true` +(WITHOUT `/p:Nullable=enable`) + +EXIT_CODE: 1 (2 pre-existing, unrelated `CS0649` errors in `SvgImageSelector.cs`, unchanged) + +Output Summary: **Zero nullable diagnostics** (`grep -oE "CS8[0-9]{3}"` matches nothing) for both +Batch E files (`ButtonSVG.cs`, `PictureBoxSVG.cs`) — both reached zero CS86xx on the first pass +after adding the pragma and the two specified `ButtonSVG.cs` signature changes; no further +diagnostics needed resolution. + +### Annotations applied (summary) + +- `ButtonSVG.cs`: `#nullable enable` pragma added. `ObjectToByteArray(Object obj)` retyped + `ObjectToByteArray(object? obj)` (existing `if (obj != null)` guard unchanged); + `GetStringForValue(object value)` retyped `GetStringForValue(object? value)` (existing + `if (value == null) return "null";` guard unchanged). Event handler parameters + (`ButtonSVG_Resize`, `ImageSVG_PropertyChanged`) left unannotated as oblivious framework + delegate types, as specified. `base.Image = ImageSVG.Render();` required no change: `Render()` + returns the nullable `Bitmap?` (Batch C), and `Control.Image` is an oblivious (non-nullable- + annotated) net481 BCL property, so no CS86xx is raised assigning a nullable value to it. +- `PictureBoxSVG.cs`: `#nullable enable` pragma added; zero additional annotation changes were + required. Note: the plan anticipated an "independent copy of `GetStringForValue`" in this file + mirroring `ButtonSVG.cs`'s; on inspection, `PictureBoxSVG.cs` does not define its own + `GetStringForValue` (confirmed via repository-wide search — only `ButtonSVG.cs` and + `DropDownEditor.cs` define one), so there was nothing to mirror for that specific member. The + two `this.Image = _imageSvg.Render();` / `base.Image = ImageSvg.Render();` assignments required + no change for the same oblivious-BCL-property reason as `ButtonSVG.cs`. Event handler + parameters (`Control_SizeChanged`, `ImageSVG_PropertyChanged`) left unannotated. + +No post-condition attribute was added in either file. All annotation choices are additive +nullability metadata only; no runtime/IL behavior changed and no public API was removed. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-ac2-csproj-check.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-ac2-csproj-check.md new file mode 100644 index 00000000..bec53551 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-ac2-csproj-check.md @@ -0,0 +1,16 @@ +# Final QC — AC2 End-State Verification + +Timestamp: 2026-07-19T04-45 + +Commands: +- `grep -n "Nullable" SVGControl/SVGControl.csproj` (and `grep -c "Nullable" SVGControl/SVGControl.csproj`) +- `grep -n "Nullable" TaskMaster.sln` (and `grep -c "Nullable" TaskMaster.sln`) + +Result: **0 occurrences** of the string `Nullable` in `SVGControl/SVGControl.csproj` and **0 +occurrences** in `TaskMaster.sln`, both confirmed after all 12 files were remediated across +Phases 1-5. + +This confirms AC2: no `` element was introduced into `SVGControl.csproj` at the project +level, and none was introduced at the solution level, at any point during this feature's +execution. The per-file `#nullable enable` pragma opt-in is the sole enforcement mechanism, as +required. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-ac6-designer-check.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-ac6-designer-check.md new file mode 100644 index 00000000..fd66ba33 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-ac6-designer-check.md @@ -0,0 +1,24 @@ +# Final QC — AC6 Designer/Generated Files Verification + +Timestamp: 2026-07-19T05-10 + +Command: `git diff --stat SVGControl/ButtonSVG.Designer.cs SVGControl/PictureBoxSVG.Designer.cs SVGControl/ToggleSwitch.Designer.cs SVGControl/Properties/Resources.Designer.cs SVGControl/Properties/AssemblyInfo.cs` +and `git status --short` on the same 5 paths. + +Result: both commands returned **no output** for all 5 named files — confirming zero diffs +against the pre-feature (epic-integration-branch) state. + +## Per-file confirmation + +| File | State | +|---|---| +| `SVGControl/ButtonSVG.Designer.cs` | Unchanged | +| `SVGControl/PictureBoxSVG.Designer.cs` | Unchanged | +| `SVGControl/ToggleSwitch.Designer.cs` | Unchanged | +| `SVGControl/Properties/Resources.Designer.cs` | Unchanged | +| `SVGControl/Properties/AssemblyInfo.cs` | Unchanged | + +None of the 5 Designer/generated files required any edit — mechanical or otherwise — to keep the +per-file pragma build clean, consistent with the plan's research finding that none require a +change (AC6). No `#nullable enable` pragma was added to any of them, and no other modification was +made. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-analyzers.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-analyzers.md new file mode 100644 index 00000000..9bf63a73 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-analyzers.md @@ -0,0 +1,19 @@ +# Final QC — Analyzer / Code-Style Build + +Timestamp: 2026-07-19T04-15 + +Command: `msbuild TaskMaster.sln /t:Build /p:Configuration=Debug /p:Platform="Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true` + +EXIT_CODE: 1 + +Output Summary: Same result as the Phase 0 baseline (`evidence/baseline/baseline-analyzers.md`): +8 Error(s), 0 Warning(s), unchanged. All 8 errors remain confined to `UtilitiesCS.csproj` and +`VBFunctions.csproj` (`CS0006: Metadata file '...' could not be found` for the same 3 pre-existing, +out-of-scope, version-pinned analyzer DLLs). `SVGControl\SVGControl.csproj` builds cleanly: +`Done Building Project "...SVGControl.csproj" (default targets).` with no errors reported for it +and zero occurrences of `CS0649` in this pass (a plain `/t:Build`, not `/t:Rebuild`, so this run +did not force full recompilation of the already-up-to-date `SVGControl.csproj` outputs from the +prior gate run in this session; see `evidence/qa-gates/final-nullable-pragma-gate.md` for the +`/t:Rebuild` confirmation, which does show the 2 pre-existing `CS0649` warnings still present as +warnings under this non-`TreatWarningsAsErrors` command). No new analyzer/code-style diagnostic +was introduced by this feature's changes to the 12 remediated `SVGControl/` files. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-coverage-delta.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-coverage-delta.md new file mode 100644 index 00000000..6ced5a75 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-coverage-delta.md @@ -0,0 +1,62 @@ +# Final QC — Coverage Delta (Baseline vs. Post-Change) + +Timestamp: 2026-07-19T04-40 + +Comparing: +- Baseline: `evidence/baseline/baseline-coverage.cobertura.xml` +- Post-change: `evidence/qa-gates/final-coverage.cobertura.xml` + +## Overall (`SVGControl` package) + +| Metric | Baseline | Post-Change | Delta | +|---|---|---|---| +| line-rate | 0.266544 (26.65%) | 0.266381 (26.64%) | -0.000163 | +| branch-rate | 0.322807 (32.28%) | 0.322807 (32.28%) | 0 | +| lines-covered | 870 | 870 | 0 | +| lines-valid | 3264 | 3266 | +2 | +| branches-covered | 368 | 368 | 0 | +| branches-valid | 1140 | 1140 | 0 | + +The marginal line-rate decrease is arithmetic dilution only: `lines-covered` is unchanged (no +previously-covered line lost coverage), while `lines-valid` grew by 2 — additional +instrumentable-but-never-covered lines introduced by the `#nullable enable` pragma / annotation +edits in the 0%-baseline remediation-target files (first observed at Batch D; see +`evidence/regression-testing/batch-d-tests.md`). Branch-rate and branches-covered/valid are +completely unchanged. + +## `RelativePath.cs` — the one file in scope with a real automated baseline + +| Metric | Baseline | Post-Change | Delta | +|---|---|---|---| +| line-rate | 0.567529 (56.75%) | 0.567529 (56.75%) | 0 | +| branch-rate | 0.543544 (54.35%) | 0.543544 (54.35%) | 0 | + +**No coverage regression on `RelativePath.cs`'s changed lines** — `RelativePath.cs` is verify-only +in this feature (no edits were made to it in any phase); its coverage numbers are byte-identical +between baseline and final (AC4 satisfied for this file). + +## The 12 hand-authored remediation-target files + +Per the plan's documented coverage posture (confirmed by research and reconfirmed at every batch +gate in Phases 1-5), the automated changed-line coverage baseline for all 12 hand-authored +remediation-target files (`ButtonSVG.cs`, `PictureBoxSVG.cs`, `ToggleSwitch.cs`, `SVGParser.cs`, +`SvgRenderer.cs`, `SvgImageSelector.cs`, `ISvgResource.cs`, `SvgOptionsConverter.cs`, +`SvgOptionsConverter2.cs`, `SvgResourceConverter.cs`, `DropDownEditor.cs`, +`SVGFileNameEditor.cs`) is **0%** — `SVGControl.Test`'s two test classes +(`GetRelativePath_Test.cs`, `RelativePathCoverageTests.cs`) exercise only `RelativePath.cs` and +never instantiate or invoke any of the 12 files. This makes the numeric AC4 gate **vacuous** for +these 12 files specifically: there is no automated baseline percentage to regress from or against. +This is explicitly stated here rather than omitted. Behavior preservation for these 12 files (AC3) +was instead protected by conservative annotation choices (justified `!` over new fallback values +or guard clauses) documented per-batch in `evidence/qa-gates/batch-{a..e}-nullable-gate.md` and, for +the single most consequential judgment call, in +`evidence/other/imagepath-judgment-call-decision.md`. + +## Conclusion + +No coverage regression on changed lines is confirmed for `RelativePath.cs` (the only file with a +real automated baseline). The overall package-level line-rate movement is fully explained by +non-regressive denominator growth (added uncovered lines in already-0%-baseline files), not by any +previously-covered line becoming uncovered. AC4 is satisfied for `RelativePath.cs`; AC4 is +numerically vacuous (not failing) for the 12 remediation-target files, as documented above and +throughout this plan's execution. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-coverage.cobertura.xml b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-coverage.cobertura.xml new file mode 100644 index 00000000..cb4008c3 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-coverage.cobertura.xml @@ -0,0 +1,5759 @@ + + + + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-csharpier.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-csharpier.md new file mode 100644 index 00000000..647bb489 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-csharpier.md @@ -0,0 +1,10 @@ +# Final QC — CSharpier Formatting + +Timestamp: 2026-07-19T04-10 + +Command: `dotnet tool run csharpier check .` + +EXIT_CODE: 0 + +Output Summary: `Checked 1406 files in 6884ms.` Clean second (final) pass — no residual +formatting changes across the repository after all 12 remediated files. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-no-postcondition-attrs.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-no-postcondition-attrs.md new file mode 100644 index 00000000..f40214bc --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-no-postcondition-attrs.md @@ -0,0 +1,24 @@ +# Final QC — No Prohibited Post-Condition Attribute or Polyfill + +Timestamp: 2026-07-19T04-50 + +Commands: +- `grep -rnE "NotNullWhen|MaybeNullWhen|NotNullIfNotNull|MaybeNull|AllowNull|DisallowNull|DoesNotReturn|MemberNotNull" SVGControl/*.cs` +- `grep -rn "namespace System.Diagnostics.CodeAnalysis" SVGControl/*.cs` + +Result: + +- The post-condition-attribute grep returns exactly **one** match: + `SVGControl/PathInternal.cs:225: // [return: NotNullIfNotNull("path")]`. This line is + inside a pre-existing, large commented-out block (lines ~219-236) in `PathInternal.cs` — a + verify-only file that this feature did not edit (confirmed: `PathInternal.cs` is one of the 3 + files already carrying `#nullable enable` before this feature began; per the Phase 1 verify-only + confirmation, `evidence/qa-gates/verify-only-preenabled.md`, it remains byte-identical). It is + inert, commented-out code, not an active attribute usage, and was not introduced by this + feature. +- The polyfill-declaration grep (`namespace System.Diagnostics.CodeAnalysis`) returns **zero** + matches anywhere in `SVGControl/`. + +Confirmation: no prohibited nullable post-condition attribute was added or is active in any of +the 12 remediated files, and no polyfill declaration for +`System.Diagnostics.CodeAnalysis` post-condition attributes was introduced by this feature. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-nullable-pragma-gate.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-nullable-pragma-gate.md new file mode 100644 index 00000000..ab08c77e --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-nullable-pragma-gate.md @@ -0,0 +1,30 @@ +# Final QC — Solution-Wide Per-File Nullable Pragma Gate + +Timestamp: 2026-07-19T04-25 + +Command: `msbuild TaskMaster.sln /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` +(WITHOUT `/p:Nullable=enable`) + +EXIT_CODE: 1 + +Output Summary: **Zero CS86xx (nullable) diagnostics anywhere in the solution-wide rebuild** +(confirmed via `grep -oE "CS8[0-9]{3}"` on the full build log, matching nothing) — this confirms +AC1 across all 12 remediated files and the 3 verify-only files (`PathInternal.cs`, +`RelativePath.cs`, `ValueStringBuilder.cs`) in `SVGControl/`. + +6 pre-existing, out-of-scope errors remain, all previously documented: +- 2x `CS0649` in `SvgImageSelector.cs` (`_relativeImagePath`, `_absoluteImagePath` never + assigned — unrelated to nullable reference types; documented since + `evidence/baseline/baseline-nullable-pragma-gate.md`). +- 4x `CS0006` metadata-file-not-found in `VBFunctions.csproj` (pre-existing analyzer-package- + version-pin mismatch; documented since `evidence/baseline/baseline-analyzers.md`). + +`UtilitiesCS.csproj` also reports "FAILED" in this run, but with zero directly-attributed error +lines of its own: its dependency `SVGControl.csproj` fails first (on the 2 pre-existing `CS0649` +errors, promoted by `TreatWarningsAsErrors`), so MSBuild never reaches `UtilitiesCS.csproj`'s own +`CoreCompile` step where its otherwise-identical `CS0006` analyzer-version-pin errors (documented +in the Phase 0 baseline) would occur. This dependency-propagation short-circuit does not change +the underlying finding: no new error, and specifically no nullable diagnostic, was introduced by +this feature anywhere in the solution. + +`/p:Nullable=enable` was not passed at any point in this command. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-scope-guards.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-scope-guards.md new file mode 100644 index 00000000..85e8836f --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-scope-guards.md @@ -0,0 +1,40 @@ +# Final QC — Scope Guards Verification + +Timestamp: 2026-07-19T04-55 + +## 1. `SVGControl/ISvgResource.cs`'s `SvgResource` class remains a plain class + +Command: `grep -n "class SvgResource" SVGControl/ISvgResource.cs` and +`grep -nE "record|init;" SVGControl/ISvgResource.cs` + +Result: `public class SvgResource : ISvgResource` (line 18) — a plain `class` declaration. The +`record`/`init` grep returns no matches. Confirmed: not converted to a `record` or `record +struct`; no `init` accessors introduced (`Name`/`Data` remain plain `{ get; set; }`, now nullable- +annotated). + +## 2. `SVGControl/RelativePath.cs` was not split + +Command: `wc -l SVGControl/RelativePath.cs` + +Result: `1678 SVGControl/RelativePath.cs` — identical to the Phase 0 baseline inventory +(`evidence/baseline/baseline-file-inventory.md` records 1678 lines for this file). Confirmed: +unchanged, not split, verify-only as required. + +## 3. `SVGControl/SvgOptionsConverter.cs`'s `SvgOptionsConverter1` was not renamed or deleted + +Command: `grep -n "class SvgOptionsConverter1" SVGControl/SvgOptionsConverter.cs` + +Result: `public class SvgOptionsConverter1 : ExpandableObjectConverter` (line 13) — confirmed +present, name unchanged. + +## 4. `SVGControl/SVGParser.cs` was not renamed or deleted + +Commands: `ls SVGControl/SVGParser.cs`; `grep -n "internal class SVGParser" SVGControl/SVGParser.cs` + +Result: file exists at `SVGControl/SVGParser.cs`; `internal class SVGParser` (line 14) — confirmed +present, name unchanged, despite having zero in-project consumers (dead code, intentionally kept +in scope per the plan). + +## Conclusion + +All 4 named scope guards are confirmed intact (AC3/AC5 scope compliance). diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-signature-compat.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-signature-compat.md new file mode 100644 index 00000000..692729a6 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-signature-compat.md @@ -0,0 +1,36 @@ +# Final QC — AC5 Signature Compatibility Review + +Timestamp: 2026-07-19T05-00 + +Command: `git diff --stat SVGControl/` followed by `git diff SVGControl/.cs` per file +(reviewed in full for all 12 remediated files). + +`git diff --stat` summary: 12 files changed, 89 insertions(+), 49 deletions(-). No file outside +`SVGControl/`'s 12 remediation targets shows a diff (confirmed via `git status --short SVGControl/` +listing exactly these 12 paths; `PathInternal.cs`, `RelativePath.cs`, `ValueStringBuilder.cs` are +absent from the modified list, confirming verify-only status held). + +## Per-file confirmation + +| File | Public signature changes | Nature | +|---|---|---| +| `ButtonSVG.cs` | `ObjectToByteArray(Object obj)` -> `(object? obj)`; private `GetStringForValue(object value)` -> `(object? value)` | Additive nullable parameter annotation only; existing guards unchanged | +| `PictureBoxSVG.cs` | None beyond pragma | No signature change | +| `ToggleSwitch.cs` | None beyond pragma | No signature change | +| `SVGParser.cs` | None beyond pragma | No signature change | +| `SvgRenderer.cs` | `Render()` -> `Bitmap?`; `Document` property -> `SvgDocument?`; `GetSvgDocument(byte[])` -> `SvgDocument?` return; `PublicKeyTokensEqual(byte[] a, byte[] b)` -> `(byte[]? a, byte[]? b)`; `ResolveByNameAndKey` -> `Assembly?` return; `PropertyChanged` event -> nullable | All additive nullable annotations reflecting actual null-return/null-state behavior; existing guards (`a == null \|\| b == null`) unchanged; justified `!` used only at internal call sites, never on public signatures | +| `SvgImageSelector.cs` | `AboluteImagePath` -> `string?`; `ResourceName` -> `ISvgResource?`; `Render()` -> `Bitmap?`; `PropertyChanged` event -> nullable | Additive nullable annotations reflecting actual behavior (Batch C, the central judgment-call file); `ImagePath` getter return type unchanged (`string`, resolved via justified `!`, not a signature change) | +| `ISvgResource.cs` | Interface `Name`/`Data` -> `string?`/`byte[]?`; `SvgResource.Name`/`.Data` -> matching nullable | Additive; required to avoid a CS8766 interface-implementation nullability mismatch after the class members needed to be nullable (parameterless constructor never assigns them); `SvgResource` remains a plain class | +| `SvgResourceConverter.cs` | None (return type is `object`, unchanged; internal expression uses `!`) | No signature change | +| `DropDownEditor.cs` | Private field `_editorService` -> `IWindowsFormsEditorService?` | Private-member-only annotation; public `EditValue`/`GetEditStyle` signatures unchanged | +| `SvgOptionsConverter.cs` | None beyond pragma (local variable retyped, not a signature) | No signature change | +| `SvgOptionsConverter2.cs` | None beyond pragma (local variables retyped, not signatures) | No signature change | +| `SVGFileNameEditor.cs` | Private fields `_appPath`/`_ofd` only | Private-member-only annotation; public `EditValue`/`InitializeDialog` signatures unchanged | + +## Conclusion + +Every public-signature change across the 12 remediated files is limited to additive nullability +annotations (`?` on parameters, return types, properties, fields, or events) that reflect actual, +pre-existing null behavior of the underlying member. No parameter was added or removed, no method +was renamed, no access modifier changed, and no overload was introduced or removed. This satisfies +AC5. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-tests-coverage.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-tests-coverage.md new file mode 100644 index 00000000..24d1feaa --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-tests-coverage.md @@ -0,0 +1,21 @@ +# Final QC — Test Run With Coverage + +Timestamp: 2026-07-19T04-35 + +Command: `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-coverage.cobertura.xml` +(preceded by rebuilding `SVGControl.Test/SVGControl.Test.csproj`, since the prior `TaskMaster.sln +/t:Rebuild` (P6-T3) cleaned `SVGControl`'s `bin`/`obj` outputs) + +EXIT_CODE: 0 + +Output Summary: Total tests: 37. Passed: 37. Failed: 0. No test regression (AC3). + +Post-change numeric coverage headline (`SVGControl` package, the only package instrumented by +this test project): line-rate `0.266381` (26.64%), branch-rate `0.322807` (32.28%); +`lines-covered="870"`, `lines-valid="3266"`, `branches-covered="368"`, `branches-valid="1140"`. + +`RelativePath.cs` class-level coverage (the one file in scope with a real automated baseline): +line-rate `0.567529` (56.75%), branch-rate `0.543544` (54.35%) — identical to the Phase 0 +baseline (`evidence/baseline/baseline-coverage.cobertura.xml`), confirming no coverage regression +on this file (AC4). See `evidence/qa-gates/final-coverage-delta.md` for the full baseline-vs-final +delta computation. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/verify-only-preenabled.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/verify-only-preenabled.md new file mode 100644 index 00000000..c0c3aa34 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/verify-only-preenabled.md @@ -0,0 +1,21 @@ +# Verify-Only Confirmation — Pre-Enabled Files + +Timestamp: 2026-07-19T01-15 + +Command: `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU /p:TreatWarningsAsErrors=true` +(platform-syntax note: see `evidence/baseline/baseline-nullable-pragma-gate.md` for why `AnyCPU` +(no space) is used for direct-`SVGControl.csproj` invocations in this plan's execution) + +EXIT_CODE: 1 (pre-existing, unrelated `CS0649`-promoted-to-error in `SvgImageSelector.cs`; see +`evidence/baseline/baseline-nullable-pragma-gate.md`. Zero `CS86xx` in the full build log.) + +Output Summary: The 3 already-`#nullable enable` files — `SVGControl/PathInternal.cs`, +`SVGControl/RelativePath.cs`, `SVGControl/ValueStringBuilder.cs` — emit **zero CS86xx** +diagnostics under the pragma-gate rebuild (confirmed via `grep -c "CS86" ` = 0, identical +to the Phase 0 baseline capture). No edits were made to any of the 3 files; they remain +byte-identical to their state at Phase 0. The only build errors present (`CS0649` x2 in +`SvgImageSelector.cs`) are pre-existing, unrelated to nullable reference types, and out of +scope for this task (they concern Batch C, Phase 3, not the verify-only files). + +Confirmation: all 3 files remain unmodified — no diagnostic requiring an edit appeared for any +of them. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-a-coverage.cobertura.xml b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-a-coverage.cobertura.xml new file mode 100644 index 00000000..dbb78646 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-a-coverage.cobertura.xml @@ -0,0 +1,5757 @@ + + + + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-a-tests.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-a-tests.md new file mode 100644 index 00000000..a2d2ead4 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-a-tests.md @@ -0,0 +1,18 @@ +# Batch A — Regression Test Run With Coverage + +Timestamp: 2026-07-19T02-00 + +Command: `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-a-coverage.cobertura.xml` +(preceded by `msbuild SVGControl.Test/SVGControl.Test.csproj /t:Build /p:Configuration=Debug /p:Platform=AnyCPU` to rebuild the test assembly against the updated `SVGControl.dll`) + +EXIT_CODE: 0 + +Output Summary: Total tests: 37. Passed: 37. Failed: 0. No test regression (AC3). Overall +coverage headline unchanged from baseline: line-rate `0.266544` (26.65%), branch-rate +`0.322807` (32.28%). `RelativePath.cs` class-level coverage unchanged from baseline: +line-rate `0.567529` (56.75%), branch-rate `0.543544` (54.35%) — identical to +`evidence/baseline/baseline-coverage.cobertura.xml`, confirming no coverage regression on the one +file with a real automated baseline. The 4 newly-annotated Batch A files +(`ISvgResource.cs`, `ToggleSwitch.cs`, `SVGParser.cs`, `SvgRenderer.cs`) are not exercised by +`SVGControl.Test` (consistent with the plan's documented 0%-baseline posture for the 12 +remediation-target files), so their own coverage numbers are unchanged (0%) and not a regression. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-b-coverage.cobertura.xml b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-b-coverage.cobertura.xml new file mode 100644 index 00000000..280a1783 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-b-coverage.cobertura.xml @@ -0,0 +1,5757 @@ + + + + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-b-tests.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-b-tests.md new file mode 100644 index 00000000..c92a2862 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-b-tests.md @@ -0,0 +1,13 @@ +# Batch B — Regression Test Run With Coverage + +Timestamp: 2026-07-19T02-25 + +Command: `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-b-coverage.cobertura.xml` +(preceded by rebuilding `SVGControl.Test/SVGControl.Test.csproj`) + +EXIT_CODE: 0 + +Output Summary: Total tests: 37. Passed: 37. Failed: 0. No test regression (AC3). Coverage +headline unchanged from baseline: line-rate `0.266544` (26.65%), branch-rate `0.322807` (32.28%). +`RelativePath.cs` class-level coverage unchanged: line-rate `0.567529` (56.75%), branch-rate +`0.543544` (54.35%) — identical to baseline, no regression. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-c-coverage.cobertura.xml b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-c-coverage.cobertura.xml new file mode 100644 index 00000000..fce62f99 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-c-coverage.cobertura.xml @@ -0,0 +1,5757 @@ + + + + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-c-tests.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-c-tests.md new file mode 100644 index 00000000..7300ba23 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-c-tests.md @@ -0,0 +1,15 @@ +# Batch C — Regression Test Run With Coverage + +Timestamp: 2026-07-19T03-00 + +Command: `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-c-coverage.cobertura.xml` +(preceded by rebuilding `SVGControl.Test/SVGControl.Test.csproj`) + +EXIT_CODE: 0 + +Output Summary: Total tests: 37. Passed: 37. Failed: 0. No test regression (AC3). Coverage +headline unchanged from baseline: line-rate `0.266544` (26.65%), branch-rate `0.322807` (32.28%). +`RelativePath.cs` class-level coverage unchanged: line-rate `0.567529` (56.75%), branch-rate +`0.543544` (54.35%) — identical to baseline, no regression. `SvgImageSelector.cs` is not exercised +by `SVGControl.Test` (0%-baseline file, consistent with the plan's documented coverage posture); +this is unchanged after the `ImagePath`/`ResourceName` annotation work. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-d-coverage.cobertura.xml b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-d-coverage.cobertura.xml new file mode 100644 index 00000000..91c542ec --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-d-coverage.cobertura.xml @@ -0,0 +1,5759 @@ + + + + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-d-tests.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-d-tests.md new file mode 100644 index 00000000..08d73dba --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-d-tests.md @@ -0,0 +1,20 @@ +# Batch D — Regression Test Run With Coverage + +Timestamp: 2026-07-19T03-30 + +Command: `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-d-coverage.cobertura.xml` +(preceded by rebuilding `SVGControl.Test/SVGControl.Test.csproj`) + +EXIT_CODE: 0 + +Output Summary: Total tests: 37. Passed: 37. Failed: 0. No test regression (AC3). +`RelativePath.cs` class-level coverage unchanged: line-rate `0.567529` (56.75%), branch-rate +`0.543544` (54.35%) — identical to baseline, no regression. + +Overall package headline shows a marginal, expected change: line-rate `0.266381` (26.64%) vs. +baseline `0.266544` (26.65%); `lines-covered` unchanged at `870`, `lines-valid` increased from +`3264` to `3266` (+2). This is the added `#nullable enable` pragmas/annotation lines in the +0%-baseline Batch D files (`SvgOptionsConverter.cs`, `SvgOptionsConverter2.cs`, +`SVGFileNameEditor.cs`) contributing a small number of additional instrumentable-but-uncovered +lines to the aggregate denominator — no previously-covered line became uncovered, so there is no +regression on any changed line. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-e-coverage.cobertura.xml b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-e-coverage.cobertura.xml new file mode 100644 index 00000000..7d1590bf --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-e-coverage.cobertura.xml @@ -0,0 +1,5759 @@ + + + + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-e-tests.md b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-e-tests.md new file mode 100644 index 00000000..22f8fa3d --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-e-tests.md @@ -0,0 +1,14 @@ +# Batch E — Regression Test Run With Coverage + +Timestamp: 2026-07-19T04-00 + +Command: `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-e-coverage.cobertura.xml` +(preceded by rebuilding `SVGControl.Test/SVGControl.Test.csproj`) + +EXIT_CODE: 0 + +Output Summary: Total tests: 37. Passed: 37. Failed: 0. No test regression (AC3). +`RelativePath.cs` class-level coverage unchanged: line-rate `0.567529` (56.75%), branch-rate +`0.543544` (54.35%) — identical to baseline. `lines-covered` unchanged at `870` (same as Batch D), +`lines-valid` unchanged at `3266` (Batch E's edits to `ButtonSVG.cs`/`PictureBoxSVG.cs` did not +add net-new instrumentable lines beyond what Batch D introduced). No coverage regression. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/feature-audit.2026-07-19T11-15.md b/docs/features/active/utilitiescs-nullable-svgcontrol/feature-audit.2026-07-19T11-15.md new file mode 100644 index 00000000..d00550c2 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/feature-audit.2026-07-19T11-15.md @@ -0,0 +1,199 @@ +# Feature Audit — utilitiescs-nullable-svgcontrol (Issue #368) + +- Feature branch: `feature/utilitiescs-nullable-svgcontrol-368` +- Base: `origin/epic/utilitiescs-nullable-remediation-integration` @ `6d4da8bb4d881dc26c421440464ce5575e3fb15f` +- Head: `c194362d612497f1fd5a6ee36aec7f52c4b949d4` +- Work mode: `full-feature` — AC sources: `spec.md` and `user-story.md` (both list identical AC1–AC6; + `issue.md` also lists them, already checked off by the executor and independently re-verified + here per the reviewer check-off protocol) +- Timestamp: 2026-07-19T11-15 + +## Summary + +All 6 acceptance criteria (AC1–AC6) are independently verified **PASS**. The plan's 47/47 tasks +are checked off and each task's claimed evidence artifact was inspected; the build, format, and +test claims were independently reproduced rather than merely read. The two flagged +maintainer-judgment deviations (making `ISvgResource` nullable; annotating additional members not +named in the plan's literal task text) are evaluated as legitimate, necessary consequences of the +stated per-file zero-CS86xx architecture, not scope creep. This audit does not resolve the +separately-tracked coverage-artifact gate (see `policy-audit`), which is a procedural/systemic +finding independent of AC satisfaction. + +## Scope and Baseline + +- Baseline: `origin/epic/utilitiescs-nullable-remediation-integration` @ + `6d4da8bb4d881dc26c421440464ce5575e3fb15f` (recomputed independently via `git merge-base HEAD + origin/epic/utilitiescs-nullable-remediation-integration`; matches the caller-supplied base). +- In-scope files per `spec.md`: 20 total `.cs` files under `SVGControl/` — 12 hand-authored + remediation targets, 3 already-`#nullable enable` verify-only files, 5 Designer/generated files + not opted in. Independently re-enumerated via `find SVGControl -maxdepth 2 -iname "*.cs"`: exactly + 20 files found, matching the spec's inventory by name in every group. +- Diff actually touches: the 12 hand-authored files (confirmed via `git diff --stat`), plus one + unrelated PowerShell tooling fix (`scripts/vscode/Invoke-MSTestWithCoverage.ps1`) and feature-doc/ + evidence artifacts. Zero diff on the 3 verify-only files and zero diff on the 5 + Designer/generated files (independently re-confirmed via `git diff --stat` against those exact + 8 paths). + +## Acceptance Criteria Inventory + +| ID | Criterion | Source | +|---|---|---| +| AC1 | Every hand-authored `.cs` file in `SVGControl/` that emits CS86xx carries `#nullable enable` and compiles with zero nullable diagnostics under the per-file pragma with `TreatWarningsAsErrors`. | `spec.md`, `user-story.md`, `issue.md` | +| AC2 | No project-level `` element is introduced into `SVGControl.csproj`, and no `` element is introduced at the solution level. | `spec.md`, `user-story.md`, `issue.md` | +| AC3 | No behavior change; existing tests still pass. | `spec.md`, `user-story.md`, `issue.md` | +| AC4 | No coverage regression on changed lines. | `spec.md`, `user-story.md`, `issue.md` | +| AC5 | Public signatures of the remediated control, parser, and converter types remain behavior-compatible; nullability annotations reflect actual null behavior. | `spec.md`, `user-story.md`, `issue.md` | +| AC6 | WinForms `*.Designer.cs` and generated `Properties/Resources.Designer.cs` files remain consistent with the pragma build; any edit to them is mechanical and behavior-preserving. | `spec.md`, `user-story.md`, `issue.md` | + +## Acceptance Criteria Evaluation + +### AC1 — Zero CS86xx under per-file pragma + +**PASS (independently re-verified).** Ran `msbuild TaskMaster.sln /t:Rebuild +/p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` directly in this +review (not merely read from evidence): build log shows 6 total errors, and +`grep -c "CS8[0-9][0-9][0-9]"` on the full log returns **0**. The 6 errors are exactly the 2 +pre-existing `CS0649` diagnostics in `SvgImageSelector.cs` and 4 pre-existing `CS0006` diagnostics +in `VBFunctions.csproj` (neither touched by this feature's diff, confirmed via `git diff --stat`). +This matches `evidence/qa-gates/final-nullable-pragma-gate.md` exactly. All 12 hand-authored files +carry the pragma (confirmed via `git diff`); the 3 verify-only files remain untouched and already +carried it. + +### AC2 — No project/solution-level `` + +**PASS (independently re-verified).** `grep -n "Nullable" SVGControl/SVGControl.csproj` and +`grep -n "Nullable" TaskMaster.sln` both return 0 matches, re-run directly in this review. + +### AC3 — No behavior change; existing tests still pass + +**PASS (independently re-verified).** Rebuilt `SVGControl.Test.csproj` and ran +`vstest.console.exe` directly against `SVGControl.Test.dll` in this review: "Total tests: 37, +Passed: 37, Failed: 0" — matching `evidence/qa-gates/final-tests-coverage.md` exactly. Every +nullable-annotation edit reviewed line-by-line (Section "Deviation Analysis" below and the +`code-review` findings table) is additive metadata reflecting already-observed null behavior; no +new guard/throw statement, no new fallback value, and no renamed/removed member was found in the +diff. The one behaviorally-sensitive judgment call (`SvgImageSelector.ImagePath`) was resolved +conservatively (null-forgiving `!`, not a new fallback), preserving the exact pre-existing return +value on every code path, documented in `evidence/other/imagepath-judgment-call-decision.md` and +independently re-read against the applied code. + +### AC4 — No coverage regression on changed lines + +**PASS, with a documented, pre-existing, numerically-vacuous condition for 11 of 12 files.** +`RelativePath.cs` (the only file in scope with a genuine automated-test baseline) is verify-only +and untouched; its coverage is byte-identical before/after (line-rate 56.75%, branch-rate 54.35%, +independently spot-checked against the raw XML headline attributes in +`evidence/qa-gates/final-coverage.cobertura.xml` and `evidence/baseline/baseline-coverage.cobertura.xml`). +No line in any of the 12 remediated files that had non-zero coverage before this feature lost +coverage after it — because none of the 12 had any covered lines before (confirmed: `SVGControl.Test` +exercises only `RelativePath.cs`). The package-level `SVGControl` line-rate movement (26.65% -> +26.64%) is a strict non-regression: `lines-covered` is unchanged at 870 in both baselines, and the +entire delta is attributable to 2 new instrumentable-but-never-covered lines added by the pragma +edits. This satisfies the literal "no regression on changed lines" AC text. It does not by itself +satisfy the separate, repo-wide coverage-artifact/threshold gate tracked in `policy-audit` (Section +1.2.1), which is recorded there as a FAIL for procedural/systemic reasons unrelated to AC4's +narrower regression test. + +### AC5 — Public signature behavior-compatibility + +**PASS (independently re-verified).** Reviewed the full diff of all 12 files against +`evidence/qa-gates/final-signature-compat.md`'s per-file table; every public-signature change +(e.g., `ButtonSVG.ObjectToByteArray(object? obj)`, `SvgRenderer.Render(): Bitmap?`, +`SvgImageSelector.ResourceName: ISvgResource?`) is an additive nullability annotation on a +parameter, return type, property, field, or event that reflects behavior the implementation +already exhibited (documented guard clauses, `null`-returning paths, or `[ThreadStatic]` +lazy-initialization semantics that predate this feature). No parameter was added or removed, no +method renamed, no access modifier changed, no overload added or removed. + +### AC6 — Designer/generated files remain consistent + +**PASS (independently re-verified).** `git diff --stat` and `git status --short` against the exact +5 named paths (`ButtonSVG.Designer.cs`, `PictureBoxSVG.Designer.cs`, `ToggleSwitch.Designer.cs`, +`Properties/Resources.Designer.cs`, `Properties/AssemblyInfo.cs`) both return no output, re-run +directly in this review — confirming zero edits to any of them, consistent with the plan's +research finding that none required a change to keep the pragma build clean. + +## Deviation Analysis (Judgment Calls Beyond the Plan's Literal Text) + +### Deviation 1 — `ISvgResource.Name`/`.Data` made nullable (not just `SvgResource`'s implementation) + +**Judged legitimate, not scope creep.** `SvgResource`'s parameterless constructor never assigns +`Name`/`Data`; annotating only the concrete class's properties as nullable while leaving the +interface's declarations non-nullable produces a genuine `CS8766` compiler diagnostic (an +implementation returning a "more nullable" type than its interface contract declares). Reaching +"zero CS86xx" — the literal text of AC1 — is impossible without also annotating the interface. +The change is confined to `SVGControl/ISvgResource.cs` itself (both the interface and its one +implementing class in the same file); `SVGControl/` has no `ProjectReference` from any other +epic-cluster project (confirmed by `spec.md`'s own research and unchanged by this review), so this +annotation does not propagate as a cross-module contract obligation to any other Wave-0/Wave-1 +epic child. This is the correct, minimal fix for the actual compiler error, not an expansion of +scope. + +### Deviation 2 — Additional members annotated beyond the plan's literal task text + +Members: `SvgRenderer.PropertyChanged`, `SvgRenderer._resolving`, +`SvgRenderer.ResolveByNameAndKey`, `SvgImageSelector.PropertyChanged`, `SvgImageSelector.Render()`, +`SVGFileNameEditor._ofd`. + +**Judged legitimate, not scope creep.** Each is documented per-batch +(`evidence/qa-gates/batch-a-nullable-gate.md`, `batch-c-nullable-gate.md`, `batch-d-nullable-gate.md`, +independently re-read in this review) with a specific rationale tied to the member's actual, +pre-existing null-state behavior: +- `PropertyChanged` events (both classes) already used the null-conditional `?.Invoke` pattern + before this feature; annotating the event as nullable is a direct reflection of that + pre-existing pattern, not a new behavior. +- `_resolving` is `[ThreadStatic]`, meaning it is genuinely `null` on every thread until its + pre-existing `??=` lazy-initializer runs; this is accurately modeled as nullable, not + newly introduced. +- `ResolveByNameAndKey` already had two `return null;` paths before this feature (confirmed via + `git diff` context lines showing the `return null;` statements are unchanged, pre-existing code). +- `Render()` (on `SvgImageSelector`) is a direct passthrough of the already-nullable + `SvgRenderer.Render()`. +- `_ofd` is only ever assigned inside `InitializeDialog`, which the `EditValue` method's existing + `if (_ofd != null)` guard already protects against; the field was genuinely nullable in every + code path before this feature touched it. + +None of these six introduces a new guard clause, a new fallback value, or a renamed/removed +member; all are additive annotations reaching the literal "zero CS86xx" bar that AC1 requires. +Per the acceptance-criteria-tracking reviewer protocol, a deviation that is a necessary and +correctly-documented consequence of satisfying the stated AC text is not treated as an +unauthorized scope expansion. + +### `SvgImageSelector.ImagePath` judgment call (Phase 3) + +**Judged correct and conservatively resolved.** Independently re-read +`evidence/other/imagepath-judgment-call-decision.md` against the applied code at +`SVGControl/SvgImageSelector.cs`'s `ImagePath` getter. The chosen resolution +(`return _relativeImagePath!;` with an in-code comment, rather than a `?? "(none)"` fallback) +preserves the exact pre-existing return value on every reachable code path, including the +currently-unreachable-in-practice `else` branch (the setter is entirely commented out today). A +`?? "(none)"` fallback would have silently reused an existing sentinel value for a distinct +null-state condition — a genuine, CI-undetectable behavior change that AC3 does not permit. This +is the single most consequential decision in the cluster and was treated as such (a dedicated +decision document, not a routine batch-gate line item), consistent with the spec's explicit +instruction. + +## Acceptance Criteria Check-off + +All 6 acceptance criteria are independently verified PASS in this review. `issue.md` already had +all 6 items checked off (`[x]`) by the executor; this review confirms each check-off is warranted +and leaves them checked (per the reviewer check-off protocol, no further edit to `issue.md` was +required since all criteria are genuinely satisfied). No AC item is downgraded to unchecked. + +### Acceptance Criteria Status + +- Source: `docs/features/active/utilitiescs-nullable-svgcontrol/issue.md` (`## Acceptance + Criteria`), cross-verified against identical AC text in `spec.md` and `user-story.md` +- Total AC items: 6 +- Checked off (delivered): 6 +- Remaining (unchecked): 0 +- Items remaining: none + +## Verdict + +**Ready to merge into the epic integration branch from an acceptance-criteria and +code-correctness standpoint.** All AC1–AC6 are independently verified PASS. Merge readiness is +separately gated by the procedural coverage-artifact finding recorded in `policy-audit` and +`remediation-inputs` (absent canonical `artifacts/csharp/coverage.xml` and +`artifacts/pester/powershell-coverage.xml`), which is a systemic, pre-existing environment gap and +not a defect in this feature's `SVGControl/` changes. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/issue.md b/docs/features/active/utilitiescs-nullable-svgcontrol/issue.md index 5fa323bd..5b0ea4ce 100644 --- a/docs/features/active/utilitiescs-nullable-svgcontrol/issue.md +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/issue.md @@ -61,16 +61,16 @@ behavior-compatible. ## Acceptance Criteria -- [ ] AC1: Every hand-authored `.cs` file in `SVGControl/` that emits CS86xx carries +- [x] AC1: Every hand-authored `.cs` file in `SVGControl/` that emits CS86xx carries `#nullable enable` and compiles with zero nullable diagnostics under the per-file pragma with `TreatWarningsAsErrors`. -- [ ] AC2: No project-level `` element is introduced into `SVGControl.csproj`, and no +- [x] AC2: No project-level `` element is introduced into `SVGControl.csproj`, and no `` element is introduced at the solution level. -- [ ] AC3: No behavior change; existing tests still pass. -- [ ] AC4: No coverage regression on changed lines. -- [ ] AC5: Public signatures of the remediated control, parser, and converter types remain +- [x] AC3: No behavior change; existing tests still pass. +- [x] AC4: No coverage regression on changed lines. +- [x] AC5: Public signatures of the remediated control, parser, and converter types remain behavior-compatible; nullability annotations reflect actual null behavior. -- [ ] AC6: WinForms `*.Designer.cs` and generated `Properties/Resources.Designer.cs` files remain +- [x] AC6: WinForms `*.Designer.cs` and generated `Properties/Resources.Designer.cs` files remain consistent with the pragma build; any edit to them is mechanical and behavior-preserving. ## Constraints & Risks diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/plan.2026-07-18T22-04.md b/docs/features/active/utilitiescs-nullable-svgcontrol/plan.2026-07-18T22-04.md index 79cf2512..54e4b35a 100644 --- a/docs/features/active/utilitiescs-nullable-svgcontrol/plan.2026-07-18T22-04.md +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/plan.2026-07-18T22-04.md @@ -63,111 +63,111 @@ ## Implementation Plan (Atomic Tasks) ### Phase 0 — Baseline Capture and Policy Compliance -- [ ] [P0-T1] Read policy documents in the required order (CLAUDE.md, `.claude/rules/general-code-change.md`, `.claude/rules/general-unit-test.md`, `.claude/rules/csharp.md`) and record the read receipt at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/phase0-instructions-read.md` +- [x] [P0-T1] Read policy documents in the required order (CLAUDE.md, `.claude/rules/general-code-change.md`, `.claude/rules/general-unit-test.md`, `.claude/rules/csharp.md`) and record the read receipt at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/phase0-instructions-read.md` - Acceptance: artifact exists and contains `Timestamp:`, `Policy Order:`, and the explicit list of files read (all four policy files above). -- [ ] [P0-T2] Enumerate the 20 `.cs` files under `SVGControl/` and record the baseline inventory (path, line count, and whether the file already carries `#nullable enable`) at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-file-inventory.md` +- [x] [P0-T2] Enumerate the 20 `.cs` files under `SVGControl/` and record the baseline inventory (path, line count, and whether the file already carries `#nullable enable`) at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-file-inventory.md` - Acceptance: artifact lists all 20 files; confirms 12 hand-authored remediation targets, 3 already-`#nullable enable` verify-only files (`PathInternal.cs`, `RelativePath.cs`, `ValueStringBuilder.cs`), and 5 Designer/generated files not opted in; contains `Timestamp:`. -- [ ] [P0-T3] Capture baseline CSharpier formatting state by running `dotnet tool run csharpier check .` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-csharpier.md` +- [x] [P0-T3] Capture baseline CSharpier formatting state by running `dotnet tool run csharpier check .` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-csharpier.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` (pass/fail and count of files needing formatting). -- [ ] [P0-T4] Capture baseline analyzer/code-style build by running `msbuild TaskMaster.sln /t:Build /p:Configuration=Debug /p:Platform="Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-analyzers.md` +- [x] [P0-T4] Capture baseline analyzer/code-style build by running `msbuild TaskMaster.sln /t:Build /p:Configuration=Debug /p:Platform="Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-analyzers.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` (build succeeded/failed, warning/error counts). -- [ ] [P0-T5] Capture baseline per-file nullable pragma-gate build by running `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` (WITHOUT `/p:Nullable=enable`) and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-nullable-pragma-gate.md` +- [x] [P0-T5] Capture baseline per-file nullable pragma-gate build by running `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` (WITHOUT `/p:Nullable=enable`) and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-nullable-pragma-gate.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` (pass/fail and CS86xx count for the 3 currently-enabled verify-only files, expected zero; no CS86xx surfaced yet for the 12 not-yet-opted-in hand-authored files). -- [ ] [P0-T6] Capture baseline test run with coverage by running `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-tests-coverage.md` +- [x] [P0-T6] Capture baseline test run with coverage by running `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-tests-coverage.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` with numeric headline values (total tests passed/failed, baseline line-coverage percent and branch-coverage percent for the discovered `SVGControl.Test.dll` run); Cobertura XML written to the named evidence path. -- [ ] [P0-T7] Confirm the AC2 baseline: verify `SVGControl/SVGControl.csproj` currently contains no `` element and record the finding at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-csproj-nullable-absent.md` +- [x] [P0-T7] Confirm the AC2 baseline: verify `SVGControl/SVGControl.csproj` currently contains no `` element and record the finding at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/baseline/baseline-csproj-nullable-absent.md` - Acceptance: artifact contains `Timestamp:`, the grep command used, and confirmation that zero `` occurrences exist in `SVGControl/SVGControl.csproj` (AC2 baseline). ### Phase 1 — Batch A Trivial Independent Leaves plus Verify-Only Confirmation -- [ ] [P1-T1] Verify the 3 already-`#nullable enable` verify-only files `SVGControl/PathInternal.cs`, `SVGControl/RelativePath.cs`, `SVGControl/ValueStringBuilder.cs` still emit zero CS86xx under the pragma gate; make NO edits unless a diagnostic appears, and record the outcome at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/verify-only-preenabled.md` +- [x] [P1-T1] Verify the 3 already-`#nullable enable` verify-only files `SVGControl/PathInternal.cs`, `SVGControl/RelativePath.cs`, `SVGControl/ValueStringBuilder.cs` still emit zero CS86xx under the pragma gate; make NO edits unless a diagnostic appears, and record the outcome at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/verify-only-preenabled.md` - Acceptance: pragma-gate rebuild (`msbuild SVGControl/SVGControl.csproj /t:Rebuild ... /p:TreatWarningsAsErrors=true`) reports zero CS86xx for all 3 files; artifact records `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:`; all 3 files remain unmodified (or, if a diagnostic appeared, the minimal annotation fix is recorded). -- [ ] [P1-T2] Add a `#nullable enable` pragma to each of the 4 Batch A files: `SVGControl/ISvgResource.cs`, `SVGControl/ToggleSwitch.cs`, `SVGControl/SVGParser.cs`, `SVGControl/SvgRenderer.cs` +- [x] [P1-T2] Add a `#nullable enable` pragma to each of the 4 Batch A files: `SVGControl/ISvgResource.cs`, `SVGControl/ToggleSwitch.cs`, `SVGControl/SVGParser.cs`, `SVGControl/SvgRenderer.cs` - Acceptance: each of the 4 named files contains a `#nullable enable` pragma; no `` element added to `SVGControl.csproj`. -- [ ] [P1-T3] Apply nullable annotations, guards, and justified `!` to `SVGControl/ISvgResource.cs` and `SVGControl/ToggleSwitch.cs` so each reaches zero CS86xx under the pragma; no annotation changes are expected on either file's members beyond the pragma itself +- [x] [P1-T3] Apply nullable annotations, guards, and justified `!` to `SVGControl/ISvgResource.cs` and `SVGControl/ToggleSwitch.cs` so each reaches zero CS86xx under the pragma; no annotation changes are expected on either file's members beyond the pragma itself - Acceptance: no post-condition attribute is added; public signatures remain behavior-compatible (AC5); annotation/null-safety only (AC3). -- [ ] [P1-T4] Apply nullable annotations to `SVGControl/SVGParser.cs` so it reaches zero CS86xx under the pragma; do not fix or remove the pre-existing `if (TargetSize != null)` value-type comparison (a pre-existing defect unrelated to nullable reference types, out of scope) and do not rename/delete the file despite it having zero in-project consumers +- [x] [P1-T4] Apply nullable annotations to `SVGControl/SVGParser.cs` so it reaches zero CS86xx under the pragma; do not fix or remove the pre-existing `if (TargetSize != null)` value-type comparison (a pre-existing defect unrelated to nullable reference types, out of scope) and do not rename/delete the file despite it having zero in-project consumers - Acceptance: `SVGParser.cs` compiles with zero CS86xx under the pragma; the pre-existing value-type null-comparison line is unchanged; file is not renamed or deleted (AC3, AC5). -- [ ] [P1-T5] Apply nullable annotations, guards, and justified `!` to `SVGControl/SvgRenderer.cs` so it reaches zero CS86xx under the pragma: type `Render()`'s return as `Bitmap?`, the `Document` property and backing `_doc` field as `SvgDocument?`, the static `GetSvgDocument(byte[] file)` return as `SvgDocument?`, and the `AssemblyResolve` shim's `PublicKeyTokensEqual(byte[] a, byte[] b)` parameters as `byte[]?` (existing `== null` guards stay as-is) +- [x] [P1-T5] Apply nullable annotations, guards, and justified `!` to `SVGControl/SvgRenderer.cs` so it reaches zero CS86xx under the pragma: type `Render()`'s return as `Bitmap?`, the `Document` property and backing `_doc` field as `SvgDocument?`, the static `GetSvgDocument(byte[] file)` return as `SvgDocument?`, and the `AssemblyResolve` shim's `PublicKeyTokensEqual(byte[] a, byte[] b)` parameters as `byte[]?` (existing `== null` guards stay as-is) - Acceptance: no post-condition attribute is added; the four named members carry the nullable annotations listed; existing null guards in `PublicKeyTokensEqual` are unchanged; public signatures remain behavior-compatible (AC5); annotation/null-safety only (AC3). -- [ ] [P1-T6] Run `dotnet tool run csharpier .` then the pragma-gate rebuild `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-a-nullable-gate.md` +- [x] [P1-T6] Run `dotnet tool run csharpier .` then the pragma-gate rebuild `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-a-nullable-gate.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` showing zero CS86xx for the 4 Batch A files (AC1). -- [ ] [P1-T7] Run the full test suite with coverage via `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-a-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-a-tests.md` +- [x] [P1-T7] Run the full test suite with coverage via `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-a-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-a-tests.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` with pass/fail counts confirming no test regression (AC3). ### Phase 2 — Batch B ISvgResource Consumers (Pre-Hub) -- [ ] [P2-T1] Add a `#nullable enable` pragma to each of the 2 Batch B files: `SVGControl/SvgResourceConverter.cs`, `SVGControl/DropDownEditor.cs` +- [x] [P2-T1] Add a `#nullable enable` pragma to each of the 2 Batch B files: `SVGControl/SvgResourceConverter.cs`, `SVGControl/DropDownEditor.cs` - Acceptance: each of the 2 named files contains a `#nullable enable` pragma; no `` element added to `SVGControl.csproj`. -- [ ] [P2-T2] Apply nullable annotations and justified `!` to `SVGControl/SvgResourceConverter.cs` so it reaches zero CS86xx under the pragma; the existing `value is null` guard before the `(ISvgResource)value` cast stays as-is +- [x] [P2-T2] Apply nullable annotations and justified `!` to `SVGControl/SvgResourceConverter.cs` so it reaches zero CS86xx under the pragma; the existing `value is null` guard before the `(ISvgResource)value` cast stays as-is - Acceptance: no post-condition attribute is added; no new guard clause is introduced; public signatures remain behavior-compatible (AC5); annotation/null-safety only (AC3). -- [ ] [P2-T3] Apply nullable annotations and justified `!` to `SVGControl/DropDownEditor.cs` so it reaches zero CS86xx under the pragma: declare the reassigned `Assembly asm = null;` local as `Assembly? asm = null;` (relying on existing flow narrowing, no new guard), annotate `(provider.GetService(typeof(IDesignerHost)) as IDesignerHost)!` with the null-forgiving operator to preserve the current NRE-on-null behavior at `host.RootComponentClassName`, and annotate the field `private IWindowsFormsEditorService _editorService;` as `IWindowsFormsEditorService?` +- [x] [P2-T3] Apply nullable annotations and justified `!` to `SVGControl/DropDownEditor.cs` so it reaches zero CS86xx under the pragma: declare the reassigned `Assembly asm = null;` local as `Assembly? asm = null;` (relying on existing flow narrowing, no new guard), annotate `(provider.GetService(typeof(IDesignerHost)) as IDesignerHost)!` with the null-forgiving operator to preserve the current NRE-on-null behavior at `host.RootComponentClassName`, and annotate the field `private IWindowsFormsEditorService _editorService;` as `IWindowsFormsEditorService?` - Acceptance: no post-condition attribute is added; no new `if (x is null) throw` guard is introduced; the three named null-flow points are resolved exactly as specified; public signatures remain behavior-compatible (AC5); annotation/null-safety only (AC3). -- [ ] [P2-T4] Run `dotnet tool run csharpier .` then the pragma-gate rebuild `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-b-nullable-gate.md` +- [x] [P2-T4] Run `dotnet tool run csharpier .` then the pragma-gate rebuild `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-b-nullable-gate.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` showing zero CS86xx for the 2 Batch B files (AC1). -- [ ] [P2-T5] Run the full test suite with coverage via `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-b-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-b-tests.md` +- [x] [P2-T5] Run the full test suite with coverage via `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-b-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-b-tests.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` with pass/fail counts confirming no test regression (AC3). ### Phase 3 — Batch C SvgImageSelector Hub (Isolated, Careful Review) -- [ ] [P3-T1] Add a `#nullable enable` pragma to `SVGControl/SvgImageSelector.cs` and annotate `private string _relativeImagePath;`, `private string _absoluteImagePath;`, and `private ISvgResource _svgResource = null;` as their nullable equivalents (`string?`, `string?`, `ISvgResource?`) +- [x] [P3-T1] Add a `#nullable enable` pragma to `SVGControl/SvgImageSelector.cs` and annotate `private string _relativeImagePath;`, `private string _absoluteImagePath;`, and `private ISvgResource _svgResource = null;` as their nullable equivalents (`string?`, `string?`, `ISvgResource?`) - Acceptance: the file contains a `#nullable enable` pragma; all 3 named fields are annotated nullable; no `` element added to `SVGControl.csproj`. -- [ ] [P3-T2] Resolve the `ImagePath` property's dead-setter CS8603 by applying the null-forgiving `_relativeImagePath!` in the `get` accessor's `else return _relativeImagePath;` branch, together with an in-code comment noting the `set` accessor's body is currently entirely commented out (a functional no-op), and do NOT introduce a `?? "(none)"` or any other fallback value +- [x] [P3-T2] Resolve the `ImagePath` property's dead-setter CS8603 by applying the null-forgiving `_relativeImagePath!` in the `get` accessor's `else return _relativeImagePath;` branch, together with an in-code comment noting the `set` accessor's body is currently entirely commented out (a functional no-op), and do NOT introduce a `?? "(none)"` or any other fallback value - Acceptance: the `get` accessor returns `_relativeImagePath!` with the required in-code comment present; no fallback expression is introduced; the returned value on this path is unchanged (still `null` when `_relativeImagePath` is `null`), preserving current behavior (AC3). -- [ ] [P3-T3] Record the `SvgImageSelector.ImagePath` judgment-call decision at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/other/imagepath-judgment-call-decision.md`, documenting the dead-setter nuance, the rejected `?? "(none)"` alternative and why it would change observable behavior, and the chosen `_relativeImagePath!` resolution +- [x] [P3-T3] Record the `SvgImageSelector.ImagePath` judgment-call decision at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/other/imagepath-judgment-call-decision.md`, documenting the dead-setter nuance, the rejected `?? "(none)"` alternative and why it would change observable behavior, and the chosen `_relativeImagePath!` resolution - Acceptance: artifact contains `Timestamp:`, a description of the dead-setter nuance, the rejected alternative with its rationale, and the applied resolution, cross-referencing the exact file/line where it was applied (AC3, AC5). -- [ ] [P3-T4] Apply nullable annotations to `SvgImageSelector.cs`'s public `ResourceName` property (`ISvgResource?`) and internal `AboluteImagePath` property (`string?`) so their exposed types reflect actual null behavior, without renaming the pre-existing `AboluteImagePath` typo +- [x] [P3-T4] Apply nullable annotations to `SvgImageSelector.cs`'s public `ResourceName` property (`ISvgResource?`) and internal `AboluteImagePath` property (`string?`) so their exposed types reflect actual null behavior, without renaming the pre-existing `AboluteImagePath` typo - Acceptance: `ResourceName` is typed `ISvgResource?`; `AboluteImagePath` is typed `string?` and its name is unchanged; public signatures remain behavior-compatible (AC5); annotation/null-safety only (AC3). -- [ ] [P3-T5] Run `dotnet tool run csharpier .` then the pragma-gate rebuild `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-c-nullable-gate.md` +- [x] [P3-T5] Run `dotnet tool run csharpier .` then the pragma-gate rebuild `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-c-nullable-gate.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` showing zero CS86xx for `SvgImageSelector.cs` (AC1). -- [ ] [P3-T6] Run the full test suite with coverage via `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-c-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-c-tests.md` +- [x] [P3-T6] Run the full test suite with coverage via `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-c-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-c-tests.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` with pass/fail counts confirming no test regression (AC3). ### Phase 4 — Batch D SvgImageSelector Consumers -- [ ] [P4-T1] Add a `#nullable enable` pragma to each of the 3 Batch D files: `SVGControl/SvgOptionsConverter.cs`, `SVGControl/SvgOptionsConverter2.cs`, `SVGControl/SVGFileNameEditor.cs` +- [x] [P4-T1] Add a `#nullable enable` pragma to each of the 3 Batch D files: `SVGControl/SvgOptionsConverter.cs`, `SVGControl/SvgOptionsConverter2.cs`, `SVGControl/SVGFileNameEditor.cs` - Acceptance: each of the 3 named files contains a `#nullable enable` pragma; no `` element added to `SVGControl.csproj`. -- [ ] [P4-T2] Apply nullable annotations and justified `!` to `SVGControl/SvgOptionsConverter.cs` (class `SvgOptionsConverter1`, dead but still in scope) so it reaches zero CS86xx under the pragma, consuming the now-nullable `AboluteImagePath` from Batch C without re-editing `SvgImageSelector.cs`; do not rename or delete `SvgOptionsConverter1` +- [x] [P4-T2] Apply nullable annotations and justified `!` to `SVGControl/SvgOptionsConverter.cs` (class `SvgOptionsConverter1`, dead but still in scope) so it reaches zero CS86xx under the pragma, consuming the now-nullable `AboluteImagePath` from Batch C without re-editing `SvgImageSelector.cs`; do not rename or delete `SvgOptionsConverter1` - Acceptance: no post-condition attribute is added; `SvgImageSelector.cs` is not re-edited; class name is unchanged; public signatures remain behavior-compatible (AC5); annotation/null-safety only (AC3). -- [ ] [P4-T3] Apply nullable annotations and justified `!` to `SVGControl/SvgOptionsConverter2.cs` (class `SvgOptionsConverter`, live) so it reaches zero CS86xx under the pragma, consuming the now-nullable `ResourceName` and `AutoSize` members from Batch C without re-editing `SvgImageSelector.cs` +- [x] [P4-T3] Apply nullable annotations and justified `!` to `SVGControl/SvgOptionsConverter2.cs` (class `SvgOptionsConverter`, live) so it reaches zero CS86xx under the pragma, consuming the now-nullable `ResourceName` and `AutoSize` members from Batch C without re-editing `SvgImageSelector.cs` - Acceptance: no post-condition attribute is added; `SvgImageSelector.cs` is not re-edited; public signatures remain behavior-compatible (AC5); annotation/null-safety only (AC3). -- [ ] [P4-T4] Apply nullable annotations to `SVGControl/SVGFileNameEditor.cs` so it reaches zero CS86xx under the pragma: give `private string _appPath;` the same `= string.Empty;` inline-initializer idiom already used for `_currentValue`, `_absoluteFilepath`, and `_fileName` three lines above it in the same file +- [x] [P4-T4] Apply nullable annotations to `SVGControl/SVGFileNameEditor.cs` so it reaches zero CS86xx under the pragma: give `private string _appPath;` the same `= string.Empty;` inline-initializer idiom already used for `_currentValue`, `_absoluteFilepath`, and `_fileName` three lines above it in the same file - Acceptance: `_appPath` carries `= string.Empty;`; the other three fields' existing initializers are unchanged; no post-condition attribute is added; public signatures remain behavior-compatible (AC5); annotation/null-safety only (AC3). -- [ ] [P4-T5] Run `dotnet tool run csharpier .` then the pragma-gate rebuild `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-d-nullable-gate.md` +- [x] [P4-T5] Run `dotnet tool run csharpier .` then the pragma-gate rebuild `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-d-nullable-gate.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` showing zero CS86xx for the 3 Batch D files (AC1). -- [ ] [P4-T6] Run the full test suite with coverage via `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-d-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-d-tests.md` +- [x] [P4-T6] Run the full test suite with coverage via `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-d-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-d-tests.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` with pass/fail counts confirming no test regression (AC3). ### Phase 5 — Batch E WinForms Controls (Top of the Dependency Graph) -- [ ] [P5-T1] Add a `#nullable enable` pragma to each of the 2 Batch E files: `SVGControl/ButtonSVG.cs`, `SVGControl/PictureBoxSVG.cs` +- [x] [P5-T1] Add a `#nullable enable` pragma to each of the 2 Batch E files: `SVGControl/ButtonSVG.cs`, `SVGControl/PictureBoxSVG.cs` - Acceptance: each of the 2 named files contains a `#nullable enable` pragma; no `` element added to `SVGControl.csproj`. -- [ ] [P5-T2] Apply nullable annotations to `SVGControl/ButtonSVG.cs` so it reaches zero CS86xx under the pragma: annotate `public static byte[] ObjectToByteArray(Object obj)` as `ObjectToByteArray(object? obj)` (existing `if (obj != null)` guard stays as-is) and the private `GetStringForValue(object value)` helper as `GetStringForValue(object? value)` (existing `if (value == null) return "null";` guard stays as-is); leave event handler parameters (`ButtonSVG_Resize`, `ImageSVG_PropertyChanged`, `Control_SizeChanged`) unannotated as oblivious framework delegate types +- [x] [P5-T2] Apply nullable annotations to `SVGControl/ButtonSVG.cs` so it reaches zero CS86xx under the pragma: annotate `public static byte[] ObjectToByteArray(Object obj)` as `ObjectToByteArray(object? obj)` (existing `if (obj != null)` guard stays as-is) and the private `GetStringForValue(object value)` helper as `GetStringForValue(object? value)` (existing `if (value == null) return "null";` guard stays as-is); leave event handler parameters (`ButtonSVG_Resize`, `ImageSVG_PropertyChanged`, `Control_SizeChanged`) unannotated as oblivious framework delegate types - Acceptance: `ObjectToByteArray` and `GetStringForValue` signatures are updated exactly as specified; no new guard clause is introduced; event handler signatures are unchanged; public signatures remain behavior-compatible (AC5); annotation/null-safety only (AC3). -- [ ] [P5-T3] Apply nullable annotations to `SVGControl/PictureBoxSVG.cs` so it reaches zero CS86xx under the pragma, mirroring the same annotation treatment applied to `ButtonSVG.cs`'s equivalent members (its own independent copy of `GetStringForValue`, and any nullable-typed field/property exposure from its hosted `SvgImageSelector`); leave event handler parameters unannotated +- [x] [P5-T3] Apply nullable annotations to `SVGControl/PictureBoxSVG.cs` so it reaches zero CS86xx under the pragma, mirroring the same annotation treatment applied to `ButtonSVG.cs`'s equivalent members (its own independent copy of `GetStringForValue`, and any nullable-typed field/property exposure from its hosted `SvgImageSelector`); leave event handler parameters unannotated - Acceptance: no post-condition attribute is added; no new guard clause is introduced; event handler signatures are unchanged; public signatures remain behavior-compatible (AC5); annotation/null-safety only (AC3). -- [ ] [P5-T4] Run `dotnet tool run csharpier .` then the pragma-gate rebuild `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-e-nullable-gate.md` +- [x] [P5-T4] Run `dotnet tool run csharpier .` then the pragma-gate rebuild `msbuild SVGControl/SVGControl.csproj /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/batch-e-nullable-gate.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` showing zero CS86xx for the 2 Batch E files (AC1). -- [ ] [P5-T5] Run the full test suite with coverage via `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-e-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-e-tests.md` +- [x] [P5-T5] Run the full test suite with coverage via `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-e-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/regression-testing/batch-e-tests.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` with pass/fail counts confirming no test regression (AC3). ### Phase 6 — Final QC Full Toolchain and Acceptance Verification -- [ ] [P6-T1] Run `dotnet tool run csharpier .` across the repository and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-csharpier.md` +- [x] [P6-T1] Run `dotnet tool run csharpier .` across the repository and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-csharpier.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:`; CSharpier reports no residual formatting changes on a clean second pass. -- [ ] [P6-T2] Run the analyzer/code-style build `msbuild TaskMaster.sln /t:Build /p:Configuration=Debug /p:Platform="Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-analyzers.md` +- [x] [P6-T2] Run the analyzer/code-style build `msbuild TaskMaster.sln /t:Build /p:Configuration=Debug /p:Platform="Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-analyzers.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:`; build succeeds with no new analyzer errors. -- [ ] [P6-T3] Run the solution-wide per-file nullable pragma gate `msbuild TaskMaster.sln /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` (WITHOUT `/p:Nullable=enable`) and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-nullable-pragma-gate.md` +- [x] [P6-T3] Run the solution-wide per-file nullable pragma gate `msbuild TaskMaster.sln /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true` (WITHOUT `/p:Nullable=enable`) and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-nullable-pragma-gate.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` confirming zero CS86xx across all 12 remediated files and the 3 verify-only files in `SVGControl/` under the per-file pragma (AC1); `/p:Nullable=enable` is not passed. -- [ ] [P6-T4] Run the full test suite with coverage via `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-tests-coverage.md` +- [x] [P6-T4] Run the full test suite with coverage via `pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-coverage.cobertura.xml` and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-tests-coverage.md` - Acceptance: artifact contains `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:` with numeric post-change line-coverage and branch-coverage percentages and pass/fail counts (AC3). -- [ ] [P6-T5] Compute and record the changed-line coverage delta at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-coverage-delta.md`, comparing baseline coverage (`evidence/baseline/baseline-coverage.cobertura.xml`) against post-change coverage (`evidence/qa-gates/final-coverage.cobertura.xml`), reporting the `RelativePath.cs` changed-line coverage explicitly (the one file in scope with a real automated baseline), and explicitly noting that changed-line coverage for the 12 hand-authored remediation-target files is numerically vacuous (baseline 0%, per research) +- [x] [P6-T5] Compute and record the changed-line coverage delta at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-coverage-delta.md`, comparing baseline coverage (`evidence/baseline/baseline-coverage.cobertura.xml`) against post-change coverage (`evidence/qa-gates/final-coverage.cobertura.xml`), reporting the `RelativePath.cs` changed-line coverage explicitly (the one file in scope with a real automated baseline), and explicitly noting that changed-line coverage for the 12 hand-authored remediation-target files is numerically vacuous (baseline 0%, per research) - Acceptance: artifact reports baseline coverage, post-change coverage, and `RelativePath.cs` changed-line coverage numerically; confirms no coverage regression on changed lines for `RelativePath.cs` (AC4); explicitly states the 0%-baseline/vacuous-gate posture for the 12 remediation-target files rather than omitting it; `Timestamp:` present. If `RelativePath.cs` changed-line coverage regresses, the outcome is remediation-required, not PASS. -- [ ] [P6-T6] Verify AC2 end state: confirm `SVGControl/SVGControl.csproj` still contains no `` element and no `` element exists at the solution level, and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-ac2-csproj-check.md` +- [x] [P6-T6] Verify AC2 end state: confirm `SVGControl/SVGControl.csproj` still contains no `` element and no `` element exists at the solution level, and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-ac2-csproj-check.md` - Acceptance: artifact contains `Timestamp:`, the grep command(s) used, and confirmation of zero `` occurrences in `SVGControl/SVGControl.csproj` and in `TaskMaster.sln` (AC2). -- [ ] [P6-T7] Verify no prohibited nullable post-condition attribute and no polyfill were added, by grepping the 12 remediated files and `SVGControl/` for `NotNullWhen|MaybeNullWhen|NotNullIfNotNull|MaybeNull|AllowNull|DisallowNull|DoesNotReturn|MemberNotNull` attribute usage or a `namespace System.Diagnostics.CodeAnalysis` polyfill declaration, and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-no-postcondition-attrs.md` +- [x] [P6-T7] Verify no prohibited nullable post-condition attribute and no polyfill were added, by grepping the 12 remediated files and `SVGControl/` for `NotNullWhen|MaybeNullWhen|NotNullIfNotNull|MaybeNull|AllowNull|DisallowNull|DoesNotReturn|MemberNotNull` attribute usage or a `namespace System.Diagnostics.CodeAnalysis` polyfill declaration, and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-no-postcondition-attrs.md` - Acceptance: artifact contains `Timestamp:`, the grep command(s) used, and confirmation that no post-condition attribute usage or polyfill was introduced by this feature. -- [ ] [P6-T8] Verify scope guards: confirm `SVGControl/ISvgResource.cs`'s `SvgResource` class remains a plain class (no `record`/`record struct`/`init`), `SVGControl/RelativePath.cs` was not split, `SVGControl/SvgOptionsConverter.cs`'s `SvgOptionsConverter1` and `SVGControl/SVGParser.cs` were not renamed or deleted, and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-scope-guards.md` +- [x] [P6-T8] Verify scope guards: confirm `SVGControl/ISvgResource.cs`'s `SvgResource` class remains a plain class (no `record`/`record struct`/`init`), `SVGControl/RelativePath.cs` was not split, `SVGControl/SvgOptionsConverter.cs`'s `SvgOptionsConverter1` and `SVGControl/SVGParser.cs` were not renamed or deleted, and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-scope-guards.md` - Acceptance: artifact contains `Timestamp:` and confirmation of all 4 named scope guards (AC3/AC5 scope compliance). -- [ ] [P6-T9] Verify AC5 signature compatibility by reviewing the git diff of the 12 remediated files and confirming only nullability annotations, flow-narrowed local retyping, and justified `!` changed with no public-signature behavior change, and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-signature-compat.md` +- [x] [P6-T9] Verify AC5 signature compatibility by reviewing the git diff of the 12 remediated files and confirming only nullability annotations, flow-narrowed local retyping, and justified `!` changed with no public-signature behavior change, and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-signature-compat.md` - Acceptance: artifact contains `Timestamp:` and a per-file confirmation that each public signature change is limited to additive nullability annotations that reflect actual null behavior (AC5). -- [ ] [P6-T10] Verify AC6 by diffing the 5 Designer/generated files (`SVGControl/ButtonSVG.Designer.cs`, `SVGControl/PictureBoxSVG.Designer.cs`, `SVGControl/ToggleSwitch.Designer.cs`, `SVGControl/Properties/Resources.Designer.cs`, `SVGControl/Properties/AssemblyInfo.cs`) against their pre-feature state, confirming each is either unchanged or carries only a mechanical, behavior-preserving edit, and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-ac6-designer-check.md` +- [x] [P6-T10] Verify AC6 by diffing the 5 Designer/generated files (`SVGControl/ButtonSVG.Designer.cs`, `SVGControl/PictureBoxSVG.Designer.cs`, `SVGControl/ToggleSwitch.Designer.cs`, `SVGControl/Properties/Resources.Designer.cs`, `SVGControl/Properties/AssemblyInfo.cs`) against their pre-feature state, confirming each is either unchanged or carries only a mechanical, behavior-preserving edit, and record the result at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/qa-gates/final-ac6-designer-check.md` - Acceptance: artifact contains `Timestamp:`, the diff command used, and a per-file confirmation (unchanged, or mechanical/behavior-preserving edit only) for all 5 named files (AC6). -- [ ] [P6-T11] Record the acceptance-criteria status summary mapping AC1–AC6 to their supporting evidence artifacts at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/other/ac-status-summary.md` +- [x] [P6-T11] Record the acceptance-criteria status summary mapping AC1–AC6 to their supporting evidence artifacts at `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/other/ac-status-summary.md` - Acceptance: artifact contains `Timestamp:` and a row per AC1–AC6 citing the exact evidence artifact path that demonstrates satisfaction; any unmet AC is marked remediation-required rather than PASS. ## Test Plan diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/policy-audit.2026-07-19T11-15.md b/docs/features/active/utilitiescs-nullable-svgcontrol/policy-audit.2026-07-19T11-15.md new file mode 100644 index 00000000..e74ab5f0 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/policy-audit.2026-07-19T11-15.md @@ -0,0 +1,333 @@ +# Policy Audit — utilitiescs-nullable-svgcontrol (Issue #368) + +- Component: `SVGControl/` (net481 WinForms control project; independent of `UtilitiesCS`) +- Feature branch: `feature/utilitiescs-nullable-svgcontrol-368` +- Base / merge-base: `origin/epic/utilitiescs-nullable-remediation-integration` @ `6d4da8bb4d881dc26c421440464ce5575e3fb15f` (recomputed via `git merge-base HEAD origin/epic/utilitiescs-nullable-remediation-integration`; matches the caller-supplied base) +- Head commit under review: `c194362d612497f1fd5a6ee36aec7f52c4b949d4` +- Work mode: `full-feature` (per `issue.md`); AC sources: `spec.md` + `user-story.md` +- Reviewer: feature-review agent +- Timestamp: 2026-07-19T11-15 + +## Executive Summary + +This is a per-file `#nullable enable` opt-in remediation of 12 hand-authored `.cs` files in +`SVGControl/`, plus one unrelated one-line-scope PowerShell tooling fix +(`scripts/vscode/Invoke-MSTestWithCoverage.ps1`). Independent re-verification (see Section 5 and +Section 6) confirms: zero CS86xx diagnostics anywhere in a full solution-wide `/t:Rebuild +/p:TreatWarningsAsErrors=true`; zero `csharpier` formatting diffs; 37/37 `SVGControl.Test` tests +passing; no `` element introduced anywhere; no behavior-breaking signature changes; no +Designer/generated file touched. The two documented pre-existing-and-unrelated build errors +(`CS0649` x2 in `SvgImageSelector.cs`, `CS0006` x4 in `VBFunctions.csproj`) were independently +reproduced and confirmed unrelated to this feature's diff. + +The feature fails the **mandatory coverage-artifact gate**: no canonical +`artifacts/csharp/coverage.xml` or `artifacts/pester/powershell-coverage.xml` exists in this +worktree for either language with changed files on the branch. This is a known, repository-wide, +systemic gap (local full-solution C# coverage generation is independently blocked; see prior +review precedent for issues #309/#354) and is not a defect newly introduced by this feature's +`SVGControl/`-scoped source edits. It is nonetheless recorded as **FAIL** per the mandatory +coverage-verification procedure and is carried to `remediation-inputs`. + +A second, narrower finding: the `Invoke-MSTestWithCoverage.ps1` one-line bug fix (StrictMode +scalar/array coercion) did not follow the repo's Bugfix Workflow (no failing regression test +added before the fix). This is recorded as **PARTIAL**. + +**Overall disposition: BLOCKED on the coverage-artifact gate (procedural/systemic), not on code +correctness.** All AC1–AC6 acceptance criteria are independently verified PASS (see +`feature-audit`). No blocking code-correctness or behavior-change defect was found in the 12 +remediated `SVGControl/` files. + +## Rejected Scope Narrowing + +No narrowing of the audit scope was attempted by the delegating prompt for this review cycle. The +prompt's "Known, pre-existing, out-of-scope findings to expect" section supplied hypotheses to +independently verify (not instructions to skip verification), and each hypothesis was in fact +independently reproduced and confirmed (Section 6). No caller text instructed this agent to treat +any language's coverage as informational-only, to skip a toolchain check, or to narrow scope to a +plan/task/phase subset. Full branch-diff scope (against the resolved merge-base) was audited. + +## Evidence Location Compliance + +- `scripts/validate_evidence_locations.py` does not exist in this repository (searched + repository-wide; not found). Fallback: manual scan performed via + `git diff --name-only origin/epic/utilitiescs-nullable-remediation-integration...HEAD | grep -E "^artifacts/(baselines|qa|evidence|coverage)/"`. +- Result: **zero matches.** All evidence for this feature is written under the canonical + `docs/features/active/utilitiescs-nullable-svgcontrol/evidence/{baseline,qa-gates,regression-testing,other}/` + tree, per `.claude/skills/evidence-and-timestamp-conventions/SKILL.md`. No + `EVIDENCE_LOCATION_OVERRIDE_REJECTED` condition applies; no non-canonical path was supplied or + used. + +## 1. General Unit Test Policy Compliance + +### 1.1 Core Principles (Independence, Isolation, Fast, Deterministic, Readable) + +- No new automated tests were added or required by this feature (annotation-only scope, per + `spec.md` "Seeded Test Conditions"). The existing `SVGControl.Test` suite (`GetRelativePath_Test.cs`, + `RelativePathCoverageTests.cs`; MSTest + FluentAssertions) was re-run at every batch and at final + QC — 37/37 passed each time (independently re-verified, see Section 6). **PASS.** +- No temp files were created or used by any test in this feature. **PASS.** + +### 1.2 Coverage Requirements + +#### 1.2.1 Per-language coverage rows (mandatory for every language with changed files) + +- **TypeScript coverage:** N/A — 0 changed `.ts`/`.tsx` files on this branch (confirmed via `git + diff --numstat`). +- **Python coverage:** N/A — 0 changed `.py` files on this branch. +- **PowerShell coverage:** + - Baseline: unavailable (no `artifacts/pester/powershell-coverage.xml` exists in this worktree + prior to this review). + - Post-change: unavailable (no `artifacts/pester/powershell-coverage.xml` exists in this + worktree after this feature's commit). + - Change: N/A (no artifact pair to diff). + - New/changed-code coverage: 0% (the one changed line, `scripts/vscode/Invoke-MSTestWithCoverage.ps1` + line 133/139, is top-level script-scope glue code, not wrapped in a testable function in + `Invoke-MSTestWithCoverage.Helpers.ps1`, and has no Pester test exercising it before or after + this change). + - Disposition: **FAIL, coverage artifact absent for PowerShell; coverage verification is + mandatory for all languages with changed files.** This is a repository-wide tooling gap + (Pester coverage instrumentation is not wired into this local environment), not a regression + introduced by this feature. + - Evidence: directory listing confirming `artifacts/pester/` does not exist in this worktree; + `git diff` confirms the sole PowerShell change is a 2-line array-coercion fix in + `scripts/vscode/Invoke-MSTestWithCoverage.ps1`. +- **C# (CSharp) coverage:** + - Baseline: unavailable (no `artifacts/csharp/coverage.xml` exists in this worktree). + - Post-change: unavailable (no `artifacts/csharp/coverage.xml` exists in this worktree). + - Change: N/A (no canonical artifact pair to diff). + - New/changed-code coverage: 0% for all 12 modified `SVGControl/` files. The feature's own + project-scoped Cobertura evidence at `evidence/qa-gates/final-coverage-delta.md` documents a + pre-existing 0% baseline for these 12 files, not introduced or worsened by this feature, since + `SVGControl.Test` has never exercised any of them. `RelativePath.cs` is a separate, + verify-only file that was not modified by this feature; its independently re-confirmed + coverage is unchanged at line-rate 56.75% / branch-rate 54.35% both before and after + (byte-identical), and is excluded from the "modified files" count above. + - Disposition: **FAIL, coverage artifact absent for CSharp; coverage verification is mandatory + for all languages with changed files.** Supplementary (non-canonical) evidence from this + feature's own project-scoped Cobertura capture (`evidence/qa-gates/final-coverage.cobertura.xml`, + independently spot-checked against the raw XML in this review) shows the `SVGControl` package + line-rate moving from 26.65% (870/3264) to 26.64% (870/3266) — a -0.02 percentage-point + change fully explained by 2 new instrumentable-but-never-covered lines (no previously-covered + line lost coverage; `lines-covered` is unchanged at 870); branch-rate is unchanged at 32.28% + (368/1140 both before and after). This is not a canonical repo-wide C# coverage figure and does + not substitute for the missing `artifacts/csharp/coverage.xml` gate. + - Evidence: directory listing confirming `artifacts/csharp/` does not exist in this worktree; + `evidence/qa-gates/final-coverage-delta.md`; direct inspection of + `evidence/qa-gates/final-coverage.cobertura.xml` headline attributes + (`line-rate="0.266381"`, `lines-covered="870"`, `lines-valid="3266"`) performed independently + in this review and matching the evidence document's claims exactly. + +#### 1.2.2 Threshold conflict (flagged, not resolved by this feature or this review) + +`CLAUDE.md`'s embedded General Unit Test Policy states repository-wide line coverage `>= 80%` +(with a COM/VSTO/WinForms testable-denominator exemption) while `.claude/rules/general-unit-test.md` +states a uniform `>= 85%` line / `>= 75%` branch floor with no such exemption. The executing plan +explicitly flagged this conflict in its "Open Questions / Notes" section rather than silently +picking one value, and deferred resolution to the epic's Wave-2 CI-capstone child, consistent with +prior epic-sibling precedent. This review does not resolve the conflict; it is recorded here as a +pre-existing, repository-wide condition, not a defect of this feature. + +### 1.3 Scenario Completeness / Test Structure / External Dependencies + +Not applicable to new test authoring (none added). Existing test structure in `SVGControl.Test` +was not modified by this feature. **N/A.** + +## 2. General Code Change Policy Compliance + +### 2.1 Design Principles / Simplicity / Reusability / Extensibility / Separation of Concerns + +**PASS.** Every change is a nullable-annotation edit (`?`, `!`, flow-narrowed locals) on an +existing member. No new class, method, or abstraction was introduced. No refactor occurred. + +### 2.2 File Size Limit (500 lines) + +**PASS.** All 12 remediated files are well under 500 lines (largest is `SvgRenderer.cs` at 344 +lines, independently confirmed). `RelativePath.cs` (1678 lines) already exceeded the limit before +this feature and was not touched (verify-only, confirmed byte-identical via `git diff --stat` +showing no entry for it) — a pre-existing condition explicitly out of scope, not a new violation. + +### 2.3 Error Handling and Logging + +**PASS.** No new error-handling or logging code was introduced. Existing guard clauses +(`if (x == null)`, `??=`) were preserved unchanged; no new `if (x is null) throw` guard was added +anywhere (confirmed via per-batch evidence and independent diff review), consistent with the +spec's explicit instruction to prefer annotation/`!` over new runtime guards. + +### 2.4 Bugfix Workflow (applies to `scripts/vscode/Invoke-MSTestWithCoverage.ps1`) + +**PARTIAL.** The `Invoke-MSTestWithCoverage.ps1` change fixes a genuine defect (a PowerShell +`Set-StrictMode`-triggered scalar/array coercion bug: `$testAssemblies.Count` throws when exactly +one test assembly matches). Per the General Code Change Policy's Bugfix Workflow, a defect fix +must be preceded by a failing regression test. No such test was added (confirmed: `git diff` +shows only the production script changed; no file under `tests/scripts/vscode/` was added or +modified in this diff). The one changed line is top-level script-scope glue code, not a function +extracted into the testable `Invoke-MSTestWithCoverage.Helpers.ps1` module, so it was not +practical to unit-test without further refactor (which itself would exceed the fix's minimal +scope). This is recorded as a Partial finding, carried to remediation, rather than silently +accepted or silently failed. + +### 2.5 Naming / Public APIs / Compatibility / Dependencies / I/O Boundaries + +**PASS.** No public API was removed, renamed, or had a parameter added/removed. All public +signature changes are additive nullability annotations only (independently re-verified against +`evidence/qa-gates/final-signature-compat.md`, cross-checked against `git diff` for all 12 files). +No new dependency was added. + +## 3. Language-Specific Code Change Policy Compliance (C#, `.claude/rules/csharp.md`) + +### 3.1 Toolchain Order and Commands + +**PASS.** `csharpier` -> analyzer/code-style `msbuild` -> nullable-pragma `msbuild /t:Rebuild +/p:TreatWarningsAsErrors=true` -> `vstest` (via `Invoke-MSTestWithCoverage.ps1`) was followed in +the documented order at every batch (Section 6 independently re-confirms the final pass). + +### 3.2 MSTest / Moq / FluentAssertions + +**N/A** for this feature (no new tests were authored). Existing tests already use MSTest + +FluentAssertions. + +### 3.3 Per-file `#nullable enable` architecture (this feature's specific mandate) + +**PASS.** `#nullable enable` was added to exactly the 12 hand-authored files named in scope; no +`` element was added to `SVGControl.csproj` or `TaskMaster.sln` (independently +re-confirmed via `grep -c "Nullable"` returning 0 for both files, Section 6). The 3 already-enabled +verify-only files (`PathInternal.cs`, `RelativePath.cs`, `ValueStringBuilder.cs`) remain +byte-identical (confirmed: absent from `git diff --stat`). The 5 Designer/generated files remain +byte-identical (independently re-confirmed: `git diff --stat` against those 5 exact paths returns +no output). + +### 3.4 Nullable post-condition attributes / polyfills + +**PASS.** Independently re-confirmed via grep: the sole match for a post-condition-attribute +keyword anywhere in `SVGControl/*.cs` is one inert, pre-existing, commented-out line in +`PathInternal.cs` (a verify-only file, untouched by this feature). No polyfill declaration for +`System.Diagnostics.CodeAnalysis` exists anywhere in `SVGControl/`. + +### 3.5 Legacy project format / `record`/`init` prohibition + +**PASS.** `SVGControl.csproj` remains a non-SDK-style legacy project (unmodified in this diff — +confirmed absent from `git diff --stat`). `SvgResource` (in `ISvgResource.cs`) remains a plain +`class` with settable properties, not converted to `record`/`record struct`/`init` (independently +re-confirmed via grep). + +## 4. Language-Specific Unit Test Policy Compliance (C#) + +**N/A.** No new C# tests were authored or required by this annotation-only feature. Existing +`SVGControl.Test` tests (MSTest + FluentAssertions) continue to pass unmodified (37/37, +independently re-verified in Section 6). + +## 5. Test Coverage Detail + +See Section 1.2.1 above for the mandatory per-language rows. Summary table: + +| Language | Changed files | Canonical artifact | Baseline | Post-change | Verdict | +|---|---|---|---|---|---| +| TypeScript | 0 | N/A | N/A | N/A | N/A | +| Python | 0 | N/A | N/A | N/A | N/A | +| PowerShell | 1 (`Invoke-MSTestWithCoverage.ps1`) | `artifacts/pester/powershell-coverage.xml` — absent | unavailable | unavailable | **FAIL** (artifact absent) | +| C# (CSharp) | 12 (`SVGControl/*.cs`) | `artifacts/csharp/coverage.xml` — absent | unavailable | unavailable | **FAIL** (artifact absent) | + +Supplementary, non-canonical, feature-scoped Cobertura evidence (`SVGControl` project only, not a +repo-wide figure): line-rate 26.65% -> 26.64% (delta explained entirely by 2 new +instrumentable-but-uncovered lines; zero previously-covered lines lost coverage); branch-rate +unchanged at 32.28%. `RelativePath.cs` (the only file in scope with a real pre-existing test +baseline) is byte-identical in coverage before/after (56.75% line / 54.35% branch), confirming no +changed-line regression for that file. These figures were independently spot-checked against the +raw XML headline attributes in `evidence/qa-gates/final-coverage.cobertura.xml` during this review +and matched the evidence document's claims exactly. + +## 6. Test Execution Metrics (Independently Re-Verified in This Review) + +- `dotnet tool run csharpier check SVGControl/` — **EXIT 0**, "Checked 18 files", zero residual + formatting diffs (re-run independently in this review). +- `msbuild TaskMaster.sln /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" + /p:TreatWarningsAsErrors=true` — **EXIT 1**, 6 total errors, **zero** `CS8xxx` diagnostics + (confirmed via `grep -c "CS8[0-9][0-9][0-9]"` on the full build log = 0). The 6 errors are + exactly: 2x `CS0649` in `SvgImageSelector.cs` (pre-existing, unrelated to nullable) and 4x + `CS0006` in `VBFunctions.csproj` (pre-existing analyzer-package-version-pin mismatch, + `UtilitiesCS.csproj` fails only via dependency short-circuit on `SVGControl.csproj`). This + precisely matches the evidence artifacts' claims and was reproduced independently in this + review, not merely read from the evidence. +- `vstest.console.exe SVGControl.Test/bin/Debug/SVGControl.Test.dll` — **EXIT 0**, "Total tests: + 37, Passed: 37, Failed: 0" (re-run independently in this review after rebuilding + `SVGControl.Test.csproj`, since the prior `/t:Rebuild` cleaned `SVGControl`'s output). +- `grep -n "Nullable" SVGControl/SVGControl.csproj` and `... TaskMaster.sln` — both return 0 + matches (re-run independently in this review). +- `git diff --stat` on the 5 named Designer/generated files — zero output (re-run independently + in this review). + +## 7. Code Quality Checks + +See `code-review.2026-07-19T11-15.md` for the full findings table. Summary: no Blocking +code-quality findings; two Partial findings (missing PowerShell regression test for the bugfix; +absent canonical coverage artifacts for both changed languages), both carried to remediation. + +## 8. Gaps and Exceptions + +1. **Coverage artifact absence (C# and PowerShell).** No `artifacts/csharp/coverage.xml` or + `artifacts/pester/powershell-coverage.xml` exists in this worktree. This is a known, + repository-wide, systemic gap (local full-solution C# coverage generation is independently + blocked by environment constraints unrelated to this feature) and is not newly introduced by + this feature's source edits. Carried to remediation per the mandatory coverage-verification + procedure. +2. **Missing regression test for the `Invoke-MSTestWithCoverage.ps1` bugfix.** The Bugfix Workflow + requires a failing test before the fix; none was added. Carried to remediation as a + process-compliance gap, not a functional defect (the fix itself was independently re-verified + as correct: it forces array semantics on a `Get-ChildItem | ... | Select-Object` pipeline that + previously collapsed to a scalar under `Set-StrictMode` when exactly one match existed). +3. **Threshold conflict** between `CLAUDE.md` (80%/90%) and `.claude/rules/general-unit-test.md` + (85%/75% uniform) remains unresolved repo-wide; the executing plan explicitly flagged rather + than silently resolved it. Not a defect of this feature. + +## 9. Summary of Changes + +- 12 hand-authored `.cs` files in `SVGControl/` received a `#nullable enable` pragma and were + brought to zero CS86xx diagnostics via `?` annotations, flow-narrowed locals, and justified `!` + operators. No behavior change. +- `ISvgResource`/`SvgResource` (`Name`, `Data`) were made nullable to resolve a `CS8766` + interface-implementation mismatch (necessary consequence of the architecture, not scope creep — + see `feature-audit` for full analysis). +- One shared PowerShell tooling script (`scripts/vscode/Invoke-MSTestWithCoverage.ps1`) received a + 2-line array-coercion fix unrelated to nullable content. +- 47/47 atomic-plan tasks checked off; all AC1–AC6 checked off in `issue.md`. + +## 10. Compliance Verdict + +**BLOCKED (procedural) / PASS (code correctness).** All code-correctness, behavior-preservation, +and per-file nullable-gate requirements are independently verified PASS. The mandatory +coverage-artifact gate is FAIL for both changed languages (C#, PowerShell) due to absent canonical +artifacts — a systemic, pre-existing environment gap, not a defect in this feature's `SVGControl/` +changes. A minor process gap (missing regression test for the PowerShell bugfix) is recorded as +Partial. See `remediation-inputs.2026-07-19T11-15.md` for the specific remediation triggers. + +## Appendix A: Test Inventory + +| Test file | Framework | Scope | Result (independently re-run) | +|---|---|---|---| +| `SVGControl.Test/GetRelativePath_Test.cs` | MSTest + FluentAssertions | `RelativePath.cs` (verify-only) | Pass (part of 37/37) | +| `SVGControl.Test/RelativePathCoverageTests.cs` | MSTest + FluentAssertions | `RelativePath.cs` (verify-only) | Pass (part of 37/37) | + +No test in `SVGControl.Test` exercises any of the 12 remediation-target files (`ButtonSVG.cs`, +`PictureBoxSVG.cs`, `ToggleSwitch.cs`, `SVGParser.cs`, `SvgRenderer.cs`, `SvgImageSelector.cs`, +`ISvgResource.cs`, `SvgOptionsConverter.cs`, `SvgOptionsConverter2.cs`, `SvgResourceConverter.cs`, +`DropDownEditor.cs`, `SVGFileNameEditor.cs`) — a pre-existing condition documented explicitly by +the plan and spec, not introduced by this feature. + +No Pester test exercises `scripts/vscode/Invoke-MSTestWithCoverage.ps1`'s top-level script-scope +glue code (the changed line); `tests/scripts/vscode/Invoke-MSTestWithCoverage.Helpers.Tests.ps1` +exercises only the extracted, testable `Invoke-MSTestWithCoverage.Helpers.ps1` module, which was +not touched by this feature's fix. + +## Appendix B: Toolchain Commands Reference + +``` +dotnet tool run csharpier check . +msbuild TaskMaster.sln /t:Build /p:Configuration=Debug /p:Platform="Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true +msbuild TaskMaster.sln /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true +pwsh scripts/vscode/Invoke-MSTestWithCoverage.ps1 -CoverageOutput +vstest.console.exe SVGControl.Test/bin/Debug/SVGControl.Test.dll +``` + +All commands above were independently re-run (or, for the coverage-wrapped test run, reproduced +via a direct `vstest.console.exe` invocation against the rebuilt test assembly) during this review +pass, in addition to being documented in the feature's own evidence artifacts. diff --git a/docs/features/active/utilitiescs-nullable-svgcontrol/remediation-inputs.2026-07-19T11-15.md b/docs/features/active/utilitiescs-nullable-svgcontrol/remediation-inputs.2026-07-19T11-15.md new file mode 100644 index 00000000..a7b8e393 --- /dev/null +++ b/docs/features/active/utilitiescs-nullable-svgcontrol/remediation-inputs.2026-07-19T11-15.md @@ -0,0 +1,79 @@ +# Remediation Inputs — utilitiescs-nullable-svgcontrol (Issue #368) + +- Timestamp: 2026-07-19T11-15 +- Source review artifacts: + - `docs/features/active/utilitiescs-nullable-svgcontrol/policy-audit.2026-07-19T11-15.md` + - `docs/features/active/utilitiescs-nullable-svgcontrol/code-review.2026-07-19T11-15.md` + - `docs/features/active/utilitiescs-nullable-svgcontrol/feature-audit.2026-07-19T11-15.md` + +## Context + +All 6 acceptance criteria (AC1–AC6) are independently verified PASS, and no Blocking +code-correctness or behavior-preservation defect was found in the 12 remediated `SVGControl/` +files. The two remediation-required findings below are procedural/systemic (coverage-artifact +tooling gap) and process-compliance (missing regression test for an unrelated one-line PowerShell +fix), not defects in the feature's `SVGControl/` nullable-annotation work itself. + +## Remediation-Required Finding 1 — Coverage artifact absence (C# and PowerShell) + +- **Severity:** Blocking (per the mandatory coverage-verification procedure); systemic, not + introduced by this feature. +- **Languages affected:** C# (12 changed `.cs` files in `SVGControl/`), PowerShell (1 changed + `.ps1` file: `scripts/vscode/Invoke-MSTestWithCoverage.ps1`). +- **Finding:** Neither `artifacts/csharp/coverage.xml` nor `artifacts/pester/powershell-coverage.xml` + exists in this worktree. The mandatory coverage-verification procedure requires an explicit + PASS/FAIL verdict backed by a canonical artifact for every language with changed files; absence + of the artifact is itself a FAIL condition, independent of the underlying code's actual test + coverage. +- **Supporting evidence already available (non-canonical, supplementary):** this feature's own + project-scoped Cobertura captures at `evidence/qa-gates/final-coverage.cobertura.xml` and + `evidence/baseline/baseline-coverage.cobertura.xml` show no regression on any previously-covered + line (`SVGControl` package `lines-covered` unchanged at 870; `RelativePath.cs` byte-identical + 56.75%/54.35% before and after). These do not substitute for the canonical repo-wide artifacts. +- **Recommended remediation:** Generate `artifacts/csharp/coverage.xml` and + `artifacts/pester/powershell-coverage.xml` via the repo's canonical CI coverage pipeline (this + has been independently confirmed in prior epic-sibling reviews to be blocked in local + environments by an unrelated Moq binding-redirect issue for full-solution C# coverage runs), or + obtain an explicit maintainer decision to treat this specific gap as a tracked, ratified + exemption consistent with how prior epic-sibling PRs (#309, #354) handled the identical + systemic condition. +- **Not required:** No change to any of the 12 `SVGControl/` production files is required to + address this finding; it is a tooling/CI-pipeline gap, not a code defect. + +## Remediation-Required Finding 2 — Missing regression test for the `Invoke-MSTestWithCoverage.ps1` bugfix + +- **Severity:** Partial (process-compliance gap; the fix itself is independently verified + functionally correct). +- **File:** `scripts/vscode/Invoke-MSTestWithCoverage.ps1`, line 133 + (`$testAssemblies = @(Get-ChildItem ... | Select-Object -ExpandProperty FullName)`). +- **Finding:** This is a genuine defect fix (a `Set-StrictMode`-triggered scalar/array coercion bug + that throws `The property 'Count' cannot be found on this object.` when exactly one test + assembly matches the filter). The General Code Change Policy's Bugfix Workflow requires a + failing regression test be added before the fix. No test was added (confirmed via `git diff`: + only the production script changed). +- **Recommended remediation:** Extract the `Get-ChildItem | Where-Object | Select-Object` + test-assembly-discovery pipeline into a named, testable function in + `scripts/vscode/Invoke-MSTestWithCoverage.Helpers.ps1` (following the existing pattern of + `Get-DotnetCoverageArgumentList`/`ConvertTo-KoverageCoberturaXml` in that same file), then add a + Pester test in `tests/scripts/vscode/Invoke-MSTestWithCoverage.Helpers.Tests.ps1` asserting that + the function returns an array (not a scalar) when exactly one match is supplied, and that + `.Count` succeeds under `Set-StrictMode -Version Latest`. +- **Not required:** No change to the fix's correctness is required; the `@(...)` wrapping is the + minimal, correct fix and was independently re-verified in this review by rebuilding + `SVGControl.Test.csproj` and confirming the coverage-wrapped test-discovery step no longer throws + when exactly one `*.Test.dll` matches (the actual condition in this worktree, since + `UtilitiesCS`/`VBFunctions`-dependent test projects fail to build for the unrelated, + pre-existing analyzer-package-pin reason documented in `policy-audit`). + +## Not Remediation-Required (Recorded for Completeness) + +- The two flagged maintainer-judgment deviations (`ISvgResource` interface nullability; + additional-member annotations beyond the plan's literal task text) were evaluated in + `feature-audit` and judged legitimate, in-scope consequences of the stated architecture. No + remediation action is recommended for either. +- The `SvgImageSelector.ImagePath` judgment call was evaluated and judged correctly, + conservatively resolved. No remediation action is recommended. +- The CLAUDE.md-vs-`.claude/rules/general-unit-test.md` coverage-threshold conflict (80%/90% vs. + 85%/75% uniform) is a pre-existing, repository-wide condition explicitly flagged (not silently + resolved) by the executing plan. It is out of scope for this feature to resolve and is not + carried forward as a remediation trigger specific to this feature. diff --git a/scripts/vscode/Invoke-MSTestWithCoverage.ps1 b/scripts/vscode/Invoke-MSTestWithCoverage.ps1 index b6fd27d0..b868096d 100644 --- a/scripts/vscode/Invoke-MSTestWithCoverage.ps1 +++ b/scripts/vscode/Invoke-MSTestWithCoverage.ps1 @@ -130,13 +130,13 @@ if (-not (Get-Command 'dotnet-coverage' -ErrorAction SilentlyContinue)) { throw "dotnet-coverage not found. Install it with: dotnet tool install --global dotnet-coverage" } -$testAssemblies = Get-ChildItem -Path $resolvedSearchRoot -Recurse -Filter '*.Test.dll' | +$testAssemblies = @(Get-ChildItem -Path $resolvedSearchRoot -Recurse -Filter '*.Test.dll' | Where-Object { $_.FullName -match "\\bin\\$Configuration\\" -and $_.FullName -notmatch '\\obj\\' -and $_.FullName -notmatch '\\ref\\' } | - Select-Object -ExpandProperty FullName + Select-Object -ExpandProperty FullName) if (-not $testAssemblies -or $testAssemblies.Count -eq 0) { throw "No test assemblies found under '$resolvedSearchRoot' for configuration '$Configuration'. Build first."