Skip to content

Releases: kd9taw/Nexus

Nexus 1.0.5

Choose a tag to compare

@github-actions github-actions released this 08 Aug 22:22

Nexus 1.0.5 — your contacts reach your logger, four characters of grid go on the air, and a transmit watchdog that actually runs

2026-08-08

Logging to N1MM+, HRD and Log4OM, two FT-mode fixes that change what leaves the antenna,
a transmit-safety fix, live drive control, and your recordings and SSTV pictures moved
somewhere you can find them.

Everyone should take this one. If you run a separate logger, contacts were never
reaching it. If you run a six-character grid, your FT8 and FT4 QSOs were stalling at the
other end. Neither showed you an error.


Logging — your contacts were not reaching N1MM+, HRD or Log4OM

Only Field Day contacts were ever sent. Nexus speaks the WSJT-X UDP protocol on 2237,
and this is exactly why it was so hard to spot: the connection looked alive. N1MM's WSJT
window filled up with decodes, status arrived, everything read as working. But the one
message a logger actually writes a contact from was only ever sent for Field Day. Every
ordinary QSO went into your own log and nowhere else — no error, nothing missing on
screen, and the FAQ saying the path was supported.

Every logged contact goes out now: FT8 and FT4, phone, CW, RTTY, SSTV, and rows you type
into the Logbook by hand.

Worth knowing if you ever chased this yourself: the N1MM contact broadcast in Settings
is a different thing and was never going to help. N1MM does not read those packets back
in — they are for club dashboards and live maps. 2237 is the one it logs from.


FT8 / FT4 — what goes on the air

A six-character grid was going out, and the message format holds four. If you had set
a six-character locator in Settings, your calls to another station carried something an
FT8 or FT4 message cannot hold. The other operator's software could not decode it as a
grid at all, so it had nothing to auto-reply to and the contact stalled on their side —
for a reason that looked like nothing whatsoever on yours. Your CQ was always fine, since
that path already trimmed it, so this only bit once you answered somebody.

Nexus sends four characters now, the same as WSJT-X. Your settings and your log keep all
six: a six-character locator is correct in both, and it is only what leaves the antenna
that is cut. Reported by kr4fqg.

A plain click on the waterfall was moving your transmit frequency too. The hint under
the waterfall says left-click sets RX, Shift or right sets TX, Ctrl sets both — and that
is what WSJT-X does. A plain left click in Nexus moved both markers, so clicking to listen
to someone also moved you on top of them. The only way to stop it was switching Hold Tx
Freq on, which is a workaround for a bug rather than what that switch is for.

A plain click now moves the green RX marker and leaves TX where you put it, whatever Hold
Tx Freq is set to. Double-clicking a decode to work a station is unchanged. Reported by
akhepcat.


Transmit safety — a station Nexus had given up on stayed armed

When you call a station in FT8 or FT4 and it never answers, Nexus stops calling after
eight overs. It kept the QSO open while it waited, which is what you want. But the TX
watchdog — the six-minute limit that exists to stop an unattended radio — was only checked
at the moment an over was being built, and a held-back over is not built. The clock was
never looked at. So the QSO sat there armed with Enable TX still lit, and if that station
was decoded again later, minutes or hours, Nexus answered it without you touching
anything.

On the shipping defaults the give-up always came first — eight FT8 overs is four minutes
against a six-minute watchdog — so on a called station the watchdog could not fire at all.
It now runs while a station is being held back, so the six minutes you set is the six
minutes you get, and TX disarms when it expires.

Nothing about the message sequence, slot timing or when Nexus decides to stop calling has
changed. If you are simply monitoring with TX armed and waiting for a decode you are
unaffected — the watchdog still does not start until there is something it is holding
back.


Drive control — ⚠️ your Pwr slider will sit somewhere different

Read this one before you transmit. Both drive sliders now use a curve instead of a
straight line. The range that actually matters on real hardware — 0 up to just past where
ALC engages — turned out to live in only the bottom 15-20% of the old travel, which made
setting drive against an ALC meter far fiddlier than it needed to be.

What a saved drive level means has not changed — only how far along the slider you move
to reach it.
Your stored setting is exactly what it was. Check it is where you want it
before you work anyone.

While that was being fixed, two other things went with it. Moving Pwr only affected audio
Nexus had not generated yet, and it generates well ahead — an FT8 over is built and queued
in one go, all thirteen seconds of it — so the level was already baked into everything
waiting to go out. Hold Tune, move the slider, and the rig's ALC sat where it was for
several seconds before catching up, which makes it very easy to overshoot into compression
while chasing a control that has not responded. Drive is now applied to each sample as it
leaves for the sound card, so what you set is what goes out on the next fraction of a
second, including audio already queued — scaled rather than rebuilt, so there is no click
when you move it mid-transmission. And the Settings panel's own Tx Power slider applied
only on release rather than while dragging; both track live now.

Reported by g0fqb, who also found the cause.


Your files — recordings and SSTV pictures moved

Recordings now go to Documents ▸ Nexus ▸ Recordings, and received SSTV images to
Pictures ▸ Nexus SSTV. Both used to sit in Nexus's own configuration folder, which is
hidden, is not the same place for a second radio, and is not somewhere anyone thinks to
look. Several people concluded recording was simply broken, and they were reasonable to.
Pictures somebody sent you are worth being able to find, open and share without going
through the app.

Your existing SSTV gallery comes with you. The first time you start this version the
images and their index are moved across, so the gallery looks exactly as it did — nothing
stranded, nothing to re-import. Recordings you already have are left where they are rather
than moved out from under you; only new ones go to Documents. If Windows cannot tell Nexus
where your Documents or Pictures folders are, it carries on using the old location rather
than guessing.

Alongside that: you can delete a received SSTV image from inside the app — hover a
thumbnail, ✕, and it asks first, naming the picture. There was no delete anywhere before,
so the gallery only ever grew. Deleting a file by hand no longer leaves a broken thumbnail
either, and pictures you copy into the folder get picked up. A recording that cannot be
saved now says so
, naming the path it tried, instead of failing silently into an empty
folder.


Smaller things

