Skip to content

[M2] Adopt headsetcontrol 4.1.0: MIN_VERSION, re-recorded fixtures, wider install routes #67

Description

@AdrianKuriata

Context

headsetcontrol 4.1.0 was released on 2026-08-27 carrying both of this
project's upstream performance patches:

  • #549 — structured output
    (--output=json) no longer forces every info capability to be read when the
    invocation only asked to set something.
  • #550 — every Audeze info
    capability is answered from one status read instead of one 21-packet sequence
    each.

Measured on the Maxwell 2 Xbox dongle (0x3329:0x4b28), three runs each,
/usr/bin/env time:

invocation 4.0.0 4.1.0 master 4.1.0-12-gca98ed4
-s 20 (write, plain output) 0.07 s 0.07 s 0.07 s
-s 20 -o json (what this app does) 2.90 s 0.07 s 0.07 s
-b -o json (one info) 1.48 s not measured 1.35 s
-b -m -o json (two infos) 2.83 s not measured 1.34 s

The 4.0.0 column is the previously recorded baseline. The two read rows were not
re-run on released 4.1.0 on purpose — see "Hardware caveat" below — so their
"after" comes from a master build, which also carries #577. The write row is
measured directly on the released binary.

Every parameter write this app makes went from 2.90 s to 0.07 s. That is the
reason to move the floor: a latency one, not a capability one. 4.0.0 still talks
to the hardware; it is just slow enough that the app's behaviour is materially
worse on it, and no released version of this app has users to lock out.

What actually changes in the CLI's output

  • api_version 1.4 → 1.5. Bumped by #549 itself, because the write
    response's contract changed.
  • A write still lists devices, but with no info values. devices is present
    and carries identity plus capabilities; battery, chatmix and the errors
    map are gone from it. write-actions-mixed.json records the old shape (two
    devices with full battery/chatmix/errors) and no longer describes reality.
  • New capability CAP_SIDETONE_STATUS, with a sidetone: {level, device_level, name} object on devices that support it. Maxwell 2 does not; the
    test device does, as of 4.1.0. features/registry.ts logs and skips it, so
    nothing breaks — rendering it is [M2] Render CAP_SIDETONE_STATUS: sidetone read back from the device #68.
  • Wider install routes: a Launchpad PPA (#547), a Fedora COPR (#548) and a
    Homebrew formula (#546) alongside the signed packages. Arch still has no
    upstream package, so the source build stays as the fallback.

Version-gate finding

Upstream #551 changed how git
builds name themselves: no longer continuous-52-gfe086cd but
4.1.0-12-gca98ed4. Version::parse takes the release prefix, so such a build
now compares as its base tag instead of falling through the "uncomparable,
therefore accepted" path. Two consequences:

  • A build of master is accepted on merit (4.1.0 ≥ 4.1.0), not waved through.
  • A build from between the tags (4.0.0-57-g…) is now rejected as 4.0.0.
    That is correct — it genuinely lacks #550 — but it is a behaviour change for
    anyone tracking upstream and belongs in the doc comment.

Nothing regresses: the old continuous-N-ghash shape still parses to None and
is still accepted.

Hardware caveat (why the read rows come from master)

4.1.0 still ships the parameter-setting packet
06 09 80 05 5A 05 00 00 09 25 00 7A inside UNIQUE_REQUESTS, which
getDeviceStatus() sends on every info read. On the original Maxwell it
causes a persistent left/right imbalance
(#561); Maxwell 2 carries
the identical sequence. #577
removes it from both, but landed on master after the 4.1.0 tag. Writes never
send that sequence, so the write measurement on released 4.1.0 was safe.

Read reliability on master was 5/5 real values (battery 95/95/94/94/94, chatmix
64 throughout) against 2/5 recorded on 4.0.0. Unresolved which patch did it —
master has #550 and #577 — so it is not an argument for this bump.

Tasks

  • MIN_VERSION → 4.1.0 in backend/detect.rs; doc comment rewritten
    around the per-call cost and the #551 consequence above. 4.0.0/4.0.1
    move from the accept loop to the reject case, and 4.1.0-12-gca98ed4
    joins the accept loop — nothing covers the <tag>-N-ghash shape today
  • Re-record write-actions-mixed.json and write-action-success.json
    against 4.1.0 (safe: writes read no info), api_version included
  • Re-record test-device-multi.json — it gains CAP_SIDETONE_STATUS and
    the sidetone object. Record with --test-device -d 0xf00b:0xa00c, which
    restricts the run to the fake device and leaves the Maxwell untouched
  • supported-release.json documents the gate's accept case as a released
    4.0.0; at a 4.1.0 floor it becomes a reject. Move the fixture, its
    provenance row in docs/architecture/testing.md and the smoke scenario
    together
  • Specs hardcoding required: "4.0.0" (src/App.spec.ts,
    src/core/backend.spec.ts, src/core/probe.spec.ts, src/screens/*.spec.ts,
    e2e/startup.e2e.ts) — mechanical; the found: "3.1.0" reject case stands
  • InstallInstructions.vue: PPA / COPR / Homebrew routes, "Since 4.0.0"
    comment dropped, source build kept as the Arch fallback; i18n keys in
    src/i18n/messages.ts (pl + en)
  • README.md prerequisites, CLAUDE.md's upstream section
  • Docs: PROJECT.md §10 row (product decision, as the 4.0.0 adoption was),
    the fixture table in docs/architecture/testing.md, detection docs

Explicit non-changes

Acceptance criteria

  • 4.1.0 accepted; 4.0.0 lands on bad-version naming both versions
  • 4.1.0-12-gca98ed4 accepted, and continuous-N-ghash still accepted
  • Recorded fixtures byte-identical to real 4.1.0 output
  • make ci and make smoke green

Metadata

Metadata

Assignees

No one assigned

    Labels

    frontendVue 3 frontendin-progressCurrently being worked on by ClauderustRust backend (src-tauri)testingUnit, E2E, contract tests

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions