Three symptoms of one gap: there is no reliable way — for a person or a program — to find out which build is running.
1. The bridge cannot distinguish two materially different builds
ping returns:
{QStringLiteral("app"), QStringLiteral("AetherSDR")},
{QStringLiteral("version"), QCoreApplication::applicationVersion()},
{QStringLiteral("authRequired"), ...}, {QStringLiteral("readOnly"), ...}
version is "26.9.3" on origin/main and on a local integration branch carrying unmerged PRs. Those can differ in ways that change measurements: the branch I was running carried #5752 and #5753, so its dBm conversion was fullScale − lna while main's was dbfs + 0.0 + (referenceLna − lna) — about 19 dB apart at every gain. Both answer ping identically.
This cost real work. I analysed main's conversion for hours against measurements taken through the other binary, and the mismatch only surfaced when someone ran strings on the executable to recover the SHA. A bench harness had no way to ask.
2. The SHA exists but is UI-only
AETHER_GIT_SHA is compiled in and surfaced in exactly one place — the About dialog. Nothing reads it programmatically, and nothing shows it on the main window.
3. It is captured at configure time, so it goes stale
CMakeLists.txt runs git rev-parse --short HEAD inside the configure step. The About dialog's own tooltip already admits the consequence:
the SHA is baked at CMake configure time, so a dev who runs cmake --build after a new commit without re-configuring sees the previous SHA here
A stale build identity is worse than none — it is confidently wrong.
Proposal
One change, three surfaces, because splitting them would land one and orphan the others.
(a) Capture git describe, at build time. One string carries both halves of the question:
git rev-parse --short HEAD → 7e841682
git describe --tags --always --dirty → v26.9.3-68-g7e841682
That reads as 68 commits past the v26.9.3 release, at 7e84168, and --dirty flags uncommitted work. Moving the capture into a generated header regenerated per build fixes (3); a release build still gets a bare v26.9.3.
(b) Add it to ping — additive, nothing removed:
{ "app": "AetherSDR", "version": "26.9.3",
"build": { "describe": "v26.9.3-68-g7e841682", "sha": "7e841682",
"baseline": "v26.9.3", "commitsSinceTag": 68, "dirty": false } }
ping is already in the kSafe read-only verb set, so this grants no new authority — it is a payload addition to an existing read-only verb. health would be an equally reasonable home if you would rather keep ping minimal.
(c) Show it in the status bar via addPermanentWidget(), only when the build is not a clean release tag. Silent for users on a release; visible exactly when someone is running something unofficial. This half was requested by an operator who noticed the transient bottom-left messages and wanted to know what he was actually running.
Why (b) is the valuable half
A harness can then pre-register the build it measured through and refuse, or flag, when the binary does not match what the analysis assumes. In our case that would have failed at the first gate instead of after the conclusions were written — and it generalises to any bug report that includes a bridge transcript.
Deliberately not proposed
Anything that changes what version means, or that exposes branch names or remotes — describe is enough, and a branch name is not a build identity.
Happy to implement whichever parts you want. (a) and (b) are small; (c) has a design question about placement and whether it belongs behind a setting.
🤖 Generated with Claude Code
Three symptoms of one gap: there is no reliable way — for a person or a program — to find out which build is running.
1. The bridge cannot distinguish two materially different builds
pingreturns:{QStringLiteral("app"), QStringLiteral("AetherSDR")}, {QStringLiteral("version"), QCoreApplication::applicationVersion()}, {QStringLiteral("authRequired"), ...}, {QStringLiteral("readOnly"), ...}versionis"26.9.3"onorigin/mainand on a local integration branch carrying unmerged PRs. Those can differ in ways that change measurements: the branch I was running carried #5752 and #5753, so its dBm conversion wasfullScale − lnawhilemain's wasdbfs + 0.0 + (referenceLna − lna)— about 19 dB apart at every gain. Both answerpingidentically.This cost real work. I analysed
main's conversion for hours against measurements taken through the other binary, and the mismatch only surfaced when someone ranstringson the executable to recover the SHA. A bench harness had no way to ask.2. The SHA exists but is UI-only
AETHER_GIT_SHAis compiled in and surfaced in exactly one place — the About dialog. Nothing reads it programmatically, and nothing shows it on the main window.3. It is captured at configure time, so it goes stale
CMakeLists.txtrunsgit rev-parse --short HEADinside the configure step. The About dialog's own tooltip already admits the consequence:A stale build identity is worse than none — it is confidently wrong.
Proposal
One change, three surfaces, because splitting them would land one and orphan the others.
(a) Capture
git describe, at build time. One string carries both halves of the question:That reads as 68 commits past the v26.9.3 release, at 7e84168, and
--dirtyflags uncommitted work. Moving the capture into a generated header regenerated per build fixes (3); a release build still gets a barev26.9.3.(b) Add it to
ping— additive, nothing removed:{ "app": "AetherSDR", "version": "26.9.3", "build": { "describe": "v26.9.3-68-g7e841682", "sha": "7e841682", "baseline": "v26.9.3", "commitsSinceTag": 68, "dirty": false } }pingis already in thekSaferead-only verb set, so this grants no new authority — it is a payload addition to an existing read-only verb.healthwould be an equally reasonable home if you would rather keeppingminimal.(c) Show it in the status bar via
addPermanentWidget(), only when the build is not a clean release tag. Silent for users on a release; visible exactly when someone is running something unofficial. This half was requested by an operator who noticed the transient bottom-left messages and wanted to know what he was actually running.Why (b) is the valuable half
A harness can then pre-register the build it measured through and refuse, or flag, when the binary does not match what the analysis assumes. In our case that would have failed at the first gate instead of after the conclusions were written — and it generalises to any bug report that includes a bridge transcript.
Deliberately not proposed
Anything that changes what
versionmeans, or that exposes branch names or remotes —describeis enough, and a branch name is not a build identity.Happy to implement whichever parts you want. (a) and (b) are small; (c) has a design question about placement and whether it belongs behind a setting.
🤖 Generated with Claude Code