The SDK hands the current value over before Watch returns, and the follower had no entry for it yet, so the first value was dropped. A silent watch is now told from an expired key and watched again rather than polled, each write takes its own temporary file, drop-in directories are no module's, and an entry added to the path check's lists is refused unless its line says why.
i3status-rust
The bars as a module (novox/hq ADR 0208, research 026/05).
- Installs
i3status-rust. The update block'scheckupdatescomes frompacman-contrib, which thepacmanmodule installs on every node; two modules declaring one package is refused at composition. Claims the mesh'snode-barseat (no verbs yet, ADR 0208 §2) and renders the blocks other modules contribute to it (ADR 0255, below). Requiresx11-displayon its own machine: its bars are i3bar's. - Owns
~/.config/i3status-rust/, both bars (top-bar.toml,bottom-bar.toml) and their icon set (icons/custom-icons.toml). - Places the two
bar { }blocks as its own i3 drop-in,~/.config/i3/config.d/60-i3status-rust.conf:- the bottom bar shows the machine;
- the top bar shows the focused window and the tray, on the primary output.
- Places two programs in
~/.local/bin:i3status-updates, the pending-updates block;i3bar-watchdog, which brings back a bar that died.
- Starts the watchdog once per session, from the session's start (the
xinitrcslotnormal). It ends with the session's own process.
Tools
| tool | does |
|---|---|
i3status_rust_reload |
the running bars re-read their files (i3status-rs restarts in place) |
i3status_rust_blocks |
each bar's blocks in order, kind and settings, and what each shows now (one run of the bar) |
i3status_rust_block_run |
one block alone, with the bar's theme and icons, to see what it shows or why it errors |
i3status_rust_themes |
the themes on the machine and the one each bar uses |
Blocks other modules contribute (novox/hq ADR 0255)
A block that depends on the machine's hardware is not written here. The module that knows the hardware
contributes it to node-bar as data that says what it shows, and this module renders it:
- What a contribution says: which bar (
bottom,top), which place (resources, beside the processor, memory and disks;status, beside the sound), an order from 0 to 99, what it shows (battery,command) and that kind's options. Nothing in it is i3status-rust's. - How it is rendered: the claim's
renders.blockis a template (its source isfiles/block.tmpl) that turns one piece into a[[block]]. The controller runs it and places the result where each bar says${contribution:node-bar:block:bar=…,place=…}. Each bar places both of its places once; the catalogue check refuses a holder that misses one. - Where it applies: a contribution may name a capability the machine must report. The
powermodule's battery block namesbatteryand its power-draw block namespower-meter, so the laptop's bar gets both and a desktop only the power draw. - A value from the bus: a block that
shows: statenames another module's state, such aspower.draw. The mesh grants this module the read, because a module on its machine offers it; the manifest names no other module. This module's bundle watches it and leaves the value's text in the account's runtime directory (i3status-rust/values/), dated with the value's ownat, and the block runs~/.local/bin/i3status-value, which prints it, or nothing when it was measured more than 30 s ago, so the block hides a value frozen at its source. A watch that says nothing for a minute is looked at once: a key that is gone has expired at its source and shows nothing; a key still there means the watch died, so it is watched again and that is logged once. A refused watch is logged and tried again, and a value no bar shows any more is no longer kept. The bus grants this module the one key each block shows (the machine's own unless the block names another,[a-z0-9-]). No file of another module is read: modules talk over the bus. - The battery is i3status-rust's own battery block, which reads the kernel's power-supply class itself: the bar reading the machine, not another module.
Still left out:
- The GPU's load, the laptop's AMD block (commented out for NVIDIA on the desktop). A generic GPU block belongs to a generic module, which does not exist yet; a GPU's power is in the power draw.
- Three Bluetooth headsets by hardware address: one person's devices, not the bar's.
The second way the README once offered, blocks with i3status-rust's if_command that hide themselves on
a machine without the hardware, was rejected: the knowledge would stay in the bar, decided at run time.
What it improves on what was found
- The weather needs no key. The found block used a weather service with an API key written in plain text in the file, and a fixed city. It now uses the Norwegian Meteorological Institute, which needs no key, located automatically.
- The update count is the module's own, adopted from the operator's
~/scripts/pkg-updates. It counts AUR updates only where an AUR helper is installed. Clicking it lists the updates in the launcher's menu, instead of a theme from a cloned theme repository. - The memory is what programs hold (
$mem_used), not$mem_total_used, which counts the cache the kernel gives back when asked and read 96 % on a machine at 73 %. It is the figure thememory-pressuremodule judges by (changed 2026-10-08). - The faces are JetBrains Mono Nerd Font, not Hack.
- The watchdog is no longer a hand-enabled user unit that ran on one workstation and not the other. It runs on both, once per session, and ends with the session.
- The docker block's click, which ran a program installed on neither machine, is gone.
What it leaves as found
~/.config/i3status-rust/scripts/(a mouse battery script for one device).~/scripts/pkg-updatesand~/scripts/i3-bar-watchdog, replaced here.- The user unit
~/.config/systemd/user/i3-bar-watchdog.serviceand its enablement link.
Migration (ADR 0182)
- Revoke the weather API key that was in the found
bottom-bar.toml. It sat in plain text on both workstations. The first push keeps the found file once and then writes the module's, which has no key. - Before the first push, on the laptop:
systemctl --user disable --now i3-bar-watchdog.service. Otherwise two watchdogs run. Then delete the unit file,~/scripts/i3-bar-watchdogand~/scripts/pkg-updates. - Until the
i3module carries the main configuration, the found~/.config/i3/configstill has its own twobar { }blocks, and i3 shows four bars. Thei3module's configuration has none.
Blockers
node-bar,x11-displayand thexinitrcslot are ADR 0208's. Until the controller knows them,mctlreads them as unknown.- The watchdog would be a user unit once user-scoped units ship (mesh-host #72). It is not, because it runs per session and ends with the session, as a session-start line already does.
pacman-contribis thepacmanmodule's, which took it over as foreseen: a package is declared once per node.
Its i3 lines are a contribution (changed 2026-10-05, novox/hq ADR 0212)
The module no longer writes a file into i3's config.d. Its window-manager lines (the source is still
under files/i3/ where it had one) are a contribution to node-display-session. The i3 module places
them in its own configuration under a # <module> line, so this module depends on a window manager
being assigned beside it.