feat!: say which distribution an install came from - #50
Merged
Conversation
The install heartbeat now carries an optional `distribution` — "direct" for a plain download, "mas" for a sandboxed Mac App Store build. Unlike every other field on this request it is not detectable, so it does not belong on SystemInfo: the two macOS builds share a bundle id and a version and the binary inside is identical, so only the consumer knows which one it is shipping. That makes it a caller argument, which is why `Client::install_heartbeat` grows a parameter — pass None when there is nothing meaningful to say (a source build, a package this crate has never heard of). Free text rather than an enum, on both halves. The platform stores whatever arrives so a new distribution can ship without a server release; parsing it into an enum here would undo that on the client side. The response field is `#[serde(default)]` so a heartbeat against a platform deployed before the field still parses instead of erroring on a missing key. BREAKING CHANGE: `Client::install_heartbeat` takes a `distribution: Option<&str>` before `cred`, and `InstallHeartbeatRequest` / `InstallHeartbeatResponse` gain a `distribution` field. Callers constructing the request struct literally need the extra field. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015cFN9hTjdVYv42FMFTxdJg
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The install heartbeat can now say how a copy was obtained —
"direct"for a plain download,"mas"for a sandboxed Mac App Store build.Why it's a parameter and not part of
SystemInfoEvery other field on this request is detected: OS, OS version, arch, locale. This one can't be. The two macOS builds are one source tree, share a bundle id, report the same version, and the binary inside is identical — nothing the process can inspect at runtime distinguishes them. Only the consumer knows which one it packaged.
So it's a caller argument, which is what makes this a breaking change:
Pass
Nonewhen there's nothing meaningful to say — a source build, or a package this crate has never heard of.Free text on both halves
The server stores whatever arrives, so a new distribution can ship without a platform release. Parsing it into an enum here would undo that on the client side, and the point of the field is to be answerable before we know every answer.
The response field is
#[serde(default)]. A platform deployed before this field omits the key entirely rather than sending null, and a heartbeat must not fail to parse against an older server. There's a test pinning that: the pre-existing response fixture carries nodistributionkey at all and still parses.Breaking change
Client::install_heartbeattakesdistribution: Option<&str>beforecred.InstallHeartbeatRequestandInstallHeartbeatResponsegain adistributionfield — callers building the request struct literally need the extra field.One known caller (
wavekat-voice);wavekat-clidoesn't touch this endpoint.Tests
Serialization with the field set; omitted entirely when
None(so the column stays NULL rather than the string "null"); read back from a response; an unrecognised value parses rather than erroring; and the no-key-at-all fixture above.cargo test91 passed,cargo fmt --checkandcargo clippy -D warningsclean.Where this sits
The platform side is already deployed. This crate needs a release before the consumer can send the value.
🤖 Generated with Claude Code
https://claude.ai/code/session_015cFN9hTjdVYv42FMFTxdJg