The record button is findable again. It had been reduced to a bare dot in a box, in a
header that also carries the band picker, tuning strip, Tune and Stop TX — small enough
that it got reported as missing before it got reported as hard to see. It says REC next to
the dot now, and the dot is red at rest. CW has one at all now — it never did, so
recording a CW contact meant leaving the cockpit.

The Needed board no longer says "Digital" for stations that are plainly FT8. A cluster
spot only gives you a frequency, and that path was asking "digital, voice or CW?" and
showing the answer — but the band plan knows 14.074 is FT8 and 14.080 is FT4, and always
did. Off a known watering hole it still says Digital rather than inventing a mode.

USB and LSB no longer read as different modes on the new-band and new-mode badges —
ADIF says they are both SSB. FM and AM stay separate, and FT4 stays separate from FT8.
Old imports carrying a band Nexus could not recognise no longer show a permanent "new
band" badge. Entities were already right: European Russia, Asiatic Russia, Kaliningrad and
Franz Josef Land are four separate DXCC entities and always were.

The Call Roster shows which station you are actually working, in the transmit colour,
and it does not fade with age like the other rows. Asked for by m7jyfradio and akhepcat.

The Tempo dial scrolls. Hover a digit of the big readout and roll — every other
cockpit already worked that way. And the wheel sensitivity slider now reaches every
dial
; it only ever affected Phone and CW, so anyone who moved it because a free-spinning
mouse was overshooting got no change and no reason why.

macOS: CAT could fail even with Hamlib installed. An app launched from Finder or the
Dock gets a fixed PATH that does not include Homebrew or MacPorts, so rigctld was
invisible to Nexus while working fine from Terminal. Those directories are checked now.

The Linux downloads say which Linux they need. Both PC Linux files require Ubuntu
24.04 or newer (ldd --version to check) and nothing said so — on anything older the
.deb installs without complaint and then does not start. The AppImage is no help there
either: it carries the application's libraries, not the system C library. The build that
produces them is now pinned rather than following whatever GitHub calls "latest", and the
release refuses to publish a Linux binary needing more than the stated minimum.


Notes

1.0.3 and 1.0.4 were bench builds and were never published — 1.0.5 is the next release
after 1.0.2.

Windows, Linux (.deb + AppImage) and both Raspberry Pi bases (bookworm, trixie).
Windows and the AppImage self-update; the .deb packages are apt-managed and notify only.

Nexus 1.0.2

Choose a tag to compare

@github-actions github-actions released this 07 Aug 05:14

Nexus 1.0.2 — a transmit-safety fix, FT-mode compound callsigns, and a rebuilt CAT rate table

2026-08-07

A transmit-safety fix, FT-mode compound callsigns, CAT rate handling, SSTV station
identification, and a set of logbook and 6 m corrections.

Everyone should take this one. The RTS fix alone is worth the install if you key a
serial interface, and the FT-mode work fixes QSOs that could never complete at all.


Transmit safety — install this if you key from a serial port

Connecting to a serial rig could put it straight into transmit, and hold it there.
Opening the port left RTS asserted for the whole session. On an interface wired to key
from RTS — a great many homebrew and commercial cables — that is the radio keyed the
moment Nexus connects, with nothing on screen saying so. Nexus now lowers the line it
does not key with, and keeps holding the one it does, so PTT still works normally
whichever line you use.

If you have ever seen a rig key on connect and blamed the cable, this was probably us.


FT8 / FT4 — compound callsigns

If your call has a /P or /R on it, or you chase stations whose calls do, this
release changes what goes on the air.

A /P or /R station now sends its grid and exchanges signal reports. Nexus was
treating any callsign containing a slash as one the protocol cannot carry, and dropping
it onto the message type that has room for neither a locator nor a number. /P and
/R are the only two suffixes the 77-bit protocol carries natively — they ride in
full, with a grid and a report, exactly as WSJT-X sends them. A portable station was
being downgraded to a call-only exchange for no reason.

A /P station working a /R rover no longer transmits a callsign belonging to
nobody.
The protocol has one suffix bit per call and one field saying what that bit
means, so a mixed pair cannot be expressed — and every over was going out with the
rover's call rendered as /P. Your own log stayed correct and the contact looked
complete, so nothing flagged it; the other operator logged a call you had never used,
and the contact would never confirm. Such a pair now uses the hashed message form,
which carries both callsigns exactly as entered.

Nine of the sixteen callsign-class pairings could not complete a QSO at all. The
most common is a home station working a DXpedition with a compound call such as
PJ4/K1ABC. When the message form that names both stations correctly has room for
nothing else, "I am calling you" and "here is your report" become the identical
transmission — and the auto-sequencer had no rule for that. Each station read the
other's report as a call, answered it, and then waited for a roger the other was
equally waiting to receive. Nothing was malformed and nothing was mis-addressed, so
nothing on screen said anything was wrong. All sixteen now run to 73 in the usual five
or six overs.

A contact you never transmitted into could be written to your log. This is the one
to know about: it reached LoTW and QRZ under your call, for a QSO that never happened,
and nothing on screen would have told you. Logging now requires evidence from both ends
— that the other station answered you on the air, and that you put an over on the air
yourself.

Two stations that called each other at the same instant never got past exchanging
grids.
Plain standard callsigns, nothing exotic. They traded grids for twenty slots
without advancing; they now finish in five overs.

A contact whose closing 73 never arrived was lost, and a CQ run stopped there.

A /P or /R station could acknowledge a signal report nobody had sent it.

Seven of the sixteen pairings genuinely cannot exchange a numeric signal report in
FT8 — the message form that carries both callsigns has no field for one, and WSJT-X
cannot send one either. Those contacts now complete and log with the report fields
empty, rather than a number nobody sent.


CAT and rig control

Picking a rig no longer overwrites a working baud rate. The rate table was built
from 61 hardware manuals transcribed by hand, and wrong rows moved working radios onto
rates they could not run — an IC-746 at 4,800 was silently moved to 19,200. It now
carries only what the rig's own driver declares: 22 radios that have exactly one legal
rate. Every other radio keeps whatever you set.

The IC-725, IC-726, IC-728 and IC-729 are in the rig list. From a field report: an
IC-728 owner could not find his radio, picked the nearest-looking Icom, and Nexus drove
a 1990s rig with a modern radio's CI-V address — every read timed out forever while
WSJT-X worked on the same cable at the same 1,200 baud.
If you substituted a different model to get going, re-pick your radio.

