Blog

Occasional updates about Divested projects and other fun from Tavi.
Sundry updates are now on the Roll page.
The text on this page is licensed CC BY-SA 4.0 unless stated otherwise.

Notes on Geiger Counters2025-09-24

Disclaimer

I am just some random software developer. I have no actual experience in this field. This information is purely for other hobbyists. I'm also not going to provide detailed explanations about their use or about radiation itself, there are more knowledgeable people who have written in depth about that. If you work around radiation in any professional manner, your workplace almost certainly already provides you with the necessary training and proper equipment. Absolutely never place your life in the hands of these cheap toys.

Preface

I have always wanted a geiger counter since I was young. It popped up every few years but they were always pricey and/or rough. I've recently been watching through The X-Files which occasionally shows them and there was also recently a thread on the front page of HN about a DIY counter using a Flipper. So I started looking into options again.

Extremely Basic Overview of Radiation

  • In this context of ionizing radiation, there are five types: neutron, alpha (α), beta (β), gamma (γ), and X-rays.
  • They are emitted during the decay process of an atomic nucleus.
  • Neutron, alpha, and beta radiation are classed as particle radiation.
  • X-rays and gamma radiation are classed as electromagnetic radiation (photons). Although they are produced differently, X-rays are formed from electrical acceleration whereas gamma is a nuclear process.
  • Different decay chains emit more of each type than others.
  • Different emissions also have varying levels of energy per photon, usually measured in electronvolts.
  • Alpha radiation is easily stopped by extremely thin materials such as paper or the very outer layer of your skin.
  • Beta radiation can be stopped by thin metal.
  • Gamma radiation however requires dense materials such as concrete or lead to be stopped.
  • Lastly and most importantly is the inverse-square law. As distance from a emitter is increased, the intensity dramatically drops.
  • For example Am-241, commonly used in smoke detectors, primarily emits alpha radiation which is nearly entirely blocked by the housing and a small amount of gamma radiation which can escape. But thanks to the inverse square law, this tiny amount of gamma radiation blurs into that of the background radiation when just inches away and is effectively harmless when they are appropriately installed (eg. on ceilings, feet away from us).

Extremely Basic Overview of Radiation Safety

  • Any exposure to ionizing radiation directly damages materials, such as the cells of living creatures. But it is also always around us, yet we still live?
  • This is because exposure is measured by: type, energy level, and time.
  • Since Alpha radiation is blocked by the very outer layer of skin, it is largely only an issue if you were to ingest, inhale, or put it inside your body some other way. Since once inside, it can then do damage to your living cells.
  • Gamma radiation on the other hand will happily punch a bunch of small holes through your body without any care.
  • Different decay chains have different energy levels, so some can be extremely energetic. These for example can cause more collateral damage in the surrounding areas than that of lower energy emissions.
  • And the more time your cells are exposed to ionizing radiation, the more damage will be done especially if they are more energetic.
  • So we need sufficient exposure to damage cells to a point where they cannot correctly or quickly replicate themselves anymore to be an actual health concern.
  • In safety systems a common term is ALARA or 'as low as reasonably achievable'. For radiation this is achieved by: minimizing time around them, increasing distance from them, avoiding large emitters, avoiding high energy emissions, and ensuring sufficient shielding around them and yourself if/when possible.

