fix(artifact-cas): stream uploads to object-store backends to bound CAS memory

Merged
JA
2mo ago
+1217-50

Summary

The Artifact CAS bytestream Write RPC buffered the entire artifact in memory before flushing it to the storage backend, so CAS memory grew roughly 1:1 with artifact size and a large upload OOM-killed the CAS pod mid-stream.

Object-store backends (S3, S3 access point, Azure Blob) now advertise a streaming capability and are fed directly from the client stream through an io.Pipe, so peak CAS memory stays bounded regardless of artifact size. The OCI backend keeps the fully-buffered path because its push implementation needs the whole layer content up front.

A backend upload failure is always surfaced as an internal error and is never misclassified as a client disconnect. The per-upload size cap is enforced on both the streaming and buffered paths. The download path, including digest verification, is unchanged.

Resolves PFM-6923.

AI assistance

Claude Code was used in producing this change.