---
title: SAIF.NetCore.Common business rules
summary: Enumerated business rules with per-rule trigger, enforcement, and outcomes.
status: draft
owner: Framework.NCore maintainers
last_reviewed: 2026-10-02
library: SAIF.NetCore.Common
reference_type: package
---

# SAIF.NetCore.Common business rules

This page captures business rules enforced by this library. `SAIF.NetCore.Common` is a foundation-layer utility library, so every rule below is a generic validation, normalization, or guard-clause behavior enforced directly by code in this library — none involve a database, SQL, or an inherited base class from another library.

## BR-001 Required argument must not be null

| Field | Value |
| --- | --- |
| **Statement** | A required argument passed to `Enforce.ArgumentNotNull<T>(value, name)` must not be null, and the supplied parameter name must not itself be blank. |
| **Trigger** | A caller invokes `Enforce.ArgumentNotNull<T>(value, name)`. |
| **Enforcement** | `Enforce.ArgumentNotNull<T>` throws `ArgumentNullException("parameterName")` when `name` is null/empty/whitespace, and `ArgumentNullException(name)` when `value` is null. |
| **Outcome** | Construction/execution fails immediately with a typed exception; no further guard-clause logic runs. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Helpers/Enforce.cs` |

---

## BR-002 Required string must not be null empty or white space

| Field | Value |
| --- | --- |
| **Statement** | A required string passed to `Enforce.ArgumentNotNullOrEmpty` must not be null or empty, and a string passed to `Enforce.ArgumentNotNullOrWhiteSpace` must not be null, empty, or all white space. |
| **Trigger** | A caller invokes either guard method. |
| **Enforcement** | Both delegate to `Enforce.ArgumentNotNull` first: a blank `parameterName` throws `ArgumentNullException("parameterName")`, and a null `parameter` throws `ArgumentNullException(parameterName)`. Only a non-null but empty/whitespace `parameter` reaches the custom `ArgumentException` with message "Parameter ({0}) cannot be null or empty." or "Parameter ({0}) cannot be null or white space." respectively, substituting the parameter name. |
| **Outcome** | A blank name or null value fails with `ArgumentNullException`; a non-null empty/whitespace value fails with the custom-message `ArgumentException`. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Helpers/Enforce.cs` |

---

## BR-003 Required object must not be null as a state check

| Field | Value |
| --- | --- |
| **Statement** | `Enforce.NotNull<T>(value)` treats a null value as an invalid object state rather than an invalid argument. |
| **Trigger** | A caller invokes `Enforce.NotNull<T>(value)`. |
| **Enforcement** | Throws `InvalidOperationException("The type {0} cannot be null.")`, substituting `typeof(T)`. |
| **Outcome** | Execution fails with `InvalidOperationException` instead of an argument exception, signalling a state problem rather than a caller error. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Helpers/Enforce.cs` |

---

## BR-004 Caller supplied condition must evaluate true

| Field | Value |
| --- | --- |
| **Statement** | `Enforce.True<T>(bool/Func<bool>)` and `Enforce.True(bool/Func<bool>, Exception)` require the supplied condition to evaluate to `true`. |
| **Trigger** | A caller invokes any of the four `Enforce.True` overloads with a condition that evaluates to `false`. |
| **Enforcement** | The `<T>` overloads construct and throw `new T()`; the `Exception` overloads throw the exception instance the caller supplied. |
| **Outcome** | Execution fails with the generic or caller-supplied exception type; a `true` condition allows execution to continue with no return value. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Helpers/Enforce.cs` |

---

## BR-005 ValidatedNotNullAttribute is a marker only

| Field | Value |
| --- | --- |
| **Statement** | `ValidatedNotNullAttribute` applied to the `value` parameter of `Enforce.ArgumentNotNull` is a static-analysis hint only and has no runtime behavior of its own. |
| **Trigger** | The compiler or a static analyzer inspects `Enforce.ArgumentNotNull`'s parameter list. |
| **Enforcement** | The attribute class is `internal`, `sealed`, and empty; it carries no fields, properties, or logic. |
| **Outcome** | Analyzers that recognize the `ValidatedNotNullAttribute` convention suppress null-dereference warnings for the guarded parameter; at runtime the attribute has no effect.* |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Helpers/Enforce.cs` |

---

## BR-006 IfNullThrow raises a caller specified exception type

| Field | Value |
| --- | --- |
| **Statement** | `GenericExtensions.IfNullThrow<T,TException>(value, message)` throws an instance of the caller-specified exception type, constructed with the supplied message, when `value` is null. |
| **Trigger** | A caller invokes `value.IfNullThrow<T,TException>(message)` on a null `value`. |
| **Enforcement** | Throws `(TException)Activator.CreateInstance(typeof(TException), message)`. |
| **Outcome** | Execution fails with the caller-chosen exception type and message; a non-null value passes through unchanged. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/GenericExtensions.cs` |

---

## BR-007 ToBoolean recognizes a fixed set of true tokens

| Field | Value |
| --- | --- |
| **Statement** | `StringExtensions.ToBoolean` returns `true` only for the case-insensitive values `Y`, `YES`, `TRUE`, `1`, and `ON`; every other value, including null, returns `false`. |
| **Trigger** | A caller invokes `someString.ToBoolean()`. |
| **Enforcement** | `StringExtensions.ToBoolean` compares the input against the fixed token list case-insensitively. |
| **Outcome** | Returns a `bool`; unrecognized or null input always yields `false` rather than throwing. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/StringExtensions.cs` |

---

## BR-008 Boolean display forms are fixed string pairs

| Field | Value |
| --- | --- |
| **Statement** | `BooleanExtensions.ToY_N_String`, `ToYesNoString`, and `ToOnOffString` render a `bool` as `Y`/`N`, `YES`/`NO`, and `On`/`Off` respectively. |
| **Trigger** | A caller invokes any `BooleanExtensions` display method on a `bool` value. |
| **Enforcement** | Each method is a direct ternary mapping from `true`/`false` to its fixed string pair. |
| **Outcome** | Returns the corresponding display string; there is no configurable alternative form. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/BooleanExtensions.cs` |

---

## BR-009 Sentinel dates render as an empty SAIF short date string

| Field | Value |
| --- | --- |
| **Statement** | `DateExtensions.ToSaifShortDateString` treats `DateTime.MinValue` and `DateTime.MaxValue` as "no date" sentinels and renders them as an empty string; any other date renders as `MM/dd/yyyy`. |
| **Trigger** | A caller invokes `ToSaifShortDateString` on a `DateTime`/`DateTime?` value. |
| **Enforcement** | `DateExtensions.ToSaifShortDateString` checks `IsMinOrMax` before formatting; a null `DateTime?` is also treated as empty. |
| **Outcome** | Returns an empty string for null/min/max; otherwise returns the culture-sensitive `MM/dd/yyyy` formatted date. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/DateExtensions.cs` |

---

## BR-010 Epoch time is whole seconds since 1970 with sentinel dates mapped to zero

| Field | Value |
| --- | --- |
| **Statement** | `DateExtensions.ToEpochTime` returns whole seconds since 1970-01-01 UTC, and a sentinel date (min/max) or a date before 1970 yields `0`. |
| **Trigger** | A caller invokes `someDate.ToEpochTime()`. |
| **Enforcement** | `DateExtensions.ToEpochTime` checks `IsMinOrMax` and the 1970 epoch boundary before computing the elapsed-seconds value. |
| **Outcome** | Returns a `long`; the input's `DateTime.Kind` is not considered, so local-time inputs are treated as if already UTC.* |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/DateExtensions.cs` |

---

## BR-011 DateRange constructors normalize an open end date to MaxValue

| Field | Value |
| --- | --- |
| **Statement** | A `DateRange` constructed via its default, begin-only, or begin/end constructors normalizes an end date of `DateTime.MinValue` to `DateTime.MaxValue`; the copy constructor does **not** re-apply this normalization, so copying an existing `DateRange` whose `EndDate` was set to `DateTime.MinValue` (via its public setter, after construction) preserves the un-normalized `MinValue` end. |
| **Trigger** | A consumer constructs a `DateRange` via any of its four constructors. |
| **Enforcement** | The default, begin-only, and begin/end constructors assign `EndDate` and substitute `DateTime.MaxValue` when the supplied end is `DateTime.MinValue`; the copy constructor (`DateRange(DateRange dateRange)`) copies `BeginDate`/`EndDate` directly from its argument with no such substitution. |
| **Outcome** | A `DateRange` built directly from dates always has a well-defined, non-`MinValue` end date, enabling `IsOpenEnded` and range-comparison logic downstream; a `DateRange` built by copying another instance can still carry a `MinValue` end if the source instance's `EndDate` was mutated to `MinValue` after construction.* |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Types/DateRange.cs` |

---