Test CAT finds a wrong baud rate on any serial radio, not just the five Icoms with a
built-in scope. Twenty-one radios are covered. It runs only after a test has already
failed, so choosing a radio stays instant. A full sweep can take 30–40 seconds, and up
to 90 on an FT-817/818 — deliberately, because the probe waits exactly as long as the
real connection does.

A port another program is holding now says so, instead of sweeping every rate and
telling you the radio never answered.

When CAT fails you are told what Hamlib actually diagnosed — "rig power is off?",
"serial port does not exist", "port is already open" — instead of the daemon's internal
socket bookkeeping. This previously worked only for Icom owners.

Icoms no longer receive a Yaesu command on every mode change. MD0; was going onto
every CI-V bus; at worst it dropped the CAT link. If you have had "modes won't switch"
on an Icom, retest that.

Thetis, PowerSDR, piHPSDR and SDR Console are selectable by name. A Hermes Lite 2
running Thetis could not get CAT working, and the hint sent its operator to the wrong
port.

TCI is gone from the rig list — the bundled Hamlib has no backend for it, so
selecting it produced a radio that never started. SunSDR and ExpertSDR owners use the
CAT server port.

A WinKeyer port that will not open now says so, instead of silently falling back to
CAT keying and looking dead.


SSTV

Your callsign is burned into every transmitted picture. SSTV was transmitting with
no station identification of any kind — no overlay, no CW ident, no FSK ID — on the one
mode where a single over is up to five minutes of continuous key-down. Your call now
appears top-left, white on a solid black plate, and Send is refused outright if you
have not set a callsign
.

Send any picture: it is resized, rotated upright and cropped for you, with a
drag-to-adjust box so you choose what survives the crop. EXIF rotation is handled, so a
photo taken sideways arrives the right way up.

The mode picker understated every mode's airtime by about a second.


Logbook and awards

Importing a confirmation report over the contacts it describes changed nothing. A
LoTW, eQSL or QRZ download of contacts already in your log was discarded as duplicate
rather than merged, so confirmations never landed. Expect "0 imported · N existing QSOs
updated".

A date-only import can no longer destroy a contact. Importing a log with dates but
no times, where you worked one station twice on a band that day, could delete one
contact and duplicate the other with the wrong QSL.

A confirmation marked V read as unconfirmed.

Purging the logbook left the LoTW and eQSL sync positions behind, so the next sync
brought back nothing.

Logging a contact re-read your whole logbook off the disk — about 3× faster now on a
large log.


6 m and the Needed board

A short-skip sporadic-E opening on 6 m did not raise an alert, and a 6 m spot's
local reports were being discarded in favour of ones the gate cannot use. 6 m could
also open on activity that never left the neighbourhood
, and changing digital mode
could make a dead band alert again
. The openings log under-counted the stations in a
VHF opening.

The Needed board hid US-spotted rows on exactly the pileups where a US spotter
matters
, and changing digital mode could make its own-radio rows lie about their age.


Appearance

Light theme: the "NEW ONE — Work it" pounce banner had no readable text — the
banner drew with a colour token that does not exist, so it painted on the page
background. The "needed" colours were the dark theme's colours everywhere they
appeared. In both themes, the ATNO, new-band and SOTA badges had unreadable labels.


Other

The window remembers its size, position and maximised state, restored before the
window is drawn, per radio, and clamped to a screen you still have.

The Memories strip is readable again — chips were collapsing to ellipses. Ten
chips maximum, with ▲▼ ordering in the Favorites view.


Known and not fixed

  • Tuning into an SSTV picture already in progress still gives you nothing.
  • A wrong rig model still reports as "the rig isn't answering." A CI-V radio silent at
    every baud is better evidence of a wrong model than a bad cable.
  • The world map keeps dark-theme colours in light mode.
  • An FT-817/818 baud sweep can exceed its time budget and report rates as untried.

Verification

Everything above is verified in CI: 2,363 workspace tests, 440 audio, 83 backend, 2,649
UI tests across 208 files, plus clippy at -D warnings. The FT-mode work is additionally
checked against WSJT-X's own message packer, and the callsign predicates are measured
against upstream's real behaviour over 66,628 inputs.

No radio was connected to any of it. The CAT and transmit-path changes are verified
against Hamlib source and by driving the shipped daemon against stand-in rigs — your
bench is the first real test. If something is wrong, v1.0.1 is the rollback, and a
report with the CAT status line verbatim is the most useful thing you can send.

73 — KD9TAW

Nexus 1.0.1

Choose a tag to compare

@github-actions github-actions released this 05 Aug 19:20

Nexus 1.0.1

