You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
headsetcontrol4.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)
Context
headsetcontrol4.1.0 was released on 2026-08-27 carrying both of thisproject's upstream performance patches:
(
--output=json) no longer forces every info capability to be read when theinvocation only asked to set something.
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:4.1.0-12-gca98ed4-s 20(write, plain output)-s 20 -o json(what this app does)-b -o json(one info)-b -m -o json(two infos)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_version1.4 → 1.5. Bumped by #549 itself, because the writeresponse's contract changed.
devicesis presentand carries identity plus capabilities;
battery,chatmixand theerrorsmap are gone from it.
write-actions-mixed.jsonrecords the old shape (twodevices with full battery/chatmix/errors) and no longer describes reality.
CAP_SIDETONE_STATUS, with asidetone: {level, device_level, name}object on devices that support it. Maxwell 2 does not; thetest device does, as of 4.1.0.
features/registry.tslogs and skips it, sonothing breaks — rendering it is [M2] Render CAP_SIDETONE_STATUS: sidetone read back from the device #68.
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-gfe086cdbut4.1.0-12-gca98ed4.Version::parsetakes the release prefix, so such a buildnow compares as its base tag instead of falling through the "uncomparable,
therefore accepted" path. Two consequences:
4.1.0≥4.1.0), not waved through.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-ghashshape still parses toNoneandis 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 7AinsideUNIQUE_REQUESTS, whichgetDeviceStatus()sends on every info read. On the original Maxwell itcauses 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.0inbackend/detect.rs; doc comment rewrittenaround the per-call cost and the #551 consequence above.
4.0.0/4.0.1move from the accept loop to the reject case, and
4.1.0-12-gca98ed4joins the accept loop — nothing covers the
<tag>-N-ghashshape todaywrite-actions-mixed.jsonandwrite-action-success.jsonagainst 4.1.0 (safe: writes read no info),
api_versionincludedtest-device-multi.json— it gainsCAP_SIDETONE_STATUSandthe
sidetoneobject. Record with--test-device -d 0xf00b:0xa00c, whichrestricts the run to the fake device and leaves the Maxwell untouched
supported-release.jsondocuments the gate's accept case as a released4.0.0; at a 4.1.0 floor it becomes a reject. Move the fixture, itsprovenance row in
docs/architecture/testing.mdand the smoke scenariotogether
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; thefound: "3.1.0"reject case standsInstallInstructions.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.mdprerequisites,CLAUDE.md's upstream sectionthe fixture table in
docs/architecture/testing.md, detection docsExplicit non-changes
drag; a call per pixel is wrong at 70 ms too.
CALL_TIMEOUTstays at 10 s. It is the hang bound from [M1] A hung headsetcontrol that forks escapes CALL_TIMEOUT #50/fix(backend): bound a call whose binary hangs behind a child of its own (#50) #51, not alatency knob.
Acceptance criteria
4.1.0accepted;4.0.0lands onbad-versionnaming both versions4.1.0-12-gca98ed4accepted, andcontinuous-N-ghashstill acceptedmake ciandmake smokegreen