Skip to content

sdk: name the v0 modules for the surface they serve - #1122

Merged
kvinwang merged 2 commits into
nextfrom
feat/sdk-v0-naming
Aug 25, 2026
Merged

sdk: name the v0 modules for the surface they serve#1122
kvinwang merged 2 commits into
nextfrom
feat/sdk-v0-naming

Conversation

@kvinwang

Copy link
Copy Markdown
Collaborator

Stacked on #1120 — review that first; this diff is only the commit on top.

Why

Every SDK came out of #1116 with the v1 code in *_v1 files and the v0 code still in the unsuffixed files it occupied before there was anything to distinguish it from. The result reads backwards: the unsuffixed file means v0, while the unsuffixed class (DstackClient) now means v1. A reader who opens dstack_client.rs lands on the legacy surface.

The renames

SDK before after
Rust src/dstack_client.rs src/dstack_client_v0.rs
Rust types/src/dstack.rs types/src/dstack_v0.rs
Python dstack_client.py dstack_client_v0.py
Go client.go, client_test.go client_v0.go, client_v0_test.go

The JS SDK kept both clients and their shared helpers in a single index.ts, so there was no v0 module to rename. It is split into client-v0.ts, client-v1.ts and shared.ts, with index.ts kept as a barrel that exports exactly what it exported before — no additions, no removals, no renamed exports.

No compatibility aliases for the old module paths. 0.6.0 is already the release where the unsuffixed client name changed meaning, and the point of that decision was that an unmigrated caller fails at build time rather than silently binding the frozen surface. A deprecated module alias would reopen the hole the rename closes.

Deprecation, visible to tooling

Go and JS already carried // Deprecated: and @deprecated, which their tooling understands. Rust had no #[deprecated] attribute at all, and Python had only a docstring note — so in two of four SDKs the legacy client was marked only for a human who went looking.

  • Rust: #[deprecated] on DstackClientV0 and TappdClient. The internal use sites get narrowly-scoped #[allow(deprecated)] rather than a crate-level allow, so the attribute still reaches downstream callers. cargo clippy --all-targets -- -D warnings is clean.
  • Python: the v0 clients warn at construction, through the same helper the file already used for TappdClient. Two tests pin that warning — TappdClient's was pinned and the new one was not, which is how a deprecation quietly stops firing.

.claude/agents/sdk-sync-checker.md listed the old paths; it now lists both surfaces' files, since a rename that leaves that agent reading the wrong file makes it silently useless.

Verification

./sdk/run-tests.sh green end to end: Rust (clippy -D warnings clean), Go (vet/gofmt clean), Python 160 passed, JS 141 passed with tsc --noEmit clean. Every rename is recorded as a rename, not a delete-plus-add, so git log --follow still works.

Copilot AI lite review requested due to automatic review settings August 25, 2026 00:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@kvinwang
kvinwang force-pushed the feat/sdk-v0-naming branch from 95deb93 to 23badaf Compare August 25, 2026 02:44
@kvinwang
kvinwang force-pushed the feat/sdk-v0-naming branch from 23badaf to 84cd7aa Compare August 25, 2026 03:06
Base automatically changed from feat/sdk-0.6-cleanups to next August 25, 2026 03:16
Every SDK ended 0.6.0 with the v1 code in `*_v1` files and the v0 code still
in the unsuffixed ones it had before there was anything to distinguish it
from. So "unsuffixed file" meant v0 while "unsuffixed class" meant v1, and a
reader opening `dstack_client.rs` landed on the legacy surface.

The v0 modules now say so: `dstack_client.rs` -> `dstack_client_v0.rs` and
types `dstack.rs` -> `dstack_v0.rs` in Rust, `dstack_client.py` ->
`dstack_client_v0.py` in Python, `client.go` -> `client_v0.go` in Go. The JS
SDK had both clients and their shared helpers in one `index.ts`; it is split
into `client-v0.ts`, `client-v1.ts` and `shared.ts`, with `index.ts` kept as
a barrel exporting exactly what it exported before.

No compatibility aliases for the old module paths. 0.6.0 is already the
release where the unsuffixed client name changed meaning, and the whole point
of that decision was that an unmigrated caller fails at build time rather
than silently binding the frozen surface; a module alias would reopen the
hole the rename closes.

Deprecation is now visible to each language's tooling rather than only to a
reader. Go and JS already carried `// Deprecated:` and `@deprecated`; Rust
had no attribute at all and Python only a docstring note. `DstackClientV0`
and `TappdClient` now carry `#[deprecated]`, with `#[allow(deprecated)]` at
the internal use sites so the attribute reaches downstream callers instead of
being blanket-suppressed, and the Python v0 clients warn at construction
through the helper the file already had for `TappdClient`. Two tests pin that
warning, which nothing did before.

`.claude/agents/sdk-sync-checker.md` listed the old paths and now lists both
surfaces' files, since a rename that leaves the agent looking at the wrong
file makes it quietly useless.
Three of them did not, and the CHANGELOG claimed things the diff does
not do.

Python read the public `use_sync_http` flag as "this instance is an
internal transport, stay quiet". It is a documented option on
`AsyncDstackClientV0`, so a caller who set it themselves was silently
opted out of the one signal that says the surface is frozen. The sync
wrappers now pass a private `_warn=False` instead, which is what they
actually mean.

Go's `ToEthereumAccount` and `ToSolanaKeypair` still carried their
`// Deprecated:` inside the first comment paragraph, where neither gopls
nor pkg.go.dev recognises it -- the same shape this branch repairs five
times over in `client_v0.go`, left on the two functions whose own doc
comments say they have security concerns.

The JSDoc on the `DstackClient` alias told readers to import
`DstackClientV0` from `./client-v0`. That text ships in `dist/index.d.ts`
and the path does not resolve for a package consumer: `client-v0` is not
a `tsup` entry and not in the `exports` map. Point at the package root.

CHANGELOG corrections: Rust warns at every *mention of the type*, not at
every call -- `#[deprecated]` on a struct does not propagate to its
inherent methods, and a client received from a factory function warns
nowhere. `TappdClient`'s `@deprecated` JSDoc is added here, not
pre-existing. And "no behaviour changes" was wrong for Python: the
warning fires at construction, so a downstream suite with
`filterwarnings = error` goes red on upgrade. Say so where they will
read it.
@kvinwang
kvinwang force-pushed the feat/sdk-v0-naming branch from 84cd7aa to 6898486 Compare August 25, 2026 03:16
@kvinwang
kvinwang merged commit e60031d into next Aug 25, 2026
15 checks passed
@kvinwang
kvinwang deleted the feat/sdk-v0-naming branch August 25, 2026 03:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants