npm remote: wire npm_remote_versions.size_bytes on the tarball cache fill
Part of S15 npm remote (#287), carried over from #549 (closed) (npm artifact-level accounting), where the wire-or-drop decision settled on wire.
What is missing
npm_remote_versions.size_bytes and its size-ordered index exist since S15
Step 1 (#338 (closed)), and NpmRemoteVersionStore.AddNpmRemoteVersionSizeBytes exists
with its own test suite. Nothing computes or emits a delta: the fill seam
carries no size signal (UpsertNpmRemoteFileForBlobInput has no size field and
the method returns only error), so the column stays 0.
The S15 plan assigns the emit to the tarball fill: the "Scope (storage
accounting)" note in Step 6 of docs/plans/2026-07-15-npm-remote.md says the
deltas (a fill adds the new blob size, a repoint adds new minus old) are
applied off the request path via the format layer's buffered-update wrapper,
"wired in Steps 9/12". Neither #346 (closed) nor #349 (closed) mentions the column, which is why
this issue exists: that one sentence in a merged step's scope note is otherwise
the only place the obligation is written down.
Shape of the fix (settled on #549 (closed))
UpsertNpmRemoteFileForBlobcomputes and returns the per-version size delta. It already reads the previous attachment row under the version'sFOR UPDATElock, so joiningblob_storage_blobs.sizefor the old and new rows gives new minus old inside the fill transaction. An unchangedblob_sha256yields 0, which is ADR-007's deduplicate-within-the-version rule.- The tarball fill hands the delta to
AddNpmRemoteVersionSizeBytesthrough the format layer'sbufferedUpdatewrapper, next to thelast_downloaded_atbumper, never inside the fill transaction: the counter is advisory, and a lost bump must not fail or serialize a fill, which is the contract stated on the store method. - Metadata documents are out of scope: they hang off the package row and the counter is per version, so only the tarball fill moves it.
Done when
A cold fill leaves size_bytes equal to the cached tarball's blob size. A
repoint moves it by new minus old, in both directions. A re-fill of the same
blob_sha256 leaves it unchanged. A fill against a soft-deleted version writes
nothing and does not fail the fill. A dropped buffered bump does not fail the
request.
Blocked by #349 (closed) (the tarball proxy handler is the call site) and the Step 9 cache-store seam it widens.