v1.40.0 ✅
ReasonMetadata— new sealed record capturingCallerMember,CallerFile,CallerLinevia compiler-injected[CallerMemberName/FilePath/LineNumber]on factory methods; zero-allocationEmptysingleton; completely separate fromTags(no framework leakage into user metadata)IReasonMetadata— secondary capability interface (same pattern asIAsyncDisposable); opt-in metadata exposure fromIReason-typed references without breaking existing implementations;Reasonbase class implements it automaticallyReasonMetadataExtensions—TryGetMetadata(IReason)andHasCallerInfo(IReason)helpers; null-safe via pattern matching- Static error factories —
ValidationError.Field(field, msg),ForbiddenError.For(action, resource),ConflictError.Duplicate(entity, field, value),ConflictError.Duplicate<T>(field, value); each capturesCallerMemberat the factory call site; old multi-arg constructors marked[Obsolete]
- RESL1010 — new analyzer: warns when a Result<T> local variable has no failure-aware usage in the enclosing block and is not returned (errors silently swallowed)
- RESL2002 — new analyzer: warns when ErrorsOf.Match() provides fewer handlers than the union has type arguments (non-exhaustive match)
- RESL1021 — new analyzer: warns when an IError/IReason implementation has a public constructor with 2+ required parameters; (), (string), (string, Exception), and [Obsolete]-marked ctors exempt
- ResultFlow
ErrorHint— Mermaid failure edges now annotate the error type for body-scan pipelines:.Ensure(pred, new NotFoundError(...))→|"fail: NotFoundError"|; syntactic extraction (no semantic model required);ErrorTypefrom type-read mode still takes precedence - 158 features, >4,300 tests