Extremely Basic Overview of Geiger Counters

  • edit: I've made a handful of corrections regarding scintillators thanks to u/Physix_R_Cool and some adjustments thanks to u/PhoenixAF. Their more detailed posts are both linked.
  • A geiger counter has become a generic term to refer to radiation measuring devices.
  • But the most well known type of geiger counter is one that uses a Geiger-Müller tube.
  • Geiger-Müller (GM) tubes are usually metal or glass tubes filled with an inert gas and have a high-voltage electrical charge applied across them. When ionizing radiation passes through, the conductivity of the gas is altered which can be measured by the device to form a reading.
  • More recently scintillation counters have become more common. These have two parts: a scintillator and a photosensor. A scintillator is a material that emits light when ionizing radiation passes through it. And then a photosensor (ie. a camera) measures the pattern of light emitted amount of light, which is proportional to the energy impacting the scintillator, which the device uses to form a reading. These have the benefit that different isotopes cause different patterns the actual energy level can be measured, which the device can use to identify the isotope.
  • GM tubes notably have a "dead time", this is a period where it cannot detect events due to the matter in the tube physically changing state. Scintillators on the other hand emit light, which well... travels at the speed of light, so they effectively do not have a "dead time" do still have a similar decay time but this is a much shorter period, which makes them able to measure & respond to events much quicker.
  • GM tubes can be sensitive to both alpha, beta, and gamma radiation. But depending on the model of tube or how the tube is encased by the counter they may not be able to measure alpha or beta radiation. Some counters will have a physical sliding sheath that allows the tube to be "toggled" between detecting alpha & beta or not.
  • The scintillators commonly used in cheap detectors cannot detect alpha or beta radiation but are very sensitive to gamma radiation. All scintillators are similary sensitive as GM tubes, but in most cheap counters they are shielded by the casing enough in order for the photosensor to not be exposed to outside light to be very poor at detecting alpha and beta radiation.
  • Size matters: a larger GM tube or a larger scintillator & photosensor area will allow for greater sensitivity. Increased photosensor area generally only improves uncertainty of energy measurements.
  • Counters are usually calibrated to a specific source such as Cs-137. This means the energy readings from other emitters will not be accurate, unless the counter provides energy compensation and most importantly is accurately calibrated to the actual expected energy ranges. GM tubes can perform compensation by having physical sheaths that block out certain low or high energy levels to narrow the exposure. Scintillators can try and identify the isotope and perform compensation directly calculate the dose from the observed energy level in software. In cheap counters, both approaches are likely just rough approximations.
  • Radiation measuring devices usually have two goals: showing dose rate (current amount) and/or dose (exposed amount).
  • Some devices will only show dose rate, these are typically called radiation or survey meters.
  • Some devices will only show dose, these are typically called dosimeters. These can also be passive, but I'm only covering active (ie. electronic) ones.
  • But either device can often do both, it just may not be its primary function or accurate.
  • Ionizing radiation is typically measured in grays (Gy). And in this context of human body exposure, dose and dose rate are usually measured in sieverts (Sv) and its respective hourly rate (Sv/hr). In the past some regions roentgens (R) and their human body exposure roentgen equivalent man (rem) units are still common were common, but the definition of them has changed over time leading to it being less accepted. Grays are also a replacement for rads. Different units are used in different contexts or regions.
  • A sievert is the typical base unit, but numbers are typically displayed as microsieverts (µSv) or millisieverts (mSv), which are one-millionth and one-thousandth of a sievert respectively.
  • Devices can usually display in clicks per second or per minute in addition to eg. sieverts. A click corresponds to a detected event.
  • Randall Munroe of XKCD has a fun (not necessarily scientific) scale chart of various real world dose examples here.
  • Geiger counters do not detect measure non-ionizing radiation.
  • Geiger counters may provide false readings if exposed to UV-C light if they use a glass GM tube.
  • Geiger counters may provide false readings if exposed to high power radio interference. This is in the same way our PC speakers used to buzz moments before a 2G/3G phone call came in.

Additional Notes About Radiation

  • edit: Corrections about contrast agents thanks to u/Altruistic_Tonight18
  • Non-ionizing radiation cannot directly cause harm, but at high enough power levels it can cause rapid localized heating which can do damage.
  • Devices such as radios, cell phones, Wi-Fi access points, Bluetooth dongles, and microwave ovens all use non-ionizing radiation. They also all have strict power limits and/or shielding requirements.
  • That little mesh on the front of your microwave oven is literally small enough to physically block the large microwaves from escaping.
  • Standing in the sun will expose you to substantially more radiation than that of a cell phone. Which is why you should wear hats, sunglassess, and sunscreen.
  • CRT displays can actually leak small amounts of X-rays, especially if the brightness is high or the power supply is poorly regulated.
  • Being exposed to radiation does not directly make you radioactive, you must be contaminated somehow first.
  • MRI scans without contrast themself will not expose you to radiation.
  • X-ray, CT, and PET scans without contrast themself will expose you to radiation, but you will not become radioactive.
  • Scans with contrast radiopharmaceuticals will both expose you to radiation, and make you temporarily radioactive. The modern isotopes used usually have short half-lifes and can be expelled by the body within a week or two.
  • Radiocontrast agents themself are not radioactive, and are distinct from radiopharmaceuticals.
  • You may encounter a close friend or family member that is radioactive from medical tests: if they've already talked to you about such procedure, then they may be curious to visualize it on a geiger. Otherwise respect their privacy.
  • You may encounter complete strangers that are radioactive from medical tests, don't harass them or scare them, just ignore them like you do other strangers.
  • If you're out and about and your geiger goes off, there is near-zero reason to start scaring people around you or call emergency services.

My Usecase and Requirements

  • I have two primary uses:
    • be able to make sure nothing in my environment at home & work is unexpected
    • be able to be mindful of unusual objects when I'm out traveling in weird & fun places such as (hypothetically)
      • is that new scanning archway at the exit of the big box store actually X-ray or just cameras?
      • a spicy rock or boulder out on a trail
      • your friend wearing a "5G protection" pendant which turns out to be a chunk of Thorium
      • that posh restaurant which thought it'd be cool to serve food on Uranium glazed fiestaware
      • the poorly maintained X-ray machine at the dentist right next door to the coffee shop in the strip mall
  • My requirements are:
    • can actually detect radiation, but no need for real accuracy
    • pocketable
    • battery that can last a few days
    • affordable, ie. not $3,000

