A project that lives on a developer's desk looks like it works. There is only one way to check: hand the devices to people and listen to what they say. Below are several bugs found exactly that way, and what each of them teaches.
The amplifier that was doing nothing
The most expensive find. On one board revision reception worked, transmission worked, the link was there — but range was noticeably worse than expected.
The cause was in the external amplifier control. The module has a pin that switches the path between transmit and receive. The firmware drove it into the wrong state, and the signal went on air bypassing the amplifier. Before and after: minus seventy-eight decibels against minus twenty. Fifty-eight decibels of difference is not "a bit better", it is a different radio.
What is instructive here is that no error was visible. Nothing crashed, nothing printed a message, the link was up. Range was simply four times shorter than the hardware allowed, and that could be blamed on anything: the antenna, the buildings, interference.
The lesson we took: "it works" and "it works as designed" are different things, and only a measurement tells them apart.
The WiFi that jammed reception
The repeater hosts a web page — a map of stations, statistics, settings. That needs WiFi, and for a long time it kept two modes at once: its own access point and a connection to the home network.
An observation came from the community: the access point is not needed when the repeater is already on a network, and an extra transmitter next to a receiver gets in the way — through the board's power rails, not only through the air.
The remark was right, and the cost was higher than we thought. When, after a refactor, one build left the client side of WiFi running with nothing to connect to, the bench showed it plainly: voice through the repeater stopped getting through entirely — zero forwarded packets out of twenty instead of the usual ten. Remove the idle transmitter and everything came back.
What is instructive here is that the suspicion came from someone watching the device at work, not from us. And that it was confirmed only by numbers.
A cross on a message that arrived
A bug that does not break the link but damages trust in it.
A message went out, reached its recipient, who read it — and the sender saw a "not delivered" cross. The delivery acknowledgement got lost on the way back, or arrived later than the app was willing to wait, and the app drew a failure.
The fix was not to wait longer but to stop lying. A message now has three states instead of two: delivered, sent without acknowledgement, and not sent. The second is an honest "we do not know": in half-duplex air the reply itself can be lost. A late acknowledgement ticks the message off retroactively.
What is instructive here is that an interface confidently showing a falsehood is worse than one admitting uncertainty.
Duplicates, noise and other small things
A few smaller finds, from the same family — visible only in a live network.
Messages doubled once a repeater appeared: it dutifully repeated other stations' packets, including the sender's own, and the sender received its own message back. In the chat that looked like a duplicate. The cure is for a station to ignore packets carrying its own sender address.
A partially received voice message played out as hiss. If some packets were lost, zeroes stayed in their place, and the codec faithfully turned zeroes into noise — so a short phrase was followed by half a minute of hissing. Now what arrived intact is played and the gap-ridden tail is dropped: a short phrase beats a phrase with noise.
The repeater seemed confused about its own channel. On its page the drop-down showed one channel and the table another. Investigation showed there was no bug: the list shows what a person picked, the table shows the real state. The fix was not code but a label — the current channel is now marked in the list itself.
What a bench cannot find
The project has a test bench: two boards, a phone, some sixty checks — text, voice, files, calls, repeater, losses, load. It catches a lot and saves hours.
But it would not have found a single one of the bugs above on its own, and the reason is clear. On the bench the boards sit half a metre apart, the air is clean, power comes from a stable supply, and the scenarios are the ones we thought of in advance. You cannot test range there, cannot reproduce city interference, and certainly cannot reproduce "a person is out walking with one radio while the other sits at home".
What the bench does superbly is something else: it confirms or refutes a hypothesis. Almost every story above followed the same shape — an observation from the field, a hypothesis, an attempt to reproduce it on the desk. Sometimes the hypothesis failed, and that is a result too: we were once sure the command was being missed by radios that listen to the air in short bursts — six consecutive checks showed that was not it, and the search had to continue.
That is why the most valuable thing in a message from the group is not the complaint but the detail. "It does not work" cannot be checked. "The nodes changed channel, the repeater did not" can be — and that took twenty minutes.
What the project can do today is in the documentation. What is being worked on and what is deferred is on the project page. Observations from the field are always welcome in the Telegram group.