OpenRiot v7.9.9 — Self-Copy, Self-Doubt, Self-Respect

“The only thing worse than a bug you can’t find is a bug that finds itself.” — The OpenRiot Crew, watching fsutil.CopyFile truncate colors.toml to zero bytes because the source and destination were the same file


Release Overview

v7.9.9 is the release where we discovered that CopyConfigs() was deploying files to the same path they already lived in, O_TRUNC was doing its job, and suddenly every template had "" for every color. The polybar was blank. The rofi was blank. The settings menu looked like a CSS file that gave up.

We fixed it. Then we made Helix dynamic. Then we made the purple cluster on the right side of the polybar actually purple instead of “purple, I guess.” Then we made the settings menu border purple so you know you’re in Settings and not Apps or Games. Then we documented the entire color architecture so nobody ever has to learn this lesson twice.

v7.9.8 was pixel-perfect. v7.9.9 is self-aware.


The Self-Copy Bug

Root cause: Three rules in packages.yaml copied config/icons/*, colors.toml, and docs/* into ~/.local/share/openriot/config/... — which is exactly where they already live in the git checkout. fsutil.CopyFile() opens the destination with O_TRUNC, then copies from the source. When they’re the same file, the source is now empty. Empty TOML → blank template values → broken polybar, broken rofi, broken everything.

Fixes:

  • Removed the self-copying rules from packages.yaml
  • Added filepath.Clean(src) == filepath.Clean(dest) guard to fsutil.CopyFile() so this can never happen again
  • Updated docs/Colors.md with an entire Derivation Architecture section explaining why you must never target ~/.local/share/openriot/... from CopyConfigs()
File Change
install/packages.yaml Removed self-copy rules for icons/*,
  colors.toml, docs/*
source/fsutil/copy.go Self-copy guard with filepath.Clean
docs/Colors.md Full Derivation Architecture docs

Dynamic Helix Colors

The Helix theme (config/helix/themes/openriot.toml) used to be static. Hardcoded hex values. Inherits from ao. When you changed colors.toml, Helix stayed the same color it was in 2023.

Now it inherits term16_dark and overrides the entire [palette] with keys from colors.toml:

  • blackBaseBG
  • redSemanticError
  • greenAccentFG
  • yellowSemanticWarning
  • blueSemanticInfo
  • magentaExtendedPurple
  • cyanSemanticCyan
  • whiteBaseFG

Run openriot --helix-setup to render the template. Or just run curl -fsSL https://OpenRiot.org/setup.sh | sh and it happens automatically.

File Change
config/helix/themes/openriot.toml.tmpl NEW — term16_dark +
  dynamic palette
config/helix/config.toml theme = "openriot"
source/helix/helix.go NEWSetup() renders template
source/commands/commands.go --helix-setup registered
source/commands/helpers.go --helix-setup in dynamic config loop
install/packages.yaml Removed preserve_if_exists for helix/*

Polybar Purple Cluster

The right-most group of polybar modules — screenrec, settings, power, lock — all use ExtendedPurple. It was #8B7CF6 (slightly muddy). Now it’s #A78BFA (brighter, more vibrant, actually reads as purple in daylight).

File Change
config/colors.toml extended.purple#A78BFA

Settings Menu Border

The settings rofi menu used theme.GetAccent() for its border — which is green (#9ECE6A), the same color as the apps menu and games menu. You couldn’t tell which menu you were in.

Now it uses theme.GetPurple() (#A78BFA). You know it’s Settings because it looks like settings. Purple is the color of configuration.

File Change
source/theme/colors.go GetPurple() helper added
source/settings/settings.go GetAccent()GetPurple() for border

APM / Power Management

The apmd flags in packages.yaml were just -A (adaptive performance). Now they’re -A -a -z 5:

  • -A — adaptive performance mode
  • -a — ignore BIOS suspend requests when on AC power
  • -z 5 — auto-suspend when battery drops below 5%

Unplugged and idle? The screen locks. Fifteen minutes later, the system sleeps. Because xautolock and apmd are a team now.

File Change
install/packages.yaml apmd flags -Aflags -A -a -z 5

The Music Player, and the Music We Love

OpenRiot ships with rmpc — a Rust TUI client for MPD — and a single alias that makes it effortless:

alias music='rmpc'

Type music in any terminal. Your library is there. No GUI. No bloat. Just your collection, indexed, searchable, and fast.

What’s in your ~/Music matters. Ours has:

  • Alkaline Trio — because some of us grew up in basements
  • Barenaked Ladies — because Canada understands irony
  • Beck — because Odelay is a verb now
  • Bruce Springsteen — because highways exist
  • CAKE — because the distance is a song, not a problem
  • Cat Stevens — because sometimes you need tea and a guitar
  • Chris Isaak — because Wicked Game never left rotation
  • Counting Crows — because August was infinite once
  • Cracker — because Low has the only correct tempo
  • Dave Matthews & Tim Reynolds — because you need at least one live album
  • Dido — because Trip Hop was a real thing
  • Foo Fighters — because Dave Grohl is the most consistent human alive
  • Gorillaz — because Damon Albarn never stops
  • Green Day — because Dookie is a document of a specific era
  • Guns N’ Roses — because Appetite is perfect
  • Jack White — because distortion is a lifestyle
  • Lou Reed — because Walk on the Wild Side is three chords and truth
  • Macklemore — because Thrift Shop is about OpenBSD hardware philosophy

That’s just what’s visible. There’s more. There’s always more.

Press Super+Shift+K or type music. MPD is already running. The FIFO is at /tmp/mpd.fifo. cava is reading it. The visualizer is green.


🧾 Files Changed

File Change
config/helix/themes/openriot.toml.tmpl NEW — term16_dark +
  dynamic palette
source/helix/helix.go NEWSetup() renders Helix theme
config/helix/config.toml theme = "openriot"
config/colors.toml extended.purple#A78BFA
source/theme/colors.go GetPurple() helper
source/settings/settings.go Settings border → purple
install/packages.yaml Removed 3 self-copy rules; apmd flags
  -A -a -z 5; removed preserve_if_exists for helix
source/fsutil/copy.go Self-copy guard
source/commands/commands.go --helix-setup registered
source/commands/helpers.go --helix-setup in render loop
docs/Colors.md NEW — full color architecture docs

🗣️ Final Words

“v7.9.8 made the launcher icon look like it belonged. v7.9.9 made sure the launcher icon actually had colors to render with.”

No more self-copies. No more blank templates. No more wondering why your polybar looks like a Windows 95 error dialog. The colors are real. The music is playing. The battery knows when to sleep.

— The OpenRiot Crew

“We fixed a bug that was copying files to themselves. If that doesn’t describe software engineering in 2026, nothing does.”