Available Contenders

  • Generic HFS-P3
    • Price: $35
    • Class: Bottom of the barrel
    • Type: GM
    • Measurement range: 0.08 µSv to 50 mSv
    • Detects: beta, gamma, X-rays
    • Size: about that of a highlighter/marker
    • Battery: claimed 50 hours / ~2 days, 400mAh internal cell
    • Display: basic OLED
    • Attachment: pocket clip
    • Note: no clicks
    • Purchase: Amazon
  • GQ GMC-300S
    • Price: $60
    • Class: Hobbyist
    • Type: GM, M4011 tube
    • Measurement range: 0.0 µSv to 327.99 µSv
    • Detects: beta, gamma, X-rays, 0.1 to 3 MeV
    • Size: thin brick
    • Battery: 14500
    • Display: basic LCD
    • Attachment: lanyard
    • Purchase: Amazon
  • GQ GMS-800
    • Price: $90
    • Class: Hobbyist
    • Type: GM
    • Measurement range: 0.0 µSv to 2 mSv
    • Detects: beta, gamma, X-rays, 0.1 to 3 MeV
    • Size: thick brick
    • Battery: 14500
    • Display: graphical LCD
    • Attachment: none?
    • Note: firmware can be replaced via the open-source (MIT) Rad Pro project
    • Purchase: Amazon
  • Better Geiger S2
    • Price: $150
    • Class: Hobbyist
    • Type: Scintillator
    • Measurement range: 0.0 µSv to 100 mSv
    • Detects: gamma, X-rays, 50 KeV minimum
    • Size: thick brick, 118l x 73w x 26h mm
    • Battery: claimed 50-90 hours / ~2-4 days, 2x AA
    • Display: detailed OLED
    • Attachment: none?
    • Purchase: Direct, Amazon
  • Better Geiger S2-Mini
    • Price: $150
    • Class: Hobbyist
    • Type: Scintillator
    • Measurement range: 0.0 µSv to 100 mSv
    • Detects: gamma, X-rays, 50 KeV minimum
    • Battery: internal cell
    • Display: detailed OLED
    • Size: thin brick, 89l x 45w x 19h mm
    • Attachment: none?
    • Purchase: Direct
  • Radiacode 102
    • Price: $250
    • Class: Hobbyist
    • Type: Scintillator, Csl (Tl)
    • Measurement range: 0.1 µSv to 1 mSv
    • Detects: gamma, X-rays, 0.02 to 3 MeV
    • Size: thin brick, 123l x 34w x 18h mm
    • Battery: claimed 200 hours / ~8 days, 1000mAh internal cell
    • Display: detailed OLED
    • Attachment: loop (carabiner, lanyard), armband, belt clip
    • Purchase: Direct, Amazon
  • Ludlum Model 25 (honorable mention)
    • Price: $200-300 used
    • Class: Professional
    • Type: GM
    • Measurement range: 0.02 µSv to 9.99 Sv
    • Detects: gamma?
    • Size: thin brick, 76l x 54w x 17h mm
    • Battery: claimed 6,000 hours / ~250 days, 2x DL2450
    • Display: basic LCD
    • Attachment: belt, lanyard, armband
    • Note: This is a proper dosimeter, not a counter. These can supposedly have their yearly calibration performed by Ludlum for $100. The 25 displays roentgens, the 25-1 variant displays sieverts. There is also a -IS (intrinsically safe) variant for use in hazardous environments, such as around flammable gasses. From what I understand their detection floor is purposely higher than typical background radiation. Actually water resistant.

My Choice

I ultimately ended up purchasing the Radiacode 102 for its higher sensitivity and broad featureset. I strongly considered the S2-Mini, but the RC102 was more polished for only slightly higher (relative) cost. The S2-Mini would've been my first choice if the firmware or hardware was open-source. The others I considered too brick like to be comfortably pocketable. I may still pick up a HFS-P3 for its small size and a GMS-800 to try the Rad Pro firmware in the future.

Hardware and Menu Interface

It is what you expect for build quality. It has no real form of water or shock resistance. The menus are quite intuitive and functional and feature handy quick shortcuts. I think the loop on the case could be a bit thicker.

Testing

I first tested it against the only known radioactive source I had, a smoke detector with Am-241, and it expectedly tripped the default alarm threshold when in direct contact. Then I did the fun part of checking everything in my home, of which I did not find anything of concern. Although the granite in my bathroom clicks slightly higher than the granite in my kitchen. I was particularly interested in checking some suspicious reflective hats I had gotten a few years ago, but those too were seemingly fine.

Battery

I charged my RC102 four and a half days ago as of this writing, yet it still has 48% battery left, which is on par with their claims. I should note I do toggle the Bluetooth function as needed, since it otherwise constantly broadcasts and has no passcode. Edit: It is now six and a half days and at 28%.

Radiacode App

