Continued the focused S3 package refactor on felix.knispel/refactor/vxdata-sdk-s3-module after commit 39fbe5e6.
Defined the explicit internal vxdata.sdk.s3 package interface and made StorageNamespace depend only on that surface.
Replaced the ambiguous concrete storage transport dispatcher with an S3ControlPlane protocol, ApiS3ControlPlane, DirectS3ControlPlane, and a one-time create_s3_control_plane() selector.
Converted direct S3 control from a dataclass into a normal behavior-owning class and kept transfer bytes in the shared upload/download engines.
Made the request-shape policy private to the engines, restored newspaper ordering, shortened implementation-history documentation, inlined shallow helpers, and named repeated limits.
Updated SDK tests and module-layout documentation. An independent review found no correctness or import-cycle blocker.
Committed and pushed 8e335d9a (refactor: clarify vxdata s3 subsystem interface).
Opened stacked PR #359 against PR #356’s head branch.
Validation passed: SDK format, lint, typecheck, 48 tests, conda package build, and monorepo boundary checks.
Lessons Learned: Pitfalls
The initial name StorageTransport hid that API-backed and credential-backed paths differ only in presigning, listing, and multipart control; transfer bytes use the same engine in both cases.
Treating direct mode as a conditional inside every transport method made the swap seam harder to explain than selecting one protocol implementation during client construction.
Keeping wire policy on StorageNamespace exposed a subsystem implementation concern solely for test injection and telemetry fields.
Full affected checks can rebuild large unrelated Python dependency chains on a branch based on a broad feature branch; focused SDK checks remain the useful inner loop.
Lessons Learned: Improvements
Start S3 design work with an explicit control-plane/data-plane callgraph: control selects API or direct signing once, while data always uses shared HTTP transfer engines.
Document whether a proposed seam is a concrete router or a structural protocol before naming it; S3ControlPlane should mean the protocol implemented by both modes.
Keep fixed request-shape policy inside transfer engines and patch the private engine seam in tests rather than storing policy on the user-facing namespace.
Preserve a short package-surface table in the SDK README so module moves and renamed architectural seams are easy to verify.