Skip to content

feat!: say which distribution an install came from - #50

Merged
wavekat-eason merged 1 commit into
mainfrom
feat/install-distribution
Aug 22, 2026
Merged

feat!: say which distribution an install came from#50
wavekat-eason merged 1 commit into
mainfrom
feat/install-distribution

Conversation

@wavekat-eason

Copy link
Copy Markdown
Contributor

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 SystemInfo

Every 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:

Client::install_heartbeat(base_url, install_id, app_version, distribution, cred)
//                                                           ^^^^^^^^^^^^ new

Pass None when 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 no distribution key at all and still parses.

Breaking change

  • Client::install_heartbeat takes distribution: Option<&str> before cred.
  • InstallHeartbeatRequest and InstallHeartbeatResponse gain a distribution field — callers building the request struct literally need the extra field.

One known caller (wavekat-voice); wavekat-cli doesn'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 test 91 passed, cargo fmt --check and cargo clippy -D warnings clean.

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

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
@wavekat-eason
wavekat-eason merged commit 9bc30b8 into main Aug 22, 2026
1 check passed
@wavekat-eason
wavekat-eason deleted the feat/install-distribution branch August 22, 2026 05:59
@github-actions github-actions Bot mentioned this pull request Aug 22, 2026
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.

1 participant