I do not recommend using the iPhone app since it phones home to Yandex and iOS provides no real mechanism to block internet access. They provide direct APK downloads for the Android app and it works fine, excluding the map function, on GrapheneOS with internet permission revoked. Even the firmware updates are bundled in the app so that works too. There is also thankfully no account function/requirement. So this is a very cool bonus feature for seeing rate and spectrum graphs as well as identified isotopes. Data access is also possible via USB.

Every Day Carry (EDC)

While the RC102 easily fits in a pocket, I opted for the $10 silicone protective case with carabiner and wore it clipped to my jeans pant loop. It dangles around, but is light enough to not bother me, although you must be mindful to not sit on it or have it eg. horizontal when closing your car door. The acid green color I chose also adds a tiny splash of color to any outfit. I spent a few hours in a particularly large concrete building and it was neat to see the background radiation nearly 2x higher indoors compared to outside of it. Otherwise I've yet to come across anything actually unusual. Do I actually plan to EDC a geiger long term? Unlikely.

Conclusion

Did I satisfy my childhood wants of a geiger? Yes. Should you EDC a geiger? Probably not. Should you own one? If you take some time to learn a basic understanding of them, I definitely think there is some benefit in having one handy.

Comment on this: Fediverse, Hacker News, Reddit

Fedora 42 /boot out of space2025-09-05

Kernel updates failed to install on one of my servers today since /boot was full. I noticed the initramfs images were 4x larger than on my other systems. Turns out Fedora Cloud includes the dracut-config-generic package by default, which generates them with all modules bundled causing the large size. Fedora also defaults to a 1GB /boot and 3x full 6.16.x kernels seemingly no longer fit in that config. Unrelated but dracut (since F42?) will also use zstd if installed. So steps below if you hit this:

  • dnf remove kernel*-6.16.2-200.fc42.x86_64 # remove old kernels to free up space
  • dnf remove dracut-config-generic # switch to hostonly=yes
  • dnf install zstd # compress initramfs with zstd
  • dracut --regenerate-all --force # regenerate current images
  • dnf update # resume normal updates

Google Aiming for Gold2025-08-27

Google is currently speedrunning the Android Open Source Project (AOSP) into the ground even in spite of the current antitrust litigation. Below is a recap of the past few months since some bits are being overlooked.

  • Google announced that after March they would no longer be publishing the source code for the in-development versions of Android. These branches were frequently used by systems for cherrypicking bug fixes to the stable releases before Google actually released them.
  • Android 16 was released in June. Google made the stark decision with this release to no longer consider Google Pixels to be the AOSP reference devices. Pixel device trees and kernel sources with git history are now no longer available. This makes it much more difficult for AOSP forks to support Pixels because they will have to make their own device trees. You can read this thread here which has comments from GrapheneOS, CalyxOS, and LineageOS developers. See also additional information from GrapheneOS and CalyxOS.
  • Source tags for the July and August Android Security Bulletins (ASB) have not been published. I'll restate that for clarity, there have been no public AOSP 16 source code releases for two months now.
    • edit 08-28: GrapheneOS has since disclosed that Google will no longer be providing public monthly branches and is instead switching to 1 yearly major upgrade + 3 quarterly security/bug updates, with a very small monthly ASB that is handled separately from a branch for select security issues.
    • edit 09-09: The August ASB patches still have no links. The September ASB patches have links but are all A15 tags. The A16 September QPR sources also have not been published. GrapheneOS has elaborated on this here.
  • Google announced concrete plans to enforce government ID verification of developers and companies for apps not in the Play Store. This would likely be enforced by the proprietary Google Package Installer which they mandate for certified Android devices. This works by having (government ID verified) developers register their app package ID and associated signing key via the Play console. They notably plan to enforce install limits on apps that share a package ID of an existing registered app. It is furthermore currently unclear if they will allow developers to sign their own same package IDs with multiple keys without install limits.
    • This will for example likely significantly impact all apps (3,896) on F-Droid.org that both don't use reproducible builds (746) and don't use a unique F-Droid.org package ID (49) (-10 for overlap) which accounts for roughly ~79.85% of their current index.
    • Developers in sanctioned regions will be inherently prohibited from this program completely blocking use of their software.
    • There is no mechanism declared for unmaintained apps, which directly hinders archival efforts and their future use.
    • edit 09-18: This also means an internet connection is required to install apps.
    • If you are a developer/organization please consider voicing any concern here.

These issues are rapidly stacking on top of others, such as the years long anti-competitive behavior of Google aggressively pushing developers to adopt Play Integrity which blocks non-certified systems even if they provide substantially added security measures such as GrapheneOS. As a short aside you might think Google doesn't consider GrapheneOS to be "big enough", except Play Services (GMS) actually explicitly checks for it and allows their Chromium-fork, Vanadium, to perform privileged FIDO2 operations.

At this point I would not be surprised if Google does a rug pull on bootloader unlocking for Pixel devices within the next year. To date no one has made a working bootloader unlock bypass for even the first generation (Verizon CID) Google Pixel from nearly nine years ago.