Changes since v1.0.0:

  • release: 1.0.1
  • fix(dxped): the per-card headline change deleted the cards worth reading
  • fix(dxped): 60 m won every path, headlined every card, and DXCC cannot credit it
  • fix(audio): the picker said "not detected" about devices it could not know were absent
  • fix(audio): retry a device that failed to open — strict resolution had no way back
  • feat(bandplan): 60 m FT8 moves to 5.3715 MHz
  • fix(awards): 60 m earns no ARRL DXCC credit — the code asserted the opposite
  • fix(tx): the slot clamp did nothing on a VOX rig — flush, don't just unkey
  • fix(audio): name Linux devices by their description, list all of them, stop lying about the fallback
  • fix(msk144): budget the waveform from the AUDIO length, not the keying window
  • chore: bench build 1.0.1
  • feat(ft1): shorten the lead-in to 300 ms so the end of the over survives
  • style(ft1): rustfmt the sweep after the clippy parenthesization
  • style(ft1): parenthesize the sweep's seed expression for clippy
  • test(ft1): measure what the lead-in buys, and what it costs in tail
  • fix(cat): command the MODE before the DIAL — the FTDX10 ±650 Hz walk
  • feat(bandplan): 4 m (70 MHz) is now a band you can reach in Settings ▸ Frequencies
  • fix(waterfall): the weak-signal guard measured 9 LUT where the honest scene measures 3.2
  • fix(ft8): close two decoder-input drifts from WSJT-X — nftx and nzhsym
  • fix(waterfall): flatten every row, so the black point stops drifting with tilt
  • fix(tuning): sub-step scroll spent at the wrong decade, and a fast spin walking through the band plan
  • fix(waterfall): the weak-signal guard passed with the weak signal deleted
  • fix(tx): the wheel could move the VFO under a held mic key
  • waterfall: park the black point at the noise floor so an empty band reads black
  • feat(tuning): scroll any digit of the main dial to tune by that decade
  • fix(waterfall): correct four claims the adversarial pass refuted, and close the averaging gap
  • fix(tx): bound the PTT hold by the slot, as WSJT-X does
  • fix(waterfall): average the frames we were throwing away
  • fix(qrz): the QRZ link needed a callsign, not a successful lookup
  • fix(waterfall): put the intensity axis on dB with an absolute reference
  • fix(msk144): the tolerance is a frequency-error budget, not a passband
  • fix(waterfall): sweep every consumer onto the dB intensity axis, and give FT its own palette
  • fix(waterfall): back out a sibling change my last commit swept in
  • fix(waterfall): stop point-sampling bins into pixels — the blocky "8 bit" look
  • fix(sstv): the core radio controls, and give the composer its space back
  • fix(tx-timing): measure the PTT-hold deadline from the key, not the tick's stale clock
  • fix(tx-safety): make Stop TX flush queued audio so a VOX rig actually stops
  • fix(tx-safety): take the decoder lock off the snapshot path so Stop TX can't be convoyed
  • fix(tx-safety): unkey the rig from its own Drop so a dead radio thread can't strand the carrier
  • fix(cw): drop the contest-category pane from the cockpit
  • chore: ignore Python bytecode from the manual build scripts
  • docs: finish the two stale-claim sweeps, all spellings
  • docs: generate the three derivative wiki pages, sweep the hand-written ones
  • docs(manual): a cover and a typographic pass the manual deserved
  • docs(guide): three alt-text claims that did not match their image
  • docs(manual): build the manual as one printable PDF
  • docs: place Official Awards screenshot in awards-journey guide
  • docs(rtty): place the RTTY cockpit screenshot
  • docs(guide): place the CW cockpit screenshot and correct the log-pane wording
  • docs(guide): place the Satellites pass-console screenshot
  • docs: place Radio, Modes and Contesting screenshots in the settings reference
  • docs: place Classic and Roster cockpit screenshots in operate-digital
  • docs(phone): place cockpit screenshot and correct the mode-badge description
  • docs(sstv): place armed-and-listening section screenshot in the guide
  • docs(manual): the remaining four 1.0 captures
  • docs(guide): three corrections the re-verification pass found
  • docs: point every Settings reference at a tab that exists
  • docs(manual): Program's network claims, opt-in claim and workflow shape
  • docs(rtty): fix wrong Settings tab, link the RTTY pointers, pair the DSP facts
  • docs: correct Stats availability — on by default, DX/Everything profiles
  • docs(guide): correct the Spots page's QSX example, tie-break and opt-in claim
  • docs(aprs): correct decode-chip precedence, level coverage, Settings links
  • docs(memories): correct SSTV recall routing
  • docs(sstv): correct the wizard enablement paths
  • docs(manual): the screenshot pipeline, and the seven 1.0 captures
  • fix(ui): Settings no longer tells the operator JT65 cannot transmit
  • docs(manual): correct the CW keyer, macro and Needed-tier tables against the code
  • test(ui): check published doc tables against the code they describe
  • docs(guide): wire the seven new section pages into the guide
  • docs(guide): rewrite the settings reference onto the 1.0 eight-tab panel
  • docs(guide): the SSTV page — written from the 1.0 view + decoder source
  • docs(guide): add the RTTY guide page
  • docs(guide): the APRS section page — written from the 1.0 cockpit source
  • docs(guide): the Program page — the channel-list workbench, written from the source
  • docs(guide): add Spots page — the raw cluster/RBN firehose
  • docs(guide): add the Stats section page
  • docs(guide): add the Memories section page

Nexus 1.0.0

Choose a tag to compare

@github-actions github-actions released this 04 Aug 14:45

Nexus 1.0.0

