Update Cua plugin to qualified stable profile kit

This commit is contained in:
Francesco Bonacci committed 2026-09-12 16:42:57 -05:00
1 parent eec9dcef03
commit 56adc00bb9
3 files changed
+265 -110

No files matched your search

@@ -1,5 +1,6 @@
{ {
"source": "local", "source": "local",
"release_ring": "fast", "release_ring": "fast",
"channels": ["stable"],
"skip_build": true "skip_build": true
} }
+102 -27
View File
@@ -1,36 +1,110 @@
# Generated from an explicit committed revision. No checkout is needed. # Separately reviewed download wrapper; original kit and source identity are unchanged.
# Normal reruns need a fresh build directory; makepkg -e reuses verified extracted trees.
# Profile kit: original source bytes and separately committed packaging tooling.
# shellcheck shell=bash disable=SC2034,SC2154 # shellcheck shell=bash disable=SC2034,SC2154
pkgname=cua-hyprland-plugin pkgname=cua-hyprland-plugin
pkgver=0.24.0 pkgver=0.26.1
pkgrel=1 pkgrel=2
pkgdesc='Cua production input candidate for pinned Hyprland 0.56.2' pkgdesc='Cua input candidate for reviewed profile omarchy-stable-20260910'
arch=('x86_64') arch=('x86_64')
url='https://github.com/trycua/cua' url='https://github.com/trycua/cua'
license=('MIT') license=('MIT')
depends=('hyprland=0.56.2-1' 'gcc-libs') depends=('hyprland=0.56.2-2' 'aquamarine=0.15.0-2' 'glibc=2.44+r24+g16be1518495f-1' 'hyprcursor=0.1.13-7' 'hyprgraphics=0.5.1-4' 'hyprlang=0.6.8-5' 'hyprutils=0.14.2-1' 'libgcc=16.2.1+r23+gd564253eb6c8-1' 'libstdc++=16.2.1+r23+gd564253eb6c8-1' 'libxkbcommon=1.13.2-1' 'wayland=1.26.0-1' 'python>=3.11' 'binutils')
makedepends=('cmake>=3.30' 'ninja' 'pkgconf' 'binutils' 'python>=3.11' 'gcc') makedepends=('cmake>=3.30' 'ninja' 'pkgconf' 'gcc')
options=('!strip' '!debug' '!lto') options=('!strip' '!debug' '!lto')
_revision='4b3396d9fe4bd3cf723b0eb8db83c18a8764b520' _stem='cua-hyprland-plugin-0.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7'
_stem='cua-hyprland-plugin-0.24.0-4b3396d9fe4bd3cf723b0eb8db83c18a8764b520' _archive_sha256='47bca9e018f32f4fcfe683f91c7475c60368f3b65d318cc35c1f2de88a4ee9ab'
_archive_sha256='73b65823b3281c027a31cd8f7d9ca9586fe7386ed1eec74174f2e72cea0af643' _kit_sha256='7beb736adfd334eed52e84070177634269e3a09f8bb25971b38606933ff4c997'
_manifest_sha256='fb5b5710218afecfa54e9803e8e95f4702e8a47ac4108abd06b4f5f3c1032eeb' _profile_sha256='5dacea79a6a5927e59fca7b51e6c04e94fa45133ac1b8fb7f4e1f442d113eb9a'
source=("https://github.com/trycua/cua/releases/download/cua-driver-rs-v${pkgver}/${_stem}.tar.gz") _verifier_sha256='480f649cbd35a0ddc7f49dc0a3a44785402c9e0ec9653b0f8ea4965d52d7f900'
sha256sums=('73b65823b3281c027a31cd8f7d9ca9586fe7386ed1eec74174f2e72cea0af643')
_cxx="${CUA_RELEASE_CXX:-/usr/bin/g++}" _cxx="${CUA_RELEASE_CXX:-/usr/bin/g++}"
_download_name='cua-hyprland-plugin-0.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7-profile-omarchy-stable-20260910-kit-1.1.0-5dacea79a6a5927e59fca7b51e6c04e94fa45133ac1b8fb7f4e1f442d113eb9a-67f89ceb47edd973aa748820eadd02ddbfb3d3e4.tar.gz'
_download_sha256='a89bfa7f6490f598719dfabdd2a5badc137e27b0764fd25e6a05e1f969433520'
source=('https://github.com/trycua/cua/releases/download/cua-hyprland-kit-v1.1.0-omarchy-stable-20260910/cua-hyprland-plugin-0.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7-profile-omarchy-stable-20260910-kit-1.1.0-5dacea79a6a5927e59fca7b51e6c04e94fa45133ac1b8fb7f4e1f442d113eb9a-67f89ceb47edd973aa748820eadd02ddbfb3d3e4.tar.gz')
noextract=("$_download_name")
sha256sums=('a89bfa7f6490f598719dfabdd2a5badc137e27b0764fd25e6a05e1f969433520')
_verify_download() {
python3 -I - "$SRCDEST/$_download_name" "$_download_sha256" "$srcdir" "$1" <<'CUA_DOWNLOAD_PY'
import hashlib
import io
from pathlib import Path, PurePosixPath
import sys
import tarfile
expected = {'KIT-PROVENANCE.json': '7beb736adfd334eed52e84070177634269e3a09f8bb25971b38606933ff4c997', 'PKGBUILD': 'b945a6a6eda13d0e382770edd5419485e3196041956663eb38f5183b05d30db3', 'PROFILE-PKGBUILD.in': 'c350d1b2375946cb0166893d67a1fc01344ee5e3215bbe801b4d54bb361d6bce', 'PROFILE-USAGE.md': 'c14d8e8103fccab59e558758f4249f86bce700a8723cd4ba1b97b1102e02bbd2', 'PROFILE.json': '5dacea79a6a5927e59fca7b51e6c04e94fa45133ac1b8fb7f4e1f442d113eb9a', 'SHA256SUMS': '34a2126bcfab983f171382aafac3ef218475b652f4583c58f4a04088044cb935', 'SOURCE-PROVENANCE.json': '54f514664c84e1358a435f29cd6befd5661b0b133d76997191c000b10f021a75', 'cua-hyprland-plugin-0.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7.tar.gz': '47bca9e018f32f4fcfe683f91c7475c60368f3b65d318cc35c1f2de88a4ee9ab', 'lifecycle.py': 'b18dceb8b8e05b93586ddd3a2f1d90d70ae1c36088e54fc05c89e08585290990', 'profile_bundle.py': 'ac883883814787da477c037f017939ee92c9fb5f46f373af7de1331b24f1f6da', 'profile_verify.py': '480f649cbd35a0ddc7f49dc0a3a44785402c9e0ec9653b0f8ea4965d52d7f900'}
stem = 'cua-hyprland-plugin-0.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7'
def require(condition, message):
if not condition:
raise SystemExit(message)
def digest(data):
return hashlib.sha256(data).hexdigest()
archive, checksum, srcdir, mode = sys.argv[1:]
archive, srcdir = Path(archive), Path(srcdir)
require(mode in {'check', 'extract'}, 'invalid kit verification mode')
require(archive.is_file() and not archive.is_symlink(), 'outer archive must be a regular file')
data = archive.read_bytes()
require(digest(data) == checksum, 'outer archive checksum mismatch')
payload = {}
with tarfile.open(fileobj=io.BytesIO(data), mode='r:gz') as contents:
for member in contents:
require(member.isfile() and not member.issparse() and not member.pax_headers,
'nonregular outer kit member')
require(member.name in expected and member.name not in payload, 'outer kit inventory mismatch')
content = contents.extractfile(member).read()
require(digest(content) == expected[member.name], 'outer kit member checksum mismatch')
payload[member.name] = content
require(payload.keys() == expected.keys(), 'outer kit inventory mismatch')
require(srcdir.is_dir() and not srcdir.is_symlink(), 'srcdir must be a real directory')
kit, source = srcdir / 'cua-profile-kit', srcdir / stem
if mode == 'extract':
require(not kit.exists() and not kit.is_symlink() and not source.exists() and not source.is_symlink(),
'prepare requires fresh kit and source destinations; use a clean srcdir')
source_payload = {}
with tarfile.open(fileobj=io.BytesIO(payload[stem + '.tar.gz']), mode='r:gz') as contents:
for member in contents:
require(member.isfile() and not member.issparse() and not member.pax_headers and
member.name.startswith(stem + '/'), 'invalid source member')
name = member.name[len(stem) + 1:]
path = PurePosixPath(name)
require(name and path.as_posix() == name and not path.is_absolute() and
'..' not in path.parts and '\\' not in name and name not in source_payload,
'unsafe or duplicate source path')
source_payload[name] = contents.extractfile(member).read()
kit.mkdir()
source.mkdir()
for name, content in payload.items():
(kit / name).write_bytes(content)
for name, content in source_payload.items():
destination = source / name
destination.parent.mkdir(parents=True, exist_ok=True)
destination.write_bytes(content)
require(kit.is_dir() and not kit.is_symlink(), 'kit must be a real directory')
require({path.name for path in kit.iterdir()} == expected.keys(), 'extracted kit inventory mismatch')
for name, checksum in expected.items():
path = kit / name
require(path.is_file() and not path.is_symlink() and digest(path.read_bytes()) == checksum,
'extracted kit checksum mismatch: ' + name)
CUA_DOWNLOAD_PY
}
_verify() { _verify() {
# Recheck even when makepkg --skipinteg or --noextract was requested. printf '%s %s\n' "$_download_sha256" "$SRCDEST/$_download_name" | sha256sum -c - || return 1
printf '%s %s\n' "$_archive_sha256" "$SRCDEST/${_stem}.tar.gz" | sha256sum -c - || return 1 _verify_download check || return 1
printf '%s %s\n' "$_manifest_sha256" "$srcdir/$_stem/SOURCE-PROVENANCE.json" | sha256sum -c - || return 1 # Explicit checks still apply to --skipinteg, --noextract and --repackage.
local verifier_sha printf '%s %s\n' "$_archive_sha256" "$srcdir/cua-profile-kit/${_stem}.tar.gz" | sha256sum -c - || return 1
verifier_sha="$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["files"]["verify.py"])' \ printf '%s %s\n' "$_kit_sha256" "$srcdir/cua-profile-kit/KIT-PROVENANCE.json" | sha256sum -c - || return 1
"$srcdir/$_stem/SOURCE-PROVENANCE.json")" || return 1 printf '%s %s\n' "$_profile_sha256" "$srcdir/cua-profile-kit/PROFILE.json" | sha256sum -c - || return 1
printf '%s %s\n' "$verifier_sha" "$srcdir/$_stem/verify.py" | sha256sum -c - || return 1 printf '%s %s\n' "$_verifier_sha256" "$srcdir/cua-profile-kit/profile_verify.py" | sha256sum -c - || return 1
python3 "$srcdir/$_stem/verify.py" --source "$srcdir/$_stem" \ python3 "$srcdir/cua-profile-kit/profile_verify.py" --kit "$srcdir/cua-profile-kit" --kit-sha256 "$_kit_sha256" \
--revision "$_revision" --driver-version "$pkgver" --cxx "$_cxx" "$@" --archive "$srcdir/cua-profile-kit/${_stem}.tar.gz" --source "$srcdir/$_stem" --cxx "$_cxx" "$@"
} }
prepare() { prepare() {
_verify_download extract || return 1
_verify _verify
} }
@@ -38,6 +112,8 @@ build() {
_verify || return 1 _verify || return 1
cmake -S "$srcdir/$_stem" -B "$srcdir/build" -G Ninja \ cmake -S "$srcdir/$_stem" -B "$srcdir/build" -G Ninja \
-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER="$_cxx" \ -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER="$_cxx" \
-DPKG_CONFIG_EXECUTABLE=/usr/bin/pkgconf -DPKG_CONFIG_ARGN= \
-DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=OFF -DCMAKE_PREFIX_PATH= \
-DBUILD_TESTING=ON -DCUA_HYPRLAND_BUILD_PLUGIN=ON \ -DBUILD_TESTING=ON -DCUA_HYPRLAND_BUILD_PLUGIN=ON \
-DCUA_HYPRLAND_EXPECTED_VERSION=0.56.2 \ -DCUA_HYPRLAND_EXPECTED_VERSION=0.56.2 \
-DCUA_HYPRLAND_INPUT=ON -DCUA_HYPRLAND_TEST_INPUT=OFF \ -DCUA_HYPRLAND_INPUT=ON -DCUA_HYPRLAND_TEST_INPUT=OFF \
@@ -47,9 +123,6 @@ build() {
check() { check() {
_verify || return 1 _verify || return 1
# package() runs under fakeroot, whose getuid() shim disagrees with kernel
# SO_PEERCRED. Test the real same-user boundary without changing the parent
# packaging environment or skipping the mandatory packaging-time test run.
( (
unset LD_PRELOAD FAKEROOTKEY FAKED_MODE unset LD_PRELOAD FAKEROOTKEY FAKED_MODE
ctest --test-dir "$srcdir/build" --output-on-failure --no-tests=error ctest --test-dir "$srcdir/build" --output-on-failure --no-tests=error
@@ -57,7 +130,6 @@ check() {
} }
package() { package() {
# Packaging always runs the tests, including makepkg --nocheck / --repackage.
check || return 1 check || return 1
_verify --build "$srcdir/build" --output "$srcdir/BUILD-PROVENANCE.json" || return 1 _verify --build "$srcdir/build" --output "$srcdir/BUILD-PROVENANCE.json" || return 1
install -Dm755 "$srcdir/build/cua-hyprland-plugin.so" \ install -Dm755 "$srcdir/build/cua-hyprland-plugin.so" \
@@ -66,6 +138,9 @@ package() {
"$pkgdir/usr/share/licenses/$pkgname/LICENSE" || return 1 "$pkgdir/usr/share/licenses/$pkgname/LICENSE" || return 1
install -Dm644 "$srcdir/$_stem/SOURCE-PROVENANCE.json" \ install -Dm644 "$srcdir/$_stem/SOURCE-PROVENANCE.json" \
"$pkgdir/usr/share/$pkgname/SOURCE-PROVENANCE.json" || return 1 "$pkgdir/usr/share/$pkgname/SOURCE-PROVENANCE.json" || return 1
install -Dm644 "$srcdir/BUILD-PROVENANCE.json" \ local name
"$pkgdir/usr/share/$pkgname/BUILD-PROVENANCE.json" install -Dm644 "$srcdir/BUILD-PROVENANCE.json" "$pkgdir/usr/share/$pkgname/BUILD-PROVENANCE.json" || return 1
for name in KIT-PROVENANCE.json PROFILE.json profile_verify.py; do
install -Dm644 "$srcdir/cua-profile-kit/$name" "$pkgdir/usr/share/$pkgname/$name" || return 1
done
} }
+162 -83
View File
@@ -1,103 +1,182 @@
# Optional Cua Hyprland plugin # Optional Cua Hyprland plugin
This package builds the optional Cua input plugin separately from Cua Driver. This package targets **Omarchy stable x86_64**, with Inkscape `1.4.4-6` and
It does not add the plugin to the Omarchy installation or change the Driver two independent background-input lanes. Cua's native qualification is recorded
package. The recipe is copied unchanged from the published Cua Driver 0.24.0 in [the kit's qualification record](https://github.com/trycua/cua/releases/download/cua-hyprland-kit-v1.1.0-omarchy-stable-20260910/QUALIFICATION.md)
build kit, including its source checks, mandatory tests, and ABI checks. and [Cua #3698](https://github.com/trycua/cua/pull/3698). Omabot replay and
Omarchy's explicit merge, signing, and publication decisions remain required.
Keep `skip_build: true` until those gates pass.
The package is in the fast release ring with `skip_build: true`. This keeps it The plugin is optional. Cua Driver works independently, and installation does
out of unscoped builds while maintainers qualify the pinned environment. not load the plugin or enable input. Metadata restricts the initial destination
An explicit package build remains available. Fast-ring membership does not to `channels: ["stable"]`; `release_ring: fast` permits a native package build.
establish compatibility: edge, rc, and stable use separate build environments, Edge, RC, and ARM publication are outside this initial scope.
and each must satisfy the exact contract before publication there.
## Source and ABI contract ## Source and build profile
The authoritative release is The package uses the [Driver 0.26.1 plugin source](https://github.com/trycua/cua/releases/tag/cua-driver-rs-v0.26.1),
[cua-driver-rs-v0.24.0](https://github.com/trycua/cua/releases/tag/cua-driver-rs-v0.24.0), including the [desktop-fault cleanup repair](https://github.com/trycua/cua/pull/3702).
at source revision `4b3396d9fe4bd3cf723b0eb8db83c18a8764b520`. It is not a repackaging of the unmodified 0.24.0 plugin. The Driver client
Both archives use the stem pairing qualified for this package remains `cua-driver-bin 0.24.0-1`, with
`cua-hyprland-plugin-0.24.0-4b3396d9fe4bd3cf723b0eb8db83c18a8764b520`. input protocol v3. Discovery protocol v2 is separate.
The release's `checksums.txt` records these SHA-256 values:
| Artifact | SHA-256 | Profile `omarchy-stable-20260910`, kit `1.1.0`, and package release `2` pin:
| --- | --- |
| Source (`.tar.gz`) | `73b65823b3281c027a31cd8f7d9ca9586fe7386ed1eec74174f2e72cea0af643` |
| Build kit (`-build-kit.tar.gz`) | `f91a7b61a39f0efdcee9558eb6725fe864340e8eacf940346499222afe7f7869` |
The supported environment is Linux x86_64, `hyprland=0.56.2-1`, headers - Hyprland `0.56.2-2`, headers `0.56.2`, and measured executable/header hashes.
`0.56.2`, GCC `16.1.1 20260728`, and shared `libstdc++.so.6.0.36`. - GCC `16.2.1 20260810`, including compiler bytes and emitted ELF identity.
The compiler probe and compositor must carry the exact GCC ELF comment; the - Shared runtime `libstdc++.so.6.0.36`, its bytes, and exact ABI package versions.
compiler, compositor, and module must resolve identical runtime bytes. The
recipe rejects mismatches. `gcc-libs` alone is not proof of runtime compatibility.
There is no qualified ARM build.
Production input is enabled at build time. Experimental signed input and The generated `PKGBUILD` identifies the immutable kit download, outer checksum,
tracing are disabled. Source and build provenance are installed with the module. and member checksums. The kit records the full source and tooling revisions,
The build requires CMake 3.30 or later and Python 3.11 or later. The default profile digest, and source archive/manifest digests. Do not infer compatibility
compiler is `/usr/bin/g++`; an absolute `CUA_RELEASE_CXX` path can select an from a matching version label or substitute an unreviewed profile.
already provisioned matching compiler without bypassing runtime checks.
The package does not provision a compiler or change runtime search paths.
## Review and qualify The download wrapper verifies its complete inventory before executing downloaded
tooling. It preserves the source archive and its historical embedded verifier,
but explicitly uses the new kit's `profile_verify.py`. Source integrity,
package-owned headers, pkg-config selection, compiler probes, runtime equality,
and production flags remain mandatory. Packaging runs all bundled CTests even
with `--nocheck` or `--repackage`; `--skipinteg` does not bypass recipe checks.
Production input is built in; experimental signed input and tracing are off.
Download both archives and `checksums.txt` from the exact release. Verify the ## What is qualified
archive hashes before extracting the kit, then verify its `SHA256SUMS` with the
source archive alongside it. Compare this package's `PKGBUILD` byte for byte
with the kit's recipe. Follow the kit's operator README and
[release packaging instructions](https://github.com/trycua/cua/blob/4b3396d9fe4bd3cf723b0eb8db83c18a8764b520/libs/cua-driver/hyprland-plugin/packaging/release/README.md).
Before enabling scheduled builds or publishing a package, maintainers need: The initial app scope is native Wayland Inkscape `1.4.4-6` with the canonical
US keymap. Two lanes require independent Driver processes and distinct native
application clients, not merely two windows. This is concurrency inside one
desktop account, not multi-user or mutually untrusted-agent isolation.
1. A native build in each intended channel's pinned x86_64 environment, with Cua's retained evidence covers background application effects, two-lane overlap,
all bundled tests passing and the packaged ELF dependencies and provenance third-owner refusal, primary-input preservation, conflicts, stale targets and
inspected. An unsigned, explicitly scoped repository build is geometry, cancellation, desktop faults, recovery, and cold package transitions.
`bin/repo build --package cua-hyprland-plugin --arch x86_64 --mirror edge`. Production-package app checks and independent primary observers are separate
Repeat with the intended channel only when its environment matches. from trace-enabled diagnostics. The complete native Linux runner passed all
2. The kit's `lifecycle.py` gate in a disposable pinned Arch environment, 128 required cells: 87 deliveries and 41 expected refusals, with no failures
including installation, removal, reinstallation, and refusal with a different or skips. That runner used source-built released Driver 0.24.0; the real-app
Hyprland package. That gate uses isolated ALPM roots and metadata dependency checks separately used the actual Omarchy `cua-driver-bin 0.24.0-1` executable.
fixtures; it does not prove live activation. See the linked qualification record for exact artifacts and observation limits.
3. Fresh-session activation and representative supported input, then upgrade,
rollback, and removal across compositor restarts. Retain evidence for the
exact package, source revision, compositor, compiler, and runtime.
Static review and download verification do not establish these native results. Duplicate motion notifications are retained and counted. They are acceptable
The source manifest's `native_certified: false` describes the generator's only when pointer identity, coordinates, focus, held input, and foreground
scope; separate native evidence must establish runtime qualification. interaction remain unchanged. Actual motion—including moving away and back—
fails isolation. After cancellation, an inert agent pointer may remain parked
if held input is released and authority is revoked.
## Update policy Current LibreOffice Calc `26.8`, Chromium/Electron raw background input,
XWayland, Unicode/IME, non-US layouts, and modified pointer gestures are outside
this profile. The plugin does not widen Driver's application admission.
Foreground input, capture, and accessibility have separate contracts; a
background refusal never authorizes a hidden foreground fallback or unlock.
Updates are explicit maintainer changes. There is no upstream polling hook, ## Omabot replay before merge
AUR synchronization, or automatic `rebuild_on` bump. Do not use Omarchy's
`pinned` metadata flag here: it controls the Omarchy release pair's rc branch
workflow, not native ABI compatibility.
For an update, select an exact Cua Driver component tag, download its matching Use the unsigned, explicitly scoped build command:
source and build kit, verify published checksums, and review the recipe and
manifest together. Replace the recipe and update this record only after reviewing
the new ABI contract. A Driver release alone does not qualify its plugin for
a changed compositor. Keep `skip_build` enabled until the required channel
evidence is available; removing it is a separate publication decision.
Do not widen the Hyprland dependency or remove compiler/runtime checks to ```sh
accommodate channel drift. If a channel cannot provide the pins, keep the bin/repo build --package cua-hyprland-plugin --arch x86_64 --mirror stable
plugin unavailable there and use Driver without this plugin. An installed ```
plugin's exact dependency can block a compositor upgrade; remove the plugin
using the restart procedure before moving to an incompatible environment.
## Activation and removal In a fresh worker matching the reviewed profile:
The package installs only the module, license, and provenance. It has no install 1. Verify the downloaded kit and source identities against the reviewed recipe.
hooks, autoloading, configuration edits, or hot replacement. Follow the Record the actual channel snapshot, Driver, compiler, compositor, runtime,
[pinned operator guide](https://github.com/trycua/cua/blob/4b3396d9fe4bd3cf723b0eb8db83c18a8764b520/libs/cua-driver/hyprland-plugin/packaging/release/USAGE.md) applications, keymap, and resulting package/module hashes.
for deliberate loading, input enablement, status checks, and supported apps. 2. Require all bundled tests and native compatibility checks. Do not weaken
Loading the module alone does not enable its input transport. exact dependencies or replace the compositor to make the build pass.
3. Install through pacman and activate in a fresh session. Replay the declared
app, two-lane, refusal, primary-input, cancellation, and fault/recovery checks
against the actual packaged Driver and module. A Cua Fleet result is not an
Omabot result; matching source alone does not certify different binaries.
4. Verify restart-based upgrade, rollback, removal, and reinstallation. Retain
evidence that binds each result to the package and mapped module bytes.
Before installing or upgrading, save your work and exit Hyprland. Install from Portable tests, screenshots, health reports, and a successful build do not
a text console, start a fresh session, and deliberately activate and verify the replace native qualification. Recheck the published Driver package before
module. Keep the prior package and its matching environment for rollback. rollout and qualify any changed pairing explicitly.
Before removal, remove any operator-added load and enable settings, exit
Hyprland, and remove the package from a text console. Start a fresh session ## Activation, updates, and removal
afterward. Upgrade, rollback, and removal require compositor restart; do not
hot-unload/reload the module or force installation past its dependency pin. The package installs the module at
`/usr/lib/cua/hyprland/cua-hyprland-plugin.so` and provenance plus the consumer
verifier under `/usr/share/cua-hyprland-plugin/`. There are no hooks, autoloading,
configuration edits, or hot replacement.
Save your work and exit Hyprland before installing, replacing, or removing the
package. Install the exact reviewed package from a text console, then start a
fresh session. Before loading, run the consumer check with the independently
reviewed kit-provenance digest from the qualification record:
```sh
python3 /usr/share/cua-hyprland-plugin/profile_verify.py \
--kit /usr/share/cua-hyprland-plugin \
--kit-sha256 7beb736adfd334eed52e84070177634269e3a09f8bb25971b38606933ff4c997 \
--consumer /usr/lib/cua/hyprland/cua-hyprland-plugin.so
```
This check requires Python 3.11+, binutils `readelf`, and system `ldd`/`pacman`,
not a compiler or headers. If it fails, leave the plugin unloaded. It verifies
installed compatibility, not runtime mapping or input effects.
After that check passes in the fresh session, load the module explicitly:
```sh
hyprctl plugin load /usr/lib/cua/hyprland/cua-hyprland-plugin.so
hyprctl -j cua:status
```
Loading alone does not enable input. To enable the trusted local transport,
add this setting to Omarchy's Lua configuration:
```lua
hl.config({plugin = {cua = {enabled = true}}})
```
Run `hyprctl reload`, then inspect `hyprctl -j cua:status` again. A runtime
keyword or Lua evaluation without a configuration reload does not reconcile
the input sockets. Verify input protocol v3, input capability, socket paths, and
compositor identity before starting Driver with
`CUA_DRIVER_RS_ENABLE_WAYLAND=1`. Verify a supported background action through
fresh Driver snapshots and the saved application result. Do not automatically
replay an action with a partial or unknown outcome.
To disable input, set the enabling value to false (or remove it) and run
`hyprctl reload`. Retained inert agent pointers can remain until the compositor
exits; disabling input does not unload the mapped module.
Before an incompatible desktop update, remove operator-added plugin activation
settings, save work, and exit the graphical session. From a text console, run
`sudo pacman -R cua-hyprland-plugin`, then apply the normal desktop update and
verify a fresh session without the plugin. Declining removal preserves the
dependency refusal. Disabling input alone leaves exact dependencies installed;
do not force an upgrade past them.
Retain the previous package with its matching compositor, runtime, Driver, and
provenance as a rollback set. Restore a consistent set outside the graphical
session, then repeat the fresh-session consumer and app checks. Do not hot
unload/reload or replace a mapped module.
## Ownership and publication
The [agreed ownership split](https://github.com/omacom/omarchy-pkgs/pull/346#issuecomment-5612834061)
assigns profiles, build kits, plugin fixes, and native input evidence to Cua.
Francesco (@f-trycua) is the Cua contact through this PR. Omarchy owns package
integration, dependency-change detection, Omabot validation, and signing and
publication decisions. Omarchy must name its package/release owner before
rollout. Maintenance is best effort, with no turnaround commitment.
Edge detects upcoming incompatibilities; RC validates the intended stable
environment. Mirror/channel changes and changes to ABI dependencies, Driver,
or admitted apps request a new candidate and affected qualification. They do
not establish compatibility or authorize additional publication channels.
`skip_build` controls selection, not publication authority. This package has no
upstream polling, AUR synchronization, or automatic rebuild bump. After replay
and explicit merge approval, the named Omarchy owner must deliberately sign
and publish the validated bytes. `bin/repo release` rebuilds before publication;
`push` and `upload-prebuilt` also publish. None supplies native qualification.
Do not silently substitute newly rebuilt bytes during signing/publication.
Finally, install the signed published package on a fresh consumer, verify its
signature and package/module digests, and perform a short activation,
background-action, and cleanup smoke. Broader channels or unattended publishing
require an enforced artifact-to-evidence gate, including prebuilt uploads.