It isn't right to consider that time as a golden age of software reliability. Software wasn't less buggy back then. My clear recollection is that it was all unbelievably buggy by today's standards. However things we take for granted now like crash reporting, emailed bug reports, etc just didn't exist, so a lot of devs just never found out they'd written buggy code and couldn't do anything even if they did. Maybe it felt like the results were reliable but really you were often just in the dark about whether people were experiencing bugs at all. This is the origin of war stories like how Windows 95 would detect and effectively hot-patch SimCity to work around memory corruption bugs in it that didn't show up in Windows 3.1.
Manual testing was no replacement for automated testing even if you had huge QA teams. They could do a good job of finding new bugs and usability issues compared to the devs-only unit testing mentality we tend to have today, but they were often quite poor at preventing regressions because repeating the same things over and over was very boring, and by the time they found the issue you may have been running out of time anyway.
I did some Windows 95 programming and Win3.1 too. Maybe you could fully understand what it was doing if you worked at Microsoft. For the rest of us, these were massive black boxes with essentially zero debugging support. If anything went wrong you got either a crash, or an HRESULT error code which might be in the headers if you're lucky, but luxuries like log files, exceptions, sanity checkers, static analysis tools, useful diagnostic messages etc were just totally absent. Windows programming was (and largely still is) essentially an exercise in constantly guessing why the code you just wrote wasn't working or was just drawing the wrong thing with no visibility into the source code. HTML can be frustratingly similar in some ways - if you do something wrong you just silently get the wrong results a lot of the time. But compared to something more modern like JavaFX/Jetpack Compose it was the dark ages.
I'm reminded of the Windows 95 uptime bug https://news.ycombinator.com/item?id=28340101 that nobody found for years because you simply couldn't keep a Windows system up that long. Something would just crash on you and bluescreen the whole thing, or you needed to touch a mandatory-reboot setting or install some software.
I get forced restarts on Windows 10 due to .net updates only. These tend to ensure applications that ran on previous CLR cannot run until the shutdown thing does the job of rebuilding everything, and it's not done online.
Reliable and buggy can go together - after all, nobody left their computer running for days on end back then, so you almost always had a "fresh slate" when starting up. And since programs would crash, you were more trained to save things.
The other major aspect was that pre-internet, security was simply not an issue at all; since each machine was local and self-contained there wasn't "elite hax0rs" breaking into your box; the most there was were floppy-copied viruses.
> a lot of devs just never found out they'd written buggy code and couldn't do anything even if they did.
This is undoubtedly true. No doubt there are countless quietly-malfunctioning embedded systems all around the world.
There also exist highly visible embedded systems such as on-air telephone systems used by high-profile talents in major radio markets around the country. In that environment malfunctions rarely go unnoticed. We'd hear about them literally the day of discovery. It's not that there were zero bugs back then, just nothing remotely like the jira-backlog-filling quantities of bugs that seem to be the norm today.
Manual testing was no replacement for automated testing even if you had huge QA teams. They could do a good job of finding new bugs and usability issues compared to the devs-only unit testing mentality we tend to have today, but they were often quite poor at preventing regressions because repeating the same things over and over was very boring, and by the time they found the issue you may have been running out of time anyway.
I did some Windows 95 programming and Win3.1 too. Maybe you could fully understand what it was doing if you worked at Microsoft. For the rest of us, these were massive black boxes with essentially zero debugging support. If anything went wrong you got either a crash, or an HRESULT error code which might be in the headers if you're lucky, but luxuries like log files, exceptions, sanity checkers, static analysis tools, useful diagnostic messages etc were just totally absent. Windows programming was (and largely still is) essentially an exercise in constantly guessing why the code you just wrote wasn't working or was just drawing the wrong thing with no visibility into the source code. HTML can be frustratingly similar in some ways - if you do something wrong you just silently get the wrong results a lot of the time. But compared to something more modern like JavaFX/Jetpack Compose it was the dark ages.