Changes since v0.27.0:

  • 1.0.0 — the beta period closes
  • docs: bring README, guide, wiki and manual current for 1.0.0
  • docs(changelog): the 1.0.0 section — eight undocumented root-cause fixes, the beta close, and the tester-only cuts
  • release: name the Debian packages for the machine, not just the arch
  • 0.29.0: the lockfile catches up (it had been stale at 0.28.0)
  • 0.29.0: the low-resolution sweep
  • fix(ui): the torn-off band map keeps its heading style
  • fix(ui): the CW decode window gets the column back — two frames and two head rows deleted
  • fix(ui): Phone's control column stops scrolling two cards and a paragraph it does not need
  • fix(ui): the shared log strip commits above the fold — heading and card-in-card deleted
  • fix(test): the pane-frame census was blind to the one spelling that wins
  • fix(ui): give the Field Day column the floor and valve its Bonuses cap only claimed
  • fix(ui): let the memory strip's height follow its own row instead of a 26px clip
  • fix(ui): give APRS the deficit valve every other cockpit has, and put it in the computed census
  • fix(ui): make the cockpit header's crush protection a property of the component
  • fix(ui): retire the dead px sizing on .ph-scope-panel, make RTTY's waterfall floor yield, and give the scope splitters the range CSS honours
  • test(ui): compute the shared pane frame family's cascade instead of matching it
  • fix(ui): give the bounded pane region a column scroller, a fill floor, and an honest tier source
  • fix(ui): give .layout.single's panel the deficit valve its wrapper could never fire
  • fix(sats): the pass console states what fits per size, and stops trapping the schedule
  • 0.28.2: the satellite log gets a grid box and loses the park row
  • feat(sats): the Satellites section is a pass console — everything for a pass on one screen
  • fix(log): keep the callbook-grid filter in the satellite exchange, and drop two wrong figures
  • fix(log): the grid costs the satellite strip no line, and no park reaches a bird
  • docs(ui): the supported window floor is 1024x768
  • feat(log): the grid is typeable, and a bird's exchange has no park in it
  • 0.28.1: the satellite-mode flap reverted, and a compact log strip
  • fix(sat): the log strip shares its column with the sky dome, so make it compact
  • Revert "Merge branch 'fix/sat-uplink-mode-stated-plain' into integrate-0.28"
  • 0.28.0: satellite operating end to end, and a transmitter that survives a band change
  • docs: correct three claims, and close the band census against the Tier enum
  • fix(sat): the uplink VFO's mode is stated from every section, no exceptions
  • fix(docs): three claims the last round got wrong — the call sites, the bands, the field
  • fix(sat): the descope's real cost is WRONG credit, and PROP_MODE alone would be worse
  • fix(sat): stop ruling on RTTY's uplink side, and unclaim what the code never did
  • docs(ui): name the real writers of set_transmitting
  • docs(ui): make the stop-line census true — verified control by control
  • fix(sat): narrow the uplink branch back to the satellite uplink mode
  • docs(sat): make every claim on the descoped log panel true
  • docs(ui): derive the stop line from the pane census — fifth wording
  • docs(ui): make the stop line the guarantee, not a proxy for it
  • feat(sat): log a contact from the Satellites section — an ordinary contact
  • fix(ui): make the sweep see the latch, bind clause (b) to senders, cover Undo
  • fix(ui): restate the stop line as the property it protects, and make the guard real
  • feat(ui): a ⊞ Panels entry for the Phone voice keyer, by narrowing the TX-hiding rule
  • fix(ui): the ⊞ Panels reason explains the screen — it never takes the tick away
  • fix(sat): mirror EVERY sideband-bearing mode, and make a terrestrial split state its own
  • fix(ui): finish the ⊞ Panels sweep — five more dead entries, and the reason a keyboard operator can reach
  • fix(sat): state the uplink VFO's mode for every held bird, not only inverting ones
  • fix(ui): a ⊞ Panels entry that can change nothing is no longer checkable
  • test(tx): pin the six unpinned may_key appliers at the wire
  • fix(sat): move Lock on out of the Doppler readout so it exists before AOS
  • chore: 0.27.3 for the bench
  • fix(tx): close the verifier findings on the PTT context-halt fix
  • fix(sat): test the rotor give-up where it happens, and keep the dial marker visible
  • fix(sat): a rotor that stops answering gives up the mast, not the dial
  • fix(tx): a band change or radio switch no longer disarms Phone/CW/RTTY PTT
  • fix(sat): the pass rail pins the radio through the verb that owns peg-lock
  • fix(sat): a Doppler correction moves the dial and writes nothing else
  • chore: 0.27.2 for the bench
  • fix(sat): a pass keeps its mode across a section change, and Lock on follows the engine's hold
  • chore: 0.27.1 for the tester build
  • fix(sat): carry the cure-message tests onto the transponder-class signature
  • feat(sat): Lock on — put the radio back on the bird after the dial gets away
  • fix(sat): the rig mode follows the transponder, and an unnameable band is not a refusal
  • fix(sat): a refused uplink names the setting that would work

Nexus 0.27.0

Choose a tag to compare

@github-actions github-actions released this 02 Aug 21:07

Nexus 0.27.0

Changes since tles:

  • 0.27.0: satellite Doppler and uplink honesty, the FT8 decode window, and the frequency you were on
  • chore: 0.27.0 tester build — seven verified streams + a fresh classified seed
  • fix(test): drop the import orphaned when LOS handback moved app-wide
  • fix(sat): an uplink Nexus cannot verify is refused, not sent
  • feat(radio): switching modes or bands returns you to the frequency you were using
  • feat(ft): hide the countries you are done chasing
  • feat(ft): full decoder configuration — AP, CQ-only AP, single decode
  • feat(sat): the strip answers both questions — Next by clock, Best by quality, across all birds
  • feat(sat): audible AOS/LOS alerts for the pass you armed
  • fix(ui): Lookup gets its own colour, and Log moves away from the call row
  • fix(e2e): the smoke test waits for the reloaded document, not the doomed one
  • docs: encode the feature-gated clippy trap in the build table
  • fix(ci): the feature-gated tempo-audio clippy variant is green again
  • fix(test): the altitude fixtures speak the per-leg Doppler DTO
  • chore: 0.26.0 tester build — nine verified streams + a fresh classified seed
  • feat(sat): Doppler works the moment you arm a pass — downlink automatic, uplink confirmed per radio
  • feat(ui): the FT cockpit is an operating surface — decode window first-class, chrome collapsed
  • perf(rx): the instruments track the audio — window, cadence, ballistics, fast meter lane
  • fix(ui): the caller card computes bearing from where the station IS, not the middle of its square
  • feat(sat): the schedule sees the whole sky — a discovery band under the favourites
  • feat(sat): birds are classified by what you work them with, and the seed stars every kind
  • feat(sat): live altitude on the bird surfaces
  • feat(sat): the sky dome reads like an instrument — icon, live az/el, rise/set bearings
  • fix(sat): the element-age readout describes the set, not its oldest bird

Nexus 0.25.0

Choose a tag to compare

@github-actions github-actions released this 02 Aug 00:39

Nexus 0.25.0

