Problem
LoggingIntegration.en.md instructs "project an Error to a log model once, in one place" — then supplies ~25 lines of ErrorLogModel.From for every adopter to copy. The projection is subtle (recursive InnerErrors traversal, InfrastructureError-only Transience/Direction fields, the InnerException-vs-InnerErrors distinction) and derives entirely from the model's shape, not application policy; a missed traversal silently degrades the operational story the library sells ("If only the outer error is logged, the most useful cause may disappear"). Separately, the doc declines to define a JSON schema while arguing that stable keys across "every error and every service" are what make correlation work — so two services on this library emit structurally different error events unless teams coordinate out-of-band.
Impact
The most error-prone copy-paste in the ecosystem, and a missing cross-service correlation contract.
Direction
- Add
Error.ToLogModel() (or equivalent) to the core: framework-agnostic, netstandard2.0, zero dependencies, returning IReadOnlyDictionary<string, object?> (code, instanceId, occurredAt, type, messages by audience, context via ToNameDictionary(), innerErrors recursively, direction/transience where applicable).
- Document the resulting field names as a stable, versioned, serialize-only schema — the runtime counterpart of the catalog's curated JSON. Rule rehydration out of scope (deserialization would bypass the validating constructors).
- Shrink LoggingIntegration to "call
ToLogModel()"; optional later: a thin FirstClassErrors.Extensions.Logging sugar package.
Acceptance criteria
- One call produces the complete canonical projection; the guide no longer asks users to copy the implementation; the field schema is documented as a contract.
Context
Surfaced by the 2026-07-20 architecture, design & ecosystem audit (doc/handwritten/for-maintainers/audit/2026-07-20-firstclasserrors-architecture-and-design-audit.md, §13.3(a)/§14-H2; branch claude/firstclasserrors-audit-83gap7).
Problem
LoggingIntegration.en.mdinstructs "project an Error to a log model once, in one place" — then supplies ~25 lines ofErrorLogModel.Fromfor every adopter to copy. The projection is subtle (recursiveInnerErrorstraversal,InfrastructureError-only Transience/Direction fields, theInnerException-vs-InnerErrorsdistinction) and derives entirely from the model's shape, not application policy; a missed traversal silently degrades the operational story the library sells ("If only the outer error is logged, the most useful cause may disappear"). Separately, the doc declines to define a JSON schema while arguing that stable keys across "every error and every service" are what make correlation work — so two services on this library emit structurally different error events unless teams coordinate out-of-band.Impact
The most error-prone copy-paste in the ecosystem, and a missing cross-service correlation contract.
Direction
Error.ToLogModel()(or equivalent) to the core: framework-agnostic, netstandard2.0, zero dependencies, returningIReadOnlyDictionary<string, object?>(code, instanceId, occurredAt, type, messages by audience, context viaToNameDictionary(), innerErrors recursively, direction/transience where applicable).ToLogModel()"; optional later: a thinFirstClassErrors.Extensions.Loggingsugar package.Acceptance criteria
Context
Surfaced by the 2026-07-20 architecture, design & ecosystem audit (
doc/handwritten/for-maintainers/audit/2026-07-20-firstclasserrors-architecture-and-design-audit.md, §13.3(a)/§14-H2; branchclaude/firstclasserrors-audit-83gap7).