Moving forward, for those currently on stock Android please consider an aftermarket system like GrapheneOS. As for longterm, while the situation of "Linux phones" such as postmarketOS is extremely rough right now in terms of both usability and security, I encourage everyone to give them a try (on a PinePhone or SDM845 device exclusively) and contribute their skills if possible because we must have a viable third option.

The best outcome would be for AOSP (and Chromium) to actually become true reference implementations controlled by a neutral joint party that caters to everyone's interests. But that is just fantasy, Google is playing 4D chess and will vigorously seek to ensure control over their precious jewels.

Comment on this: Fediverse, Hacker News, Privacy Guides Forum

Hard Drives have TBW limits too2025-08-25

Every so often people talk about drives and how SSDs are worse because they have a terabytes written (TBW) limit, except hard drives have them too! Most manufacturers however either just don't publish the ratings or use a different term. The term is usually a workload rate limit (WRL). You can read more about this from WD here and from Seagate here. The WRL can be roughly converted to a TBW rating by multiplying the WRL by the years of the warranty. Notably this number seems to not scale with drive size like it does with SSDs.

Web Server Upgrade2025-08-14

I've migrated the web server to a new VPS. I was on the last one for over five years, but the performance has been quite abysmal for a while now due to its ancient Sandy Bridge era host. The new VPS has 2x cores (of Zen2), 6x more RAM, dramatically more IOPS, slightly faster network, and checksumming (ext4 -> btrfs).

Jellyfin Corruption2025-08-04

Yesterday I started streaming from my Jellyfin instance and some time in it completely went away. Turns out the VM disk filled up. After resizing it on the host and guest, the service still failed to start. The error was System.InvalidOperationException: There is an error in XML document (0, 0).. After searching most people say the whole database is corrupt, but in this case it was just the migrations.xml file, which I restored from backup and it started up correctly afterwards. The future Jellyfin 10.11.0 appears to add a check to prevent starting when less than 2GB of disk space is available.

As for why it ran out of disk space, streamed video was being remuxed for compatibility which was taking up disk space and the default option does not immediately remove old parts unless the setting Dashboard > Playback > Transcoding > Delete segments is enabled. Additionally it writes to the actual disk by default instead of /tmp since most systems likely lack enough space there.

Ryzen Laptop Suspend Issues2025-08-03

I have two identical Ryzen 7530U laptops and one recently started immediately resuming when suspended. After a few hours of troubleshooting I still have no idea why it does this. The AMD s2idle debug utility reported it as a PS/2 wakeup event. I tried setting gpiolib_acpi.ignore_interrupt=AMDI0030:00@44 kernel command line argument to mitigate it but that didn't work. I did find that setting acpi.ec_no_wakeup=Y mitigated the issue successfully without any other noticeable impact.

LUKS Iterations2025-08-02

Quick reminder to check/increase the iterations on your LUKS keyslots. Default autodetection can for example result in quite low settings such as 3 iterations at 512MB cost if your CPU is slow. I recommend setting 16+ iterations at max 4GB cost. Do note that this can cause unlocking to take 15+ seconds.

cryptsetup luksConvertKey /dev/nvme0n1p3 --pbkdf argon2id --pbkdf-memory 4194304 --pbkdf-parallel 4 --pbkdf-force-iterations=16

Invizible v2.5.4 beta security issue2025-07-21

I was reviewing through some projects yesterday and noticed this commit in Invizible. This change deletes the Tor state file on Tor connection failure. However this state file stores the list of chosen guards to make guard selection attacks harder. This could allow a network attacker to easily force a client onto specific guard nodes. After some back and forth @Gedsh reverted the commit. It only affects this sole beta version.

Comment on this: Fediverse

Resigning ucode to mitigate security issues2025-07-14

Today's real-ucode update now includes an optional subpackage amd-ucode-firmware-resigned which contains new microcodes resigned with the old format to allow loading on pre 2025-01 BIOSes. This is necessary to mitigate security issues such as the recent TSA vulnerability on systems without vendor updates.

  • Remove the exclusion if you had one from /etc/dnf/dnf.conf first
  • Update package list: dnf install https://divested.dev/rpm/fedora/divested-release-20250714-1.noarch.rpm
  • Update real-ucode: dnf update --refresh
  • Swap them: dnf swap amd-ucode-firmware amd-ucode-firmware-resigned
  • Update initramfs: dracut -f
  • Disable hash verification: grubby --update-kernel=ALL --args="microcode.amd_sha_check=off"
  • dmesg | grep microcode >> before
  • lscpu >> before
  • Reboot to apply new microcode
  • dmesg | grep microcode >> after
  • lscpu >> after
  • Compare: meld before after
  • Enjoy!

Comment on this: Fediverse

ECH rollout stats2025-07-08

Fresh results of ECH availability on the top 10k domains (as ranked by Open PageRank) is available here. I've updated the script to also discern between hosted on Cloudflare or not.