## BR-012 A date range is valid only when begin does not exceed end

| Field | Value |
| --- | --- |
| **Statement** | `DateRangeExtensions.IsValidRange` requires `BeginDate <= EndDate`; `IsOpenEnded` is true when begin equals `DateTime.MinValue` or end equals `DateTime.MaxValue`; a future range is valid with begin after now, and a past range is valid with end before now. |
| **Trigger** | A caller invokes `IsValidRange`, `IsOpenEnded`, `IsFutureRange`, or `IsPastRange` on a `DateRange`. |
| **Enforcement** | `IsFutureRange`/`IsPastRange` first test `IsValidRange` and return `false` immediately when the range is invalid; only a valid range proceeds to the corresponding direct date comparison against `DateTime.Now`. `IsValidRange`/`IsOpenEnded` perform their direct date comparison without this prerequisite. |
| **Outcome** | Returns a `bool`; `IsFutureRange`/`IsPastRange` results depend on the server's current clock and time zone.* |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/DateRangeExtensions.cs` |

---

## BR-013 Overlapping ranges require both ranges valid and respect the same date overlap flag

| Field | Value |
| --- | --- |
| **Statement** | `DateRangeExtensions.IsOverlapping(range1, range2, inAllowSameDateOverlap)` is intended to return `true` only when both ranges pass `IsValidRange`, treating a shared boundary date as overlap unless `inAllowSameDateOverlap` is `true`; as implemented, its `range2 != null` guard throws `NullReferenceException` before that logic runs, for essentially every call. |
| **Trigger** | A caller invokes `IsOverlapping` with two `DateRange` instances, null or not. |
| **Enforcement** | `IsOverlapping` first evaluates `range2 != null`, which invokes `DateRange`'s custom `!=` operator with `d1 = range2`, `d2 = null`; the operator body unconditionally evaluates `d2.BeginDate`, dereferencing the null literal regardless of whether the caller's `range2` was itself null, so the guard throws before the intended `IsValidRange`/`IsBetween` logic ever runs.* |
| **Outcome** | `IsOverlapping` throws `NullReferenceException` for essentially every ordinary call with a non-null `range2` as well as a null one — it does not reliably return `bool` as its signature implies; see [BR-016](#br-016-daterange-equality-is-defined-by-equal-begin-and-end-dates) for the same underlying operator defect.* |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/DateRangeExtensions.cs` |

---

## BR-014 Contiguous-range evaluation has three selectable policies and a short circuit for fewer than two ranges

| Field | Value |
| --- | --- |
| **Statement** | `DateRangeExtensions.IsContiguous(ranges, option)` returns `true` for fewer than 2 ranges, and otherwise requires every consecutive pair (ordered by `BeginDate`) to satisfy the selected policy: `StartMatchesEnd` (begin equals previous end), `StartIsNextDay` (previous end + 1 day equals begin, the default), or `AllowGaps` (begin is at or after previous end). |
| **Trigger** | A caller invokes `IsContiguous` on an `IEnumerable<DateRange>`. |
| **Enforcement** | `IsContiguous` orders the input by `BeginDate` and applies the selected `ContiguousOptions`/`DateRangeExtensions.ContiguousOptions` comparison to each consecutive pair. |
| **Outcome** | Returns `bool`; the default policy (`StartIsNextDay`) requires a strict day-after-day sequence with no gaps or overlaps. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/DateRangeExtensions.cs` |

---

## BR-015 In-range tests default to include-begin exclude-end

| Field | Value |
| --- | --- |
| **Statement** | `DateRangeExtensions.IsInRange` and `DateRangeExtensions.AsOf<T>` default to the `FirstOnly` comparison mode, which includes the range's begin date and excludes its end date. |
| **Trigger** | A caller invokes `IsInRange` or `AsOf<T>` without specifying an `IncludeComparisons` value. |
| **Enforcement** | Both members default their `IncludeComparisons` parameter to `FirstOnly` and delegate to `IComparableExtensions.IsBetween`. |
| **Outcome** | Returns `bool` (`IsInRange`) or the deferred `IEnumerable<T>` sequence of all matching items (`AsOf<T>`, built from a LINQ `Where` clause), not just the first match; a null `DateTime?` input to `IsInRange` returns `false` rather than throwing. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/DateRangeExtensions.cs` |

---

## BR-016 DateRange equality is defined by equal begin and end dates

| Field | Value |
| --- | --- |
| **Statement** | Two `DateRange` instances are equal (via `==`, `!=`, and `Equals`) only when their `BeginDate` and `EndDate` are both equal. |
| **Trigger** | A consumer compares two `DateRange` instances with `==`, `!=`, or calls `.Equals(object)`. |
| **Enforcement** | `DateRange` overrides `==`/`!=`/`Equals`/`GetHashCode` to compare both date fields. |
| **Outcome** | Both `==` and `!=` return `bool` normally when both operands are ordinary non-null `DateRange` instances, comparing `BeginDate`/`EndDate` directly. Neither operator null-checks its operands, so passing an actual null reference to either side throws `NullReferenceException`; `DateRangeExtensions.IsOverlapping`'s pairwise overlap check (`range2 != null`) hits this specifically because it calls `!=` with a literal `null` second argument, and the operator body still dereferences `d2.BeginDate` unconditionally. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Types/DateRange.cs` |

---

## BR-017 A Julian value requires at least four digits and a day of year within the valid range

| Field | Value |
| --- | --- |
| **Statement** | `Julian.IsValid` requires the input to contain at least 4 digits, and `Julian.ToDate` additionally rejects a day-of-year greater than 365 (or 366 in a leap year). |
| **Trigger** | A caller invokes `Julian.IsValid(value, out message)` or `Julian.ToDate(value, millenium)`. |
| **Enforcement** | `IsValid` checks digit count and returns `false` with the message "The julian must contain at least 4 numbers" on failure; `ToDate` calls `IsValid` first, then throws `ApplicationException` when the day-of-year check fails. |
| **Outcome** | `IsValid` returns `bool` with an out message; `ToDate` throws `ApplicationException` for an invalid or out-of-range value, otherwise returns the computed `DateTime`. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Helpers/Julian.cs` |

---

## BR-018 Two digit EDI years resolve to the 2000s and a missing time means midnight

| Field | Value |
| --- | --- |
| **Statement** | `DateMaker.MakeDateTime` treats a 2-digit year as being in the 2000s (prefixed with `"20"`), and a `time` argument that is omitted defaults to midnight (`"000000"`, right-padded with zeros). |
| **Trigger** | A caller invokes `DateMaker.MakeDateTime(date, time)` with a 6-digit `yyMMdd` date or an omitted `time`. |
| **Enforcement** | `MakeDateTime` prefixes a 6-character `date` string with `"20"` before parsing, and right-pads `time` to 6 characters with `'0'` before building the `DateTime`. |
| **Outcome** | Returns a `DateTime` for the 2000s year assumption; this is a documented limitation for dates before 2000 or after 2099.* |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Helpers/DateMaker.cs` |

---

## BR-019 Title-casing preserves a fixed set of organization abbreviations roman numerals and lowercase words

| Field | Value |
| --- | --- |
| **Statement** | `StringExtensions.ToTitleCase` keeps organization abbreviations, US state/direction codes, and Roman numerals (for example `SAIF`, `LLC`, `II`, `III`, `NE`, `PO`, `USA`) uppercase, keeps listed articles and prepositions (`is`, `in`, `the`, `an`, `of`, `on`, `and`, `de`) lowercase except as the first character, and always uppercases the result's first character. |
| **Trigger** | A caller invokes `someString.ToTitleCase()`. |
| **Enforcement** | `StringExtensions.ToTitleCase` delegates to the internal `TitleCase.ToTitleCase` engine, which classifies each word token against its fixed word lists before reassembling the string. |
| **Outcome** | Returns the title-cased string; a null or empty input is returned unchanged. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/InternalUtility/TitleCase.cs` |

---

## BR-020 A validation result is valid only when it has no errors

| Field | Value |
| --- | --- |
| **Statement** | `ValidationResult.IsValid` is `true` only when `Errors` contains no entries; entries in `Messages` do not affect validity. |
| **Trigger** | A caller reads `ValidationResult.IsValid` after populating `Errors`/`Messages`. |
| **Enforcement** | `ValidationResult.IsValid` is a virtual property implemented as `!Errors.Any()`. |
| **Outcome** | Returns `bool`; `SaifValidationException` built from a `ValidationResult` sets no `Exception.Message` of its own, so the base `Exception.Message` default is used. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Types/ValidationResult.cs` |

---

## BR-021 A header is stripped only when found strictly after position zero

| Field | Value |
| --- | --- |
| **Statement** | `ByteExtensions.StripHeader` only strips a located header and reports `found = true` when the header's starting position is greater than `0`; a header found exactly at position `0`, or not found at all, reports `found = false` and returns the original array unchanged. |
| **Trigger** | A caller invokes `ByteExtensions.StripHeader(bytes, searchFor, out found, maxBytesToSearch)`. |
| **Enforcement** | `StripHeader` checks `position > 0` after calling `Search`, so a `position == 0` match takes the same `found = false` branch as a true not-found result. |
| **Outcome** | Returns the (possibly unmodified) byte array and the `found` flag; a header already at the start of the array is reported as not found. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/ByteExtensions.cs` |

---

## BR-022 A Windows identity name without a backslash yields the same value for user and domain

| Field | Value |
| --- | --- |
| **Statement** | `SecurityPrincipalExtensions.UserId` and `.Domain` split a `DOMAIN\user` identity name into its domain and user segments; when the name contains no backslash, both members return the whole name unchanged. |
| **Trigger** | A caller invokes `UserId`/`Domain` on an `IIdentity` whose `Name` may or may not contain a backslash. |
| **Enforcement** | Both members check for a `\` separator in `IIdentity.Name` and split on it when present, otherwise return the name as-is. |
| **Outcome** | Returns a `string`; callers cannot distinguish a domain-less name from a parse failure, since both return the full name. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/SecurityPrincipalExtensions.cs` |

---

## BR-023 Blank input converts to decimal zero while other input converts directly or throws

| Field | Value |
| --- | --- |
| **Statement** | `StringExtensions.ConvertToDecimalOrZero` returns `0` only when its input string is null, empty, or all white space; for any other input it calls `Convert.ToDecimal` without a try/catch, so a non-numeric or out-of-range string propagates the resulting exception (for example `FormatException` or `OverflowException`) instead of returning `0`. `NumericExtensions.IsNumeric` is a separate, unrelated check that detects numeric strings using 32-bit integer parsing only, not decimal or floating-point parsing. |
| **Trigger** | A caller invokes `ConvertToDecimalOrZero` or `IsNumeric` on a string. |
| **Enforcement** | `ConvertToDecimalOrZero` checks for null/empty/whitespace and returns `0` on that path only; otherwise it calls `Convert.ToDecimal(decimalValue)` directly with no exception handling. `IsNumeric` delegates to `int.TryParse`. |
| **Outcome** | `ConvertToDecimalOrZero` returns `0` for blank input, a culture-sensitive converted `decimal` for ordinary numeric input, and otherwise throws; it does not tolerate non-numeric or overflowing input the way its name implies. `IsNumeric` returns `bool`, and reports a string that is numeric but out of 32-bit integer range (for example a large decimal) as not numeric, independent of what `ConvertToDecimalOrZero` would do with the same input.* |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/StringExtensions.cs` / `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/NumericExtensions.cs` |

---

## BR-024 Duplicate IncludeComparisons enums create an ambiguous reference risk

| Field | Value |
| --- | --- |
| **Statement** | `IncludeComparisons` is independently declared in both `SAIF.NetCore.Common.Enums` and `SAIF.NetCore.Common.Extensions` (declared in `GenericExtensions.cs` at namespace scope, not nested within the `GenericExtensions` class); a consumer that imports both the `Enums` and `Extensions` namespaces and references the bare type name gets an ambiguous-reference compile error (CS0104). `ContiguousOptions` and `OverlappingDateOptions` in `Enums` are distinct, separately named types from the nested `DateRangeExtensions.ContiguousOptions`/`DateRangeExtensions.OverlappingOptions` — `OverlappingDateOptions` does not even share a name with `OverlappingOptions` — so neither pair creates a CS0104 risk; they are simply two incompatible parameter types that happen to model similar policies, and each API accepts only one specific qualified type. |
| **Trigger** | A consumer file has `using SAIF.NetCore.Common.Enums;` and `using SAIF.NetCore.Common.Extensions;` together and references `IncludeComparisons` by its bare name. |
| **Enforcement** | C# name lookup resolves the enclosing namespace before `using` directives, so library call sites such as `IComparableExtensions.IsBetween` bind to the `Extensions`-namespace `IncludeComparisons` even where the file also has `using SAIF.NetCore.Common.Enums;`; a consumer file with both `using` directives and no namespace qualifier instead gets CS0104 at compile time for `IncludeComparisons` only.* |
| **Outcome** | Library-internal call sites compile unambiguously because they live inside the `Extensions` namespace; consumer code that imports both namespaces and references bare `IncludeComparisons` fails to compile. `DateRangeExtensions.IsContiguous(IEnumerable<DateRange>, ContiguousOptions)` accepts only the nested `DateRangeExtensions.ContiguousOptions`, and `DateRangeExtensions.IsOverLapping(IEnumerable<DateRange>, OverlappingOptions)` accepts only the nested `DateRangeExtensions.OverlappingOptions`; passing the top-level `Enums.ContiguousOptions`/`Enums.OverlappingDateOptions` to either method is a compile-time type mismatch, not an ambiguity.* |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/GenericExtensions.cs` / `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/DateRangeExtensions.cs` / `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Enums/IncludeComparisons.cs` / `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Enums/ContiguousOptions.cs` / `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Enums/OverlappingDateOptions.cs` |

---

## BR-025 A dead System Xml Schema using directive has no effect on compiled behavior

| Field | Value |
| --- | --- |
| **Statement** | `DateExtensions.cs` imports `System.Xml.Schema` but no member in the file references any type from that namespace, so the `using` directive has no effect on compiled behavior. |
| **Trigger** | The compiler processes `DateExtensions.cs`. |
| **Enforcement** | The `using System.Xml.Schema;` directive at the top of the file resolves no identifiers used elsewhere in the file. |
| **Outcome** | No behavioral effect; the directive is leftover and could be removed without changing compiled output. |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/DateExtensions.cs` |

---

## BR-026 A missing MVC route segment defaults to Home Index

| Field | Value |
| --- | --- |
| **Statement** | `UriExtensions.ControllerAndActionName` defaults the returned route to `"Home/Index"` when `uri` is null or has no controller path segment, and otherwise appends a literal `"Index"` directly after `uri.Segments[2]` with no separator inserted — when a controller segment exists but no action segment does. Because `Uri.Segments` retains any trailing slash that is already present on a path segment, the result can still read as `"{Controller}/Index"` when the controller segment itself ends in `/` (for example `http://h/app/controller/` → `"controller/Index"`), while a controller segment with no trailing slash produces a run-together result (for example `http://h/app/controller` → `"controllerIndex"`). |
| **Trigger** | A caller invokes `ControllerAndActionName` on a `Uri` with fewer than 4 path segments, or a `null` `Uri`. |
| **Enforcement** | `ControllerAndActionName` initializes `name = "Home/Index"`, returns that default immediately for a null `uri`, concatenates `uri.Segments[2]` and `uri.Segments[3]` when more than 3 segments exist, and otherwise falls back to `string.Format("{0}Index", uri.Segments[2])` when more than 2 segments exist — the format string itself inserts no separator between the controller segment and `"Index"`; any `/` in the result comes solely from a trailing slash already present in `uri.Segments[2]`. |
| **Outcome** | Returns a `string`; unlike `PageName`, `ControllerAndActionName` does not throw for a null `uri` and instead returns the `"Home/Index"` default. The fallback result is `"controller/Index"` when the matched segment retains its trailing slash, and `"controllerIndex"` when it does not — so the result is not unconditionally free of a `Controller/Index`-shaped string.* |
| **Source** | `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/UriExtensions.cs` |

---

## Notes
- Statements marked with `*` describe a defect, limitation, or culture/clock dependency that was inferred from reading the implementation rather than from an explicit design document; they remain accurate descriptions of observed behavior.
- Statements marked with `**` could not be confirmed against a concrete consumer or design decision; treat them as unverified until confirmed against source evidence.
- [BR-013](#br-013-overlapping-ranges-require-both-ranges-valid-and-respect-the-same-date-overlap-flag) and [BR-016](#br-016-daterange-equality-is-defined-by-equal-begin-and-end-dates) describe the same underlying `NullReferenceException` risk from different call sites: `DateRangeExtensions.IsOverlapping`'s own null guard, and the `DateRange.==`/`!=` operator overloads it calls into.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [API reference](api/index.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts. Statements marked with `**` could not be confirmed; treat
> as unknown until verified.

## Sources
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Helpers/Enforce.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/GenericExtensions.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/StringExtensions.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/BooleanExtensions.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/DateExtensions.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/DateRangeExtensions.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/ByteExtensions.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/SecurityPrincipalExtensions.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/NumericExtensions.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Types/DateRange.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Types/ValidationResult.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Helpers/Julian.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Helpers/DateMaker.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/InternalUtility/TitleCase.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Enums/IncludeComparisons.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Enums/ContiguousOptions.cs`
- `src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Enums/OverlappingDateOptions.cs`