Changes since v0.24.0:

  • 0.25.0: the satellite catalog ships with the app, SSTV receives on its own
  • fix(layout): a pop-out is fitted to its own content, not to the dense cockpit
  • feat(sat): ship the amateur catalog in the installer as a seed snapshot
  • chore: 0.24.9 tester build - the SSTV receiver fix
  • fix(sstv): opening the SSTV view starts the receiver
  • chore: 0.24.8 tester build - the full integration
  • feat(sat): the bird list is the amateur satellite population, not one Celestrak group
  • docs(changelog): one Added and one Fixed section after the integration merges
  • style: rustfmt the CQ+73 decode-row test assert
  • fix(rtty): the transcript stops rebuilding thousands of spans twice a second
  • perf(map): stop reallocating the canvas backing store every tick
  • chore: 0.24.7 tester build - the black-screen rescue + Connect star tracking
  • fix(ui): the Openings Log square works, and a broken screen can no longer black out the app
  • feat(connect): the sky follows your stars - iconed, named, and honest
  • chore: 0.24.6 tester build - satellite routing rule + honest refresh
  • feat(sat): a Satellite designation in the routing rules - each rig does its own job
  • chore: 0.24.5 tester build - packet-bird routing + simplex fix
  • fix(sat): a packet bird is FM to the radio, and a simplex bird rides one dial
  • chore: 0.24.4 tester build - TLE currency + the pick deadlock fix
  • chore: CI-parity sweep - the fold API keeps its eight named facts, fmt applied
  • feat(sat): the elements stay current - a mirrored, honest, self-limiting TLE pipeline
  • fix(sat): the transponder pick no longer hangs the app - an edition-2021 lifetime trap held the engine lock forever
  • chore: 0.24.3 tester build - the 9700 satellite tune fix
  • fix(sat): the pick reaches the rig - real routing fallback, read-back honesty, and true 9700 satellite mode
  • chore: 0.24.2 tester build - sat parity + polish
  • polish(sat): the section reads as one instrument - operations, honesty and idiom pass
  • feat(sat): picking a transponder tunes the right radio, immediately
  • fix(ft): TX Off finishes the over in flight; Stop TX stays the kill switch
  • feat(operate): QRZ page one click from the caller photo; 73 signoffs join the CQ filter
  • chore: 0.24.1 tester build - the satellite batch
  • chore: merge origin/main (0.24.0 release) — unshipped sat notes move to a fresh Unreleased
  • feat(sat): picking a bird is the whole act - the litigated satellite UX
  • feat(sat): rotor-less Doppler, commanded uplink sideband, and needs-aware passes
  • fix: a same-band FM/SSB hop clears stale activity but must NOT abort an over in flight
  • feat: Unassisted mode — one switch for a no-assistance contest entry
  • fix: never score NCDXF beacons or W1AW bulletins as needs

Amateur satellite catalog + TLE mirror

Choose a tag to compare

@github-actions github-actions released this 02 Aug 02:44

Auto-generated every 6 h: the amateur satellite population derived from the SatNOGS DB (CC BY-SA 4.0, (c) SatNOGS / Libre Space Foundation contributors), with orbital elements assembled from the Celestrak amateur and satnogs groups (data courtesy of CelesTrak, Dr. T.S. Kelso) and the SatNOGS TLE API. Nexus installs refresh from this mirror instead of each fetching upstream directly. As an adaptation of BY-SA material these assets are published under CC BY-SA 4.0; the same statement travels inside tles.json's own attribution field, which is the authoritative one (these notes are written once, at creation).

Nexus 0.24.0

Choose a tag to compare

@github-actions github-actions released this 31 Jul 16:17

Nexus 0.24.0

