0139 the sparse overloads take the second edge under 0138s precedent - CyrilB1531/lodestar GitHub Wiki

0139 โ€” The sparse overloads take the second edge, under 0138's precedent

Status: accepted ยท Date: 2026-09-16 ยท Applies: 0012, 0071, 0132, 0138

Context

#765 gives the scalers the sparse overloads docs/equivalence.md has scoped out since Lodestar.Preprocessing 0.1.0. The sparse primitive is CsrMatrix, which 0071 moved into Lodestar.Abstractions so that every package could share one.

So this package needs a second inter-package edge, in the same lot as the sparse overloads themselves.

Decision

Lodestar.Preprocessing โ†’ Lodestar.Abstractions, on the published floor 0.1.1, declared the way 0012 requires: a PackageReference with a ProjectReference behind LodestarUseProjectRefs for the developer loop, and a ProjectReference of its own in the netstandard mirror, since SetTargetFramework does not cross a PackageReference.

This record applies 0138 rather than re-arguing it. That decision settled the principle a month of lots will keep meeting โ€” a member another Lodestar package publishes is depended on, not copied โ€” weighed the two alternatives, and named the five files an edge touches. Nothing here is new except which package and which member: CsrMatrix instead of Distributions.NormalQuantile, and a type rather than a function.

The one thing worth writing down separately is that this is the second edge in the same package inside one lot, and it did not need a fresh argument. That is what a precedent is for.

Consequences

  • The sixteenth edge. tools/check_nuspec_dependencies.py's EXPECTED is the authority and CLAUDE.md's table and count follow it.
  • Lodestar.Abstractions carries no dependency of its own, so a consumer of the scalers restores two Lodestar packages and nothing else.
  • Only three scalers take a CsrMatrix, which is the reference's own line rather than this package's: StandardScaler with centring off, MaxAbsScaler, and RobustScaler with centring off. Centring is refused because subtracting a mean or a median makes every absent zero a stored value, and MinMaxScaler has no sparse overload at all โ€” the reference raises for it, and a missing overload is the same refusal at compile time.
  • A third edge from this package would be routine under this record and 0138; a first edge from another package is not, and earns its own.