Changelog
What changed, and what it cost
Including the things that went wrong. A changelog that only lists features is a marketing page with dates on it, and the entries worth reading are usually the ones admitting something was broken.
0.10.2
11 September 2026
Two settings that could aim the tester at the network under test
- The webhook and the internet-check target could be pointed at the network under test. Both are set from the console, which anyone on the hotspot can reach, and both make the tester connect to whatever they name: every saved report posted to a machine on the tested network, or a port on it tried at every test. Now an address inside the tested drop's own subnet is refused when it is set, and judged again on what it resolves to before every send and every test, so a target that is fine at your bench is still refused at a site whose addresses overlap it. An endpoint of your own anywhere else is unaffected. A test whose target turns out to be inside reports the internet as not tested, which is the truth.
- The console says what the device is doing. The sharing dialog shows how many packets the tester has refused to pass between the hotspot and the network under test since it booted, and whether the hotspot is offering a router, both read from the device. The hotspot dialog shows the name the tester is actually answering to on the network, read from the responder rather than assumed, so a rename forced by a conflicting client is visible instead of silent.
0.10.1
10 September 2026
With sharing off, the tester still forwarded
- A phone on the hotspot could reach the network under test through the tester, with sharing off. Seen on the bench the same afternoon 0.10.0 shipped: a phone joined the hotspot and pinged a wired laptop, and the laptop heard the pings arrive from the tester's own port, still carrying the phone's hotspot address. The network stack underneath this firmware forwards between its two interfaces whenever it can, because sharing needs it to, and it does not know that sharing is a setting. Worse, the hotspot told every phone that joined to send anything not on the hotspot through the tester, so no one had to configure anything. Now the tester refuses every forward while sharing is off, in both directions, inside the stack, and the hotspot no longer offers itself as a router in that mode. The console shows how many packets it has refused since boot, and whether the hotspot is offering a router, both read from the device rather than assumed. The first version of the refusal compared addresses; review found the stack leaves them stale on exactly this path, so one forged packet could have made the tester refuse its own next one. It compares identities instead, and that version is what shipped.
- What it does not change. The console is still open to anyone on the hotspot, by design, and two of its settings still make the tester transmit to an address a visitor chooses. That is tracked on its own.
0.10.0
10 September 2026
The VLANs on the wire, and sharing a stranger cannot switch on
- A stranger in radio range could make the tester a router onto your client's network. The hotspot is open by default and the console has no login, both on purpose, and turning internet sharing on took one plain web address. Anyone who joined the hotspot from a waiting room or a car park could open it and be forwarded out through the drop under test. The manual said sharing was off unless you turned it on and the device warned you first, which was true of whoever held the console and of nobody else. Now only the button on the tester turns sharing on, held until the light turns amber, and only once the hotspot has a key. The console can turn it off and never on, from the hotspot or from the network under test, and the tester never shares its connection over an open hotspot, so clearing the key turns sharing off. The first fix written for this in development refused an open hotspot and trusted a keyed one, and review showed the flaw: the key is set from that same console, so anyone on the open hotspot could set one of their own and walk straight through. It did not ship.
- The dead-jack report drew a conclusion from silence. On a jack with no link the tester hears nothing, and the report still wrote "No VLAN tags in 0 frames. Traffic here is untagged", the one inference this site says it never makes, a few lines under its own warning that the receiver itself might be what is broken. Zero frames now says that nothing can be said about tagging. With frames to judge by, no tags is still reported as untagged, because then it is the finding.
- It reports which VLANs the traffic carried, and which one you are on. The tester was already unwrapping every tag to reach the protocol underneath, and throwing the VLAN id away. It now keeps up to eight and counts any beyond that rather than dropping them, and never calls a port a trunk or an access port, which one port's traffic cannot show. The list is headed "seen so far" and says "Heard, not allowed": a VLAN with no traffic while it listened is invisible to it. A reply addressed to the tester that arrives untagged proves which VLAN this end is on; the number comes only from the switch's advertisement, and without it the tester says you are on none of the VLANs listed rather than guessing.
- A DHCP offer the tester cannot read is named, instead of looking like no server at all. An offer that arrives tagged is dropped by the network stack, so on a trunk port the jack read as though nothing answered DHCP. The listener sits below the stack, sees it anyway, and now says which VLAN it arrived tagged for.
- It can name a duplex mismatch, when the switch will say how it sees the port. A mismatch links, passes every check, and collapses under load, and from one end it looks the same as an honest half duplex link. When the switch advertises its own speed and duplex, the tester compares and names the mismatch. Most switches do not send this, and silence is reported as silence, never as agreement. The one on the development bench sends the field empty, so a real mismatch has so far been tested only against frames built by hand.
- The screen gained a third page, and had been cutting the end off an address. The VLANs, the far end's duplex and a second DHCP server reached every face but the screen; a third page now carries them, and appears only when there is something on it. Separately, on a 192.168 network the first row could cut the address itself, the row's whole reason for existing, because speed and duplex shared its twenty-one columns. The address now has the row to itself. Nothing had counted those columns, and a photograph of the panel found it.
- A test no longer goes on asking a jack that has gone. A cable pulled mid-test cost that test 2963 ms against an ordinary 932, and 2101 of it was the gateway ping waiting out three timeouts on a gateway that was no longer there. The tester now checks for a lost link between one step and the next and stops: three pulls stopped after 1276, 1015 and 1014 ms. A test cut short says nothing at all, because it measured nothing, and the link-down FAIL that follows is the truth. A report being saved when the cable goes is still written. The timeouts were not shortened, because on a jack that is legitimately slow that would degrade the reading this instrument exists to take.
- The log promised in 0.3.0 had never been written, on any unit. The code that appends to it existed and nothing called it. It is written now, for one of five recorded reasons: any save a person asks for, the first test on a new link, a verdict that changes, a link lost after a good reading, and a heartbeat after five quiet minutes. It downloads from the console, clears with its own control rather than with "delete all", and stops at the same free-space floor the reports already respected.
- The front page had the tester's speed wrong by about a factor of two. It said "about half a second", written before anybody had measured one. Twenty-two consecutive runs on a healthy jack say 934 ms, and the front page now says so. About once a minute a run also refreshes the public address and takes a little over four seconds, and the manual breaks that run down leg by leg. The internet check's limit read five seconds and could run to eleven; there are now two limits, each named for the wait it bounds.
- "not tested" was the least legible text in the report. The phrase the instrument's whole argument rests on was 2.98:1 on white, under even the floor for large text. It is 5.48:1 now, and the build measures all seventeen report colours against their real backgrounds and fails below 4.5:1.
- The console is laid out like a front panel, in five regions with the verdict always in the header, and prints the settings a test ran under beside its result, the way a certificate prints its conditions. On the development unit that surfaced a tester that had been quietly acting as a router since the afternoon. A refused save no longer wipes the notes you had typed.
- A script injection was written into this release and closed before it shipped. Device hostnames overheard on the segment reach the console's table, and a new sentence built from them ran script when every device sent the same crafted name. Review caught it and confirmed it by exploiting it. The console now contains no innerHTML at all, and the build fails if one comes back carrying anything but fixed text.
- One slow test is still unexplained. A test with the cable pulled while it ran was once seen taking 20170 ms. It has not been reproduced, and the limits on the individual steps do not account for all of it.
0.9.0
6 September 2026
A screen, and a button that stops losing presses
- A 1.3 inch panel, optional at run time. The verdict in letters, the speed and address, and which switch port you are plugged into, without taking a phone out. A second page carries the netmask, gateway, DNS, the public address and 802.1X. A unit with no panel fitted runs exactly the same.
- The button was losing presses, and the cause was not the one it looked like. It read the pin when the main loop got round to looking, and the loop is away for up to four seconds during a test, so a press that began and ended in that window was not delayed, it was never seen. An interrupt now records when each edge happened and the loop asks afterwards what they meant.
- And a second cause, found only after the first was fixed. The page timer stored the press time with its lowest bit forced to one, so that a press on millisecond zero could not be mistaken for no press at all. On every even millisecond that stored a time one millisecond in the future, the timeout arithmetic underflowed to forty nine days, and the page turned and came straight back. Half of all page turns, presenting as a button that had not registered. The sentinel is gone and the state it protected now lives where a test can reach it.
- Both holds now say what they will do while you hold them. One reboots the tester and one leaves its WiFi open with no password, and both act when you let go, so the last second before you release is the last chance to change your mind. Colour cannot say "this reboots".
- A hold the tester could not warn you about is refused. The warning is drawn by the same loop that runs the test, so a hold made entirely while a test was running used to commit unwarned. It now says why nothing happened instead.
- Three ways a gesture could fire without being made, all found by review rather than in the field, all now closed: two taps during a report save measured as one hold, because the interrupt is disabled while flash is written and the missing release looked like contact bounce; a one millisecond knock against something in a bag could turn a long unattended press into the gesture that opens the WiFi; and two page turns six hundred milliseconds apart, judged together after a blocked loop, saved a report and posted it to a webhook nobody had asked to trigger.
- The panel no longer writes its own 802.1X sentence. It used to build one from a single flag, which collapsed four findings into one, so on a port running MACsec key agreement every other face reported the strongest finding this instrument can make and the panel said the opposite.
- "Report not written" is no longer printed over a report that was. A write that comes up short deliberately keeps the partial file, and that was the one failure path being described as if nothing had been saved.
0.8.0
5 September 2026
Listening: 802.1X, other DHCP servers, and a witness for every silence
- The tester can say a port asked it to authenticate. It can never say a port did not, and there is no reading that means so. A switch sends its identity requests when a device appears and then stops, so on a port whose requests finished before you arrived, no amount of waiting produces one. A tester that offered "802.1X not in use" would be inventing it out of a silence that proves nothing.
- It reports what else answers DHCP on this segment, with the MAC address of each, which is what you need to find the port a second server is plugged into. It reports what replied, never how many exist.
- Every absence now carries a witness: how long the tester listened and how many frames went past while it did. "Nothing heard, 0 frames" is a broken receiver. "Nothing heard, 344 frames" is a real observation about a live segment. Those two used to look identical.
- Fixed: the tester displayed switches that do not exist. The CDP decoder matched on a MAC address alone, and that address also carries VTP, DTP, PAgP and UDLD. On a port with no LLDP, a DTP frame produced a confident switch name and port number for a switch that was never there.
- Fixed: the switch section of the log vanished when nothing was heard, so a quiet segment and a deaf tester both left no trace.
- Fixed: a cable moved between two jacks faster than the link check could see reported the previous jack's findings on the new one.
- Eight further defects, found by attacking the new code rather than waiting for it to fail in the field, including a frame that could manufacture a false "this port asked us to authenticate" out of a length field it chose itself.
0.7.0
4 September 2026
Storage moves inside, and a crash goes with it
- Reports now live in internal flash. Capacity is 394, measured by filling the partition rather than estimated. The tester no longer depends on a memory card being present, or being genuine.
- The microSD store was removed rather than repaired. It was write-only, a rename left it holding the old name and label, a delete never touched it, and two testers sharing a card overwrote each other in silence. Underneath all of it: any policy that deletes an original needs to know a second copy exists, and the device could not know.
- Fixed: listing several hundred reports rebooted the tester. The directory walk opened each file, which is a full name lookup per entry, on the task a five second watchdog is watching. With 414 reports stored it took 7.7 to 12.9 seconds and panicked the device. Reading names without opening takes 322 ms. Both figures measured on hardware, and the page now renders in 1.2 s.
- Fixed: the tester was ten times slower when nobody was watching. Serial writes block until a host drains them, so an unattended device crawled: a report that saved in 970 ms with a console attached took 12.7 s without one. This also invalidated several earlier timings, which were measurements of the watched device.
- Fixed: it refused to save with more than half the space free. The full threshold was sized in megabytes, correct for a 118 GB card and useless against a 3.4 MB partition.
- Download a report, download them all as a ZIP, delete them all. With no card, this is how evidence leaves the instrument. The delete asks first and names the number it is about to destroy.
- Reports list newest first. It used to be filesystem order, which is nothing a person would recognise.
- A favicon, carried inside every saved report so it survives being mailed.
- Corrected three messages that told a technician the card held their evidence when it did not.
0.6.0
4 September 2026
Notifications, a hotspot key, and a way back in
- Webhook notifications. Each saved report posts a flat JSON summary to an address you configure, on its own task so an unreachable endpoint cannot freeze the instrument. Delivery verified end to end against a real receiver.
- A password for the hotspot, and a five second button hold that clears it. Anyone holding the button is standing at the device, which is the same trust boundary the key protects.
- The single-uplink assumption the verdict rests on is now enforced by a check rather than described in a comment.
0.5.0
4 September 2026
The console stops being the bottleneck
- The web console moved to an event-driven server. The stock one serves a single client and holds its only slot for five seconds whenever a browser opens a speculative connection, which browsers do constantly. Measured before and after, against concurrent load: 17 of 36 requests failed, then 0 of 36; slowest tenth went from 8.2 s to 253 ms.
- Rename and delete for saved reports, storage state, and a way back to the console from an opened report.
- Time zone as a real zone rather than an hour offset, so daylight saving is right in March and in November, and it survives a restart.
0.4.0
4 September 2026
Reports a client can be handed
- A double press saves a self-contained HTML report, with a label and typed notes, a verdict, every reading, and both local and UTC time.
- The console redesigned around the verdict, with the checks below it.
- The unit now has one identity everywhere. It was reporting three different MAC addresses for itself across three surfaces.
- The first automated checks, each one watched failing on a planted fault before being trusted.
0.3.0
3 September 2026
Time, and a record
- Real wall-clock time by SNTP, so a report says when rather than how long since boot.
- Every kept run appended to a line-delimited log, which survives being unplugged mid-write.
0.2.0
3 September 2026
Honest states, and the WAN
- Public address and gateway latency added to the test.
- No-link and no-DHCP became real answers rather than a blank page. A tester that shows nothing when a drop is dead is a tester that looks broken exactly when it is working.
- Fixed a data race on the discovered neighbour, and made stale switch data expire instead of following the tester to the next jack.
0.1.0
2 September 2026
First working instrument
- Link, DHCP, gateway, DNS and internet, resolving to one verdict.
- Passive LLDP and CDP discovery, reading the switch, port and VLAN without transmitting anything to ask.
- The WiFi hotspot and the live console.
- Verified side by side against a NetAlly LinkSprinter.