Automation
AI
Test Automation
A Security Indicator Must Refuse to Lie: Building Omaudit Status for Omarchy

A Security Indicator Must Refuse to Lie: Building Omaudit Status for Omarchy

6 min read
🎯

The short version

  • Omaudit Status is a Quickshell companion for Omaudit, not a second security scanner.
  • It turns validated audit results into green, amber, red, or dim/error shield states in the Omarchy bar.
  • The adapter bounds, minimizes, and validates the result. The QML service independently bounds and validates the minimized document.
  • Audit scope is part of result identity. Changing the scope clears the old state immediately and rejects an in-flight result from the previous scope.
  • The plugin can open Omaudit's terminal review flow, but it never accepts baselines, modifies plugins, remediates findings, or requests elevation.

A green shield means Omaudit reported the tracked plugins unchanged under the configured scan scope, and both adapter layers accepted the status document. It is not proof that a plugin is safe or that every possible risk was detected.

That is why I built Omaudit Status as a narrow companion to Omaudit, not as another scanner. Omaudit remains the source of truth for capability discovery, grades, scores, baselines, and drift. The plugin's job is to transport a trustworthy summary into the Omarchy bar.

A capability finding is not a malware verdict
Plugins run with the current user's permissions. A capability signal tells you what deserves review. It does not prove that a plugin is malicious, safe, sandboxed, or approved.

Omaudit scans; the plugin transports the result

Omaudit performs the capability inspection. Omaudit Status invokes it with a fixed argument list, receives the machine-readable result, checks the document, limits what reaches the interface, and shares the same summary across monitors. The widget does not inspect plugin source code itself.

Code
Omaudit CLI
    | fixed argv + bounded pipes
    v
Python validation adapter
    | minimized ASCII-safe JSON
    v
singleton Quickshell service
    |              |
monitor 1      monitor 2
    \              /
       review popup
ShieldMeaning
GreenTracked plugins are unchanged under the current audit scope.
AmberA plugin is not tracked or still needs baseline review.
RedCapability drift or a composition risk requires review.
Dim/errorOmaudit is unavailable, timed out, overflowed, or returned invalid evidence.

The popup adds totals for unchanged, changed, not-tracked, and composition-risk results, the worst current grade, and a limited worst-first list. A composition risk is Omaudit's signal that a combination of capabilities deserves review; Omaudit Status does not invent that finding. Aggregate totals still cover the full scan even when only the most important rows are displayed.

The first security bug was not a scanner bug. It was an allocation bug

The initial 0.1.0 implementation collected complete Omaudit stdout and stderr before parsing, then let QML accumulate the adapter output again. A plugin-controlled audit result could therefore consume unbounded memory before any later display limit mattered.

Version 0.1.1 fixes the boundary at each layer instead of relying on one final slice.

  • The adapter drains Omaudit through bounded pipes with an 8 MiB stdout ceiling and 64 KiB stderr ceiling.
  • A scan has a 120-second timeout. Overflow or timeout terminates the complete process group on supported Linux systems.
  • Saved fixture input is held to the same 8 MiB input ceiling.
  • The adapter validates and minimizes the document before emitting ASCII-safe JSON.
  • QML consumes output incrementally, discards stderr without retaining it, and caps the minimized adapter document at 2 MiB characters.
  • Overflow, malformed data, contradictory totals, duplicate identities, unsupported grades, and invalid evidence all become a visible error state.
A display limit is not an ingestion limit
Showing only 100 rows does not protect memory if the process already captured a huge untrusted document. Bound the stream before parsing, then bound the normalized output again before rendering.

The harder bug: a result can be correct and still belong to the wrong policy

Omaudit Status audits third-party plugins by default. Users can opt into first-party plugins with `omaudit check --json --all`. During physical testing, changing that setting persisted the new scope but left the old one-plugin result visible until a manual refresh. The number was valid for the old policy and misleading for the new one.

This is a configuration-generation race. In plain terms, a scan is a question and its result is an answer. If the question changes while the answer is being prepared, the old answer cannot be displayed as though it answered the new question.

Code
generation 12: third-party scope ---- scan running ----X reject
                         setting changes
                         old state cleared
generation 13: all plugins ---------------------> publish
  • The configured audit scope is part of scan identity.
  • A scope change increments the generation and clears the prior result immediately.
  • The active scan records the generation and scope it started with.
  • Normal completion and overflow handling both check that identity before publication.
  • If configuration changes during a scan, one replacement scan is queued after the active process exits. Scans never overlap.
  • Quattro bar configuration changes are bridged back into the singleton service after the host reinjects the new widget settings.

This rule matters beyond security tools. Any UI that summarizes evidence under configurable scope, filters, paths, tenants, or thresholds should bind the result to the exact configuration that produced it.

One service, two monitors, zero duplicate scanners

Quickshell can render the same bar widget on multiple monitors. Starting one audit process per widget would waste work and create inconsistent race windows. Omaudit Status uses one keep-loaded service for scanning and state. Each monitor resolves that service and renders the same document.

Ordinary refresh requests during an active scan are ignored, so scans do not overlap. If the audit scope changes during a scan, one replacement run is queued after completion.

The plugin is intentionally unable to fix what it finds

  • No automatic baseline acceptance.
  • No plugin disable, removal, update, or remediation.
  • No telemetry or network service.
  • No privilege elevation.
  • No claim to sandbox plugins or detect malware.
  • The terminal review button opens Omaudit's own review flow without accepting decisions on the user's behalf.

That limitation is useful. A status surface should make risk visible and lead the operator to evidence. It should not quietly cross from observation into mutation.

Install the companion after installing Omaudit

Omaudit Status requires Omarchy 4 with Quattro, Python 3.11 or newer, and Omaudit v0.1.0 or newer available on `PATH`. It does not install or update Omaudit for you.

Code
omarchy plugin add https://github.com/godhiraj-code/omarchy-omaudit-status --enable --yes

Click the shield to open the review popup. Middle-click, right-click, or press `R` in the popup to refresh. First-party auditing is off by default because stock Omarchy components legitimately use broad shell capabilities and can dominate the initial review.

Release checks

Version 0.1.1 was validated with the official Omarchy plugin validator, real default and `--all` Omaudit scans, 38 Python contract and lifecycle tests, adversarial JavaScript status-model tests, Linux shell syntax checks, and Git whitespace checks.

A physical two-monitor Omarchy 4/Quattro run confirmed the green, amber, red, and error states, real default and expanded-scope scans, one shared service across monitors, and nonoverlapping refresh behavior.

The reusable engineering lesson

  • Security or compliance checks that need an ambient desktop signal without moving policy decisions into the widget.
  • Multi-monitor environments where every surface must share one current result.
  • Adapters that process tool-controlled or plugin-controlled output and need hard stream ceilings.
  • Any configurable scan where an older answer must be rejected after scope changes.
  • Review workflows where observation should remain separate from remediation.
When the shield should go dim
If the result is too large, malformed, stale for the current scope, or tied to an older configuration, show an error and ask for review. A reassuring state is not worth preserving after its assumptions change.

The complete implementation, threat model, verification commands, and installation guide are available in the Omaudit Status repository. Omaudit itself remains available from the official Omaudit repository.

Dhiraj Das

About the Author

Dhiraj Das | Automation Consultant | 10+ years building automation systems that expose failures, reduce flakiness, and make complex workflows repeatable. He now applies that discipline independently to AI-agent validation, run replay, LLM testing, and postmortems.

He shares small open source utilities from real automation work, including: waitless (flaky tests), sb-stealth-wrapper (bot detection), selenium-teleport (state persistence), selenium-chatbot-test (AI chatbot testing), lumos-shadowdom (Shadow DOM), and visual-guard (visual regression).

Share this article: