fix(371): remediate nullable debt in Outlook item-adapter cluster (MailItem/Item/Conversation/Attachment/Table) - #387
Merged
Conversation
Capture policy-read, csharpier, analyzer, pragma-only nullable, and coverage baselines for the utilitiescs-nullable-outlook-mailitem-item child (#371). In-scope CS86xx baseline = 0 (all 30 files oblivious); in-scope OutlookObjects production line coverage = 87.07%. Solution-wide TWAE Rebuild halts on pre-existing out-of-scope SVGControl CS0649; authoritative in-scope CS86xx verified via isolated UtilitiesCS build. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXCu1xPtNbJs2HwKxgS9Bv
…odule2, ItemComparer) Add per-file #nullable enable pragma to the two commented-out dead files. No live code; zero CS86xx. CaptureEmailAddressesModule2Tests green (2/2). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXCu1xPtNbJs2HwKxgS9Bv
Add whole-file #nullable enable to the host-neutral cid: image resolver. One CS8602 fixed with a justified null-forgiving operator (guarded by the preceding IsNullOrEmpty check); public signatures unchanged. 0 CS86xx. CidImageResolver tests green (3/3); changed line covered, no regression. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXCu1xPtNbJs2HwKxgS9Bv
Add per-file #nullable enable to MailResolution, MailItemExtensions, OlItemPseudoInterface, OlItemSummary, OlToDoTable. Annotation-only nullable returns/locals reflecting actual null behavior (MailItem?/byte[]?/Task<object?>/ Outlook.Table? and nullable locals). dynamic item line left byte-unchanged and flagged. 0 CS86xx; 51/51 Batch C tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXCu1xPtNbJs2HwKxgS9Bv
…able Add #nullable enable to OutlookItem, OutlookItemExtensions, OutlookItemFlaggable, OutlookItemTry, OutlookItemTryGet, OutlookItemFlaggableTry. Deliberate unconstrained-generic T? contract for TryGet<T>/TryCall<T>/GetPropertyValueIfExists<T> and out T?, propagated consistently to the try/catch-swallowing decorators' reference-type members. Nullable fields/getters; justified ! at reflection derefs. Seams preserved. OutlookItem.cs left intact at 504 lines (flagged). 0 CS86xx; 175/175 Batch D tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXCu1xPtNbJs2HwKxgS9Bv
Add #nullable enable to AttachmentSerializable and AttachmentHelper. Nullable POCO props/lazy fields/out params reflecting actual null behavior; AttachmentData setter rebuilt as explicit Lazy<byte[]?> (ToLazy has a class constraint). FilePathSave/FolderPathSave keep the #364 FilePathHelper non-nullable default contract as-is. Verified #364 FilePathHelper contract landed (P5-T1). 0 CS86xx; 40/40 Batch E tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXCu1xPtNbJs2HwKxgS9Bv
…e enable Add #nullable enable to ItemInfo (nullable POCO IItemInfo props mirroring the Batch G MailItemHelper decisions), EmailDetails (nullable dictRemap params), and EmailDetailsWrapper (nullable default-null params; seam preserved). 0 CS86xx; 25/25 Batch F tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXCu1xPtNbJs2HwKxgS9Bv
Opt in all 5 MailItemHelper.* files as one unit. Lazy backing fields nullable (resolving 125 CS8618; net481 has no MemberNotNull); the four lazy props without a ?? fallback (Sender/FolderInfo/AttachmentsInfo/Globals) annotated nullable per P7-T6 with value?.ToLazy() setters. Html.cs interior pragma region normalized to whole-file. ResolveMail -> MailItem? consuming Initializer.GetOrLoad. Cross-batch reconcile: EmailDetails helper derefs (!) and CidImageResolver attachments params nullable. #363/#364 contracts verified (P7-T1/T2). 0 CS86xx as one unit; 125/125 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXCu1xPtNbJs2HwKxgS9Bv
Opt in both ConversationHelper.* files as one unit. Nullable DataFrame?/ Table?/Conversation? returns and null-default params reflecting actual null behavior; shared LogConversationTiming details -> string? consumed consistently cross-file; GetConversationTable param nullable to match the RunWithTimeout delegate target. #364 PrettyText verified (P8-T2); #363 ForEach resolves at build time (P8-T1 flag, not a block). 0 CS86xx as one unit; 75/75 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXCu1xPtNbJs2HwKxgS9Bv
…able Opt in all 4 OlTableExtensions.* files as one unit. ETL-family tuples -> (object[,]? , Dictionary?) reflecting the genuine (null,null) error path; nullable objectConverters/progress/objFields/objIndices across the ETL call graph; TableAccess GetTable/TryGetTableAsync nullable returns. #363 ArrayExtensions contract verified (P9-T1). Cross-batch reconcile: Formatting.cs ETL consumers deconstruct nullable with justified !; oblivious DfDeedle unaffected. 0 CS86xx as one unit; 162/162 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXCu1xPtNbJs2HwKxgS9Bv
…or behavior compatibility The full-solution nullable gate surfaced that making the ETL-family public tuples and GetTableInViewAsync nullable introduced 7 CS86xx in the nullable-enabled out-of-scope consumers DfDeedle.cs/DfDeedle.FrameUtilities.cs, violating public-signature behavior-compatibility. Revert those public signatures to non-null; express the genuine null paths with justified ! at the internal return sites. Total UtilitiesCS CS86xx = 0; 162/162 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXCu1xPtNbJs2HwKxgS9Bv
Final toolchain pass on the complete remediation: CSharpier clean, analyzer 0 errors/0 in-scope warnings, pragma-only nullable gate 0 CS86xx across all 30 files (and 0 total across UtilitiesCS), 4511/4511 tests green. Coverage flat vs baseline (in-scope 87.07%; overall 65.30%); no changed-line regression. No <Nullable> element. AC1-AC6 checked off in spec.md and user-story.md; DoD and seeded test conditions satisfied. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UXCu1xPtNbJs2HwKxgS9Bv
…cts nullable remediation Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eature-audit) blocking_count = 0. All 30 in-scope OutlookObjects files verified CS86xx-clean under the pragma-only nullable gate; partial-class groups verified as consistent units; SVGControl pre-existing halt and isolated-build substitution methodology independently verified sound; Batch I self-correction (commit 2f6f3fe) verified behavior-compatible; coverage flat, no regression. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ailitem-item-371 Sync with sibling children (#370/#374/#375) that merged into epic/utilitiescs-nullable-remediation-integration in parallel. No overlap with this child's in-scope files (OutlookObjects/{MailItem,Item,Conversation, Attachment,Table}); only conflict was an additive atomic-executor agent-memory index entry, resolved by keeping both entries. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
UtilitiesCS/OutlookObjects/{MailItem,Item,Conversation,Attachment,Table}/, 30 production.csfiles) via the epic's per-file#nullable enableopt-in architecture. Annotation and null-safety only — no behavior changes, no refactors, no API redesign.utilitiescs-nullable-remediationepic, depending on the already-mergedutilitiescs-nullable-extensions(Feature: utilitiescs-nullable-extensions #363, PR fix(363): nullable-reference remediation of UtilitiesCS/Extensions via per-file #nullable enable #379) andutilitiescs-nullable-helperclasses(Feature: utilitiescs-nullable-helperclasses #364, PR nullable(#364): per-file #nullable enable opt-in for UtilitiesCS/HelperClasses #382) children for their upstream contracts (LazyExtension,Initializer.GetOrLoad,IEnumerableExtensions.ForEach,PrettyPrint.PrettyText,ArrayExtensions.ToStringArray/SliceRow/To2D,FilePathHelper).MailItemHelper— 5 files,ConvHelper— 2 files,OlTableExtensions— 4 files) were annotated and verified as single consistent units.Verification
UtilitiesCSassembly (including out-of-scope nullable-enabled consumers): 0 — no regression introduced.<Nullable>element added toUtilitiesCS.csprojorTaskMaster.sln./p:Nullable=enablewas never passed — the nullable/type-check gate for this child is the documented pragma-only deviation:msbuild TaskMaster.sln /t:Rebuild /p:Configuration=Debug /p:Platform="Any CPU" /p:TreatWarningsAsErrors=true.SVGControlCS0649 error (confirmed present at the branch point, unrelated to this change); CS86xx is authoritatively measured via an isolatedUtilitiesCS.csprojrebuild, the same technique used by the already-merged sibling child Feature: utilitiescs-nullable-helperclasses #364. Independently verified sound by feature-review.OutlookObjectsline coverage flat at 87.07%; overall flat; no changed-line regression.OutlookItem.cs(504 lines) andOlToDoTable.EnsureItemValues'sdynamic itemremain unmodified pre-existing conditions, flagged per plan (not fixed — out of scope).CidImageResolver.csis the sole non-COM-exempt file in scope; coverage held at 94.7%, unchanged.2f6f3fec) reverted an initially-introduced nullable change toOlTableExtensions.ETL/EtlAsync/GetTableInViewAsync/EtlPrepAsyncreturn-tuple types after Phase 10's full-solution gate showed it broke public-signature behavior-compatibility for out-of-scope consumers (Extensions/DfDeedle.cs,DfDeedle.FrameUtilities.cs); final state is behavior-compatible.Acceptance Criteria
spec.md(Definition of Done + AC1-AC6 + seeded test conditions) — 17/17 checked.user-story.md(Acceptance Criteria) — 6/6 checked.Feature Review
blocking_count = 0(policy-audit, code-review, feature-audit all PASS). Artifacts:docs/features/active/utilitiescs-nullable-outlook-mailitem-item/{policy-audit,code-review,feature-audit}.2026-07-19T12-50.md.Test plan
#nullable enableand are CS86xx-clean under the pragma-only gate<Nullable>element added anywhere in the solutionUtilitiesCS.Testsuite green (4511/4511)Closes #371
Co-Authored-By: Claude Fable 5 noreply@anthropic.com