Comment on this: Fediverse

Packaging Udderance2025-06-26

Today I spent a few hours packaging Udderance as an Android app for true/reliable offline usage with all assets bundled. I had some small issues encountered during the process and noted them below.

  • My assets directory was getting clobbered in the URI to load. This was annoying but easy to workaround by intercepting and rewriting it.
  • The Android WebView does not support using the speechSynthesis API for TTS. Fine, whatever. I'll just strictly enable Sherpa.
  • Sherpa wasn't loading, but then I remembered I had the JIT disabled by default for apps on GrapheneOS. Toggling that and Sherpa works.
  • When Udderance detects it is running as a PWA, it hides the header & footer. I adjusted that to handle running from Android app assets to match. But strangely then the page was getting cropped off by the status and nav bar. I worked around this by replacing them with line breaks instead.
  • I then remembered that I'd have to compile Sherpa from source to meet the F-Droid inclusion criteria. So I did. However the fdroidserver instance fails to compile it with the Emscripten toolchain available in Debian repositories and generated a corrupted binary when using Emscripten from git. So I instead dropped Sherpa for this and manually proxy the TTS requests from the page to the system.
  • Then fdroidserver was failing to run the scripts to assemble everything. Turns out Debian's default dash shell does not support arrays or &> redirection and bash doesn't run aliases by default when non-interactive.

I've submitted it to F-Droid for inclusion, and it should hopefully land soon!

Comment on this: Fediverse

Security Sliders2025-06-25

Long ago in August of 2021 I disabled the JIT for Firefox in Brace. During testing I realized that the browser needed to be restarted for this to take effect.

Back in October of 2024 I was made aware of how the Tor Browser security slider changes these settings without a restart, preventing them from having effect and also creating a fingerprinting mess. For months after this every time I used the slider myself I was reminded of this. The issue was made public in March, but was still unfixed. It concerned me a bit so at the end of April I noted this issue to Jonah of Privacy Guides so they could publish a writeup and put impetus on Tor Project to fix it. Yesterday's Tor Browser update, version 14.5.4, finally fixes this years long issue on both desktop and Android platforms.

Tor Project had this issue explicitly documented since at least May of 2024 and it was likely known offhandedly for years longer. I won't use this against them, but more so as a call to the community to get more involved. If you have the time and skills please consider contributing to the Tor Project, their mission is critical and everyone can benefit from it.

Comment on this: Fediverse

Moving Against GenAI2025-06-23

I've a new zebra profile picture, crudely hand drawn by me. It took quite a few steps with GIMP to cleanup/convert from photo to lineart, I may make a short tutorial on that in the future. I've also removed the quick overviews from Kairoscope in favor of proper sources.

Archiving YouTube Channels2025-06-21

Over the past few years YouTube has been adding more and more restrictions in place to watching videos ranging from fake buffering to adding DRM to completely blocking playback. I've used Tor Browser for years to watch my favorite content creators, but that has been impacted by these changes which made even short videos a tedious chore. So I started instead just bulk archiving my favorite channels, both as a way to watch them normally and as a way to preserve their content in the event YouTube decides to more aggressively enforce their restrictions (eg. mandatory account requirement). If you're reading this you've probably heard of yt-dlp (or its predecessor youtube-dl), however the defaults will miss quite a bit of necessary extras, so below I document strongly recommended options as well as some tips. I will get straight to the point with the whole command.

yt-dlp --format 'bestvideo+bestaudio/best' --merge-output-format=mkv --embed-chapters --embed-metadata --embed-thumbnail --convert-thumbnails jpg --write-subs --write-auto-subs --sub-langs=en --write-description --mtime --download-archive 0COMPLETED --batch-file 0SOURCES

OK so how to use this command?