Changes since v0.21.5:

  • chore: release-prep 0.24.0 — version surfaces + changelog editorial pass
  • fix(cat): Test CAT diagnoses the rig instead of shrugging - baud ladder, backend attribution, CI-V port identity
  • chore: 0.23.0 — satellite operating joins the tester build
  • test(ui): the recall-card mock needs resolveEntity after the merge
  • chore: 0.22.2 tester build - full recall card + SSTV pane pass
  • feat(log): the full caller card returns on resolution; SSTV joins the pane grid
  • chore: src-tauri lockfile follows the merged 0.22.1 version
  • fix(sat): keep the full TLE epoch — it was truncated to whole seconds
  • docs: ui-layout skill - the build-time procedure for the layout contract
  • chore: 0.22.1 tester rebuild - pane roles + log-form wrap
  • docs: the UI layout contract joins the contributor guide
  • fix(layout): panes have roles - control strips stop hoarding columns, the log form wraps
  • docs(sat): record why the real-signal fixture stays at eight passes
  • chore: 0.22.0 tester build - changelog for the layout overhaul
  • feat(layout): Phone, CW and RTTY adopt the pane grid; width finally rescues height
  • feat(layout): pane-grid cockpit primitives - one frame, one region, one dock
  • fix(ui): portaled dialogs and tooltips finally honor the UI scale
  • fix(layout): one responsive vocabulary - data-viewport everywhere, @media retired
  • fix(windows): band-map geometry is validated against real monitors on open
  • fix(ui): one pinned-scroll discipline; focus moves never pan hidden boxes
  • fix(layout): persisted geometry is clamped on load, not just at drag time
  • fix(layout): restore the cockpit deficit valve and retire the floors that clipped the log form
  • fix(sat): actually wire the track loop to the shared driver
  • test(sat): validate Doppler against carriers actually recorded off the air
  • test(sat): fly a whole pass onto a real rotctld, and make the loop testable
  • test(sat): validate the geometry against an independent implementation
  • docs: changelog for operator-follow and the passband strip
  • feat(sat): the transponder passband strip — inversion you can see
  • fix(sat): wire operator-follow, and stop the pointing error counting the trim
  • feat(sat): report passband offset and width, so nothing has to reconstruct them
  • feat(sat): hero sky dome, globe pass mode, and a track badge that cannot lie
  • feat(sat): one honest status surface — true position, commanded position, range, Doppler
  • feat(sat): Phase 1 UI — transponder picker, Doppler and rotator settings
  • docs: CHANGELOG for satellite operating (Phase 1)
  • feat(sat): Phase 1 complete — Doppler runs the pass, and the rotator gets manners
  • feat(sat): the engine-side Doppler tick, and the module lands where the architecture says
  • feat(sat): the radio-binding decision layer — VFO mapping and rate limits
  • feat(sat): FT-mode and satellite are opposite TX intents — model them as such
  • feat(sat): the Doppler core — range-rate geometry, transponder data, and the tuning engine
  • chore: version 0.21.7 for the AI-CW-fix rebuild
  • fix: the AI CW engine is a PAIR of files — ship both, guard the build, and stop a QSY erasing the fault
  • chore: version 0.21.6 for the audit-batches test build
  • fix: a same-band FM/SSB hop clears stale activity but must NOT abort an over in flight
  • fix: adversarial-review round — the MSRV the security bump forced, two broken gates, and a biased eviction
  • fix: the cssVar memo empties at the START of the draw — the first frame after a theme switch painted old colors
  • style: plain comments on the thread_local sweep counter (doc comments can't attach through the macro)
  • docs: CHANGELOG for the recurrences batch (audit Batch 3)
  • fix: the pop-out maps agree with the docked one, the globe breathes, and four trivial recurrences
  • deps: the divergence gate's first catch — the shipped AI-CW decoder was on a vulnerable tract
  • ci: the gates that were switched off — live-feature tests, the src-tauri supply chain, and the stylesheet half of the demo gate
  • test: the sweep counter is per-thread — parallel tests inflated a process-global count
  • fix: the cheap recurrences — DNS off the mutex, the regrown snapshot sweep, and coin-flip answers made deterministic
  • fix: adversarial-review round — the resurrection bug, the failed-read stamp, and the legacy-midnight migration
  • ui: the edit payload stops pretending to clear upload stamps — the backend ruling owns that now
  • fix: the recovery gate's mtime comes from the save itself — never from a post-rename stat
  • test: station_identity integration literal gains the new QsoRecord fields
  • docs: CHANGELOG for the log-integrity batch (audit Batch 2)
  • perf+docs: the upload-stamp path stops re-parsing the whole log, and the manual tells the truth about ADIF
  • fix: loading a config profile can no longer remove your power ceiling — profile load is a merge
  • fix: one entity identity — the NEW ONE badge and the DXCC counts stop disagreeing with the awards engine
  • fix: the log stops lying about time, loses nothing on import, and corrections reach the services
  • fix: a band-plan channel token can no longer become the stored band identity
  • fix: ADIF parser mirrors the writer's mode-identity cascade — Tempo QSOs survive a restart
  • fix: adversarial-review round — the CAT-broker backend joins the poison sweep, broker re-key is idempotent again
  • docs: CHANGELOG for the TX-safety batch (audit Batch 1)
  • fix: tune auto-release regains a hard ceiling — the setting is clamped at the point of use
  • fix: one tx_owner() arbiter — an APRS beacon or auto-ack can no longer key over a live mic or broker over
  • fix: poison recovery for the engine and source locks — the deaf-radio doctrine, applied to its own outliers
  • fix: commit_tx validates the whole plan, not just the tier — and the promised slot refusal now exists
  • fix: keying-identity gate asks the mode plugin, not an Ft8|Ft4 allow-list
  • fix: TIME_OFF/QSO_DATE_OFF parse panicked on multibyte input reachable from a WSJT-X datagram
  • fix: APRS position parser panicked on 8-bit bytes inside the fixed 19-byte layout
  • docs: the on-air claim, file by file, and rename the protocol spec
  • README: use the Nexus splash art as the banner
  • Wiki: the on-air claim, all of it this time, plus the template that regenerates it
  • Wiki: refresh to truth, spine on the two positioning pages, and CITATION.cff
  • CHANGELOG: the launch-window work is Unreleased, not shipped in 0.21.5
  • SUPPORT and CONTRIBUTING: finish routing bug reports to GitHub
  • Issue templates become forms, with the fields that decide investigations
  • Record the full-corpus tag census in the needs fixture
  • Fix false "new mode" needs: honest claim + surface-scoped chips
  • needByCall carries each call's STRONGEST need, not whichever alert came last
  • Roster "sort by need" ranks by chase importance, not by an arbitrary tag
  • README: bug reports go to GitHub Issues
  • Call Roster and Band Activity filters persist across a restart
  • README: voice pass on the two dash-asides that were mine

Nexus 0.21.5

Choose a tag to compare

@github-actions github-actions released this 30 Jul 02:37

Nexus 0.21.5

Nexus 0.21.5 is an APRS release. APRS gains the internet side of the network, real
station symbols, a detail card per station, and a decode readout that names why it is not hearing
anything instead of showing an empty screen. Alongside it, mode-aware radio routing lets a
multi-radio station send each mode to the rig that does it best, and a third radio works properly
for the first time.

Nothing in this release starts transmitting on its own. The receive-only iGate and the N1MM
broadcast are both off after upgrading and only that switch can turn them on.

Downloads

Platform File
Windows 10/11 (x64) Nexus_0.21.5_x64-setup.exe
Linux (x86-64) Nexus_0.21.5_amd64.AppImage or Nexus_0.21.5_amd64.deb
Raspberry Pi / arm64, Debian 12 Nexus_0.21.5_arm64_bookworm.deb
Raspberry Pi / arm64, Debian 13 Nexus_0.21.5_arm64_trixie.deb

Checksums for every file are in SHA256SUMS.txt. To verify before installing:

sha256sum -c SHA256SUMS.txt --ignore-missing

On Windows, in PowerShell:

Get-FileHash Nexus_0.21.5_x64-setup.exe -Algorithm SHA256

Upgrading

Install over the top; your settings, logbook and memories are kept. Three things worth knowing:

  • The receive-only iGate is off. Contributing to a global network under your callsign stays a
    deliberate choice, so it never switches itself on.
  • The N1MM per-QSO broadcast is off, even if you already had an N1MM address configured. The
    fix below gives it its own switch.
  • Radio routing is unchanged until you add a rule. With no rules, routing stays band-only
    exactly as before.

APRS now sees the whole network, and can contribute to it

APRS used to show you exactly what your own antenna decoded, and nothing else. That is the honest
picture of what your radio can reach, but on a quiet channel it is also indistinguishable from a
broken receiver — which is what several operators were looking at.

Nexus can now also connect to APRS-IS, the internet side of APRS, and plot what the wider
network is reporting near you alongside what you actually hear. Turn it on in
Settings ▸ Modes ▸ APRS, where every APRS setting now lives, beside RTTY and CW.

  • Every station is tagged with how it reached youRF when your own receiver decoded it,
    net when only the internet reported it, RF+net when both did. You can never mistake "the
    network says this station exists" for "my antenna can hear this station", and one click hides the
    internet stations entirely, leaving the view of what this radio genuinely reaches.
  • It is also a diagnostic. The internet feed runs whether or not the APRS decoder is armed, and
    gets its own status chip beside the decoder's. Internet stations appearing while the RF chip stays
    silent tells you the fault is in the radio chain — antenna, cable, sound card, tuning — and not in
    the app. That was previously guesswork.
  • You choose what comes through. A radius around your grid square (150 km by default — APRS is
    a local mode), a list of watched callsigns that come through from anywhere however far away they
    are, and switches for weather stations, objects and items, and text messages.
  • No passcode needed to watch. The feed connects read-only, which every APRS-IS server accepts
    from any licensed operator.

The internet status chip on the APRS board is also its control: click it for the feed switch, the
range radius, and your watched callsigns. The radius is there because the chip's own advice when the
feed goes quiet is "widen the radius" — the control belongs where the advice is. Both places edit
the same settings, so they can never disagree about whether the feed is on.

With the feed running you can also switch on a receive-only iGate: packets your own antenna
hears
are contributed to APRS-IS, so stations around you reach the global map through your station.
It is a separate switch from the feed, and it stays in Settings rather than on the cockpit, because
it publishes under your callsign — contributing to a global network under your own call should be a
considered decision, not something a stray click can start.

Nexus only ever sends packets it actually heard on the air, and honours every rule the network asks
of an iGate: it never re-sends a packet that already came from the internet, never sends one whose
sender marked it NOGATE or RFONLY, suppresses duplicates, and caps its own upload rate so a
stuck transmitter nearby cannot flood the network in your name.

Nexus does not gate the other way — internet traffic is never transmitted on the air. That
direction means a radio keying up unattended, which is not something this app will do.

The APRS map grows up

Every station on the APRS map was the same grey dot. The packets were carrying the answer the whole
time — APRS stations pick their own icon, and Nexus was throwing it away.

Stations now draw as their actual APRS symbol, on the map and in the station list: cars, trucks,
bicycles and people, weather stations, digipeaters and iGates, campsites, balloons, boats and
aircraft. Vehicles under way point the way they are heading. Where an operator has put an overlay
character
on their symbol — the I on a full iGate, the R on a receive-only one, the hop count
on a digipeater — it shows on top of the icon, because that character is often the most useful thing
about the station. A symbol Nexus does not recognise draws the standard "unknown" glyph, never a
blank. The icons are drawn in Nexus rather than borrowed, so there is nothing extra to install.

Symbols also carry a colour for their family: homes and portable stations, vehicles, aircraft,
boats, weather stations, digipeaters and gateways, and hand-placed objects. Colour says what a
station is — nothing here means urgency. The palette varies brightness as well as hue so the
families stay apart for colourblind operators, and it has a separate version for the light theme.

You can still tell what your own antenna heard. That used to be the solid-versus-hollow dot.
The shape now says what a station IS, so the ring around it says how it reached you: solid for RF,
doubled when you heard it both ways, dashed and dimmed for internet-only. Solid still means yours.
Below a local scale the map goes back to plain dots — a continent covered in icons answers a
question nobody asked.

The map opens on the local picture. APRS is a local mode — 2 m simplex plus a digipeater or two
reaches tens of kilometres — so the map now opens reaching about 275 km in each direction, and you
can zoom in much further than before. Previously it opened at a scale where roughly 23 km fell on a
single pixel, so a station 40 km away drew less than two pixels from your own marker and an entire
local net stacked up underneath it as one dot. A freshly decoded station now appears the moment it
lands rather than waiting up to a minute for something unrelated to repaint the screen, and clicking
a station in the list highlights it on the map immediately. With no grid square set, the map centres
on the traffic you are hearing instead of painting an empty box with no coastline and no stations.

Click a station for everything known about it. Clicking used to highlight it and nothing else.
It now opens a detail card, from either the map or the list:

  • The symbol at readable size, with what it actually means in words.
  • How it reached you, per source, with separate ages — "your receiver decoded this station
    4 min ago; the internet feed reported it 20 s ago". Those are two different facts and only one of
    them says anything about your antenna, so they are never merged into a single "last heard".
  • Position with grid square, and distance and bearing from your station.
  • Course, speed and altitude when the station is moving.
  • The weather, when it is a weather station. Those readings used to be shown as the raw field
    string — 220/004g011t085r000p000P000h68b10156. Nexus now reads it: temperature, wind direction
    and speed, gusts, rainfall, humidity and barometric pressure. A sensor a station does not have is
    left out rather than shown as zero — r... on the wire means "no rain gauge fitted", not "no
    rain", and reporting 0.00 in would be inventing a measurement.
  • The comment text, the digipeater path, and whether the packet reached you direct or digipeated.
  • The raw packet, collapsed until you want it.
  • One click to QRZ, or to the station's page on aprs.fi.

Behind all of it, the map keeps stations, each with its own history: last position, when it was
last heard by your radio and by the internet, symbol, course and speed. A station stays for an hour
after its last packet and starts to fade after twenty minutes of silence, so a quiet station recedes
instead of vanishing. You can change the hour in Settings ▸ Modes ▸ APRS, and setting "Keep
stations for" to 0 means exactly that — no fade, no removal, every station kept until the
2000-station ceiling — because some operators genuinely want an all-day picture.

APRS tells you exactly why it is not decoding

An empty APRS screen used to mean half a dozen very different things and looked identical for all of
them: the app listening to the wrong sound card, the radio parked on another frequency, a signal
arriving too corrupted to check, or a genuinely quiet channel. Only packets that passed their
checksum ever reached the screen, so everything else vanished without trace.

The APRS header now carries a decode readout that names which one you are looking at, in six honest
states: no input, silent, wrong frequency or mode, bursts heard but failing their
checksum
, listening on a quiet channel, and decoding with a count and how long ago the
last packet landed. Beside them it shows the input level in dBFS, so what the decoder is hearing
is a number you can read rather than something to infer from which mess...

Read more

Nexus 0.21.0

Choose a tag to compare

@github-actions github-actions released this 29 Jul 05:43

Nexus 0.21.0

Changes since v0.20.0:

  • Release 0.21.0: version surfaces and the public changelog
  • QRZ: pull confirmations automatically, as a MODSINCE delta
  • APRS: fill the window — the host was missing display:contents
  • Alerts: stop a new DXCC re-alerting on every cycle
  • APRS map runaway: the real cause was the canvas being IN FLOW
  • Fix the APRS map growing without bound; guard it with a test
  • Bump to 0.20.2 for a tester build of the UI batch
  • Fix the SstvProgress test fixture for the new hedr_shift_hz field
  • UI batch 4: APRS gets the map it never had
  • UI batch 3: SSTV band view — the waterfall becomes the picture
  • UI batch 1/2: satellites globe + DXpedition month calendar
  • Bump to 0.20.1 for a tester build of the two lock fixes
  • Build the TX waveform with the engine mutex released, not held
  • MODEM_LOCK: recover from poisoning instead of killing the radio for the session