First have your top level directory which you will do the processing in. Save that command in a file eg. archive.sh, then create a folder for each given channel you want to save. In each channel folder you will want to create the 0SOURCES file containing the link to their channel (eg. https://www.youtube.com/@CHANNEL_HERE). Then simply invoke the script: sh ../archive.sh.

What do the options do?

  • --format 'bestvideo+bestaudio/best': Prefer the best quality video and best quality audio by merging two distinct streams, or falling back to best singular stream if unavailable.
  • --merge-output-format=mkv: Put everything into an MKV container.
  • --embed-chapters: Adds chapter markers to the MKV.
  • --embed-metadata: Adds the video description, release date, and ID to the MKV.
  • --embed-thumbnail: Adds the thumbnail to the MKV.
  • --convert-thumbnails jpg: Convert the thumbnail from Google's default WebP to JPG, which is better supported by media players.
  • --write-subs --write-auto-subs: Write subtitles, prefer real ones with fallback to automatically generated ones.
  • --sub-langs=en: Specify the language you want for subtitles. List of codes here.
  • --write-description: Write the video description to a .description file.
  • --mtime: Adjust the output file timestamp to match to the server's recorded time of the content.
  • --download-archive 0COMPLETED: This keeps a list of every video that has been downloaded to prevent rechecking/redownloading them each run.
  • --batch-file 0SOURCES: This specifies what links to download.

Any tips?

  • Always update yt-dlp first! Some distros fall behind, so best to just use their GitHub release and run yt-dlp --update before continuing.
  • With the external .description and .vtt (subtitles) files, you can grep through them as a rough method of full text search of a channel!
  • Setup a Jellyfin instance and add your top-level archive directory as a 'Home Videos and Photos' collection, and it will put each channel into its own sub-folder. This lets you correctly sort them by release date and track your watch progress/history.
  • If you're downloading over Tor using torsocks you must use the standard yt-dlp binary, as their yt-dlp_linux binary is statically linked which is incompatible and will bypass torsocks.
  • Sometimes you can download videos but not their subtitles depending on your IP, so watch out for that.
  • Sometimes if a video was recently added, the highest quality format is unavailable, even if it shows up on the website.
  • You can sometimes find unlisted videos by downloading their playlists, duplicate the channel link in 0SOURCES and append /playlists. Be sure to comment it after, as playlist processing can easily get you rate-limited.
  • If yt-dlp outputs that a video is age-restricted or private you can see if archive.org has a copy, add https://web.archive.org/web/https://www.youtube.com/watch?v=VIDEO_ID_HERE to your 0SOURCES file. Be sure to comment it after.
  • If you have a slow Internet connection you might want to rate limit the process so as to not make your Internet unusable, add the --limit-rate 4M option, changing it to however fast/slow you want it.

Comment on this: Fediverse

Converting HTML to Markdown2025-06-20

I needed to do this earlier and pulled pandoc out, except the output was not great. Turns out you need to specify markdown_strict instead. If you have tables you may also want to to append +pipe_tables to the output format.

pandoc --wrap=none --from html --to markdown_strict page.html --output page.md

Kairoscope Updates2025-06-20

I've prioritized and added more reading sources, as well as tidied up the pages.

Welcome2025-06-19

I figured it was about time I started a blog. I've backfilled it a little from my recent toots, along with some extras sprinkled in there.
I've also made a handful of updates to the website the past few days, especially the homepage. And I've added a 'GenAI usage disclosure' section, which I encourage others to do as well.

Comment on this: Fediverse

Dark Mode2025-06-19

I've added dark mode to my current websites. I still use mini.css which was last updated in 2018 and it predates prefers-color-scheme. So I manually merged the colors from mini-dark.css into mini-default.css and minified it again. My last attempt years ago was just loading both style sheets and setting them using the @media rule but that wasted bandwidth.

Comment on this: Fediverse

Udderance Updates2025-06-18

  • added 14 more phrase boards after implementing a Open Board Format converter
  • made sub menu navigation cleaner by collapsing others
  • added support for Escape key to close dialogs/submenus
  • generated the remaining 5647 translations, still to be imported

Comment on this: Fediverse

Freshly Picked Onions2025-06-17

Back in January when I tore down all of the DivestOS infrastructure, I also took down my onion services. Today they are back and with nice vanity addresses. I was reminded to do this after seeing someone with an awesome purple roots Tor t-shirt.

  • divested.dev: divestedqc3zjycupgdvmpzzlxtw6jkxsin2xo4g4nxzsu77jknygxqd.onion
  • kairoscope.org: screenerivy55uviqfvyqtx5sjwxbeuwairfusxedszywr5p6g7us6qd.onion
  • udderance.app: udderaacpou4mku6xptn7ebdzgzw63mtz6jnyafk6jd43xoiu6ymbbqd.onion

Brace Updates2025-06-16

Fedora just shipped chrony 4.7 today and Brace's previous override caused the service to be terminated by systemd due to the upstream service file switching from forking to notify type.

Comment on this: GitHub

Cables Fail - Part 22025-06-15

Recently my friend swapped out one of their 1Gb switches with a 10Gb switch, but it refused to link up with their other 10Gb switch. After some troubleshooting today, it turned out to be the cable linking them. Despite being CAT 6A, it could only successfully negotiate at 1Gb. I wouldn't be surprised if there were carrier errors at 1Gb too, but I didn't bother checking logs.

Udderance Updates2025-06-15

  • Boards are now machine translated into 35 languages
  • Pictograms now work in Safari
  • Phrase buttons are now in a dialog view instead of a collapse view for quicker navigation
  • Phrase board generation has been overhauled to allow for sub boards as a prerequisite for importing Open Board Format files
  • Many homepage improvements: features, compatibility matrix, explanations, etc.

More information on the choice of languages: These added 35 cover every TTS voice that Apple provides for different languages. So feel free to pick a matching board and voice and use it entirely in your native language!

Comment on this: Fediverse

Udderance Updates2025-06-14

Just added pictogram support for 700+ phrases to Udderance thanks to the Mulberry Symbols project. Was easier than I expected, although my server is having a difficult time serving them up quickly. I disabled compression of SVG files to help, but I will need to pre-compress them and adjust my Apache config to handle that.

Comment on this: Fediverse

Udderance Updates2025-06-13

  • Support for dynamic phrase board generation and presets
  • A board preset cloned from Cboard AAC
  • Improved voice list handling
  • Support for Sherpa TTS via WASM for more voices and as a fallback when WebSpeech is unavailable (many Linux distros don't seem to setup/enable Speech Dispatcher)
  • Tiny additions like a button to clear the history log
  • Various bug fixes

Comment on this: Fediverse

iPhone Review2025-06-12

Notes after daily driving an iPhone for six months after having spent a decade maintaining my own Android distro: ios-review.txt

Comment on this: Fediverse, Privacy Guides Forum

I've published some recommended settings lists for GrapheneOS and iOS.

Comment on this: Fediverse, Privacy Guides Forum

Launching Udderance2025-06-10

Happy Tuesday! 🛸🐮
Here is another small project I made yesterday.
Udderance is a text-to-speech (TTS) based augmentative and alternative communication (AAC) tool with a focus on simplicity and cross-platform usage.
It is meant to be installed as a PWA (via your browser) on your phone.

Comment on this: Fediverse, Privacy Guides Forum, Hacker News

Strange ZFS behavior2025-06-07

I recently added some drives to a ZFS pool. When I did an rsync to the dataset, it had seemingly recopied some directory metadata despite them not actually changing. I think I've observed this previously, but didn't document it last time.

Summarizing a YouTube video2025-06-04, License: CC0

Someone on a forum asked for a summary of a YouTube video so I figured I'd see how well Ollama/Gemma3 can do it. I used some bash fun to convert the subtitles, as I found existing tools overcomplicated. You'll also need to increase your Ollama context limit from the default 4k to 16k or higher if the video is particularly long.

videoID="[YOUTUBE VIDEO ID]";
yt-dlp --write subs --write-auto-subs --skip-download "https://www.youtube.com/watch?v=$videoID";
cat "*$videoID*.vtt" | grep -v "<>" | grep -v "\-\->" | grep -v "><" | awk '!seen[$0]++' | tail -n +4 | tr '\n' ' ' > "/tmp/transcript-$videoID";
ollama run gemma3:12b-it-qat "Please write a breakdown and summary of the following, ignore any sponsorship segments: $(cat /tmp/transcript-$videoID)" > "summary-$videoID";

Donations2025-05-29

I removed the donation options six months back when I shuttered DivestOS. Today they are available again for those of you who are interested in financially supporting my work.

Kairoscope Updates2025-05-29

There are now 21 tests and it now has a dedicated domain.

Comment on this: Fediverse

Launching Kairoscope2025-05-27

May is mental health awareness month, so to promote it I’ve implemented a handful of mental health screeners in the form of completely client side tests. Have fun!
Please let me know if you encounter any issues with them.

Comment on this: Fediverse, Privacy Guides Forum, Hacker News

Cables Fail - Part 12025-05-20

I've had many cables fail over the years, so I figured I'd start documenting them. I just swapped out all SATA cables on my NAS after one drive started spewing UDMA errors a few days ago. Said problematic cable was untouched and working for ~3 years and then decided to retire early.

Fedora iptables fun2025-04-28

Fedora pushed out an iptables update today which altered some paths. firewalld, Docker, and other tools broke. Chaos ensued.

CAA Record Clipping2025-04-21

I've started migrating to Porkbun since Gandi has yet to cease constantly hiking their prices. After I moved my first domain over I quickly hit an error where CAA records were being clipped off. Porkbun was quick to help here: It seems Cloudflare DNS (which Porkbun depends on) is quite strict in their parsing and it must not contain any spaces. I later made a script to bulk test/verify DNS records are set as expected, I'll be publishing it eventually.

Bounds checking in hmalloc2025-03-21

I've started working on a feature in the GrapheneOS hardened_malloc project that enables system wide buffer over/under-flow detection by overriding common block operation functions (eg. memcpy/memset) and performing size checks against the known sizes available in the malloc's metadata. It works quite well system wide in my testing, but still needs some extra work. @cgzones has been a kind help to me in making it comprehensive and accurate. This feature provides substantial security benefits to traditional (Intel/AMD) systems.

Comment on this: Privacy Guides Forum

SCFW3 Updates2025-03-20

trash.sh now blocks many known AI crawlers and the ancient versions list has been refreshed.

Comment on this: GitHub

Brace Updates2025-02-18

  • JavaScript JIT is now disabled for WebKitGTK and GJS thanks to @RKNF404
  • Tweaks to browser extension overrides

Comment on this: GitHub

Ending DivestOS and apps2024-12-23

Thank you everyone. Full announcement

Comment on this: Fediverse, Privacy Guides Forum, Hacker News, F-Droid Forum, Techlore Forum